Skip to content

Commit

Permalink
more refactoring by o1
Browse files Browse the repository at this point in the history
voltrevo committed Oct 3, 2024

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
1 parent 5651654 commit bb3858f
Showing 4 changed files with 130 additions and 111 deletions.
70 changes: 19 additions & 51 deletions src/Game.tsx
Original file line number Diff line number Diff line change
@@ -1,42 +1,30 @@
import React, { useState, useRef } from 'react';
import { Board } from './Board';
import React, { useState } from 'react';
import TurboStackCtx from './TurboStackCtx';
import { stdMaxLines } from './params';
import { relScoreDisplay } from './relScoreDisplay';
import { choosePreviewBoard, scoreDisplay } from './gameUtils';
import Grid from './components/Grid';
import { useMousePosition } from './hooks/useMousePosition';
import { Board } from './Board';

const Game: React.FC = () => {
const ctx = TurboStackCtx.use();
const board = ctx.board.use();
const [mousePos, setMousePos] = useState<{ i: number; j: number }>();
const highScores = ctx.highScores.use();
const currentChoices = ctx.currentChoices.use();
const currentTop5Choices = ctx.currentTop5Choices.use();
const gameAreaRef = useRef<HTMLDivElement>(null);
const [showAi, setShowAi] = useState(false);
const [top5Only, setTop5Only] = useState(false);
const autoPlay = ctx.autoPlay.use();
const currentChoiceWeights = ctx.currentChoiceWeights.use();
const currentCellWeights = ctx.currentCellWeights.use();
const currentTop5CellWeights = ctx.currentTop5CellWeights.use();
const applicableChoices = top5Only ? currentTop5Choices : currentChoices;
const applicableChoices = top5Only ? ctx.currentTop5Choices.use() : ctx.currentChoices.use();

const handleMouseMove = (event: React.MouseEvent) => {
if (!gameAreaRef.current) return;
const rect = gameAreaRef.current.getBoundingClientRect();
const cellWidth = rect.width / 10;
const cellHeight = rect.height / 15;
const { mousePos, gameAreaRef, handleMouseMove } = useMousePosition();

setMousePos({
i: (event.clientY - rect.top) / cellHeight + 5,
j: (event.clientX - rect.left) / cellWidth,
});
};

let previewBoard: Board | undefined = undefined;
let previewBoardIndex: number | undefined = undefined;
let previewBoardRating: number | undefined = undefined;
let relPreviewBoardRating: number | undefined = undefined;
let previewBoard: Board | undefined;
let previewBoardIndex: number | undefined;
let previewBoardRating: number | undefined;
let relPreviewBoardRating: number | undefined;

if (!autoPlay) {
const result = choosePreviewBoard(board, applicableChoices, mousePos);
@@ -56,30 +44,7 @@ const Game: React.FC = () => {
}
};

const renderGrid = () => {
const cells = [];
for (let i = 5; i < 20; i++) {
for (let j = 0; j < 10; j++) {
const isFilled = board.get(i, j);
const applicableWeights = top5Only ? currentTop5CellWeights : currentCellWeights;
const weight = applicableWeights ? applicableWeights[i][j] : 0;
const isPreview = !isFilled && previewBoard && previewBoard.get(i, j);

const className = isFilled
? 'cell filled'
: isPreview
? 'cell preview'
: 'cell';

cells.push(
<div key={`${i}-${j}`} className={className}>
{showAi && <div className="ai-dot" style={{ opacity: weight }}></div>}
</div>
);
}
}
return <div className="grid">{cells}</div>;
};
const applicableWeights = top5Only ? currentTop5CellWeights : currentCellWeights;

return (
<div className="game-container">
@@ -89,7 +54,12 @@ const Game: React.FC = () => {
onMouseMove={handleMouseMove}
onClick={handleClick}
>
{renderGrid()}
<Grid
board={board}
previewBoard={previewBoard}
currentCellWeights={applicableWeights}
showAi={showAi}
/>
{board.finished && (
<div className="game-over">
<h2>Game Over</h2>
@@ -179,9 +149,7 @@ const Game: React.FC = () => {
</div>
)}
<div style={{ marginTop: '0.5em' }}>
<button onClick={() => ctx.downloadData()}>
Download your data
</button>
<button onClick={() => ctx.downloadData()}>Download your data</button>
</div>
<h3>
<input
@@ -196,4 +164,4 @@ const Game: React.FC = () => {
);
};

export default Game;
export default Game;
104 changes: 44 additions & 60 deletions src/Review.tsx
Original file line number Diff line number Diff line change
@@ -1,29 +1,35 @@
import React, { useState, useRef, useEffect } from 'react';
import React, { useState, useEffect } from 'react';
import TurboStackCtx from './TurboStackCtx';
import { stdMaxLines } from './params';
import getReviewData, { ReviewData } from './getReviewData';
import dataCollector from './dataCollector';
import { relScoreDisplay } from './relScoreDisplay';
import { choosePreviewBoard, scoreDisplay } from './gameUtils';
import Grid from './components/Grid';
import { useMousePosition } from './hooks/useMousePosition';

const Review: React.FC = () => {
const ctx = TurboStackCtx.use();
const board = ctx.board.use();
const [mousePos, setMousePos] = useState<{ i: number; j: number }>();
const currentChoices = ctx.currentChoices.use();
const currentChoiceWeights = ctx.currentChoiceWeights.use();
const gameAreaRef = useRef<HTMLDivElement>(null);
const [reviewData, setReviewData] = useState<ReviewData>();
const [reviewIndex, setReviewIndex] = useState(0);
const [progress, setProgress] = useState('');

const { mousePos, gameAreaRef, handleMouseMove } = useMousePosition();

useEffect(() => {
(async () => {
if (!ctx.scoreModel) {
return;
}

const rd = await getReviewData(ctx.reviewMode.get(), ctx.scoreModel, setProgress);
const rd = await getReviewData(
ctx.reviewMode.get(),
ctx.scoreModel,
setProgress
);

if (rd.length === 0) {
return;
@@ -35,20 +41,12 @@ const Review: React.FC = () => {
})();
}, [ctx]);

const handleMouseMove = (event: React.MouseEvent) => {
if (!gameAreaRef.current) return;
const rect = gameAreaRef.current.getBoundingClientRect();
const cellWidth = rect.width / 10;
const cellHeight = rect.height / 15;

setMousePos({
i: (event.clientY - rect.top) / cellHeight + 5,
j: (event.clientX - rect.left) / cellWidth,
});
};

const { choice: previewBoard } = choosePreviewBoard(board, currentChoices, mousePos);
let previewWeight: number | undefined = undefined;
const { choice: previewBoard } = choosePreviewBoard(
board,
currentChoices,
mousePos
);
let previewWeight: number | undefined;

if (previewBoard && currentChoiceWeights) {
const pi = currentChoices.indexOf(previewBoard);
@@ -80,45 +78,8 @@ const Review: React.FC = () => {
ctx.setCurrentPiece(reviewData[ri].pieceType);
};

const renderGrid = () => {
const cells = [];
for (let i = 5; i < 20; i++) {
for (let j = 0; j < 10; j++) {
const isFilled = board.get(i, j);

const isPreviousMove =
!isFilled && reviewData && reviewData[reviewIndex].to.get(i, j);

const currentCellWeights = ctx.currentCellWeights.get();
const weight = currentCellWeights ? currentCellWeights[i][j] : 0;

const isPreview =
!isFilled && previewBoard && previewBoard.get(i, j);

const className = isFilled
? 'cell filled'
: isPreview
? 'cell preview'
: isPreviousMove
? 'cell previous-move'
: 'cell';

cells.push(
<div key={`${i}-${j}`} className={className}>
<div className="ai-dot" style={{ opacity: weight }}></div>
</div>
);
}
}
return <div className="grid">{cells}</div>;
};

if (!reviewData) {
return (
<div>
Loading... {progress}
</div>
);
return <div>Loading... {progress}</div>;
}

return (
@@ -129,17 +90,38 @@ const Review: React.FC = () => {
onMouseMove={handleMouseMove}
onClick={handleClick}
>
{renderGrid()}
<Grid
board={board}
previewBoard={previewBoard}
currentCellWeights={ctx.currentCellWeights.get()}
showAi={true}
onCellRender={(i, j) => {
const isFilled = board.get(i, j);
const isPreviousMove =
!isFilled &&
reviewData &&
reviewData[reviewIndex].to.get(i, j);
return isPreviousMove ? (
<div className="previous-move-marker"></div>
) : null;
}}
/>
</div>
<div className="score-panel" style={{ width: '17em' }}>
<h3>
Review: {reviewIndex + 1} / {reviewData.length}
</h3>
<h3>
Yellow: {relScoreDisplay(reviewData[reviewIndex].weight - reviewData[reviewIndex].maxWeight)}
Yellow:{' '}
{relScoreDisplay(
reviewData[reviewIndex].weight - reviewData[reviewIndex].maxWeight
)}
</h3>
<h3>
Selected: {relScoreDisplay(previewWeight && previewWeight - reviewData[reviewIndex].maxWeight)}
Selected:{' '}
{relScoreDisplay(
previewWeight && previewWeight - reviewData[reviewIndex].maxWeight
)}
</h3>
<h3>
Lines: {board.lines_cleared} / {stdMaxLines}
@@ -150,7 +132,9 @@ const Review: React.FC = () => {
<button onClick={() => ctx.page.set('game')}>Play Game</button>
</div>
<div style={{ marginTop: '0.5em' }}>
<button onClick={() => ctx.downloadData()}>Download your data</button>
<button onClick={() => ctx.downloadData()}>
Download your data
</button>
</div>
</div>
</div>
47 changes: 47 additions & 0 deletions src/components/Grid.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
import React from 'react';
import { Board } from '../Board';

type GridProps = {
board: Board;
previewBoard?: Board;
currentCellWeights?: number[][];
showAi?: boolean;
onCellRender?: (i: number, j: number) => React.ReactNode;
startRow?: number;
endRow?: number;
};

const Grid: React.FC<GridProps> = ({
board,
previewBoard,
currentCellWeights,
showAi,
onCellRender,
startRow = 5,
endRow = 20,
}) => {
const cells = [];
for (let i = startRow; i < endRow; i++) {
for (let j = 0; j < 10; j++) {
const isFilled = board.get(i, j);
const weight = currentCellWeights ? currentCellWeights[i][j] : 0;
const isPreview = !isFilled && previewBoard && previewBoard.get(i, j);

const className = isFilled
? 'cell filled'
: isPreview
? 'cell preview'
: 'cell';

cells.push(
<div key={`${i}-${j}`} className={className}>
{showAi && <div className="ai-dot" style={{ opacity: weight }}></div>}
{onCellRender && onCellRender(i, j)}
</div>
);
}
}
return <div className="grid">{cells}</div>;
};

export default Grid;
20 changes: 20 additions & 0 deletions src/hooks/useMousePosition.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
import { useState, useRef } from 'react';

export function useMousePosition() {
const [mousePos, setMousePos] = useState<{ i: number; j: number }>();
const gameAreaRef = useRef<HTMLDivElement>(null);

const handleMouseMove = (event: React.MouseEvent) => {
if (!gameAreaRef.current) return;
const rect = gameAreaRef.current.getBoundingClientRect();
const cellWidth = rect.width / 10;
const cellHeight = rect.height / 15;

setMousePos({
i: (event.clientY - rect.top) / cellHeight + 5,
j: (event.clientX - rect.left) / cellWidth,
});
};

return { mousePos, gameAreaRef, handleMouseMove };
}

0 comments on commit bb3858f

Please sign in to comment.