0.0.3 • Published 7 years ago

roboboard v0.0.3

Weekly downloads
1
License
MIT
Repository
-
Last release
7 years ago

RoboBoard Build Status Coverage Status

A simple Node.js application

Design

The project implements a simple board game.

The game consists of a board and a robot. The board is a n×n grid, the bottom left corner is the 0x0 point. The robot accepts commands to pivot (turn in place) to right and left, and move; it can be placed anywhere on the board. The robot rejects moving outside the bounds of the board.

The interface to the game is textual, in what we call a gamescript, it context-free, case-sensitive and line delimited, the following ABNF-ish describes the overall script:

game-script = PLACE|MOVE|TURN|REPORT;

PLACE = "PLACE" POSITION ORIENTATION NL;

POSITION = 1*DIGIT 1*DIGIT ; two section of at least one digit
ORIENTATION = ("NORTH" | "SOUTH" | "EAST" | "WEST") NL;


MOVE = "MOVE" NL;

TURN = LEFT|RIGHT NL;

LEFT = "LEFT";
REPORT = "REPORT"

NL = LF ; newline is the linefeed (\n) not carrage return (\r)

Implementation

The application is written in ES6 with flow-type and uses babel to compile to ES5. The code is linted with eslint using an extended airbnb/javascript configurations with slight modifications.

ES6 provides us with advance programming features and flow-type brings type safety to JavaScript and along with eslint it elemints a huge class of bugs and errors at compile time.

The application is broken into non-interdependent functional components that provide the overall functionality required. The packages are further split into more fine grain ES6 modules.

Why?

Composability, for example, if one wants to port this game to browser, they can simply import the engine and parser without caring or depending to the cli interface.

Testability, breaking the application into simple components allows us more through unit testing.

Each components' main packages are put under an eponym directory as index.js, with other packages under the same directory as package_name.js.

The main three components are as following:

Parser

parser defines an AST and parser for gamescript

Engine

Engine contains the domain logic of the game, it implements a single board and robot system with a simple interface to issue commands to the robot; Engine is responsible for enforcing bound checks on move and other validation.

CLI

The cli module provides the interface for executing gamescripts from a file and an interactive mode to play the game by typing commands directly in an interactive shell.

As the name board was taken on npmjs the commandline interface is called roboboard, following is the help command output:

$ roboboard help

  Commands:

    help [command...]  Provides help for a given command.
    run <file>         runs the provide gamescript
    interactive        runs the game engine in interactive mode

The run method is pretty simpl, you call roboboard run path/to/game/script and it will run and print the output:

For example,

running roboboard run test/gamescript_2.txt will yield:

Warning: Ignoring line 1. No robot placed
Info: Executing Instruction: PLACE 1,2,EAST: current state: 1, 2, EAST
Warning: Ignoring line 3. Robot already placed
Info: Executing Instruction: MOVE: current state: 2, 2, EAST
Info: Executing Instruction: LEFT: current state: 2, 2, NORTH
Info: Executing Instruction: MOVE: current state: 2, 3, NORTH
Info: Executing Instruction: MOVE: current state: 2, 4, NORTH
Info: Executing Instruction: MOVE: current state: 2, 5, NORTH
Warning: Ignoring line 9. Illegal move: out of bounds
Info: 2, 5, NORTH

The interactive mode accepts a slightly different syntax for convenience, you can see the details by running the help command after entering interactive mode:

 $ roboboard interactive
> help

  Commands:

    help [command...]  Provides help for a given command.
    exit               Exits application.
    place <x> <y> <o>  runs the provide gamescript
    move               making a move
    left               turning left
    right              turning right
    report             prints the current state of the board

 
(^C again to quit)
> 

Issuing commands works like this:

> place 1 2 east
Info: Command Executed
> move
Info: Command Executed
> left
Info: Command Executed
> move
Info: Command Executed
> right
Info: Command Executed
> move
Info: Command Executed
> re
3, 3, EAST
> place 0 0 north
Warning: Command Rejected: Robot already placed
> move
Info: Command Executed
> move
Info: Command Executed
> move
Warning: Command Rejected: Illegal move: out of bounds
> move
Warning: Command Rejected: Illegal move: out of bounds
> right
Info: Command Executed
> move
Info: Command Executed
> move
Info: Command Executed
> move
Info: Command Executed
> re
5, 0, SOUTH
> move
Warning: Command Rejected: Illegal move: out of bounds

Warning: the interactive mode is highly addictive.

Build and Usage

Building

To build the project, simply clone this repository and run yarn install followed by yarn build, you may use npm if you fancy.

Installing

You can install the roboboard game directly from npm registery by running yarn global add roboboard or npm install -g roboboard, if you don't have yarn installed.

Alternatively, you can install your local build by running npm install -g . from the project directory after build.

Tests

We use jest as a test runner and assertion library, it provides a much better out of the box experience and very little overhead for running tests.

Tests are collocated with packages as $package_name.test.js, the tests gets compiled along the code and written in a way that they can be excuted under build as well as src, this provides as a mechanism to test the compiled case in case the compiled code creates any bugs.

To run tests execute yarn run test and to test the compiled code run yarn run test-build, of course, after running yarn run build.

For other commands please see the package.json scripts section.

TODO

Add tests for CLI

LICENSE

MIT.

0.0.3

7 years ago

0.0.2

7 years ago

0.0.1

7 years ago