Created
September 13, 2020 11:32
-
-
Save adeonhy/1ec97f1229dd47f0c4d189ca7bf2b7bb to your computer and use it in GitHub Desktop.
This file contains hidden or 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
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