Comments (25)
FWIW, this is how I've been doing it for Super Star Trek:
- The main code is in an ES6 module with a few exported functions to configure print, input, run, exit: https://github.com/lmorchard/basic-computer-games/blob/84-js-super-star-trek/84%20Super%20Star%20Trek/javascript/superstartrek.mjs#L28-L44
- A script to run it at a command line calls those functions to configure for STDIN / STDOUT: https://github.com/lmorchard/basic-computer-games/blob/84-js-super-star-trek/84%20Super%20Star%20Trek/javascript/cli.mjs
- A web page to run it using xterm.js, with a bit of bootstrapping to configure the game code: https://github.com/lmorchard/basic-computer-games/blob/84-js-super-star-trek/84%20Super%20Star%20Trek/javascript/index.html#L174-L232
Kind of hacked together, but seems to be working decently so far
from basic-computer-games.
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.
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.
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.
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.
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.
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.
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.
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:
- Port all programs, structuring them along the way as possible (some are pretty obscure! So this isn't so easy as it looks)
- 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.
- Keep same variable names in order to correct and refer easily against the original. (read first rule: "...and compare implementations across common modern languages.")
- Keep comments from the original game.
When the programs are ported, more people should make another pass that will take even more time:
- Commenting the code properly. (per rule 3)
- Replacing single letter variables with more proper names. (per rule 4)
- Re-structuring the code (per rule 4)
- Supporting properly lowercase/uppercase.
- Declaring all variables properly (per rule 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.
CC @lmorchard who is writing a pretty complex one in JS
from basic-computer-games.
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.
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.
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.
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.
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.
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.
@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.
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.
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.
Gee... that remembers me that: "Any application that can be written in JavaScript, will eventually be written in JavaScript."
from basic-computer-games.
Is anything in here helpful?
https://github.com/coding-horror/basic-computer-games/tree/main/00_Common
from basic-computer-games.
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.
There is also this
https://troypress.com/wp-content/uploads/user/js-basic/index.html
from basic-computer-games.
Yes, we have a decent solution now, closing this.
from basic-computer-games.
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)
- terminal_style.css pegs cpu usage HOT 1
- Mastermind.py has trouble counting black and white pegs. HOT 5
- Typo in the Basic and JavaScript versions of SALVO HOT 2
- hangman.rb doesn't randomize the order of puzzle words HOT 9
- Are less mainstream languages allowed? HOT 4
- DEC Basic Computer Games HOT 2
- A little more about the spirit of the project??? HOT 6
- Super Star Trek README has a typo that's a rude word. HOT 1
- Edited latest commit requesting review for pull request (Life for Two.py)
- Super Star Trek - Ship class does not work correctly HOT 2
- A function never called in tictactoe2.py HOT 1
- Hacktoberfest HOT 1
- Confusion between 91_Train and 92_Trap Rust HOT 3
- 84_Super_Star_Trek java issues HOT 1
- Lunar lander initial weight HOT 1
- Battle doesn't seem to accept the num,num format suggested in the readme HOT 4
- Python Acey-Ducey has a "1" card instead of the "10" HOT 5
- Code decomposition question HOT 4
- Another possible tourist trade bug in King HOT 2
- Hacktoberfest
Recommend Projects
-
React
A declarative, efficient, and flexible JavaScript library for building user interfaces.
-
Vue.js
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
-
Typescript
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
-
TensorFlow
An Open Source Machine Learning Framework for Everyone
-
Django
The Web framework for perfectionists with deadlines.
-
Laravel
A PHP framework for web artisans
-
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.
-
Visualization
Some thing interesting about visualization, use data art
-
Game
Some thing interesting about game, make everyone happy.
Recommend Org
-
Facebook
We are working to build community through open source technology. NB: members must have two-factor auth.
-
Microsoft
Open source projects and samples from Microsoft.
-
Google
Google ❤️ Open Source for everyone.
-
Alibaba
Alibaba Open Source for everyone
-
D3
Data-Driven Documents codes.
-
Tencent
China tencent open source team.
from basic-computer-games.