diff options
-rw-r--r-- | api/game/socket.py | 10 | ||||
-rwxr-xr-x | api/game/voerbak | bin | 16592 -> 16624 bytes | |||
-rw-r--r-- | api/game/voerbak.c | 11 | ||||
-rw-r--r-- | api/game/voerbak_connector.py | 3 | ||||
-rw-r--r-- | components/gameBar.tsx | 8 | ||||
-rw-r--r-- | pages/game.tsx | 140 |
6 files changed, 127 insertions, 45 deletions
diff --git a/api/game/socket.py b/api/game/socket.py index 33fbf1b..f4ea3a5 100644 --- a/api/game/socket.py +++ b/api/game/socket.py @@ -17,6 +17,12 @@ class game: # if not self.board.player_1 == player_1_move: return self.board.drop_fisje(column) self.io.emit("fieldUpdate", { "field": self.board.board }) + self.io.emit("turnUpdate", { "player1": self.board.player_1 }) + if len(self.board.win_positions) > 0 or self.board.board_full: + self.io.emit("finish", { + "winPositions": self.board.win_positions, + "boardFull": self.board.board_full + }) def run(app): io = SocketIO(app, cors_allowed_origins="*") @@ -30,7 +36,9 @@ def run(app): @io.on("newMove") def new_move(data): # json_data = json.loads(data) - games[0].move(data["token"], data["move"]) + game = games[0] + if(len(game.board.win_positions) > 0 or game.board.board_full): return + game.move(data["token"], data["move"]) io.run(app, host="127.0.0.1", port=5000, debug=True) diff --git a/api/game/voerbak b/api/game/voerbak Binary files differindex e7b7a14..e474172 100755 --- a/api/game/voerbak +++ b/api/game/voerbak diff --git a/api/game/voerbak.c b/api/game/voerbak.c index f0ecb4a..5674f5e 100644 --- a/api/game/voerbak.c +++ b/api/game/voerbak.c @@ -60,6 +60,12 @@ bool checkWin(int board[], int width, int height, int pos) { return won; } +bool boardFull(int board[], int width, int height) { + for (int i = 0; i < width * height; i++) + if (board[i] == 0) return false; + return true; +} + bool dropFisje(int board[], int width, int height, int column, int disc) { for (int row = 0; row < height; row++) { int pos = column + row * width; @@ -93,6 +99,11 @@ int main() { printf("m:%s\n", player_1 ? "true" : "false"); fflush(stdout); + if (boardFull(board, width, height)) { + printf("d:full\n"); + fflush(stdout); + } + printBoard(board, width, height); } diff --git a/api/game/voerbak_connector.py b/api/game/voerbak_connector.py index 9627f29..5ccaed8 100644 --- a/api/game/voerbak_connector.py +++ b/api/game/voerbak_connector.py @@ -20,6 +20,7 @@ class bord: self.height = h self.player_1 = True self.board = "0" * (w * h) + self.board_full = False self.win_positions = [] self.process = subprocess.Popen([VOERBAK_LOCATION], stdin=subprocess.PIPE, @@ -42,6 +43,8 @@ class bord: elif buffer.startswith("m:"): substr = buffer[2:] self.player_1 = True if substr == "true" else False + elif buffer.startswith("d:"): + self.board_full = True buffer = self.get_output() self.board = buffer diff --git a/components/gameBar.tsx b/components/gameBar.tsx index daa723e..b1e6a2d 100644 --- a/components/gameBar.tsx +++ b/components/gameBar.tsx @@ -26,7 +26,9 @@ var GameBarAlignStyle: CSSProperties = { display: "inline-block" } -export function GameBar() { +export function GameBar(props: { + turn: boolean; +}) { return <Vierkant className="gameBar" style={{ padding: 8, width: "calc(100% - 12px)" @@ -36,7 +38,7 @@ export function GameBar() { <div style={{ width: 32, height: 32, margin: 8, - backgroundColor: "var(--disk-b)", + backgroundColor: props.turn ? "var(--disk-b)" : "var(--disk-a)", borderRadius: 16, display: "inline-block" }}/> @@ -45,7 +47,7 @@ export function GameBar() { margin: 12, verticalAlign: "top", display: "inline-block" - }}>Tegenstander</h2> + }}>{ props.turn ? "Jouw beurt" : "Tegenstander" }</h2> </div> <div style={{ ...GameBarAlignStyle, diff --git a/pages/game.tsx b/pages/game.tsx index 8be8f5a..57eca5e 100644 --- a/pages/game.tsx +++ b/pages/game.tsx @@ -9,37 +9,12 @@ import { CenteredPage } from '../components/page'; import { VoerBord } from '../components/voerBord'; import { DialogBox } from '../components/dialogBox'; import { CurrentGameSettings } from '../components/gameSettings'; -import { Button, SearchBar } from '../components/ui'; +import { Button, SearchBar, IconLabelButton } from '../components/ui'; import { GameBar } from '../components/gameBar'; import WifiTetheringRoundedIcon from '@material-ui/icons/WifiTetheringRounded'; import LinkRoundedIcon from '@material-ui/icons/LinkRounded'; - -var InviteButtonStyle: CSSProperties = { - backgroundColor: "var(--page-background)", - height: 160, - padding: 12 -} - -var InviteButtonIconStyle: CSSProperties = { - fontSize: 100, - position: "absolute", - top: 12, - left: "50%", - transform: "translateX(-50%)" -} - -var InviteButtonLabelStyle: CSSProperties = { - position: "absolute", - bottom: 12, - left: "50%", - transform: "translateX(-50%)", - textAlign: "center", - color: "var(--text-alt)", - width: 136, - fontSize: 20, - userSelect: "none" -} +import RefreshIcon from '@material-ui/icons/Refresh'; interface VoerGameProps { @@ -50,19 +25,30 @@ class VoerGame extends Component<VoerGameProps> { super(props); if (typeof document === "undefined") return; - this.io = socket(window.location.origin, { resource: 'api/game/socket/socket.io' }); - - this.io.on("connect", () => { - console.log("connect") - this.io.emit("resign", {"cool": "data"}); - }) - this.io.on("disconnect", () => { - console.log("disconnect") - }) + this.io = socket(); + + this.io.on("connect", () => console.log("connect")); + this.io.on("disconnect", () => console.log("disconnect")); + this.io.on("fieldUpdate", (data: { field: string }) => { + this.setState({ board: data.field.split("").map(i => Number(i)) }); for(let i = 0; i < data.field.length; i++) document.getElementById(`pos-${i}`).parentNode.children.item(1).classList.add(`state-${data.field[i]}`); - }) + }); + + this.io.on("turnUpdate", (data: { player1: boolean }) => this.setState({ turn: data.player1 })); + + this.io.on("finish", (data: { + winPositions: Array<Array<number>> + boardFull: boolean }) => { + + this.setState({ winPositions: data.winPositions }); + + var outcome = -1; + if (data.winPositions.length > 0) outcome = this.state.board[data.winPositions[0][0]]; + if (data.boardFull) outcome = 0; + this.setState({ outcome }); + }); } io: Socket; @@ -72,9 +58,17 @@ class VoerGame extends Component<VoerGameProps> { state: { userID: string; + turn: boolean; + winPositions: Array<Array<number>>; + outcome: number; + board: Array<number>; } = { - userID: "" - } + userID: "", + turn: true, + winPositions: [], + outcome: -1, + board: [], + }; board = [...Array(this.width * this.height)].map(() => 0); userID = ""; @@ -93,7 +87,7 @@ class VoerGame extends Component<VoerGameProps> { move: column, token: cookies.load("token"), gameID: "fortnite" - }) + }); } render() { @@ -105,11 +99,75 @@ class VoerGame extends Component<VoerGameProps> { margin: "0 auto" }}> <VoerBord width={this.width} height={this.height} onMove={m => this.move(m % this.width + 1)}/> - <GameBar/> + <GameBar turn={this.state.turn}/> + <GameOutcomeDialog outcome={this.state.outcome} visible={this.state.outcome != -1}/> </div> } } +function GameOutcomeDialog(props: { + outcome: number; + visible: boolean; +}) { + return <DialogBox title="Speluitkomst" style={{ display: props.visible ? "inline-block" : "none" }}> + <div style={{ + width: "100%", + textAlign: "center" + }}> + <h2 style={{ + color: + props.outcome == 0 ? "var(--text)" : + props.outcome == 1 ? "var(--disk-a-text)" : + props.outcome == 2 ? "var(--disk-b-text)" : + "var(--text)", + opacity: props.outcome == 0 ? .75 : 1, + marginTop: 8 + }}>{ + props.outcome == 0 ? "Gelijkspel" : + props.outcome == 1 ? "Verloren" : + props.outcome == 2 ? "Gewonnen" : + "???" + }</h2> + { false && <p style={{ marginTop: 24 }}> + 0 Gemiste winstzetten<br/> + 6 Optimale zetten<br/> + 0 Blunders + </p> } + <IconLabelButton text="Opnieuw spelen" icon={<RefreshIcon/>} style={{ + float: "none", + marginTop: 24, + padding: "12px 32px" + }}/> + </div> + </DialogBox> +} + +var InviteButtonStyle: CSSProperties = { + backgroundColor: "var(--page-background)", + height: 160, + padding: 12 +} + +var InviteButtonIconStyle: CSSProperties = { + fontSize: 100, + position: "absolute", + top: 12, + left: "50%", + transform: "translateX(-50%)" +} + +var InviteButtonLabelStyle: CSSProperties = { + position: "absolute", + bottom: 12, + left: "50%", + transform: "translateX(-50%)", + textAlign: "center", + color: "var(--text-alt)", + width: 136, + fontSize: 20, + userSelect: "none" +} + export default function GamePage() { return ( <div> |