diff --git a/src/Home.tsx b/src/Home.tsx index f10ae33..07b0263 100644 --- a/src/Home.tsx +++ b/src/Home.tsx @@ -1,35 +1,89 @@ import * as React from 'react'; -import { FunctionComponent, useState } from 'react'; -import {context} from './context' +import { FunctionComponent, useState } from 'react'; +import BoardView from './components/BoardView'; +import { context } from './context' +import { Board, GameMove, Hole, Store } from './mancala'; +import { Game } from './mancala'; +import { decodeText, encodeText } from './rtmt/byte_util'; +import { Bytes } from './rtmt/rtmt'; import { RTMTWS } from './rtmt/rtmt_websocket'; +import { channel_game_move, channel_leave_game, channel_on_game_update } from './channel_names'; -const Home:FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => { - const [clicks, setClicks] = useState(initial); +const testBoard = (): Board => { + const board = new Board( + [new Hole(0), new Hole(4), new Hole(4), new Hole(3), new Hole(2), new Hole(1)], + [new Hole(4), new Hole(4), new Hole(4), new Hole(4), new Hole(4), new Hole(10)], + new Store(0), new Store(0)) + return board +} - React.useEffect(()=>{ +const testGame = new Game("0", "1", testBoard(), "player2") - +const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => { + const [userKey, setUserKey] = useState(undefined); - const rtmtws = context.rtmt as RTMTWS - if(rtmtws){ - rtmtws.initWebSocket(onConnectionDone) - }else{ - console.log("context.rtmt is not RTMTWS"); - } - }) + const [game, setGame] = useState(undefined) - const onConnectionDone = ()=>{ - context.rtmt.sendMessage("new_game", "") - context.rtmt.listenMessage("new_game", (message)=>{ - console.log("new message"); + React.useEffect(() => { + context.userKeyStore.getUserKey((userKey: string) => { + setUserKey(userKey) + const rtmtws = context.rtmt as RTMTWS + if (rtmtws) { + rtmtws.initWebSocket(userKey, onConnectionDone) + } else { + console.log("context.rtmt is not RTMTWS"); + } + }) + + context.rtmt.listenMessage(channel_on_game_update, (message: Bytes) => { + const newGame: Game = JSON.parse(decodeText(message)) + console.log("on game update"); + console.log(newGame); + setGame(new Game(newGame.player1, newGame.player2, newGame.board, newGame.turn)) + }) + + context.rtmt.listenMessage(channel_on_game_update, (message: Bytes) => { + const newGame: Game = JSON.parse(decodeText(message)) + console.log("on game update"); + console.log(newGame); + setGame(new Game(newGame.player1, newGame.player2, newGame.board, newGame.turn)) + }) + }, []) + + const onConnectionDone = () => { + + } + + const newGameClick = () => { + context.rtmt.sendMessage("new_game", new Uint8Array()) + context.rtmt.listenMessage("on_game_start", (message) => { + const newGame: Game = JSON.parse(decodeText(message)) + console.log("on_game_start"); + console.log(newGame); + setGame(new Game(newGame.player1, newGame.player2, newGame.board, newGame.turn)) }) } - return <> -

Clicks: {clicks}

- - - + const leaveGame = () => { + context.rtmt.sendMessage(channel_leave_game, new Uint8Array()) + } + + const onHoleSelect = (index: number, hole: Hole) => { + const gameMove: GameMove = { index: index } + context.rtmt.sendMessage(channel_game_move, encodeText(JSON.stringify(gameMove))) + } + + return
+

Mancala

+ {!game && } + {game && } + {game && } + {game &&
{game.checkGameTurn(userKey) ? "Your Turn" : "Opponent Turn"}
} +
} export default Home \ No newline at end of file diff --git a/src/channel_names.ts b/src/channel_names.ts new file mode 100644 index 0000000..2324d47 --- /dev/null +++ b/src/channel_names.ts @@ -0,0 +1,6 @@ +export const channel_new_game = "new_game" +export const channel_on_game_start = "on_game_start" +export const channel_game_move = "game_move" +export const channel_on_game_update = "on_game_update" +export const channel_leave_game = "leave_game" +export const channel_on_game_end = "on_game_end" diff --git a/src/components/BoardView.tsx b/src/components/BoardView.tsx new file mode 100644 index 0000000..b7addf3 --- /dev/null +++ b/src/components/BoardView.tsx @@ -0,0 +1,112 @@ +import * as React from 'react'; +import { FunctionComponent, useState } from 'react'; +import { Hole, Store, Game } from '../mancala'; + +const BallView: FunctionComponent = () => { + + return (
+
) +} + +function range(size: number) { + var ans = []; + for (let i = 0; i < size; i++) { + ans.push(i); + } + return ans; +} + +const HoleView: FunctionComponent<{ hole: Hole, color: string, onClick: () => void }> = ({ hole, color, onClick }) => { + const balls = [...range(hole.ballCount)].map((i) => ) + + return (
+ {balls} +
) +} + +const StoreView: FunctionComponent< + { store: Store, color: string, gridColumn: string, gridRow: string }> = ({ store, color, gridColumn, gridRow }) => { + const balls = [...range(store.ballCount)].map((i) => ) + return (
+ {balls} +
) + } + +const BoardView: FunctionComponent<{ game?: Game, userKey: string, onHoleSelect: (index: number, hole: Hole) => void }> = ({ + game, userKey, onHoleSelect }) => { + + const player1Holes = game?.board.player1Holes.map((hole) => ( + { + if (game.turn == "player1") onHoleSelect(game.board.player1Holes.indexOf(hole), hole) + }} /> + )) + + const player2Holes = game!!.board.player2Holes.map((hole) => ( + { + if (game.turn == "player2") onHoleSelect(game.board.player2Holes.indexOf(hole), hole) + }} /> + )) + + return ( +
+ { + game.getPlayerNameByKey(userKey) == "player2" ? ( + <> + + + {player1Holes.reverse()} + {player2Holes} + + ) : ( + <> + + + {player2Holes.reverse()} + {player1Holes} + + ) + } + +
+ ) +} + +export default BoardView \ No newline at end of file