X-Git-Url: https://git.cworth.org/git?a=blobdiff_plain;f=tictactoe.js;h=4e76638a7cd3290df810eee00cd677c3af1ec0f8;hb=76e5097689002f03c721c388e2ca71c52abf3354;hp=18fe3428806bee30c2c533182b15e02fee36993b;hpb=d04124365041fb3d9606a0aa56b49a2147565038;p=empires-server diff --git a/tictactoe.js b/tictactoe.js index 18fe342..4e76638 100644 --- a/tictactoe.js +++ b/tictactoe.js @@ -1,20 +1,35 @@ const express = require("express"); -const cors = require("cors"); -const body_parser = require("body-parser"); -const path = require("path"); -const nunjucks = require("nunjucks"); - -const app = express(); -app.use(cors()); -app.use(body_parser.urlencoded({ extended: false })); -app.use(body_parser.json()); - -nunjucks.configure("templates", { - autoescape: true, - express: app -}); +const Game = require("./game.js"); + +const engine_name = "tictactoe"; + +const router = express.Router(); + +class TicTacToe extends Game { + constructor() { + super(engine_name); + this.moves = []; + this.board = Array(9).fill(null); + } + + /* Returns Boolean indicating whether move was legal and added. */ + add_move(square) { + /* Cannot move to an occupied square. */ + if (this.board[square]) + return false; + + this.board[square] = 'X'; + this.moves.push(square); -app.get('/', (request, response) => { + return true; + } + + broadcast_move(square) { + this.broadcast_event("move", square); + } +} + +router.get('/', (request, response) => { const game = request.game; if (! request.session.nickname) @@ -23,4 +38,42 @@ app.get('/', (request, response) => { response.render('tictactoe-game.html'); }); -exports.app = app; +router.post('/move', (request, response) => { + const game = request.game; + const square = request.body.square; + + const legal = game.add_move(square); + + /* Inform this client whether the move was legal. */ + response.send(JSON.stringify(legal)); + + /* And only if legal, inform all clients. */ + if (! legal) + return; + + game.broadcast_move(square); +}); + +router.get('/events', (request, response) => { + const game = request.game; + + /* These headers will keep the connection open so we can stream events. */ + const headers = { + "Content-type": "text/event-stream", + "Connection": "keep-alive", + "Cache-Control": "no-cache" + }; + response.writeHead(200, headers); + + /* Add this new client to our list of clients. */ + const id = game.add_client(response); + + /* And queue up cleanup to be triggered on client close. */ + request.on('close', () => { + game.remove_client(id); + }); +}); + +exports.router = router; +exports.name = engine_name; +exports.Game = TicTacToe;