diff --git a/backend/src/main/java/djmil/cordacheckers/api/GameProposalController.java b/backend/src/main/java/djmil/cordacheckers/api/GameProposalController.java
index 490f1d9..f209746 100644
--- a/backend/src/main/java/djmil/cordacheckers/api/GameProposalController.java
+++ b/backend/src/main/java/djmil/cordacheckers/api/GameProposalController.java
@@ -50,7 +50,7 @@ public class GameProposalController {
gpSender,
gpReceiver,
gpReceiverColor,
- // gpRequest.board() // GiteaIssue #3: use provided board configuration
+ gpRequest.board(),
gpRequest.message());
URI locationOfNewGameProposal = ucb
diff --git a/webapp/src/components/Checkers.jsx b/webapp/src/components/Checkers.jsx
index be54ea1..52ed697 100644
--- a/webapp/src/components/Checkers.jsx
+++ b/webapp/src/components/Checkers.jsx
@@ -65,102 +65,103 @@ export function Player({ color, name }) {
/*
* Board
*/
-export function Board({ game }) {
+export function Board({ game, onClick }) {
+ const board = (game && game.board && typeof game.board === 'object') ? game.board : defaultBoard;
- const board = (game && game.board && typeof game.board === 'object') ? game.board : defaultBoard();
+ const BlackTile = () => {
+ return
+ }
+
+ const WhiteTile = ({ id }) => {
+ const stone = board[id];
+ const isInteractive = (typeof onClick === 'function') ? ' interactive' : '';
+
+ return (
+ isInteractive && onClick(id)}>
+
+
+ );
+ }
return
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
-
-
-
-
+
+
+
+
}
-function defaultBoard() {
- return {
- 1: { color: "BLACK", type: "MAN" },
- 2: { color: "BLACK", type: "MAN" },
- 3: { color: "BLACK", type: "MAN" },
- 4: { color: "BLACK", type: "MAN" },
- 5: { color: "BLACK", type: "MAN" },
- 6: { color: "BLACK", type: "MAN" },
- 7: { color: "BLACK", type: "MAN" },
- 8: { color: "BLACK", type: "MAN" },
- 9: { color: "BLACK", type: "MAN" },
- 10: { color: "BLACK", type: "MAN" },
- 11: { color: "BLACK", type: "MAN" },
- 12: { color: "BLACK", type: "MAN" },
- 21: { color: "WHITE", type: "MAN" },
- 22: { color: "WHITE", type: "MAN" },
- 23: { color: "WHITE", type: "MAN" },
- 24: { color: "WHITE", type: "MAN" },
- 25: { color: "WHITE", type: "MAN" },
- 26: { color: "WHITE", type: "MAN" },
- 27: { color: "WHITE", type: "MAN" },
- 28: { color: "WHITE", type: "MAN" },
- 29: { color: "WHITE", type: "MAN" },
- 30: { color: "WHITE", type: "MAN" },
- 31: { color: "WHITE", type: "MAN" },
- 32: { color: "WHITE", type: "MAN" },
- }
+const blackMan = { color: Color.black, type: 'MAN' };
+const blackKing = { color: Color.black, type: 'KING' };
+const whiteMan = { color: Color.white, type: 'MAN' };
+const whiteKing = { color: Color.white, type: 'KING' };
+
+export const defaultBoard = {
+ 1: blackMan, 2: blackMan, 3: blackMan, 4: blackMan, 5: blackMan, 6: blackMan, 7: blackMan, 8: blackMan, 9: blackMan, 10: blackMan, 11: blackMan, 12: blackMan,
+ 21: whiteMan, 22: whiteMan, 23: whiteMan, 24: whiteMan, 25: whiteMan, 26: whiteMan, 27: whiteMan, 28: whiteMan, 29: whiteMan, 30: whiteMan, 31: whiteMan, 32: whiteMan,
}
-function WhiteTile({ id, stone }) {
- return (
- console.log('click', id)}
- >
-
-
- );
-}
+export function nextStone(currentStone) {
+ const color = currentStone?.color;
+ const type = currentStone?.type;
-function BlackTile() {
- return
+ if (!color || !type)
+ return blackMan;
+
+ if (color === Color.black && type === 'MAN')
+ return blackKing;
+
+ if (color === Color.black && type === 'KING')
+ return whiteMan;
+
+ if (color === Color.white && type === 'MAN')
+ return whiteKing;
+
+ if (color === Color.white && type === 'KING')
+ return null;
}
\ No newline at end of file
diff --git a/webapp/src/container/Games.jsx b/webapp/src/container/Games.jsx
index 38406f4..fd8d594 100644
--- a/webapp/src/container/Games.jsx
+++ b/webapp/src/container/Games.jsx
@@ -26,7 +26,11 @@ export default function Games({ context: { gamesReducer, gamesApi }, players })
{/*
*/}
-
+
dispatchGames({ type: 'nextNewGame', board })}
+ onActiveGameMove={(uuid, from, to) => console.log(uuid, 'move', from, '->', to)}
+ />
diff --git a/webapp/src/container/games/GameBoard.css b/webapp/src/container/games/GameBoard.css
index bd5e884..2c90743 100644
--- a/webapp/src/container/games/GameBoard.css
+++ b/webapp/src/container/games/GameBoard.css
@@ -14,7 +14,7 @@
margin-top: -1px;
}
-.GameBoard .Tile.white:hover {
+.GameBoard .Tile.white.interactive:hover {
background-color:azure;
}
diff --git a/webapp/src/container/games/GameBoard.jsx b/webapp/src/container/games/GameBoard.jsx
index dad8c10..22043f9 100644
--- a/webapp/src/container/games/GameBoard.jsx
+++ b/webapp/src/container/games/GameBoard.jsx
@@ -1,35 +1,58 @@
-import React, { useContext } from 'react';
+import React, { useContext, useState } from 'react';
import { useLocation, matchPath } from 'react-router-dom';
import { GamesContext } from '../../context/games';
-import { Color, Player, Board } from '../../components/Checkers';
+import { Color, Player, Board, nextStone } from '../../components/Checkers';
import './GameBoard.css';
-export default function GameBoard({ username }) {
+export default function GameBoard({ username, onNewGameBoardStone, onActiveGameMove }) {
const games = useContext(GamesContext);
const { pathname } = useLocation();
+ const [startId, setStartId] = useState(null);
- const game = (() => {
+ const onClick_NewGame = (cellId) => {
+ let nextBoard = { ...games.newGame.board };
+ nextBoard[cellId] = nextStone(nextBoard[cellId]);
+
+ onNewGameBoardStone(nextBoard);
+ }
+
+ const onClick_ActiveGame = (cellId) => {
+ if (startId === cellId)
+ return setStartId(null);
+
+ if (startId === null)
+ return setStartId(cellId);
+
+ if (game?.uuid)
+ onActiveGameMove(game.uuid, startId, cellId);
+
+ setStartId(null);
+ };
+
+ const [game, onClick] = (() => {
if (matchPath('/games/new', pathname))
- return gameFrom(games.newGame);
+ return [gameFrom(games.newGame), onClick_NewGame];
if (matchPath('/games/proposal', pathname))
- return games.findGame({ uuid: games.proposal.selectedUUID });
+ return [games.findGame({ uuid: games.proposal.selectedUUID }), null];
else if (matchPath('/games/active', pathname))
- return games.findGame({ uuid: games.active.selectedUUID });
+ return [games.findGame({ uuid: games.active.selectedUUID }), onClick_ActiveGame];
else if (matchPath('/games/archive', pathname))
- return games.findGame({ uuid: games.archive.selectedUUID });
+ return [games.findGame({ uuid: games.archive.selectedUUID }), null];
- return {}; // defaults
+ return [{}, null]; // defaults
})(); // <<-- Execute
const opponentColor = Color.opposite(game?.myColor);
const [opponentName, myName] = game?.opponentName ? [game.opponentName, username] : ['', ''];
+ const optionalOnClick = (onClick && game?.board) ? (id) => onClick(id) : null;
+
return (
)
diff --git a/webapp/src/reducer/games.js b/webapp/src/reducer/games.js
index 379d4e8..71f20f7 100644
--- a/webapp/src/reducer/games.js
+++ b/webapp/src/reducer/games.js
@@ -1,5 +1,6 @@
import { useReducer } from 'react';
import { nextState } from '../util/StateHelper';
+import { defaultBoard } from '../components/Checkers';
export const gamesInitialState = {
gamesList: null,
@@ -7,7 +8,7 @@ export const gamesInitialState = {
newGame: {
opponentName: '',
opponentColor: '',
- board: null,
+ board: defaultBoard,
message: '',
},