Skip to content

Instantly share code, notes, and snippets.

Embed
What would you like to do?
type square =
| Blank
| O
| X;
let stringOfSquare = square =>
switch (square) {
| Blank => "b"
| O => "o"
| X => "x"
};
type turn =
| O
| X;
let stringOfTurn = turn =>
switch (turn) {
| O => "O"
| X => "X"
};
let otherTurn = turn =>
switch (turn) {
| O => X
| X => O
};
let squareOfTurn = (turn: turn): square =>
switch turn {
| X => X
| O => O
};
type grid = array(array(square));
let initialGrid: grid = Array.make_matrix(3, 3, Blank);
let squareOfIndex = (grid: array(array(square)), index) => {
let (row, col) = (index / 3, index mod 3);
Array.get(Array.get(grid, row), col)
};
let nextGrid = (grid, index, newValue) =>
grid
|> Array.mapi((rowi, rows) => {
rows
|> Array.mapi((coli, square) => {
let (ri, ci) = (index / 3, index mod 3);
(rowi == ri && coli == ci) ? newValue : square;
});
}
);
let checkWon = (grid: grid): bool => {
let check = (x, y, z) =>
if (x == Blank) {
false
} else {
x == y && x == z
};
switch grid {
| [|[|x, y, z|], _, _|] when check(x, y, z) => true
| [|_, [|x, y, z|], _|] when check(x, y, z) => true
| [|_, _, [|x, y, z|]|] when check(x, y, z) => true
| [|[|x, _, _|], [|y, _, _|], [|z, _, _|]|] when check(x, y, z) => true
| [|[|_, x, _|], [|_, y, _|], [|_, z, _|]|] when check(x, y, z) => true
| [|[|_, _, x|], [|_, _, y|], [|_, _, z|]|] when check(x, y, z) => true
| [|[|x, _, _|], [|_, y, _|], [|_, _, z|]|] when check(x, y, z) => true
| [|[|_, _, x|], [|_, y, _|], [|z, _, _|]|] when check(x, y, z) => true
| _ => false
};
};
[@react.component]
let make = () => {
let (grid, setGrid) = React.useState(() => initialGrid);
let (turn, setTurn) = React.useState(() => X);
let (message, setMessage) = React.useState(() => "");
React.useEffect1(
() => {
setMessage(_ => stringOfTurn(turn) ++ "'s turn")
None
},
[|turn|],
);
let changeSquare = (position, turn) => {
let square = squareOfIndex(grid, position);
if (square == Blank) {
setGrid(_ => nextGrid(grid, position, squareOfTurn(turn)));
if (checkWon(grid)) {
setMessage(_ => stringOfTurn(turn) ++ " WON!!!!!!!!!!!!!");
} else {
setTurn(_ => otherTurn(turn));
};
} else {
Js.log("cannot put there");
}
Js.log(("this square is", square));
Js.log(("current turn is", turn));
Js.log(("position is", position));
};
let setupSquare = (square, position: int) => {
<button
key={string_of_int(position)}
onClick={_ => changeSquare(position, turn)}>
{React.string(stringOfSquare(square))}
</button>;
};
let showGrid = grid => {
grid
|> Array.mapi((rowi, rows) =>
<div>
{rows
|> Array.mapi((coli, square) =>
setupSquare(square, rowi * 3 + coli)
)
|> React.array}
</div>
)
|> React.array;
};
<div>
<p> {React.string(message)} </p>
{showGrid(grid)}
</div>;
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment