Diff
src/App.js | 53 +++++++++++++++++++++++++++++++++++------------------
src/Board.js | 87 --------------------------------------------------------------------------------
src/Game.js | 27 ++++++++++++++++-----------
3 files changed, 41 insertions(+), 126 deletions(-)
@@ -7,32 +7,25 @@
let index = parseInt(val[1], 10) - 1;
return SUITS[index];
}
let text = (val ===0 || val ===1)? "" : suitLookup(val);
let text = (val ==="0" || val ==="1")? "" : suitLookup(val);
return `<td class=cell data-tile=${val} data-suit=${val[1]} key=${id} >${text}</td>`
return `<td class=cell data-tile=${val} data-suit=${val[1]} data-id=${id} key=${id} >${text}</td>`
}
class OkiyaClient {
constructor(rootElement) {
this.client = Client({ game: Okiya });
this.client = Client({ game: Okiya, numPlayers: 2, });
this.client.start();
this.rootElement = rootElement;
this.client.subscribe(state => this.update(state));
this.createBoard();
this.attachListeners();
}
createBoard() {
this.rootElement.innerHTML = `
<table id=board></table>
<p class="winner"></p>
<div class="lastplayed"></div>`;
this.client.subscribe(state => {
this.update(state)
this.attachListeners();
});
}
update(state) {
let tbody = [];
for (let i = 0; i < 4; i++) {
let cells = [];
@@ -40,13 +33,15 @@
const id = 4 * i + j;
cells.push(Tile(state.G.cells[id], id, this));
}
tbody.push(`<tr key=${i}>${cells}</tr>`);
tbody.push(`<tr key=${i}>${cells.join("\n")}</tr>`);
}
let lastPlayed = "";
let lastPlayed = "", winner = "", html = `
<table class=board>${tbody.join("\n")}</table>
<p class="winner"></p>`;
if (state.G.lastPlayed)
lastPlayed = `<div>
if (state.G.lastPlayed && state.ctx.gameover === undefined) {
html += `<div>
<p>Last Played Tile: </p>
<table class="board">
<tr>
@@ -54,22 +49,29 @@
</tr>
</table>
</div>`;
}
this.rootElement.innerHTML = `
<table class=board>${tbody.join("\n")}</table>
<p class="winner"></p>
${lastPlayed}`;
if (state.ctx.gameover) {
if (state.ctx.gameover.draw) {
html += `div id="winner">Draw!</div>`;
} else {
html += `<div id="winner">Winner: ${state.ctx.gameover.winner === "0" ? "Red" : "Black"}`;
if (state.ctx.gameover.stalemate) {
html += "<span> by stalemate</span>";
}
}
}
this.rootElement.innerHTML = html;
}
attachListeners() {
const handleCellClick = event => {
const id = parseInt(event.target.dataset.id);
this.client.moves.clickCell(id);
};
const cells = this.rootElement.querySelectorAll('.cell');
cells.forEach(cell => {
@@ -77,7 +79,6 @@
});
}
}
const appElement = document.getElementById('app');
const app = new OkiyaClient(appElement);
@@ -1,87 +1,0 @@
import React from 'react';
import './board.css'
class Board extends React.Component {
onClick(id) {
if (this.isActive(id)) {
this.props.moves.clickCell(id);
this.props.events.endTurn();
}
}
isActive(id) {
if (!this.props.isActive) return false;
if (this.props.G.cells[id] === 0 || this.props.G.cells[id] === 1) return false;
return true;
}
render() {
let winner = '';
let lastPlayed = '';
if (this.props.ctx.gameover) {
winner =
this.props.ctx.gameover.winner !== undefined ? (
<div id="winner">Winner: {this.props.ctx.gameover.winner === "0" ? "Red" : "Black"}
{this.props.ctx.gameover.stalemate !== undefined ? <span> by stalemate</span> : "" }
</div>
) : (
<div id="winner">Draw!</div>
);
}
if (this.props.G.lastPlayed) {
lastPlayed = <div>
<p>Last Played Tile: </p>
<table class="board">
<tr>
{Tile(this.props.G.lastPlayed)}
</tr>
</table>
</div>
}
function Tile(val, interactive=false, id=null, ctx=null) {
const suitLookup = function(val) {
const SUITS = ['♠','♥','♦','♣'];
let index = parseInt(val[1], 10) - 1;
return SUITS[index];
}
let text = (val ===0 || val ===1)? "" : suitLookup(val)
if(interactive) {
return <td data-tile={val} data-suit={val[1]} key={id} onClick={() => ctx.onClick(id)}>
{text}
</td>
}
else {
return <td data-tile={val} data-suit={val[1]}>
{text}
</td>
}
}
let tbody = [];
for (let i = 0; i < 4; i++) {
let cells = [];
for (let j = 0; j < 4; j++) {
const id = 4 * i + j;
cells.push(Tile(this.props.G.cells[id], true, id, this));
}
tbody.push(<tr key={i}>{cells}</tr>);
}
return (
<div>
<table class="board">
<tbody>{tbody}</tbody>
</table>
{winner}
{lastPlayed}
</div>
);
}
}
export default Board;
@@ -56,23 +56,28 @@
"D4",
];
function validMove(cell, id, tile) {
const borders = [0, 1, 2, 3, 4, 7, 8, 11, 12, 13, 14, 15];
const BORDER_TILE_IDS = [0, 1, 2, 3, 4, 7, 8, 11, 12, 13, 14, 15];
function validMove(cell, id, lastPlayedTile) {
if (tile === null) {
return borders.includes(id);
if (lastPlayedTile === null) {
return BORDER_TILE_IDS.includes(id);
}
return cell[0] === tile[0] || cell[1] === tile[1];
return cell[0] === lastPlayedTile[0] || cell[1] === lastPlayedTile[1];
}
function unclaimed(tile) {
return !(tile === 0 || tile === 1);
}
export const Okiya = {
minPlayers: 2,
maxPlayers: 2,
turn: {
moveLimit: 1,
minMoves: 1,
maxMoves: 1
},
@@ -93,14 +98,10 @@
}),
moves: {
clickCell: ({G, playerId}, id) => {
console.log(G)
console.log(id)
console.log(G.cells)
console.log(G.cells[id])
clickCell({ G, playerID }, id) {
if (unclaimed(G.cells[id]) && validMove(G.cells[id], id, G.lastPlayed)) {
G.lastPlayed = G.cells[id];
G.cells[id] = playerId;
G.cells[id] = playerID;
} else {
return INVALID_MOVE;
}
@@ -109,7 +110,7 @@
endIf: ({G, ctx}) => {
if (IsVictory(G.cells)) {
return { winner: ctx.currentPlayer };
return { winner: ctx.currentPlayer, stalemate: false, draw: false };
}
if (G.cells.filter(unclaimed).length === 0) {