🏡 index : github.com/captn3m0/okiya.git

Diff

 src/App.js   | 53 +++++++++++++++++++++++++++++++++++------------------
 src/Board.js | 87 --------------------------------------------------------------------------------
 src/Game.js  | 27 ++++++++++++++++-----------
 3 files changed, 41 insertions(+), 126 deletions(-)

diff --git a/src/App.js b/src/App.js
index 75dd4a2..d29559e 100644
--- a/src/App.js
+++ a/src/App.js
@@ -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() {
    // This event handler will read the cell id from a cell’s
    // `data-id` attribute and make the `clickCell` move.
    const handleCellClick = event => {
      const id = parseInt(event.target.dataset.id);
      this.client.moves.clickCell(id);
    };

    // Attach the event listener to each of the board cells.
    const cells = this.rootElement.querySelectorAll('.cell');
    cells.forEach(cell => {
@@ -77,7 +79,6 @@
    });
  }
}


const appElement = document.getElementById('app');
const app = new OkiyaClient(appElement);
diff --git a/src/Board.js b/src/Board.js
deleted file mode 100644
index b3e9865..0000000 100644
--- a/src/Board.js
+++ /dev/null
@@ -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;
    // TODO: Improve
    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;
diff --git a/src/Game.js b/src/Game.js
index 4386be7..9687762 100644
--- a/src/Game.js
+++ a/src/Game.js
@@ -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];

// cell is a string identifier from the Deck identifying the Tile (A1-D4)
// id is the index of the cell in the cells array
function validMove(cell, id, lastPlayedTile) {
  // If first move, only allow borders
  if (tile === null) {
    return borders.includes(id);
  if (lastPlayedTile === null) {
    return BORDER_TILE_IDS.includes(id);
  }
  // else match against the last played tile
  return cell[0] === tile[0] || cell[1] === tile[1];
  return cell[0] === lastPlayedTile[0] || cell[1] === lastPlayedTile[1];
}

// Claimed tiles are set to 0 or 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) {