]> git.cworth.org Git - lmno.games/blobdiff - scribe/scribe.jsx
Score each mini glyph and render the winner for each
[lmno.games] / scribe / scribe.jsx
index d8f6afc9bf334b9ff523626854ff6883bfa870a4..75742ca8ec160513fbde5f962298d747d12586df 100644 (file)
@@ -357,8 +357,12 @@ function Square(props) {
 }
 
 function MiniGrid(props) {
+
+  const mini_grid = props.mini_grid;
+  const squares = mini_grid.squares;
+
   function grid_square(j) {
-    const value = props.squares[j];
+    const value = squares[j];
     const last_move = props.last_moves.includes(j);
 
     /* Even if the grid is active, the square is only active if
@@ -378,7 +382,7 @@ function MiniGrid(props) {
   /* Even if my parent thinks I'm active because of the last move, I
    * might not _really_ be active if I'm full. */
   let occupied = 0;
-  props.squares.forEach(element => {
+  mini_grid.squares.forEach(element => {
     if (element.symbol)
       occupied++;
   });
@@ -387,6 +391,11 @@ function MiniGrid(props) {
   if (props.active && occupied < 9)
     class_name += " active";
 
+  let winner = null;
+  if (mini_grid.winner) {
+    winner = <div className="winner">{mini_grid.winner}</div>;
+  }
+
   return (
     <div className={class_name}>
       {grid_square(0)}
@@ -398,6 +407,7 @@ function MiniGrid(props) {
       {grid_square(6)}
       {grid_square(7)}
       {grid_square(8)}
+      {winner}
     </div>
   );
 }
@@ -427,7 +437,7 @@ class Board extends React.Component {
          */
         const target = this.props.last_two_moves[0][1];
         let occupied = 0;
-        this.props.squares[target].forEach(element => {
+        this.props.mini_grids[target].squares.forEach(element => {
           if (element.symbol)
             occupied++;
         });
@@ -446,10 +456,10 @@ class Board extends React.Component {
     const last_moves = this.props.last_two_moves.filter(move => move[0] === i)
           .map(move => move[1]);
 
-    const squares = this.props.squares[i];
+    const mini_grid = this.props.mini_grids[i];
     return (
       <MiniGrid
-        squares={squares}
+        mini_grid={mini_grid}
         active={grid_active}
         last_moves={last_moves}
         onClick={(j) => this.props.onClick(i,j)}
@@ -502,9 +512,14 @@ class Game extends React.Component {
       game_info: {},
       player_info: {},
       other_players: [],
-      squares: [...Array(9)].map(() => Array(9).fill({
-        symbol: null,
-        glyph: false
+      mini_grids: [...Array(9)].map(() => ({
+        score_plus: null,
+        score_o: null,
+        winner: null,
+        squares: Array(9).fill({
+          symbol: null,
+          glyph: false
+        })
       })),
       moves: [],
       next_to_play: "+",
@@ -726,20 +741,45 @@ class Game extends React.Component {
 
     /* Set the team's symbol into the board state. */
     const symbol = team_symbol(this.state.next_to_play);
-    const new_squares = this.state.squares.map(arr => arr.slice());
-    new_squares[mini_grid_index][position] = {
+    const new_mini_grids = this.state.mini_grids.map(obj => {
+      const new_obj = {...obj};
+      new_obj.squares = obj.squares.slice();
+      return new_obj;
+    });
+    const new_mini_grid = new_mini_grids[mini_grid_index];
+    new_mini_grid.squares[position] = {
       symbol: symbol,
       glyph: false
     };
 
     /* With the symbol added to the squares, we need to see if this
      * newly-placed move forms a glyph or not. */
-    const connected = this.find_connected(new_squares[mini_grid_index], position);
+    const connected = this.find_connected(new_mini_grid.squares, position);
     const is_glyph = this.is_glyph(connected);
 
+    /* Either set (or clear) the glyph Boolean for each connected square. */
     for (let i = 0; i < 9; i++) {
       if (connected[i])
-        new_squares[mini_grid_index][i].glyph = is_glyph;
+        new_mini_grid.squares[i].glyph = is_glyph;
+    }
+
+    /* If this is the last cell of played in a mini-grid then it's
+     * time to score it. */
+    const occupied = new_mini_grid.squares.reduce(
+      (acc, val) => acc + (val.symbol !== null ? 1 : 0), 0);
+    if (occupied === 9) {
+      for (let i = 0; i < 9; i++) {
+        if (new_mini_grid.squares[i].glyph) {
+          if (new_mini_grid.squares[i].symbol === '+')
+            new_mini_grid.score_plus++;
+          else
+            new_mini_grid.score_o++;
+        }
+      }
+      if (new_mini_grid.score_plus > new_mini_grid.score_o)
+        new_mini_grid.winner = '+';
+      else
+        new_mini_grid.winner = 'o';
     }
 
     /* And append the move to the list of moves. */
@@ -754,7 +794,7 @@ class Game extends React.Component {
 
     /* And shove all those state modifications toward React. */
     this.setState({
-      squares: new_squares,
+      mini_grids: new_mini_grids,
       moves: new_moves,
       next_to_play: next_to_play
     });
@@ -847,7 +887,7 @@ class Game extends React.Component {
         <div className="game-board">
           <Board
             active={board_active}
-            squares={state.squares}
+            mini_grids={state.mini_grids}
             last_two_moves={state.moves.slice(-2)}
             onClick={(i,j) => this.handle_click(i, j, first_move)}
           />