add game record display overflow canvas for moves made at previously played points

This commit is contained in:
sorrelbri 2020-06-25 19:44:51 -07:00
parent 9ed4fc0a39
commit a290ec532d
2 changed files with 122 additions and 20 deletions

View file

@ -8,8 +8,14 @@ const Menu = ({ showMenu, clickClose, ...props }) => {
if (e.target.className === "Game__Menu-container") clickClose(); if (e.target.className === "Game__Menu-container") clickClose();
}; };
const canvasRef = useRef(); const canvasRef = useRef();
const overflowRef = useRef();
const drawGameRecord = () => { const drawGameRecord = () => {
return <canvas ref={canvasRef} />; return (
<>
<canvas ref={canvasRef} />
<canvas ref={overflowRef} />
</>
);
}; };
useEffect(() => { useEffect(() => {
@ -35,7 +41,49 @@ const Menu = ({ showMenu, clickClose, ...props }) => {
ctx.stroke(); ctx.stroke();
} }
if (!meta?.gameRecord) return; if (!meta?.gameRecord) return;
meta.gameRecord.forEach(({ player, pos }, index) => { ctx.textAlign = "center";
ctx.textBaseline = "middle";
const { overflow } = meta.gameRecord.reduce(
(dict, { player, pos }, index) => {
const past = dict[`${pos.x}-${pos.y}`];
if (past) {
// overflow: [ { move:#, player:'color', subsequentMoves: [ { move: #, player: 'color' } ] } ]
if (dict.overflow) {
const indexOfPrior = dict.overflow.findIndex(
({ move }) => move === past
);
if (indexOfPrior !== -1) {
// if multiple past moves at this point exist
dict.overflow[indexOfPrior].subsequentMoves.push({
move: index + 1,
player,
});
return dict;
}
// if a second move at this point has not yet been encountered
// prior move will be black if no active handicap and move is odd or if active handicap and move is even
const playerPrior =
(active.handicap && !(past % 2)) || past % 2 ? "black" : "white";
return {
...dict,
overflow: [
...dict.overflow,
{
move: past,
player: playerPrior,
subsequentMoves: [{ move: index + 1, player }],
},
],
};
}
// if no move has yet been encountered at a previously made move
return {
...dict,
overflow: [
{ move: past, subsequentMoves: [{ move: index + 1, player }] },
],
};
}
ctx.beginPath(); ctx.beginPath();
ctx.arc( ctx.arc(
(pos.y - 1) * space + offset, (pos.y - 1) * space + offset,
@ -49,15 +97,67 @@ const Menu = ({ showMenu, clickClose, ...props }) => {
ctx.fillStyle = player === "white" ? "#fff" : "#000"; ctx.fillStyle = player === "white" ? "#fff" : "#000";
ctx.fill(); ctx.fill();
ctx.fillStyle = player === "white" ? "#000" : "#fff"; ctx.fillStyle = player === "white" ? "#000" : "#fff";
ctx.textAlign = "center";
ctx.textBaseline = "middle";
ctx.fillText( ctx.fillText(
index + 1, index + 1,
(pos.y - 1) * space + offset, (pos.y - 1) * space + offset,
(pos.x - 1) * space + offset (pos.x - 1) * space + offset
); );
return { ...dict, [`${pos.x}-${pos.y}`]: index + 1 };
},
{}
);
if (!overflow?.length) return;
// Draw Overflow Moves (moves made at prior points)
const canvas2 = overflowRef.current;
const ctx2 = canvas2.getContext("2d");
canvas2.width = scale;
canvas2.height = space * overflow.length;
ctx2.textAlign = "center";
ctx2.textBaseline = "middle";
overflow.forEach(({ move, subsequentMoves, player }, index) => {
subsequentMoves.forEach(({ player, move }, subIndex) => {
ctx2.beginPath();
ctx2.arc(
subIndex * space + offset,
index * space + offset,
offset * 0.95,
0,
Math.PI * 2,
true
);
ctx2.stroke();
ctx2.fillStyle = player === "white" ? "#fff" : "#000";
ctx2.fill();
ctx2.fillStyle = player === "white" ? "#000" : "#fff";
ctx2.fillText(move, subIndex * space + offset, index * space + offset);
}); });
}, [showMenu, meta]); ctx2.fillStyle = "#000";
ctx2.fillText(
"at",
subsequentMoves.length * space + offset,
index * space + offset
);
ctx2.fillStyle = player === "white" ? "#fff" : "#000";
ctx2.beginPath();
ctx2.arc(
(subsequentMoves.length + 1) * space + offset,
index * space + offset,
offset * 0.95,
0,
Math.PI * 2,
true
);
ctx2.fill();
ctx2.stroke();
ctx2.fillStyle = player === "white" ? "#000" : "#fff";
ctx2.fillText(
move,
(subsequentMoves.length + 1) * space + offset,
index * space + offset
);
});
}, [showMenu, meta, active.handicap, boardSize]);
return ( return (
<div <div
@ -68,7 +168,6 @@ const Menu = ({ showMenu, clickClose, ...props }) => {
<button onClick={clickClose}>X</button> <button onClick={clickClose}>X</button>
<div className="Game__Menu__game-record-container"> <div className="Game__Menu__game-record-container">
{drawGameRecord()} {drawGameRecord()}
<div className="Game__Menu__game-record-overflow"></div>
</div> </div>
</div> </div>
</div> </div>

View file

@ -5,6 +5,7 @@ div.Game__Menu-container {
background: rgba(0,0,0,0.5); background: rgba(0,0,0,0.5);
display: flex; display: flex;
flex-flow: column nowrap;
justify-content: center; justify-content: center;
align-items: center; align-items: center;
height: 100vh; height: 100vh;
@ -14,8 +15,10 @@ div.Game__Menu-container {
.Game__Menu-container__Menu { .Game__Menu-container__Menu {
background: #eef; background: #eef;
width: 80vw; max-height: 90vh;
min-height: 20vh; max-width: 80vw;
padding: 2vh;
overflow: scroll;
} }
div.Game__Menu__game-record-container { div.Game__Menu__game-record-container {