GithubHelp home page GithubHelp logo

Comments (25)

lmorchard avatar lmorchard commented on June 22, 2024 4

FWIW, this is how I've been doing it for Super Star Trek:

Kind of hacked together, but seems to be working decently so far

from basic-computer-games.

lmorchard avatar lmorchard commented on June 22, 2024 3

Stating the obvious, but if we settled on a common setup for this sort of thing, it wouldn't be too hard to establish a project-wide web-based runner

from basic-computer-games.

LukasMurdock avatar LukasMurdock commented on June 22, 2024 3

FWIW @nanochess With the print() and input() functions you’ve already built out (in at least the first three, I haven’t looked further), adding a window check should enable them to work with both browsers and Node.js

// Determine if code is running in browser;
// by default there is no window object in Node.js.
const isRunningInBrowser = typeof window !== 'undefined';

And then a simple if enables both browser and Node.js

function print(string) {
    if (isRunningInBrowser) {
        // Adds trailing newline to match console.log behavior
        document
            .getElementById('output')
            .appendChild(document.createTextNode(string + '\n'));
    } else {
        console.log(string);
    }
}

function input() {
    if (isRunningInBrowser) {
        // Accept input from the browser DOM input
        return new Promise(function (resolve) {
            let input_element = document.createElement('INPUT');
            input_element.setAttribute('type', 'text');
            input_element.setAttribute('length', '50');
            document.getElementById('output').appendChild(input_element);
            input_element.focus();
            let input_str = undefined;
            input_element.addEventListener('keydown', function (event) {
                if (event.code === 'Enter') {
                    input_str = input_element.value;
                    document
                        .getElementById('output')
                        .removeChild(input_element);
                    print(input_str);
                    print('');
                    resolve(input_str);
                }
            });
        });
    } else {
        // Accept input from the command line in Node.js
        // See: https://nodejs.dev/learn/accept-input-from-the-command-line-in-nodejs
        return new Promise(function (resolve) {
            const readline = require('readline').createInterface({
                input: process.stdin,
                output: process.stdout,
            });
            readline.question('', function (input) {
                resolve(input);
                readline.close();
            });
        });
    }
}

As console.log comes with newlines, I changed print() to include newlines so the expected behavior is the same—but that means that to print without a newline requires another function

function printInline(string) {
    if (isRunningInBrowser) {
        document
            .getElementById('output')
            .appendChild(document.createTextNode(string));
    } else {
        process.stdout.write(string);
    }
}

As I’m writing this I realize I could have just used process.stdout.write in print()—but adding a newline character to every print statement is a bit of a slog.

from basic-computer-games.

domenic avatar domenic commented on June 22, 2024 3

I really like the style of the input/print functions I found in Acey Ducey. I rewrote them a bit to use modern JS idioms in #332, and factored them into their own module. But the overall style of preserving a "terminal-like" experience in the browser is very nice.

from basic-computer-games.

LukasMurdock avatar LukasMurdock commented on June 22, 2024 3

Something worth considering with modules is—as of current—if you try to load the HTML file locally (i.e. with a file:// URL), you'll run into CORS errors due to JavaScript module security requirements. You need to do your testing through a server.

From an instruction standpoint, the reveal of “just double-click the HTML file” seems quite appealing.

from basic-computer-games.

mojoaxel avatar mojoaxel commented on June 22, 2024 3

With #687 we move to node.js as main target!
For playing games online we have a very simple node-terminal-emulator. Here is an example:

lacagy HTML Version:
https://coding-horror.github.io/basic-computer-games/57_Literature_Quiz/javascript/litquiz.html

node.js version & terminal emuilator:
https://coding-horror.github.io/basic-computer-games/00_Common/javascript/WebTerminal/terminal.html#57_Literature_Quiz/javascript/litquiz.mjs

from basic-computer-games.

mojoaxel avatar mojoaxel commented on June 22, 2024 2

I also think the "javascript" implementation should target node (command line) as a default.
It than would be quite easy to write a simple polyfill for input/output in the browser (I also like @LukasMurdock's aproach in #117 (comment)).

That would keep the code simpler (no DOM handling) and we could have one singel implementation for node and the browser.

from basic-computer-games.

MartinThoma avatar MartinThoma commented on June 22, 2024 2

Just a side note as I haven't seen it in this discussion:

I absolutely love the Github Page which is generated:
https://coding-horror.github.io/basic-computer-games/ . Even if we want a JavaScript (node) terminal version of the games, I would like to keep the Github pages version.

from basic-computer-games.

nanochess avatar nanochess commented on June 22, 2024 1

I think the project should reach the widest possible audience, so working directly in browser is the best solution yet. Also my current input/output solution works both in computers and cellphones. (see second rule: "...strive to replicate the command line / console output and behavior illustrated in the original book. ")

I'm having a crash with third rule "Please DO update for modern coding conventions. Support uppercase and lowercase. Use structured programming. Use subroutines. Try to be an example of good, modern coding practices!" because we need to be aware that the original programs weren't exactly an example of structured programming. Even for BASIC standards most programs are terribly ugly!

So far my current approach is this:

  1. Port all programs, structuring them along the way as possible (some are pretty obscure! So this isn't so easy as it looks)
  2. Implemented one function for each GOSUB/RETURN subroutine. But only if possible, because some spaghetti code exits from the inside to another part on the code.
  3. Keep same variable names in order to correct and refer easily against the original. (read first rule: "...and compare implementations across common modern languages.")
  4. Keep comments from the original game.

When the programs are ported, more people should make another pass that will take even more time:

  1. Commenting the code properly. (per rule 3)
  2. Replacing single letter variables with more proper names. (per rule 4)
  3. Re-structuring the code (per rule 4)
  4. Supporting properly lowercase/uppercase.
  5. Declaring all variables properly (per rule 6).
  6. Separating the print/input functions in a separate library so the games can be executed with NodeJS.

Only the rule 2 from guidelines has prevented me from going text to full graphics XD

from basic-computer-games.

fwenzel avatar fwenzel commented on June 22, 2024

CC @lmorchard who is writing a pretty complex one in JS

from basic-computer-games.

coding-horror avatar coding-horror commented on June 22, 2024

Yes, this is a good discussion to have -- what are our available options?

  • render to the javascript console in the browser
  • render to a simple HTML target that emulates the console
  • (others?)

We should pick a method and stick with it for all the JS implementations

from basic-computer-games.

fwenzel avatar fwenzel commented on June 22, 2024

I guess option 3 is command line scripting via node (example https://nodejs.org/api/readline.html#readline_rl_question_query_options_callback). Though I recognize that won't be vanilla JS, reading user input via node standard lib.

from basic-computer-games.

thomasqbrady avatar thomasqbrady commented on June 22, 2024

Personally, as someone who grew up copying BASIC programs out of magazines and is now a full-time javascript developer, I think the best bet would be option 1 from Jeff's list above. It's closest to the original experience of writing and using BASIC, AND easiest for a brand new user to access. Getting a new user to the point that they can take user input in a Node script is a very different thing (including importing standard library features, callbacks and/or promises, etc.) from using Window.prompt().

Also, the spirit (as I understand it) of this project is to re-implement the games in modern contexts. The examples I'm seeing so far of javascript ports with print(), tab(), input() functions look more like ports than re-implementations. I would think rewriting parts of the BASIC standard library in javascript so that the original source code requires less re-writing doesn't help new users of javascript learn how to think about programming. Am I thinking of this the wrong way?

from basic-computer-games.

fwenzel avatar fwenzel commented on June 22, 2024

Agree. It would be an entirely different, fun, thing to write a BASIC interpreter in all these languages so it can just run the original game....... but that's not what this repo is about. So a straight-up port of print() to whatever language doesn't really teach anyone how to think about that language.

from basic-computer-games.

coding-horror avatar coding-horror commented on June 22, 2024

I am sure we will be doing a lot of refactoring along the way as we go.

It is a goal to use all the modern features of the languages to make the code more readable and easier to follow. We're not striving for cleverness, but rather clarity, and "teachability".

Is it good, clear code?

from basic-computer-games.

lmorchard avatar lmorchard commented on June 22, 2024

I would think rewriting parts of the BASIC standard library in javascript so that the original source code requires less re-writing doesn't help new users of javascript learn how to think about programming. Am I thinking of this the wrong way?

FWIW, the bits I did aren't a BASIC standard library so much as a very minimal interface to work with web vs CLI driver scripts

Also, the spirit (as I understand it) of this project is to re-implement the games in modern contexts.

Personally, I wouldn't want to re-implement everything from scratch. I might be a glutton for punishment, but I started tinkering with Super Star Trek as a literal conversion from the BASIC in order to make sure I at least understood the original.

From there, I've kept a few things basically the same - e.g. the original used string manipulation to maintain both the data model and presentation of the current sector in space. I thought it was interesting, so I kept that in JS rather than change to something else like an array.

But, there was a fairly complex tangle of code to calculate distance & direction that I couldn't quite make clean without GOTO. So, I just changed that to use Math.atan2

Might be nostalgia speaking, but I think it could be interesting to keep a mix of the original flavor with some modernizations.

from basic-computer-games.

thomasqbrady avatar thomasqbrady commented on June 22, 2024

@lmorchard I think that conversion to Math.atan2 is a great example. I think you made the right decision there. And like Jeff said, choosing simplicity over cleverness seems like the right approach. My main question was whether we were thinking of this as an exercise in porting or re-writing, the former being totally compatible with re-creating parts of BASIC in javascript, the latter leaning toward substituting modern approaches or the target platform's standard library (like Math in javascript).

Certainly not trying to be negative about anyone's work so far, but aiming for constructive criticism.

from basic-computer-games.

coding-horror avatar coding-horror commented on June 22, 2024

latter leaning toward substituting modern approaches or the target platform's standard library (like Math in javascript).

I think that's the general approach we want, to use the modern features of modern languages.

We definitely aren't looking to emulate BASIC.

from basic-computer-games.

ideadapt avatar ideadapt commented on June 22, 2024

I guess option 3 is command line scripting via node (example https://nodejs.org/api/readline.html#readline_rl_question_query_options_callback). Though I recognize that won't be vanilla JS, reading user input via node standard lib.

I like the idea of using NodeJS. At least should it not be excluded. Although a little more than just Window.prompt is required to read from stdin, its still very easy todo (see #171). The current browser based javascript implementations emulate a terminal prompt via html / css, which is far more verbose in my opinion, and misses the chance to reduce the code to its functional minimum.
Maybe browser and nodejs based javascript implementations can co-exist, even for the same game :).

from basic-computer-games.

NezumiRonin avatar NezumiRonin commented on June 22, 2024

Gee... that remembers me that: "Any application that can be written in JavaScript, will eventually be written in JavaScript."

from basic-computer-games.

coding-horror avatar coding-horror commented on June 22, 2024

Is anything in here helpful?

https://github.com/coding-horror/basic-computer-games/tree/main/00_Common

from basic-computer-games.

mojoaxel avatar mojoaxel commented on June 22, 2024

With #649 I've added a very basic example (without input) as an example on how this could look like. The javascript part is implemented as a node.js script. Together with a very simple polyfill for console.log this also runs in the browser. I think with this approach we also could handle input.

from basic-computer-games.

coding-horror avatar coding-horror commented on June 22, 2024

There is also this

https://troypress.com/wp-content/uploads/user/js-basic/index.html

image

from basic-computer-games.

coding-horror avatar coding-horror commented on June 22, 2024

Yes, we have a decent solution now, closing this.

from basic-computer-games.

MartinThoma avatar MartinThoma commented on June 22, 2024

This looks amazing ❤️

Small note : on my android phone the new version is not usable as it doesn't show a keyboard. The old version did

from basic-computer-games.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.