[insert python joke]
An implementation of Snake (game), managing objects, groups, and (their) attributes with Ludus. Along with users and their personalities (high score), by JSON. Manually playable by either a CLI (Command-Line Interface) using unicode glyph attributes - customisable by TOML, or by a BUI (Browser-User Interface) using the Eel (python) package to host a webpage on localhost:8000. Whereby an API (Application Program Interface) allows the front-end Java-Script to access the backend Python, managing the game. To then display on the front-end, and take any browser inputs - using (minismised) jQuery and HTML5 canvas element(s) - customisable by JSON
- Initiate the
Snakeclass whilethe the game is not over (Snake.is_game_over) continue- Render (
Snake.render) a frame of the game to the console, taking theglyphattribute of each, or the codepoint of theblankglyph if not an object coordinate sleep, as to delay the next instructions (giving time between frames, to be at a sensible speed)- Update (
Snake.update) the game to the next frame, as by moving the snake in the direction ofvelocityof the head, shifting all velocities, and enforcing (Snake.__enforce__) the rules. For example:- If the snake were to collide with itself or the wall, killing the snake, and so ending the game
- If the snake head were to collide/intercept with the coordinate of food, then removing the food (consumed), to then extend the length (by 1) of the snake
- Render (
- Initiate (
eel.init) Eel, hooking it to the web directory/folder - Start (
eel.start) by hosting a webpage on localhost, port 8000, opening the (Chrome) browser (in application mode) - Get the
#snake-game-canvas, and assign a variable (ctx) to the2dcontext of this canvas window.begin- Copy the width of
snake-game-canvasby loading in canvas.json (withloadJSON) to the global width variable (window.width)- Send an API request to begin (
eel.snakeBegin) the snake game- Hook a
keypressevent.onthe body of the HTML document/page, such as to set the snake's direction (eel.snakeSetDirection) by an API request - only after having translating (translateKey) the key to a valid direction (as to active the relative on-screen button) - Copy the attributes by loading attributes.json (with
loadJSON) to the global attributes variable (window.attributes)renderimmediately as to not halt the user from seeing the game prior to the firstupdateinitiateIntervalofupdate, at an interval of100ms
- Hook a
- Send an API request to begin (
- Copy the width of
- Call
update, as to continually animate the game- Update (
eel.snakeUpdate) the snake game instance - callingSnake.update, and passing an string argument of the current username (window.username), to be passed to theSnake.scoreboardfunction. As to store a high score for that user (if applicable) as a dump to users.json - Check if the game is over (
eel.snakeIsGameOver) with an API request, if soclearIntervalas to prevent updating the finished game (resulting in an error raised of a missing snake body), otherwise update the current score (editCurrentScore) from the snake length (eel.snakeLength) and update the high score (editHighScore) if applicable`
- Update (
- Call
render, as to draw and display the objects (including the grid) onto the#snake-game-canvas- Get the objects (
eel.getObjects) of the game by an API request, copy to the internal object of_objects - Get the groups' attributes (
eel.getAttributes) of the game by an API request, copy to the internal object of_attributes- Sort the objects into
layersof their body coordinates, bypriorityLevel, in ascending order draweach object in ascendingpriorityLevelonto#snake-game-canvasby filling a rectangle, using the respective colour found in attributes.json for each group
- Sort the objects into
- Draw a grid (
drawGrid) using the respective colour found in attributes.json, to easily differentiate coordinates
- Get the objects (
Both styles of play, whether that be command-line (CLI) or browser (BUI) have customisable interfaces, using JSON and TOML files (whichever I found most appropriate, i.e. for JS exclusively JSON)
To customise how Snake.render prints (a frame of) the game, edit snake/attributes/toml/attributes.toml. By default the given codepoints of the glyphs of wall, snake, food, and track are shown as the unicode character commented after. To change, simply change the codepoint to another unicode character
there MUST be a U+ prefix before the unicode codepoint, otherwise no character will be printed for that group
To customise the resolution, the width and height can be passed as integer arguments when initiating the Snake class instance. Where the default value for both is 20
To customise the colour of groups displayed on the HTML5 canvas in the browser, edit web/json/attributes.json. These can be changed, and do not necessarily need to be hex(adecimal) codes (for example rgb(255, 0, 0) would be the same as #FF0000, and even the colour keyword red)
for my ease, I have used British English spellings throughout the application, UNLESS necessary - such as in CSS - however may update with workarounds later (for example postcss)
To customise the resolution, the width (passed to the Snake class) can be changed by editing the integer value to key width of snake-game-canvas in web/json/canvas.json, whereas the height is determined by the aspect-ratio of the #snake-game-canvas canvas (set in style.css), this is to keep the
for example, by default the #snake-game-canvas has a aspect-ratio: 4/3
For execution python>=3 needs to be installed, with the standard library, with the additional packages found in requirements.txt. These can be installed using pip install with the -r flag - or simply by executing either:
./install.ps1(Linux, macOS)
./install.shpython main.py(Linux, macOS)
python3 main.py