movable stones!
This commit is contained in:
parent
dbb70cabba
commit
ae6ba413a2
@ -30,43 +30,49 @@ export default function useGamesApi(gamesReducer, config) {
|
|||||||
pushGameProposalCancel: ({ uuid }) => ifNot(games.isPushingGameProposalCancel) &&
|
pushGameProposalCancel: ({ uuid }) => ifNot(games.isPushingGameProposalCancel) &&
|
||||||
doPushing(`/api/gameproposal/${uuid}/cancel`, 'PUT', null, {
|
doPushing(`/api/gameproposal/${uuid}/cancel`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameProposalCancel) => dispatchGames({ type: 'next', isPushingGameProposalCancel }),
|
onPushing: (isPushingGameProposalCancel) => dispatchGames({ type: 'next', isPushingGameProposalCancel }),
|
||||||
onSuccess: (canceledGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(canceledGame), proposal: gamesInitialState.proposal })
|
onSuccess: (canceledGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(canceledGame), proposal: gamesInitialState.proposal })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameProposalReject: ({ uuid }) => ifNot(games.isPushingGameProposalReject) &&
|
pushGameProposalReject: ({ uuid }) => ifNot(games.isPushingGameProposalReject) &&
|
||||||
doPushing(`/api/gameproposal/${uuid}/reject`, 'PUT', null, {
|
doPushing(`/api/gameproposal/${uuid}/reject`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameProposalReject) => dispatchGames({ type: 'next', isPushingGameProposalReject }),
|
onPushing: (isPushingGameProposalReject) => dispatchGames({ type: 'next', isPushingGameProposalReject }),
|
||||||
onSuccess: (rejectedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(rejectedGame), proposal: gamesInitialState.proposal })
|
onSuccess: (rejectedGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(rejectedGame), proposal: gamesInitialState.proposal })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameProposalAccept: ({ uuid }) => ifNot(games.isPushingGameProposalAccept) &&
|
pushGameProposalAccept: ({ uuid }) => ifNot(games.isPushingGameProposalAccept) &&
|
||||||
doPushing(`/api/gameproposal/${uuid}/accept`, 'PUT', null, {
|
doPushing(`/api/gameproposal/${uuid}/accept`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameProposalAccept) => dispatchGames({ type: 'next', isPushingGameProposalAccept }),
|
onPushing: (isPushingGameProposalAccept) => dispatchGames({ type: 'next', isPushingGameProposalAccept }),
|
||||||
onSuccess: (acceptedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(acceptedGame), proposal: gamesInitialState.proposal })
|
onSuccess: (acceptedGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(acceptedGame), proposal: gamesInitialState.proposal })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameSurrender: ({ uuid }) => ifNot(games.isPushingGameSurrender) &&
|
pushGameSurrender: ({ uuid }) => ifNot(games.isPushingGameSurrender) &&
|
||||||
doPushing(`/api/game/${uuid}/surrender`, 'PUT', null, {
|
doPushing(`/api/game/${uuid}/surrender`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameSurrender) => dispatchGames({ type: 'next', isPushingGameSurrender }),
|
onPushing: (isPushingGameSurrender) => dispatchGames({ type: 'next', isPushingGameSurrender }),
|
||||||
onSuccess: (finishedGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(finishedGame), proposal: gamesInitialState.active })
|
onSuccess: (finishedGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(finishedGame), active: gamesInitialState.active })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameDrawRequest: ({ uuid }) => ifNot(games.isPushingGameDrawRequest) &&
|
pushGameDrawRequest: ({ uuid }) => ifNot(games.isPushingGameDrawRequest) &&
|
||||||
doPushing(`/api/game/${uuid}/drawreq`, 'PUT', null, {
|
doPushing(`/api/game/${uuid}/drawreq`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameDrawRequest) => dispatchGames({ type: 'next', isPushingGameDrawRequest }),
|
onPushing: (isPushingGameDrawRequest) => dispatchGames({ type: 'next', isPushingGameDrawRequest }),
|
||||||
onSuccess: (drawReqGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(drawReqGame), proposal: gamesInitialState.active })
|
onSuccess: (drawReqGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(drawReqGame), active: gamesInitialState.active })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameDrawAccept: ({ uuid }) => ifNot(games.isPushingGameDrawAccept) &&
|
pushGameDrawAccept: ({ uuid }) => ifNot(games.isPushingGameDrawAccept) &&
|
||||||
doPushing(`/api/game/${uuid}/drawacc`, 'PUT', null, {
|
doPushing(`/api/game/${uuid}/drawacc`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameDrawAccept) => dispatchGames({ type: 'next', isPushingGameDrawAccept }),
|
onPushing: (isPushingGameDrawAccept) => dispatchGames({ type: 'next', isPushingGameDrawAccept }),
|
||||||
onSuccess: (drawAccGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(drawAccGame), proposal: gamesInitialState.active })
|
onSuccess: (drawAccGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(drawAccGame), active: gamesInitialState.active })
|
||||||
}),
|
}),
|
||||||
|
|
||||||
pushGameDrawReject: ({ uuid }) => ifNot(games.isPushingGameDrawReject) &&
|
pushGameDrawReject: ({ uuid }) => ifNot(games.isPushingGameDrawReject) &&
|
||||||
doPushing(`/api/game/${uuid}/drawrej`, 'PUT', null, {
|
doPushing(`/api/game/${uuid}/drawrej`, 'PUT', null, {
|
||||||
onPushing: (isPushingGameDrawReject) => dispatchGames({ type: 'next', isPushingGameDrawReject }),
|
onPushing: (isPushingGameDrawReject) => dispatchGames({ type: 'next', isPushingGameDrawReject }),
|
||||||
onSuccess: (drawRejGame) => dispatchGames({ type: 'next', gamesList: games.nextGameList(drawRejGame), proposal: gamesInitialState.active })
|
onSuccess: (drawRejGame) => dispatchGames({ type: 'next', gamesList: games.nextGame(drawRejGame), active: gamesInitialState.active })
|
||||||
|
}),
|
||||||
|
|
||||||
|
pushGameMove: ({ uuid, move, message }) => ifNot(games.isPushingGameMove) &&
|
||||||
|
doPushing(`/api/game/${uuid}/move`, 'PUT', null, {
|
||||||
|
onPushing: (isPushingGameMove) => dispatchGames({ type: 'next', isPushingGameMove }),
|
||||||
|
onSuccess: (game) => dispatchGames({ type: 'next', gamesList: games.nextGame(game), active: gamesInitialState.active })
|
||||||
}),
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
.Stone {
|
.Stone {
|
||||||
cursor: default; /* disable 'I beam' cursor change */
|
cursor: default; /* disable 'I beam' cursor change */
|
||||||
user-select: none;
|
user-select: none;
|
||||||
|
pointer-events: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.Board {
|
.Board {
|
||||||
@ -26,4 +27,8 @@
|
|||||||
|
|
||||||
.Tile.white {
|
.Tile.white {
|
||||||
background: white;
|
background: white;
|
||||||
|
}
|
||||||
|
|
||||||
|
.Tile.selected {
|
||||||
|
color: grey;
|
||||||
}
|
}
|
@ -1,5 +1,5 @@
|
|||||||
import './Checkers.css'
|
import './Checkers.css'
|
||||||
import React from 'react'
|
import React, { useState } from 'react'
|
||||||
|
|
||||||
export const Color = {
|
export const Color = {
|
||||||
white: "WHITE",
|
white: "WHITE",
|
||||||
@ -18,13 +18,19 @@ export const Color = {
|
|||||||
/*
|
/*
|
||||||
* Stone
|
* Stone
|
||||||
*/
|
*/
|
||||||
export function Stone({ color, type }) {
|
export function Stone({ color, type, move }) {
|
||||||
|
const style = !move ? null : {
|
||||||
|
position: 'absolute',
|
||||||
|
left: move[0],
|
||||||
|
top: move[1],
|
||||||
|
}
|
||||||
|
|
||||||
switch (color) {
|
switch (color) {
|
||||||
case Color.white:
|
case Color.white:
|
||||||
return <WhiteStone type={type} />;
|
return <WhiteStone type={type} style={style} />;
|
||||||
|
|
||||||
case Color.black:
|
case Color.black:
|
||||||
return <BlackStone type={type} />;
|
return <BlackStone type={type} style={style} />;
|
||||||
|
|
||||||
case '':
|
case '':
|
||||||
case undefined:
|
case undefined:
|
||||||
@ -32,22 +38,22 @@ export function Stone({ color, type }) {
|
|||||||
return; // no stone :)
|
return; // no stone :)
|
||||||
|
|
||||||
default:
|
default:
|
||||||
console.warn("Unknown color: ", color)
|
console.warn('Unknown color', color)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
export function WhiteStone({ type }) {
|
export function WhiteStone({ type, style }) {
|
||||||
if (type === 'KING')
|
if (type === 'KING')
|
||||||
return <span className="Stone white king">⛁</span>
|
return <span className='Stone white king' style={style} >⛁</span>
|
||||||
else
|
else
|
||||||
return <span className="Stone white man">⛀</span>
|
return <span className='Stone white man' style={style}>⛀</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
export function BlackStone({ type }) {
|
export function BlackStone({ type, style }) {
|
||||||
if (type === 'KING')
|
if (type === 'KING')
|
||||||
return <span className="Stone white king">⛃</span>
|
return <span className='Stone black king' style={style}>⛃</span>
|
||||||
else
|
else
|
||||||
return <span className="Stone black man">⛂</span>
|
return <span className='Stone black man' style={style}>⛂</span>
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -65,75 +71,102 @@ export function Player({ color, name }) {
|
|||||||
/*
|
/*
|
||||||
* Board
|
* Board
|
||||||
*/
|
*/
|
||||||
export function Board({ game, onClick }) {
|
export function Board({ game, onStoneClick, onStoneMove }) {
|
||||||
const board = (game && game.board && typeof game.board === 'object') ? game.board : defaultBoard;
|
const [[moveId, moveX, moveY], setMove] = useState([0, 0, 0]);
|
||||||
|
|
||||||
const BlackTile = () => {
|
const board = (game && game.board && typeof game.board === 'object') ? game.board : defaultBoard;
|
||||||
return <div className='Tile black' />
|
const isInteractive = (typeof onStoneClick === 'function' || typeof onStoneMove === 'function') ? ' interactive' : '';
|
||||||
}
|
|
||||||
|
|
||||||
const WhiteTile = ({ id }) => {
|
const WhiteTile = ({ id }) => {
|
||||||
const stone = board[id];
|
const stone = board[id];
|
||||||
const isInteractive = (typeof onClick === 'function') ? ' interactive' : '';
|
|
||||||
|
|
||||||
return (
|
return (
|
||||||
<div className={'Tile white' + isInteractive} onClick={() => isInteractive && onClick(id)}>
|
<div className={'Tile white' + isInteractive + (id === moveId ? ' selected' : '')}
|
||||||
|
onClick={!onStoneClick ? null :
|
||||||
|
() => onStoneClick(game.uuid, id)
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseDown={!onStoneMove || !stone ? null :
|
||||||
|
(e) => setMove([id, e.clientX, e.clientY])
|
||||||
|
}
|
||||||
|
|
||||||
|
onMouseUp={!onStoneMove || !moveId ? null :
|
||||||
|
() => { onStoneMove(game.uuid, [moveId, id]); setMove([0, 0, 0]) }
|
||||||
|
}
|
||||||
|
>
|
||||||
<Stone color={stone?.color} type={stone?.type} />
|
<Stone color={stone?.color} type={stone?.type} />
|
||||||
</div>
|
</div>
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
return <div className={'Board' + (game?.myColor === Color.black ? ' flip' : '')} >
|
const BlackTile = () => {
|
||||||
<div className='row'>
|
return <div className='Tile black' />
|
||||||
<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'>
|
const movingStone = board[moveId];
|
||||||
<BlackTile /> <WhiteTile id={17} />
|
|
||||||
<BlackTile /> <WhiteTile id={18} />
|
return (
|
||||||
<BlackTile /> <WhiteTile id={19} />
|
<div className={'Board' + (game?.myColor === Color.black ? ' flip' : '')}
|
||||||
<BlackTile /> <WhiteTile id={20} />
|
onMouseMove={!moveId ? null :
|
||||||
|
(e) => e.buttons ? setMove([moveId, e.clientX, e.clientY]) : setMove([0, 0, 0])
|
||||||
|
}
|
||||||
|
>
|
||||||
|
|
||||||
|
{!movingStone ? null :
|
||||||
|
<Stone color={movingStone.color} type={movingStone.type} move={[moveX, moveY]} />
|
||||||
|
}
|
||||||
|
|
||||||
|
<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>
|
</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>
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const blackMan = { color: Color.black, type: 'MAN' };
|
const blackMan = { color: Color.black, type: 'MAN' };
|
||||||
|
@ -6,6 +6,7 @@ import NewGame from './games/view/NewGame';
|
|||||||
import { GameProposalSelector, ActiveGameSelector, GameArchiveSelector } from './games/view/GameSelector';
|
import { GameProposalSelector, ActiveGameSelector, GameArchiveSelector } from './games/view/GameSelector';
|
||||||
import { Create, Accept, Reject, Cancel, DrawRequest, DrawAccept, DrawReject, Surrender, Backward, Forward } from './games/ActionPanel';
|
import { Create, Accept, Reject, Cancel, DrawRequest, DrawAccept, DrawReject, Surrender, Backward, Forward } from './games/ActionPanel';
|
||||||
import GameBoard from './games/GameBoard';
|
import GameBoard from './games/GameBoard';
|
||||||
|
import { nextStone } from '../components/Checkers';
|
||||||
import Message2Opponent from './games/Message2Opponent';
|
import Message2Opponent from './games/Message2Opponent';
|
||||||
import Counter from '../components/Counter';
|
import Counter from '../components/Counter';
|
||||||
|
|
||||||
@ -26,11 +27,7 @@ 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
|
<GameBoardRoutes gamesReducer={gamesReducer} gamesApi={gamesApi} username={players.currentUser} />
|
||||||
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>
|
||||||
|
|
||||||
@ -113,6 +110,27 @@ function ActionPanel({ gamesApi }) {
|
|||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function GameBoardRoutes({ gamesReducer, gamesApi, username }) {
|
||||||
|
const [games, dispatchGames] = gamesReducer;
|
||||||
|
|
||||||
|
const onStoneClick = (uuid, cellId) => {
|
||||||
|
let board = { ...games.newGame.board };
|
||||||
|
board[cellId] = nextStone(board[cellId]);
|
||||||
|
dispatchGames({ type: 'nextNewGame', board });
|
||||||
|
}
|
||||||
|
|
||||||
|
const onStoneMove = (uuid, move) => console.log(uuid, 'move', move);
|
||||||
|
|
||||||
|
return (
|
||||||
|
<Routes>
|
||||||
|
<Route path='new' element={<GameBoard username={username} onStoneClick={onStoneClick} />} />
|
||||||
|
<Route path='proposal' element={<GameBoard username={username} />} />
|
||||||
|
<Route path='active' element={<GameBoard username={username} onStoneMove={onStoneMove} />} />
|
||||||
|
<Route path='archive' element={<GameBoard username={username} />} />
|
||||||
|
</Routes>
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
function countGames(gamesList) {
|
function countGames(gamesList) {
|
||||||
|
|
||||||
var awaiting = {
|
var awaiting = {
|
||||||
|
@ -6,7 +6,6 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.GameBoard .Tile {
|
.GameBoard .Tile {
|
||||||
font-size: 200%;
|
|
||||||
line-height: 34px;
|
line-height: 34px;
|
||||||
height: 34px;
|
height: 34px;
|
||||||
width: 34px;
|
width: 34px;
|
||||||
@ -14,6 +13,10 @@
|
|||||||
margin-top: -1px;
|
margin-top: -1px;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
.GameBoard .Board .Stone {
|
||||||
|
font-size: 200%;
|
||||||
|
}
|
||||||
|
|
||||||
.GameBoard .Tile.white.interactive:hover {
|
.GameBoard .Tile.white.interactive:hover {
|
||||||
background-color:azure;
|
background-color:azure;
|
||||||
}
|
}
|
||||||
|
@ -1,58 +1,37 @@
|
|||||||
import React, { useContext, useState } from 'react';
|
import React, { useContext } 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, nextStone } from '../../components/Checkers';
|
import { Color, Player, Board } from '../../components/Checkers';
|
||||||
import './GameBoard.css';
|
import './GameBoard.css';
|
||||||
|
|
||||||
export default function GameBoard({ username, onNewGameBoardStone, onActiveGameMove }) {
|
export default function GameBoard({ username, onStoneClick, onStoneMove }) {
|
||||||
const games = useContext(GamesContext);
|
const games = useContext(GamesContext);
|
||||||
const { pathname } = useLocation();
|
const { pathname } = useLocation();
|
||||||
const [startId, setStartId] = useState(null);
|
|
||||||
|
|
||||||
const onClick_NewGame = (cellId) => {
|
const game = (() => {
|
||||||
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 [games.newGame, onClick_NewGame];
|
return games.newGame;
|
||||||
|
|
||||||
if (matchPath('/games/proposal', pathname))
|
if (matchPath('/games/proposal', pathname))
|
||||||
return [games.findGame({ uuid: games.proposal.selectedUUID }), null];
|
return games.findGame({ uuid: games.proposal.selectedUUID });
|
||||||
else if (matchPath('/games/active', pathname))
|
|
||||||
return [games.findGame({ uuid: games.active.selectedUUID }), onClick_ActiveGame];
|
|
||||||
else if (matchPath('/games/archive', pathname))
|
|
||||||
return [games.findGame({ uuid: games.archive.selectedUUID }), null];
|
|
||||||
|
|
||||||
return [{}, null];
|
if (matchPath('/games/active', pathname))
|
||||||
|
return games.findGame({ uuid: games.active.selectedUUID });
|
||||||
|
|
||||||
|
if (matchPath('/games/archive', pathname))
|
||||||
|
return games.findGame({ uuid: games.archive.selectedUUID });
|
||||||
|
|
||||||
|
return {};
|
||||||
})(); // <<-- 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.black} name={opponentName} />
|
<Player color={opponentColor || Color.black} name={opponentName} />
|
||||||
<Board game={game} onClick={optionalOnClick} />
|
<Board game={game} onStoneClick={onStoneClick} onStoneMove={onStoneMove} />
|
||||||
<Player color={game?.myColor || Color.white} name={myName} />
|
<Player color={game?.myColor || Color.white} name={myName} />
|
||||||
</div>
|
</div>
|
||||||
)
|
)
|
||||||
|
@ -38,9 +38,10 @@ export const gamesInitialState = {
|
|||||||
isPushingGameDrawRequest: false,
|
isPushingGameDrawRequest: false,
|
||||||
isPushingGameDrawAccept: false,
|
isPushingGameDrawAccept: false,
|
||||||
isPushingGameDrawReject: false,
|
isPushingGameDrawReject: false,
|
||||||
|
isPushingGameMove: false,
|
||||||
|
|
||||||
findGame,
|
findGame,
|
||||||
nextGameList,
|
nextGame,
|
||||||
};
|
};
|
||||||
|
|
||||||
function reducer(state, action) {
|
function reducer(state, action) {
|
||||||
@ -86,8 +87,6 @@ function findGame({ uuid }) {
|
|||||||
return this.gamesList?.find((game) => game.uuid === uuid);
|
return this.gamesList?.find((game) => game.uuid === uuid);
|
||||||
}
|
}
|
||||||
|
|
||||||
function nextGameList(nextGame) {
|
function nextGame(nextGame) {
|
||||||
return this.gamesList?.map(
|
return this.gamesList?.map((game) => (game.uuid === nextGame?.uuid) ? nextGame : game);
|
||||||
(game) => (nextGame?.uuid === game.uuid) ? nextGame : game
|
|
||||||
);
|
|
||||||
}
|
}
|
@ -1,14 +1,14 @@
|
|||||||
export function nextState(state, action) {
|
export function nextState(state, delta) {
|
||||||
const nextState = { ...state };
|
const nextState = { ...state };
|
||||||
|
|
||||||
Object.keys(action)
|
Object.keys(delta)
|
||||||
.slice(1) // skip first property i.e. 'next'
|
.slice(1) // skip first property i.e. 'next'
|
||||||
.forEach(key => {
|
.forEach(key => {
|
||||||
if (Object.hasOwn(nextState, key)) {
|
if (Object.hasOwn(nextState, key)) {
|
||||||
console.log("next [", key, "] = ", action[key]);
|
console.log("next [", key, "] = ", delta[key]);
|
||||||
nextState[key] = action[key];
|
nextState[key] = delta[key];
|
||||||
} else {
|
} else {
|
||||||
console.warn("nextState: bad action property\n", key + ":", action[key]);
|
console.warn("nextState: bad action property\n", key + ":", delta[key]);
|
||||||
}
|
}
|
||||||
})
|
})
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user