]> git.cworth.org Git - lmno-server/blob - scribe.js
scribe: Reject moves that are illegal by the move constraint
[lmno-server] / scribe.js
1 const express = require("express");
2 const Game = require("./game.js");
3
4 class Scribe extends Game {
5   constructor(id) {
6     super(id);
7     this.teams = [{id:0, name:"+"}, {id:1, name:"o"}];
8     this.state = {
9       moves: [],
10       squares: Array(9).fill(null).map(() => Array(9).fill(null)),
11       team_to_play: this.teams[0],
12     };
13   }
14
15   /* Returns true if move was legal and added, false otherwise. */
16   add_move(player, move) {
17
18     const state = this.state;
19     const i = move[0];
20     const j = move[1];
21     const result = super.add_move(player, move);
22
23     /* If the generic Game class can reject this move, then we don't
24      * need to look at it any further. */
25     if (! result.legal)
26       return result;
27
28     /* Ensure move is legal by Scribe rules. First, if this is only
29      * the first or second move, then any move is legal.
30      */
31     if (state.moves.length >= 2) {
32       const prev = state.moves.slice(-2, -1)[0];
33
34       /* Then check for mini-grid compatibility with move from two moves ago. */
35       if (move[0] != prev[1]) {
36         /* This can still be legal if the target mini grid is full. */
37         let count = 0;
38         for (let square of state.squares[prev[1]]) {
39           if (square)
40             count++;
41         }
42         if (count != 9) {
43           return { legal: false,
44                    message: "Move is inconsistent with your previous move" };
45         }
46       }
47
48     }
49
50
51     /* Cannot move to an occupied square. */
52     if (state.squares[i][j])
53     {
54       return { legal: false,
55                message: "Square is already occupied" };
56     }
57
58     state.squares[i][j] = state.team_to_play;
59     state.moves.push(move);
60
61     if (state.team_to_play.id === 0)
62       state.team_to_play = this.teams[1];
63     else
64       state.team_to_play = this.teams[0];
65
66     return { legal: true };
67   }
68 }
69
70 Scribe.router = express.Router();
71
72 Scribe.meta = {
73   name: "Scribe",
74   identifier: "scribe",
75   options: {
76     allow_guest: true
77   }
78 };
79
80 exports.Game = Scribe;