NewGame: game board configuration
- GameBoard interactivity
This commit is contained in:
parent
016423aeb6
commit
b6146eed6b
@ -50,7 +50,7 @@ public class GameProposalController {
|
|||||||
gpSender,
|
gpSender,
|
||||||
gpReceiver,
|
gpReceiver,
|
||||||
gpReceiverColor,
|
gpReceiverColor,
|
||||||
// gpRequest.board() // GiteaIssue #3: use provided board configuration
|
gpRequest.board(),
|
||||||
gpRequest.message());
|
gpRequest.message());
|
||||||
|
|
||||||
URI locationOfNewGameProposal = ucb
|
URI locationOfNewGameProposal = ucb
|
||||||
|
@ -65,102 +65,103 @@ export function Player({ color, name }) {
|
|||||||
/*
|
/*
|
||||||
* Board
|
* 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 <div className='Tile black' />
|
||||||
return <div className='Board'>
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile /> <WhiteTile id={1} stone={board[1]} />
|
|
||||||
<BlackTile /> <WhiteTile id={2} stone={board[2]} />
|
|
||||||
<BlackTile /> <WhiteTile id={3} stone={board[3]} />
|
|
||||||
<BlackTile /> <WhiteTile id={4} stone={board[4]} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={5} stone={board[5]} /> <BlackTile />
|
|
||||||
<WhiteTile id={6} stone={board[6]} /> <BlackTile />
|
|
||||||
<WhiteTile id={7} stone={board[7]} /> <BlackTile />
|
|
||||||
<WhiteTile id={8} stone={board[8]} /> <BlackTile />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile /> <WhiteTile id={9} stone={board[9]} />
|
|
||||||
<BlackTile /> <WhiteTile id={10} stone={board[10]} />
|
|
||||||
<BlackTile /> <WhiteTile id={11} stone={board[11]} />
|
|
||||||
<BlackTile /> <WhiteTile id={12} stone={board[12]} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={13} stone={board[13]} /> <BlackTile />
|
|
||||||
<WhiteTile id={14} stone={board[14]} /> <BlackTile />
|
|
||||||
<WhiteTile id={15} stone={board[15]} /> <BlackTile />
|
|
||||||
<WhiteTile id={16} stone={board[16]} /> <BlackTile />
|
|
||||||
</div>
|
|
||||||
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile /> <WhiteTile id={17} stone={board[17]} />
|
|
||||||
<BlackTile /> <WhiteTile id={18} stone={board[18]} />
|
|
||||||
<BlackTile /> <WhiteTile id={19} stone={board[19]} />
|
|
||||||
<BlackTile /> <WhiteTile id={20} stone={board[20]} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={21} stone={board[21]} /> <BlackTile />
|
|
||||||
<WhiteTile id={22} stone={board[22]} /> <BlackTile />
|
|
||||||
<WhiteTile id={23} stone={board[23]} /> <BlackTile />
|
|
||||||
<WhiteTile id={24} stone={board[24]} /> <BlackTile />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<BlackTile /> <WhiteTile id={25} stone={board[25]} />
|
|
||||||
<BlackTile /> <WhiteTile id={26} stone={board[26]} />
|
|
||||||
<BlackTile /> <WhiteTile id={27} stone={board[27]} />
|
|
||||||
<BlackTile /> <WhiteTile id={28} stone={board[28]} />
|
|
||||||
</div>
|
|
||||||
<div className='row'>
|
|
||||||
<WhiteTile id={29} stone={board[29]} /> <BlackTile />
|
|
||||||
<WhiteTile id={30} stone={board[30]} /> <BlackTile />
|
|
||||||
<WhiteTile id={31} stone={board[31]} /> <BlackTile />
|
|
||||||
<WhiteTile id={32} stone={board[32]} /> <BlackTile />
|
|
||||||
</div>
|
|
||||||
</div>
|
|
||||||
}
|
|
||||||
|
|
||||||
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" },
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function WhiteTile({ id, stone }) {
|
const WhiteTile = ({ id }) => {
|
||||||
|
const stone = board[id];
|
||||||
|
const isInteractive = (typeof onClick === 'function') ? ' interactive' : '';
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='Tile white'
|
<div className={'Tile white' + isInteractive} onClick={() => isInteractive && onClick(id)}>
|
||||||
onClick={() => console.log('click', id)}
|
|
||||||
>
|
|
||||||
<Stone color={stone?.color} type={stone?.type} />
|
<Stone color={stone?.color} type={stone?.type} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
return <div className='Board'>
|
||||||
|
<div className='row'>
|
||||||
|
<BlackTile /> <WhiteTile id={1} />
|
||||||
|
<BlackTile /> <WhiteTile id={2} />
|
||||||
|
<BlackTile /> <WhiteTile id={3} />
|
||||||
|
<BlackTile /> <WhiteTile id={4} />
|
||||||
|
</div>
|
||||||
|
<div className='row'>
|
||||||
|
<WhiteTile id={5} /> <BlackTile />
|
||||||
|
<WhiteTile id={6} /> <BlackTile />
|
||||||
|
<WhiteTile id={7} /> <BlackTile />
|
||||||
|
<WhiteTile id={8} /> <BlackTile />
|
||||||
|
</div>
|
||||||
|
<div className='row'>
|
||||||
|
<BlackTile /> <WhiteTile id={9} />
|
||||||
|
<BlackTile /> <WhiteTile id={10} />
|
||||||
|
<BlackTile /> <WhiteTile id={11} />
|
||||||
|
<BlackTile /> <WhiteTile id={12} />
|
||||||
|
</div>
|
||||||
|
<div className='row'>
|
||||||
|
<WhiteTile id={13} /> <BlackTile />
|
||||||
|
<WhiteTile id={14} /> <BlackTile />
|
||||||
|
<WhiteTile id={15} /> <BlackTile />
|
||||||
|
<WhiteTile id={16} /> <BlackTile />
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<div className='row'>
|
||||||
|
<BlackTile /> <WhiteTile id={17} />
|
||||||
|
<BlackTile /> <WhiteTile id={18} />
|
||||||
|
<BlackTile /> <WhiteTile id={19} />
|
||||||
|
<BlackTile /> <WhiteTile id={20} />
|
||||||
|
</div>
|
||||||
|
<div className='row'>
|
||||||
|
<WhiteTile id={21} /> <BlackTile />
|
||||||
|
<WhiteTile id={22} /> <BlackTile />
|
||||||
|
<WhiteTile id={23} /> <BlackTile />
|
||||||
|
<WhiteTile id={24} /> <BlackTile />
|
||||||
|
</div>
|
||||||
|
<div className='row'>
|
||||||
|
<BlackTile /> <WhiteTile id={25} />
|
||||||
|
<BlackTile /> <WhiteTile id={26} />
|
||||||
|
<BlackTile /> <WhiteTile id={27} />
|
||||||
|
<BlackTile /> <WhiteTile id={28} />
|
||||||
|
</div>
|
||||||
|
<div className='row'>
|
||||||
|
<WhiteTile id={29} /> <BlackTile />
|
||||||
|
<WhiteTile id={30} /> <BlackTile />
|
||||||
|
<WhiteTile id={31} /> <BlackTile />
|
||||||
|
<WhiteTile id={32} /> <BlackTile />
|
||||||
|
</div>
|
||||||
|
</div>
|
||||||
}
|
}
|
||||||
|
|
||||||
function BlackTile() {
|
const blackMan = { color: Color.black, type: 'MAN' };
|
||||||
return <div className='Tile black' />
|
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,
|
||||||
|
}
|
||||||
|
|
||||||
|
export function nextStone(currentStone) {
|
||||||
|
const color = currentStone?.color;
|
||||||
|
const type = currentStone?.type;
|
||||||
|
|
||||||
|
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;
|
||||||
}
|
}
|
@ -26,7 +26,11 @@ export default function Games({ context: { gamesReducer, gamesApi }, players })
|
|||||||
<div className='right-side'>
|
<div className='right-side'>
|
||||||
<ActionPanel gamesApi={gamesApi} />
|
<ActionPanel gamesApi={gamesApi} />
|
||||||
{/* <GameMessage /> */}
|
{/* <GameMessage /> */}
|
||||||
<GameBoard username={players.currentUser} />
|
<GameBoard
|
||||||
|
username={players.currentUser}
|
||||||
|
onNewGameBoardStone={(board) => dispatchGames({ type: 'nextNewGame', board })}
|
||||||
|
onActiveGameMove={(uuid, from, to) => console.log(uuid, 'move', from, '->', to)}
|
||||||
|
/>
|
||||||
<Message2Opponent dispatchGames={dispatchGames} />
|
<Message2Opponent dispatchGames={dispatchGames} />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
|
@ -14,7 +14,7 @@
|
|||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.GameBoard .Tile.white:hover {
|
.GameBoard .Tile.white.interactive:hover {
|
||||||
background-color:azure;
|
background-color:azure;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,35 +1,58 @@
|
|||||||
import React, { useContext } from 'react';
|
import React, { useContext, useState } from 'react';
|
||||||
import { useLocation, matchPath } from 'react-router-dom';
|
import { useLocation, matchPath } from 'react-router-dom';
|
||||||
import { GamesContext } from '../../context/games';
|
import { GamesContext } from '../../context/games';
|
||||||
|
|
||||||
import { Color, Player, Board } from '../../components/Checkers';
|
import { Color, Player, Board, nextStone } from '../../components/Checkers';
|
||||||
import './GameBoard.css';
|
import './GameBoard.css';
|
||||||
|
|
||||||
export default function GameBoard({ username }) {
|
export default function GameBoard({ username, onNewGameBoardStone, onActiveGameMove }) {
|
||||||
const games = useContext(GamesContext);
|
const games = useContext(GamesContext);
|
||||||
const { pathname } = useLocation();
|
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))
|
if (matchPath('/games/new', pathname))
|
||||||
return gameFrom(games.newGame);
|
return [gameFrom(games.newGame), onClick_NewGame];
|
||||||
|
|
||||||
if (matchPath('/games/proposal', pathname))
|
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))
|
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))
|
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
|
})(); // <<-- Execute
|
||||||
|
|
||||||
const opponentColor = Color.opposite(game?.myColor);
|
const opponentColor = Color.opposite(game?.myColor);
|
||||||
const [opponentName, myName] = game?.opponentName ? [game.opponentName, username] : ['', ''];
|
const [opponentName, myName] = game?.opponentName ? [game.opponentName, username] : ['', ''];
|
||||||
|
|
||||||
|
const optionalOnClick = (onClick && game?.board) ? (id) => onClick(id) : null;
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className='GameBoard'>
|
<div className='GameBoard'>
|
||||||
<Player color={opponentColor || Color.white} name={opponentName} />
|
<Player color={opponentColor || Color.white} name={opponentName} />
|
||||||
<Board game={game} />
|
<Board game={game} onClick={optionalOnClick} />
|
||||||
<Player color={game?.myColor || Color.black} name={myName} />
|
<Player color={game?.myColor || Color.black} name={myName} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -1,5 +1,6 @@
|
|||||||
import { useReducer } from 'react';
|
import { useReducer } from 'react';
|
||||||
import { nextState } from '../util/StateHelper';
|
import { nextState } from '../util/StateHelper';
|
||||||
|
import { defaultBoard } from '../components/Checkers';
|
||||||
|
|
||||||
export const gamesInitialState = {
|
export const gamesInitialState = {
|
||||||
gamesList: null,
|
gamesList: null,
|
||||||
@ -7,7 +8,7 @@ export const gamesInitialState = {
|
|||||||
newGame: {
|
newGame: {
|
||||||
opponentName: '',
|
opponentName: '',
|
||||||
opponentColor: '',
|
opponentColor: '',
|
||||||
board: null,
|
board: defaultBoard,
|
||||||
message: '',
|
message: '',
|
||||||
},
|
},
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user