NewGame: game board configuration
- GameBoard interactivity
This commit is contained in:
parent
016423aeb6
commit
b6146eed6b
@ -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
|
||||
|
@ -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();
|
||||
|
||||
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" },
|
||||
const BlackTile = () => {
|
||||
return <div className='Tile black' />
|
||||
}
|
||||
}
|
||||
|
||||
function WhiteTile({ id, stone }) {
|
||||
const WhiteTile = ({ id }) => {
|
||||
const stone = board[id];
|
||||
const isInteractive = (typeof onClick === 'function') ? ' interactive' : '';
|
||||
|
||||
return (
|
||||
<div className='Tile white'
|
||||
onClick={() => console.log('click', id)}
|
||||
>
|
||||
<div className={'Tile white' + isInteractive} onClick={() => isInteractive && onClick(id)}>
|
||||
<Stone color={stone?.color} type={stone?.type} />
|
||||
</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() {
|
||||
return <div className='Tile black' />
|
||||
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,
|
||||
}
|
||||
|
||||
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'>
|
||||
<ActionPanel gamesApi={gamesApi} />
|
||||
{/* <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} />
|
||||
</div>
|
||||
|
||||
|
@ -14,7 +14,7 @@
|
||||
margin-top: -1px;
|
||||
}
|
||||
|
||||
.GameBoard .Tile.white:hover {
|
||||
.GameBoard .Tile.white.interactive:hover {
|
||||
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 { 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 (
|
||||
<div className='GameBoard'>
|
||||
<Player color={opponentColor || Color.white} name={opponentName} />
|
||||
<Board game={game} />
|
||||
<Board game={game} onClick={optionalOnClick} />
|
||||
<Player color={game?.myColor || Color.black} name={myName} />
|
||||
</div>
|
||||
)
|
||||
|
@ -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: '',
|
||||
},
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user