Created
October 18, 2022 02:09
-
-
Save msukmanowsky/986fc87ccaa3879a878fef90718fa7bb to your computer and use it in GitHub Desktop.
TicTacToe using boardgame.io
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { Game, Move } from "boardgame.io"; | |
import { INVALID_MOVE } from "boardgame.io/core"; | |
export interface TicTacToeState { | |
cells: (null | string)[]; | |
} | |
function isVictory(cells: (null | string)[]): boolean { | |
const positions = [ | |
// Horizontal | |
[0, 1, 2], | |
[3, 4, 5], | |
[6, 7, 8], | |
// Vertical | |
[0, 3, 6], | |
[1, 4, 7], | |
[2, 5, 8], | |
// Diagonal | |
[0, 4, 8], | |
[2, 4, 6], | |
]; | |
const isRowComplete = (row: number[]) => { | |
const symbols = row.map((i) => cells[i]); | |
return symbols.every((i) => i !== null && i === symbols[0]); | |
}; | |
return positions.map(isRowComplete).some((i) => i === true); | |
} | |
function isDraw(cells: (null | string)[]): boolean { | |
return cells.filter((c) => c === null).length === 0; | |
} | |
export const TicTacToe: Game<TicTacToeState> = { | |
name: "TicTacToe", | |
setup: () => ({ cells: Array(9).fill(null) }), | |
turn: { | |
minMoves: 1, | |
maxMoves: 1, | |
}, | |
moves: { | |
clickCell: ({ G, playerID }, id) => { | |
if (G.cells[id] !== null) { | |
return INVALID_MOVE; | |
} | |
G.cells[id] = playerID; | |
}, | |
}, | |
endIf: ({ G, ctx }) => { | |
if (isVictory(G.cells)) { | |
return { winner: ctx.currentPlayer }; | |
} | |
if (isDraw(G.cells)) { | |
return { draw: true }; | |
} | |
}, | |
}; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import type { NextPage } from "next"; | |
import TicTacToeClient from "../components/TicTacToeClient"; | |
const Home: NextPage = () => { | |
return <TicTacToeClient />; | |
}; | |
export default Home; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Ctx } from "boardgame.io"; | |
import type { BoardProps } from "boardgame.io/react"; | |
import { TicTacToeState } from "../src/Game"; | |
export interface TicTacToeBoardProps extends BoardProps<TicTacToeState> {} | |
function getWinner(ctx: Ctx): string | null { | |
if (!ctx.gameover) return null; | |
if (ctx.gameover.draw) return "Draw"; | |
return `Player ${ctx.gameover.winner} wins!`; | |
} | |
export default function TicTacToeBoard({ ctx, G, moves }: TicTacToeBoardProps) { | |
const winner = getWinner(ctx); | |
const tbody = []; | |
for (let row = 0; row < 3; row++) { | |
let cells = []; | |
for (let col = 0; col < 3; col++) { | |
const id = 3 * row + col; | |
cells.push( | |
<td key={id}> | |
{G.cells[id] ? ( | |
<div>{G.cells[id]}</div> | |
) : ( | |
<button | |
style={{ width: "2rem", height: "2rem" }} | |
onClick={() => moves.clickCell(id)} | |
/> | |
)} | |
</td> | |
); | |
} | |
tbody.push(<tr key={row}>{cells}</tr>); | |
} | |
return ( | |
<div> | |
<h1>TicTacToe</h1> | |
<table id="board"> | |
<tbody>{tbody}</tbody> | |
</table> | |
{winner && <p>{winner}</p>} | |
</div> | |
); | |
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
import { Client } from "boardgame.io/react"; | |
import { TicTacToe } from "../src/Game"; | |
import TicTacToeBoard from "./TicTacToeBoard"; | |
export default Client({ game: TicTacToe, board: TicTacToeBoard }); |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment