X-Git-Url: https://git.cworth.org/git?p=lmno.games;a=blobdiff_plain;f=scribe%2Fscribe.jsx;h=07920773c9f79caa371b178639deaa35fea5a040;hp=be0de3799acf1f6bedaeb2171de86e9588832c38;hb=e79802f7979a2b3162efb0968c223f527d354410;hpb=656345d535b978e92cd9da0801a28f4571aaa6f2 diff --git a/scribe/scribe.jsx b/scribe/scribe.jsx index be0de37..0792077 100644 --- a/scribe/scribe.jsx +++ b/scribe/scribe.jsx @@ -79,6 +79,123 @@ events.addEventListener("game-state", event => { * Game and supporting classes * *********************************************************/ +const scribe_glyphs = [ + { + name: "Single", + squares: [1,0,0, + 0,0,0, + 0,0,0] + }, + { + name: "Double", + squares: [1,1,0, + 0,0,0, + 0,0,0] + }, + { + name: "Line", + squares: [1,1,1, + 0,0,0, + 0,0,0] + }, + { + name: "Pipe", + squares: [0,0,1, + 1,1,1, + 0,0,0] + }, + { + name: "Squat-T", + squares: [1,1,1, + 0,1,0, + 0,0,0] + }, + { + name: "4-block", + squares: [1,1,0, + 1,1,0, + 0,0,0] + }, + { + name: "T", + squares: [1,1,1, + 0,1,0, + 0,1,0] + }, + { + name: "Cross", + squares: [0,1,0, + 1,1,1, + 0,1,0] + }, + { + name: "6-block", + squares: [1,1,1, + 1,1,1, + 0,0,0] + }, + { + name: "Bomber", + squares: [1,1,1, + 0,1,1, + 0,0,1] + }, + { + name: "Chair", + squares: [0,0,1, + 1,1,1, + 1,0,1] + }, + { + name: "J", + squares: [0,0,1, + 1,0,1, + 1,1,1] + }, + { + name: "Earring", + squares: [0,1,1, + 1,0,1, + 1,1,1] + }, + { + name: "House", + squares: [0,1,0, + 1,1,1, + 1,1,1] + }, + { + name: "H", + squares: [1,0,1, + 1,1,1, + 1,0,1] + }, + { + name: "U", + squares: [1,0,1, + 1,0,1, + 1,1,1] + }, + { + name: "Ottoman", + squares: [1,1,1, + 1,1,1, + 1,0,1] + }, + { + name: "O", + squares: [1,1,1, + 1,0,1, + 1,1,1] + }, + { + name: "9-block", + squares: [1,1,1, + 1,1,1, + 1,1,1] + } +]; + function copy_to_clipboard(id) { const tmp = document.createElement("input"); @@ -165,6 +282,50 @@ function PlayerInfo(props) { ); } +function Glyph(props) { + + const glyph_dots = []; + + let last_square = 0; + for (let i = 0; i < 9; i++) { + if (props.squares[i]) + last_square = i; + } + + const height = Math.floor(20 * (Math.floor(last_square / 3) + 1)); + + const viewbox=`0 0 60 ${height}`; + + for (let row = 0; row < 3; row++) { + for (let col = 0; col < 3; col++) { + if (props.squares[3 * row + col]) { + let cy = 10 + 20 * row; + let cx = 10 + 20 * col; + glyph_dots.push( + + ); + } + } + } + + return (
+ {props.name} +
+ + + {glyph_dots} + + +
+
+ ); +} + function Square(props) { let className = "square"; @@ -174,6 +335,10 @@ function Square(props) { className += " open"; } + if (props.last_move) { + className += " last-move"; + } + const onClick = props.active ? props.onClick : null; return ( @@ -187,17 +352,31 @@ function Square(props) { function MiniGrid(props) { function grid_square(j) { const value = props.squares[j]; + const last_move = props.last_moves.includes(j); return ( props.onClick(j)} /> ); } + /* 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 => { + if (element) + occupied++; + }); + + let class_name = "mini-grid"; + if (props.active && occupied < 9) + class_name += " active"; + return ( -
+
{grid_square(0)} {grid_square(1)} {grid_square(2)} @@ -213,11 +392,54 @@ function MiniGrid(props) { class Board extends React.Component { mini_grid(i) { + /* This mini grid is active only if both: + * + * 1. It is our turn (this.props.active === true) + * + * 2. One of the following conditions is met: + * + * a. This is this players first turn (last_two_moves[0] === null) + * b. This mini grid corresponds to this players last turn + * c. The mini grid that corresponds to the players last turn is full + */ + let active = false; + if (this.props.active) { + active = true; + if (this.props.last_two_moves[0]) { + /* First index (0) gives us our last move, (that is, of the + * last two moves, it's the first one, so two moves ago). + * + * Second index (1) gives us the second number from that move, + * (that is, the index within the mini-grid that we last + * played). + */ + const target = this.props.last_two_moves[0][1]; + let occupied = 0; + this.props.squares[target].forEach(element => { + if (element) + occupied++; + }); + /* If the target mini-grid isn't full then this grid is + * only active if it is that target. */ + if (occupied < 9) + active = (i === target); + } + } + + /* We want to highlight each of the last two moves (both "+" and + * "o"). So we filter the last two moves that have a first index + * that matches this mini_grid and pass down their second index + * be highlighted. + */ + const last_moves = this.props.last_two_moves.filter(move => move[0] === i) + .map(move => move[1]); + const squares = this.props.squares[i]; return ( this.props.onClick(i,j)} /> ); @@ -268,9 +490,9 @@ class Game extends React.Component { game_info: {}, player_info: {}, other_players: [], - squares: Array(9).fill(null).map(() => Array(9).fill(null)), - moves: 0, - next_to_play: "+" + squares: [...Array(9)].map(() => Array(9).fill(null)), + moves: [], + next_to_play: "+", }; } @@ -306,12 +528,13 @@ class Game extends React.Component { } receive_move(move) { - if (this.state.moves === 81) { + if (this.state.moves.length === 81) { return; } const symbol = team_symbol(this.state.next_to_play); const new_squares = this.state.squares.map(arr => arr.slice()); new_squares[move[0]][move[1]] = symbol; + const new_moves = [...this.state.moves, move]; let next_to_play; if (this.state.next_to_play === "+") next_to_play = "o"; @@ -319,7 +542,7 @@ class Game extends React.Component { next_to_play = "+"; this.setState({ squares: new_squares, - moves: this.state.moves + 1, + moves: new_moves, next_to_play: next_to_play }); } @@ -347,7 +570,7 @@ class Game extends React.Component { render() { const state = this.state; - const first_move = state.moves === 0; + const first_move = state.moves.length === 0; const my_team = state.player_info.team; var board_active; @@ -412,9 +635,23 @@ class Game extends React.Component { this.handle_click(i, j, first_move)} />
+
, +
+ { + scribe_glyphs.map(glyph => { + return ( + + ); + }) + }
]; }