Merge pull request #2 from jhalitaksoy/feature/animation
Feature/animation
This commit is contained in:
commit
eaf0d760df
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "mancala-frontend",
|
||||
"version": "0.1.3-beta.1",
|
||||
"version": "0.1.3-beta.2",
|
||||
"description": "",
|
||||
"main": "index.js",
|
||||
"scripts": {
|
||||
@ -14,7 +14,7 @@
|
||||
"author": "",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"mancala.js": "^0.0.2-beta.0",
|
||||
"mancala.js": "^0.0.2-beta.1",
|
||||
"react": "^17.0.2",
|
||||
"react-dom": "^17.0.2"
|
||||
},
|
||||
|
||||
252
src/Home.tsx
252
src/Home.tsx
@ -1,143 +1,198 @@
|
||||
import * as React from 'react';
|
||||
import { FunctionComponent, useState } from 'react';
|
||||
import BoardView from './components/BoardView';
|
||||
import { context } from './context'
|
||||
import { RTMTWS } from './rtmt/rtmt_websocket';
|
||||
import { channel_game_move, channel_leave_game, channel_on_game_update, channel_on_game_user_leave } from './channel_names';
|
||||
import Button from './components/Button';
|
||||
import InfoPanel from './components/InfoPanel';
|
||||
import { CommonMancalaGame, MancalaGame, Pit } from 'mancala.js'
|
||||
import { GameMove } from './models/GameMove';
|
||||
import * as React from "react";
|
||||
import { FunctionComponent, useEffect, useState } from "react";
|
||||
import BoardView from "./components/BoardView";
|
||||
import { context } from "./context";
|
||||
import { RTMTWS } from "./rtmt/rtmt_websocket";
|
||||
import {
|
||||
channel_game_move,
|
||||
channel_leave_game,
|
||||
channel_on_game_update,
|
||||
channel_on_game_user_leave,
|
||||
} from "./channel_names";
|
||||
import Button from "./components/Button";
|
||||
import InfoPanel from "./components/InfoPanel";
|
||||
import { CommonMancalaGame, MancalaGame, Pit } from "mancala.js";
|
||||
import { GameMove } from "./models/GameMove";
|
||||
|
||||
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting"
|
||||
type ConnectionState = "connecting" | "error" | "connected" | "reconnecting";
|
||||
|
||||
const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
||||
const [userKey, setUserKey] = useState(undefined);
|
||||
|
||||
const [connectionState, setConnetionState] = useState<ConnectionState>("connecting")
|
||||
const [connectionState, setConnetionState] =
|
||||
useState<ConnectionState>("connecting");
|
||||
|
||||
const [searchingOpponent, setSearchingOpponent] = useState<boolean>(false)
|
||||
const [searchingOpponent, setSearchingOpponent] = useState<boolean>(false);
|
||||
|
||||
const [game, setGame] = useState<CommonMancalaGame>(undefined)
|
||||
const [game, setGame] = useState<CommonMancalaGame>(undefined);
|
||||
const gameRef = React.useRef<CommonMancalaGame>(game);
|
||||
|
||||
const [crashMessage, setCrashMessage] = useState<string>(undefined)
|
||||
const [crashMessage, setCrashMessage] = useState<string>(undefined);
|
||||
|
||||
const [userKeyWhoLeave, setUserKeyWhoLeave] = useState<string>(undefined)
|
||||
const [userKeyWhoLeave, setUserKeyWhoLeave] = useState<string>(undefined);
|
||||
|
||||
const [animationPitIndex, setAnimationPitIndex] = useState<number>(-1);
|
||||
|
||||
const [intervalId, setIntervalId] = useState<number>(-1);
|
||||
|
||||
useEffect(() => {
|
||||
gameRef.current = game;
|
||||
});
|
||||
|
||||
const onConnectionDone = () => {
|
||||
setConnetionState("connected")
|
||||
}
|
||||
setConnetionState("connected");
|
||||
};
|
||||
|
||||
const onConnectionLost = () => {
|
||||
connectToServer("reconnecting")
|
||||
}
|
||||
connectToServer("reconnecting");
|
||||
};
|
||||
|
||||
const onConnectionError = (event: Event) => {
|
||||
setConnetionState("error")
|
||||
}
|
||||
setConnetionState("error");
|
||||
};
|
||||
|
||||
const connectToServer = (connectionState: ConnectionState) => {
|
||||
setConnetionState(connectionState)
|
||||
setConnetionState(connectionState);
|
||||
context.userKeyStore.getUserKey((userKey: string) => {
|
||||
setUserKey(userKey)
|
||||
const rtmtws = context.rtmt as RTMTWS
|
||||
setUserKey(userKey);
|
||||
const rtmtws = context.rtmt as RTMTWS;
|
||||
if (rtmtws) {
|
||||
rtmtws.initWebSocket(userKey, onConnectionDone, onConnectionLost, onConnectionError)
|
||||
rtmtws.initWebSocket(
|
||||
userKey,
|
||||
onConnectionDone,
|
||||
onConnectionLost,
|
||||
onConnectionError
|
||||
);
|
||||
} else {
|
||||
console.error("context.rtmt is not RTMTWS");
|
||||
}
|
||||
})
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
const listenMessages = () => {
|
||||
context.rtmt.listenMessage(channel_on_game_update, (message: Object) => {
|
||||
const newGame: CommonMancalaGame = message as CommonMancalaGame;
|
||||
setGame(MancalaGame.createFromMancalaGame(newGame))
|
||||
})
|
||||
const mancalaGame = MancalaGame.createFromMancalaGame(newGame);
|
||||
if (gameRef.current && mancalaGame.history.length > 0) {
|
||||
const lastHistoryItem =
|
||||
mancalaGame.history[mancalaGame.history.length - 1];
|
||||
if (lastHistoryItem.gameSteps.length > 0) {
|
||||
let stepIndex = 0;
|
||||
if (intervalId) {
|
||||
clearInterval(intervalId);
|
||||
}
|
||||
const id = setInterval(() => {
|
||||
if (stepIndex === lastHistoryItem.gameSteps.length) {
|
||||
clearInterval(id);
|
||||
setAnimationPitIndex(-1);
|
||||
setGame(mancalaGame);
|
||||
} else {
|
||||
const gameStep = lastHistoryItem.gameSteps[stepIndex];
|
||||
const index = mancalaGame.board.getPitIndexCircularly(
|
||||
gameStep.index
|
||||
);
|
||||
setAnimationPitIndex(index);
|
||||
}
|
||||
stepIndex++;
|
||||
}, 250);
|
||||
setIntervalId(intervalId);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
context.rtmt.listenMessage("on_game_start", (message: Object) => {
|
||||
const newGame: CommonMancalaGame = message as CommonMancalaGame;
|
||||
setSearchingOpponent(false)
|
||||
setGame(MancalaGame.createFromMancalaGame(newGame))
|
||||
})
|
||||
setSearchingOpponent(false);
|
||||
setGame(MancalaGame.createFromMancalaGame(newGame));
|
||||
});
|
||||
|
||||
context.rtmt.listenMessage("on_game_crashed", (message : any) => {
|
||||
const newCrashMessage = message as string
|
||||
context.rtmt.listenMessage("on_game_crashed", (message: any) => {
|
||||
const newCrashMessage = message as string;
|
||||
console.error("on_game_crash");
|
||||
console.error(newCrashMessage);
|
||||
setCrashMessage(newCrashMessage)
|
||||
})
|
||||
setCrashMessage(newCrashMessage);
|
||||
});
|
||||
|
||||
context.rtmt.listenMessage(channel_on_game_user_leave, (message : any) => {
|
||||
context.rtmt.listenMessage(channel_on_game_user_leave, (message: any) => {
|
||||
const userKeyWhoLeave = message;
|
||||
setUserKeyWhoLeave(userKeyWhoLeave)
|
||||
})
|
||||
}
|
||||
setUserKeyWhoLeave(userKeyWhoLeave);
|
||||
});
|
||||
};
|
||||
|
||||
React.useEffect(() => {
|
||||
listenMessages()
|
||||
connectToServer("connecting")
|
||||
}, [])
|
||||
listenMessages();
|
||||
connectToServer("connecting");
|
||||
}, []);
|
||||
|
||||
const resetGameState = () => {
|
||||
setGame(undefined)
|
||||
setCrashMessage(undefined)
|
||||
setUserKeyWhoLeave(undefined)
|
||||
}
|
||||
setGame(undefined);
|
||||
setCrashMessage(undefined);
|
||||
setUserKeyWhoLeave(undefined);
|
||||
};
|
||||
|
||||
const newGameClick = () => {
|
||||
resetGameState()
|
||||
setSearchingOpponent(true)
|
||||
context.rtmt.sendMessage("new_game", {})
|
||||
}
|
||||
resetGameState();
|
||||
setSearchingOpponent(true);
|
||||
context.rtmt.sendMessage("new_game", {});
|
||||
};
|
||||
|
||||
const leaveGame = () => {
|
||||
context.rtmt.sendMessage(channel_leave_game, {})
|
||||
}
|
||||
context.rtmt.sendMessage(channel_leave_game, {});
|
||||
};
|
||||
|
||||
const onHoleSelect = (index: number, hole: Pit) => {
|
||||
const gameMove: GameMove = { index: index }
|
||||
context.rtmt.sendMessage(channel_game_move, gameMove)
|
||||
}
|
||||
const gameMove: GameMove = { index: index };
|
||||
context.rtmt.sendMessage(channel_game_move, gameMove);
|
||||
};
|
||||
|
||||
const showConnectionState = connectionState != "connected"
|
||||
const showConnectionState = connectionState != "connected";
|
||||
|
||||
const connectionStateText = () => {
|
||||
let map: { [key: string]: string } = {
|
||||
"connecting": context.texts.Connecting,
|
||||
"connected": context.texts.Connected,
|
||||
"error": context.texts.CannotConnect,
|
||||
"reconnecting": context.texts.ConnectingAgain
|
||||
connecting: context.texts.Connecting,
|
||||
connected: context.texts.Connected,
|
||||
error: context.texts.CannotConnect,
|
||||
reconnecting: context.texts.ConnectingAgain,
|
||||
};
|
||||
|
||||
return map[connectionState]
|
||||
}
|
||||
return map[connectionState];
|
||||
};
|
||||
|
||||
const renderNewGameButton = () => {
|
||||
const newGame = <Button text={context.texts.NewGame} color="#005f73" onClick={newGameClick} />
|
||||
const newGame = (
|
||||
<Button
|
||||
text={context.texts.NewGame}
|
||||
color="#005f73"
|
||||
onClick={newGameClick}
|
||||
/>
|
||||
);
|
||||
if (userKeyWhoLeave) {
|
||||
return newGame
|
||||
return newGame;
|
||||
}
|
||||
if (crashMessage) {
|
||||
return newGame
|
||||
return newGame;
|
||||
}
|
||||
if (!game) {
|
||||
return newGame
|
||||
return newGame;
|
||||
} else if (game.state == "ended") {
|
||||
return newGame
|
||||
}
|
||||
return <></>
|
||||
return newGame;
|
||||
}
|
||||
return <></>;
|
||||
};
|
||||
|
||||
return <div style={{
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
display: "flex",
|
||||
flexDirection: "column",
|
||||
alignItems: "center",
|
||||
background: "#EEEEEE",
|
||||
flex: "1",
|
||||
}}>
|
||||
{showConnectionState &&
|
||||
<div style={{
|
||||
}}
|
||||
>
|
||||
{showConnectionState && (
|
||||
<div
|
||||
style={{
|
||||
position: "absolute",
|
||||
bottom: "0px",
|
||||
left: "0px",
|
||||
@ -147,33 +202,54 @@ const Home: FunctionComponent<{ initial?: number }> = ({ initial = 0 }) => {
|
||||
minHeight: "1vw",
|
||||
background: "#2F2504",
|
||||
color: "white",
|
||||
}}>
|
||||
}}
|
||||
>
|
||||
{connectionStateText()}
|
||||
</div>}
|
||||
<div style={{
|
||||
</div>
|
||||
)}
|
||||
<div
|
||||
style={{
|
||||
padding: "0px 50px",
|
||||
background: "rgb(228, 228, 228)",
|
||||
display: 'flex',
|
||||
display: "flex",
|
||||
flexDirection: "row",
|
||||
alignItems: "center",
|
||||
justifyContent: "space-between",
|
||||
alignSelf: "stretch"
|
||||
}}>
|
||||
alignSelf: "stretch",
|
||||
}}
|
||||
>
|
||||
<h1 style={{ margin: "10px 0px" }}>{context.texts.Mancala}</h1>
|
||||
<div>
|
||||
{renderNewGameButton()}
|
||||
{game && !userKeyWhoLeave && !crashMessage && (game?.state === "playing" || game?.state === "initial") && < Button color="#005f73" text={context.texts.Leave} onClick={leaveGame} />}
|
||||
{game &&
|
||||
!userKeyWhoLeave &&
|
||||
!crashMessage &&
|
||||
(game?.state === "playing" || game?.state === "initial") && (
|
||||
<Button
|
||||
color="#005f73"
|
||||
text={context.texts.Leave}
|
||||
onClick={leaveGame}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
|
||||
</div>
|
||||
<InfoPanel
|
||||
game={game}
|
||||
crashMessage={crashMessage}
|
||||
userKey={userKey}
|
||||
userKeyWhoLeave={userKeyWhoLeave}
|
||||
searchingOpponent={searchingOpponent} />
|
||||
{game && <BoardView userKey={userKey} game={game} onHoleSelect={onHoleSelect} />}
|
||||
</div >
|
||||
}
|
||||
searchingOpponent={searchingOpponent}
|
||||
/>
|
||||
{game && (
|
||||
<BoardView
|
||||
userKey={userKey}
|
||||
game={game}
|
||||
onHoleSelect={onHoleSelect}
|
||||
animationPitIndex={animationPitIndex}
|
||||
/>
|
||||
)}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
export default Home
|
||||
export default Home;
|
||||
|
||||
@ -1,38 +1,44 @@
|
||||
import { Bank, MancalaGame, Pit } from 'mancala.js';
|
||||
import * as React from 'react';
|
||||
import { FunctionComponent, useState } from 'react';
|
||||
import { Bank, MancalaGame, Pit } from "mancala.js";
|
||||
import * as React from "react";
|
||||
import { FunctionComponent, useState } from "react";
|
||||
|
||||
type Theme = {
|
||||
background : string,
|
||||
boardColor: string
|
||||
boardColorWhenPlayerTurn: string
|
||||
storeColor: string
|
||||
storeColorWhenPlayerTurn: string
|
||||
holeColor: string
|
||||
ballColor: string
|
||||
}
|
||||
background: string;
|
||||
boardColor: string;
|
||||
boardColorWhenPlayerTurn: string;
|
||||
storeColor: string;
|
||||
storeColorWhenPlayerTurn: string;
|
||||
holeColor: string;
|
||||
ballColor: string;
|
||||
ballLightColor: string;
|
||||
holeAnimateColor: string;
|
||||
};
|
||||
|
||||
const theme: Theme = {
|
||||
background : "#EEEEEE",
|
||||
background: "#EEEEEE",
|
||||
boardColor: "#4D606E",
|
||||
boardColorWhenPlayerTurn: "#84b8a6",
|
||||
storeColor: "#3FBAC2",
|
||||
storeColorWhenPlayerTurn: "#6cab94",
|
||||
holeColor: "#D3D4D8",
|
||||
ballColor: "#393E46",
|
||||
}
|
||||
ballLightColor: "#393E46",
|
||||
holeAnimateColor: "#afb3a4",
|
||||
};
|
||||
|
||||
const BallView: FunctionComponent<{color : string}> = ({color}) => {
|
||||
|
||||
return (<div style={{
|
||||
const BallView: FunctionComponent<{ color: string }> = ({ color }) => {
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
background: color,
|
||||
margin: "1px",
|
||||
width: "1vw",
|
||||
height: "1vw",
|
||||
borderRadius: "10vw"
|
||||
}} >
|
||||
</div>)
|
||||
}
|
||||
borderRadius: "10vw",
|
||||
}}
|
||||
></div>
|
||||
);
|
||||
};
|
||||
|
||||
function range(size: number) {
|
||||
var ans = [];
|
||||
@ -42,95 +48,202 @@ function range(size: number) {
|
||||
return ans;
|
||||
}
|
||||
|
||||
const HoleView: FunctionComponent<{ hole: Pit, color: string, onClick: () => void }> = ({ hole, color, onClick }) => {
|
||||
const balls = [...range(hole.stoneCount)].map((i) => <BallView color={theme.ballColor}/>)
|
||||
const PitContainer: FunctionComponent<{
|
||||
pit: Pit;
|
||||
isAnimating: boolean;
|
||||
onClick: () => void;
|
||||
}> = ({ pit, isAnimating, onClick }) => {
|
||||
if (isAnimating) {
|
||||
pit.stoneCount += 1;
|
||||
}
|
||||
return (
|
||||
<>
|
||||
<HoleView
|
||||
hole={pit}
|
||||
color={isAnimating ? theme.holeAnimateColor : theme.holeColor}
|
||||
stoneColor={isAnimating ? theme.ballLightColor : theme.ballColor}
|
||||
onClick={onClick}
|
||||
/>
|
||||
</>
|
||||
);
|
||||
};
|
||||
|
||||
return (<div
|
||||
const HoleView: FunctionComponent<{
|
||||
hole: Pit;
|
||||
color: string;
|
||||
stoneColor: string;
|
||||
onClick: () => void;
|
||||
}> = ({ hole, color, stoneColor, onClick }) => {
|
||||
const balls = [...range(hole.stoneCount)].map((i) => (
|
||||
<BallView color={stoneColor} />
|
||||
));
|
||||
|
||||
return (
|
||||
<div
|
||||
onClick={onClick}
|
||||
style={{
|
||||
background: color,
|
||||
margin: "5px",
|
||||
padding: "5px",
|
||||
borderRadius: "10vw",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
alignContent: 'center',
|
||||
justifyContent: 'center',
|
||||
justifyItems: 'center',
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
alignContent: "center",
|
||||
justifyContent: "center",
|
||||
justifyItems: "center",
|
||||
flexWrap: "wrap",
|
||||
}} >
|
||||
}}
|
||||
>
|
||||
{balls}
|
||||
</div>)
|
||||
}
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const StoreView: FunctionComponent<
|
||||
{ store: Bank, color: string, gridColumn: string, gridRow: string }> = ({ store, color, gridColumn, gridRow }) => {
|
||||
const balls = [...range(store.stoneCount)].map((i) => <BallView color={theme.ballColor}/>)
|
||||
return (<div style={{
|
||||
const StoreView: FunctionComponent<{
|
||||
store: Bank;
|
||||
color: string;
|
||||
stoneColor: string;
|
||||
gridColumn: string;
|
||||
gridRow: string;
|
||||
}> = ({ store, color, stoneColor, gridColumn, gridRow }) => {
|
||||
const balls = [...range(store.stoneCount)].map((i) => (
|
||||
<BallView color={stoneColor} />
|
||||
));
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
gridColumn: gridColumn,
|
||||
gridRow: gridRow,
|
||||
background: color,
|
||||
margin: "5px",
|
||||
borderRadius: "10vw",
|
||||
display: 'flex',
|
||||
alignItems: 'center',
|
||||
justifyContent: 'center',
|
||||
alignContent: 'center',
|
||||
display: "flex",
|
||||
alignItems: "center",
|
||||
justifyContent: "center",
|
||||
alignContent: "center",
|
||||
flexWrap: "wrap",
|
||||
}} >
|
||||
}}
|
||||
>
|
||||
{balls}
|
||||
</div>)
|
||||
}
|
||||
|
||||
const BoardView: FunctionComponent<{ game?: MancalaGame, userKey: string, onHoleSelect: (index: number, hole: Pit) => void }> = ({
|
||||
game, userKey, onHoleSelect }) => {
|
||||
|
||||
const player1Pits = game?.board.player1Pits.map((hole) => (
|
||||
<HoleView hole={hole} color={theme.holeColor} onClick={() => {
|
||||
if (game.turnPlayerId === game.player1Id) onHoleSelect(game.board.player1Pits.indexOf(hole), hole)
|
||||
}} />
|
||||
))
|
||||
|
||||
const player2Pits = game!!.board.player2Pits.map((hole) => (
|
||||
<HoleView hole={hole} color={theme.holeColor} onClick={() => {
|
||||
if (game.turnPlayerId === game.player2Id) onHoleSelect(game.board.player2Pits.indexOf(hole), hole)
|
||||
}} />
|
||||
))
|
||||
|
||||
const isUserTurn = game.checkIsPlayerTurn(userKey)
|
||||
|
||||
const storeColor = isUserTurn ? theme.storeColor : theme.storeColorWhenPlayerTurn;
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
const BoardView: FunctionComponent<{
|
||||
game?: MancalaGame;
|
||||
userKey: string;
|
||||
onHoleSelect: (index: number, hole: Pit) => void;
|
||||
animationPitIndex: number;
|
||||
}> = ({ game, userKey, onHoleSelect, animationPitIndex }) => {
|
||||
const player1Pits = game?.board.player1Pits.map((pit) => {
|
||||
const isAnimating = pit.index === animationPitIndex;
|
||||
return (
|
||||
<div style={{
|
||||
margin: '10px',
|
||||
padding: '20px',
|
||||
display: 'grid',
|
||||
gridTemplateColumns: 'repeat(8, 11vw)',
|
||||
gridTemplateRows: 'repeat(2, 11vw)',
|
||||
<PitContainer
|
||||
pit={pit}
|
||||
isAnimating={isAnimating}
|
||||
onClick={() => {
|
||||
if (game.turnPlayerId === game.player1Id)
|
||||
onHoleSelect(game.board.player1Pits.indexOf(pit), pit);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const player2Pits = game!!.board.player2Pits.map((pit) => {
|
||||
const isAnimating = pit.index === animationPitIndex;
|
||||
return (
|
||||
<PitContainer
|
||||
pit={pit}
|
||||
isAnimating={isAnimating}
|
||||
onClick={() => {
|
||||
if (game.turnPlayerId === game.player2Id)
|
||||
onHoleSelect(game.board.player2Pits.indexOf(pit), pit);
|
||||
}}
|
||||
/>
|
||||
);
|
||||
});
|
||||
|
||||
const isUserTurn = game.checkIsPlayerTurn(userKey);
|
||||
|
||||
const animatingPlayer1Bank =
|
||||
game.board.player1Bank.index === animationPitIndex;
|
||||
const animatingPlayer2Bank =
|
||||
game.board.player2Bank.index === animationPitIndex;
|
||||
|
||||
const storeColorPlayer1 = animatingPlayer1Bank
|
||||
? theme.holeAnimateColor
|
||||
: isUserTurn
|
||||
? theme.storeColor
|
||||
: theme.storeColorWhenPlayerTurn;
|
||||
|
||||
const storeStoneColorPlayer1 = animatingPlayer1Bank
|
||||
? theme.ballLightColor
|
||||
: theme.ballColor;
|
||||
|
||||
const storeColorPlayer2 = animatingPlayer2Bank
|
||||
? theme.holeAnimateColor
|
||||
: isUserTurn
|
||||
? theme.storeColor
|
||||
: theme.storeColorWhenPlayerTurn;
|
||||
|
||||
const storeStoneColorPlayer2 = animatingPlayer2Bank
|
||||
? theme.ballLightColor
|
||||
: theme.ballColor;
|
||||
return (
|
||||
<div
|
||||
style={{
|
||||
margin: "10px",
|
||||
padding: "20px",
|
||||
display: "grid",
|
||||
gridTemplateColumns: "repeat(8, 11vw)",
|
||||
gridTemplateRows: "repeat(2, 11vw)",
|
||||
borderRadius: "3vw",
|
||||
background: isUserTurn ? theme.boardColor : theme.boardColorWhenPlayerTurn
|
||||
}}>
|
||||
{
|
||||
userKey === game.player2Id ? (
|
||||
background: isUserTurn
|
||||
? theme.boardColor
|
||||
: theme.boardColorWhenPlayerTurn,
|
||||
}}
|
||||
>
|
||||
{userKey === game.player2Id ? (
|
||||
<>
|
||||
<StoreView store={game!!.board.player1Bank} color={storeColor} gridColumn="1 / 2" gridRow="1 / 3" />
|
||||
<StoreView store={game!!.board.player2Bank} color={storeColor} gridColumn="8 / 9" gridRow="1 / 3" />
|
||||
<StoreView
|
||||
store={game!!.board.player1Bank}
|
||||
color={storeColorPlayer1}
|
||||
stoneColor={storeStoneColorPlayer1}
|
||||
gridColumn="1 / 2"
|
||||
gridRow="1 / 3"
|
||||
/>
|
||||
<StoreView
|
||||
store={game!!.board.player2Bank}
|
||||
color={storeColorPlayer2}
|
||||
stoneColor={storeStoneColorPlayer2}
|
||||
gridColumn="8 / 9"
|
||||
gridRow="1 / 3"
|
||||
/>
|
||||
{player1Pits.reverse()}
|
||||
{player2Pits}
|
||||
</>
|
||||
) : (
|
||||
<>
|
||||
<StoreView store={game!!.board.player2Bank} color={storeColor} gridColumn="1 / 2" gridRow="1 / 3" />
|
||||
<StoreView store={game!!.board.player1Bank} color={storeColor} gridColumn="8 / 9" gridRow="1 / 3" />
|
||||
<StoreView
|
||||
store={game!!.board.player2Bank}
|
||||
color={storeColorPlayer2}
|
||||
stoneColor={storeStoneColorPlayer2}
|
||||
gridColumn="1 / 2"
|
||||
gridRow="1 / 3"
|
||||
/>
|
||||
<StoreView
|
||||
store={game!!.board.player1Bank}
|
||||
color={storeColorPlayer1}
|
||||
stoneColor={storeStoneColorPlayer1}
|
||||
gridColumn="8 / 9"
|
||||
gridRow="1 / 3"
|
||||
/>
|
||||
{player2Pits.reverse()}
|
||||
{player1Pits}
|
||||
</>
|
||||
)
|
||||
}
|
||||
|
||||
)}
|
||||
</div>
|
||||
)
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
export default BoardView
|
||||
export default BoardView;
|
||||
|
||||
@ -3373,10 +3373,10 @@ magic-string@^0.22.4:
|
||||
dependencies:
|
||||
vlq "^0.2.2"
|
||||
|
||||
mancala.js@^0.0.2-beta.0:
|
||||
version "0.0.2-beta.0"
|
||||
resolved "https://registry.yarnpkg.com/mancala.js/-/mancala.js-0.0.2-beta.0.tgz#360cd909b6ee743a3e3cbea203457c82917d6fcb"
|
||||
integrity sha512-3UOo94K81GmqhQ8m2vFoU608yMyDWbn+EI7OfPjcmQJHf+n8+bu1Ju/bUYNMP5qoFU0rQnxaXKU+Z1hK3hw/Rg==
|
||||
mancala.js@^0.0.2-beta.1:
|
||||
version "0.0.2-beta.1"
|
||||
resolved "https://registry.yarnpkg.com/mancala.js/-/mancala.js-0.0.2-beta.1.tgz#333d613b349e743a00141d231e1f49ab1f99b4fe"
|
||||
integrity sha512-RS5DFYOjcKMONqZ4DsZudscN+2OhcRBJV2fX3KjqGBvREgMjCxDZVjFMhdZxnP5HFXdRSbUeMivyisGGGQbJ/A==
|
||||
|
||||
map-cache@^0.2.2:
|
||||
version "0.2.2"
|
||||
|
||||
Loading…
Reference in New Issue
Block a user