Before to converting the BASIC Computer Game of Awari, I figured that the person that had converted three games from BASIC to JavaScript might have stopped there because it got more difficult. As such, it would make sense for me to do a few others first before jumping in to that one.

Since he started converting games from A, and I have already downloaded the BASIC source code from all of the games at Vintage BASIC Games, there are a couple of other games before A called 23 Matches and 3D Plot. These look to be good material for me to start learning about the conversion process.

The already converted games at BASIC Games to JavaScript use a ConsoleWindow object to simulate the old-style screen. It makes sense for me to use carry on using that instead of reinventing the wheel, which I’ve done at the following codePen page: http://codepen.io/pmw57/full/dvRYRZ/

brphyvv

Here is a sample of some of the BASIC code from before the conversion process.

300 PRINT "HOW MANY DO YOU WISH TO REMOVE",
310 INPUT K
320 IF K > 3 THEN 430
330 IF K <= 0 THEN 430
340 N = N - K
350 PRINT "THERE ARE NOW";N;"MATCHES REMAINING."
...
430 PRINT "VERY FUNNY! DUMMY!"
440 PRINT "DO YOU WANT TO PLAY OR GOOF AROUND?"
450 PRINT "NOW, HOW MANY MATCHES DO YOU WANT",
460 GOTO 310

When converting the BASIC code to JavaScript, the first thing to do is to remove the unused line numbers, so that it’s easier to use the remaining numbered lines to understand how to use the GOTO statements (and THEN numbers) to properly structured code.

PRINT "HOW MANY DO YOU WISH TO REMOVE",
310 INPUT K
IF K > 3 THEN 430
IF K <= 0 THEN 430
N = N - K
PRINT "THERE ARE NOW";N;"MATCHES REMAINING."
...
430 PRINT "VERY FUNNY! DUMMY!"
PRINT "DO YOU WANT TO PLAY OR GOOF AROUND?"
PRINT "NOW, HOW MANY MATCHES DO YOU WANT",
GOTO 310

Here, the if statements can be put together in to one single combined statement (using an OR condition). The code from 430 can be placed inside of that if statement, so long as we loop from the end back up to line 310. We can use a do/while loop to achieve that.

I found it invaluable to create a separate in-between version of the code, using proper structure with some of the line numbers moved to statements, to help make it easier to compare between the original code and the desired converted code.

PRINT "HOW MANY DO YOU WISH TO REMOVE", // 300
do {
  INPUT K // 310
  IF (K <= 0 || K > 3) {
    PRINT "VERY FUNNY! DUMMY!" // 430
    PRINT "DO YOU WANT TO PLAY OR GOOF AROUND?"
    PRINT "NOW, HOW MANY MATCHES DO YOU WANT",
  }
} while (K <= 0 || K > 3);
N = N - K // 340
PRINT "THERE ARE NOW";N;"MATCHES REMAINING."
...

We can also change the print statements to use the ConsoleWindow with con.write or con.writeLine, depending on if a newline is required at the end of the output, and use lowercase for the rest of the statements and variables.

I feel that I also have to updated ConsoleWindow so that numbers are properly handled. BASIC adds a space before positive numbers where the negative sign would be, and also adds a space after the number. I don’t want to do that every time on lines that use numbers, so instead I can give the number to ConsoleWindow and have it return the appropriately formatted number with correct padding.

The above goto statement returns you back to line 310, which is in effect a do/while loop that keeps on looping until a valid input is received.

con.write("HOW MANY DO YOU WISH TO REMOVE");
do {
    INPUT k
    if (k <= 0 || k > 3) {
        con.writeLine("VERY FUNNY! DUMMY!");
        con.writeLine("DO YOU WANT TO PLAY OR GOOF AROUND?");
        con.write("NOW, HOW MANY MATCHES DO YOU WANT");
    }
} while (k <= 0 || k > 3);
n = n - k;
con.writeLine("THERE ARE NOW" + con.num(n) + "MATCHES REMAINING.");
...

The only other thing that needs to be dealt with is the input statement. With the BASIC language, execution of the code stops when the input occurs, and only carries on when the input has been entered.

JavaScript though, is a non-blocking language. Things on the web page must be able to continue working without being blocked by the code, so a different technique needs to occur. Where we can still ask for the input, but we have to end the code there and then continue on with the execution of the code once the input has been received.

In order to achieve that we need to stop the above code at the input, and place the rest of it in a separate function starting from the if statement. Because the do statement cannot be split across different functions, we need to replace it with a different technique, that of using and calling different functions, and have the input in a separate function too, so that at the end of the code, we can tell it to start over from the start of the input.

function getMatchesToRemove() {
    con.write("HOW MANY DO YOU WISH TO REMOVE");
    getMatches();
}
function getMatches() {
    state = STATES.GET_MATCHES;
    con.readLine(commandDispatcher);
}
function setMatches(response) {
    IF (k <= 0 || k > 3) {
        con.writeLine("VERY FUNNY! DUMMY!");
        con.writeLine("DO YOU WANT TO PLAY OR GOOF AROUND?");
        con.write("NOW, HOW MANY MATCHES DO YOU WANT");
        return getMatches();
    }
    con.writeLine("THERE ARE NOW" + con.num(n) + "MATCHES REMAINING.");
    n = n - k;
    ...
}

The only other thing that we need to get this working, is to connect the getMatches() function with setMatches(). This can be done thanks to another feature from ConsoleWindow where after the con.readLine() command gains input, it passes the response to the commandDispatcher.

The commandDispatcher uses the state value to determine where to send the response. We can tell the command dispatcher to send the response where we need it, to the setInput() function, which will allow the execution of the code to carry on from that point.

var state = 0;
var states = {
    GET_MATCHES: 1
};
function commandDispatcher(response) {
    if (state === states.GET_MATCHES) {
        setTimeout(setInput(response), 0);
    }
}

I can tell already that the input situation is going to make things more difficult, because if the input is occurring within a for loop or other control structures, I’ll have to unwrap and remove all of those structures so that after the input, I can then carry on the code execution after that point.

There are better ways of obtaining this input via a webpage, but for the moment I’m going for a straight conversion, and once all 101 games have been converted I will then consider doing an improved version of the code for them.

In the meantime though, the converted code for 23 Matches can be explored over at http://codepen.io/pmw57/full/dvRYRZ/

Advertisements