Refactor parity bits game

- Changed parity indicators to display the count of black cells instead of "odd" or "even".
- Made yellow highlights translucent to allow visibility of underlying black cells.
- Added a "Random Start" option to initialize the grid with a random subset of black cells.
This commit is contained in:
gpt-engineer-app[bot] 2025-08-22 17:36:53 +00:00
parent 6813e73b97
commit 5c407b8b7f

View file

@ -27,6 +27,8 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
showColParity: boolean;
rowParities: boolean[];
colParities: boolean[];
rowCounts: number[];
colCounts: number[];
}>({
isAnimating: false,
currentRow: -1,
@ -34,7 +36,9 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
showRowParity: false,
showColParity: false,
rowParities: [],
colParities: []
colParities: [],
rowCounts: [],
colCounts: []
});
// Reset game when grid size changes
@ -113,17 +117,23 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
// Calculate all parities first
const rowParities: boolean[] = [];
const colParities: boolean[] = [];
const rowCounts: number[] = [];
const colCounts: number[] = [];
for (let i = 0; i < gridSize; i++) {
const rowBits = parityGrid[i].slice(0, gridSize);
const rowCount = rowBits.filter(bit => bit).length;
const expectedParity = calculateParity(rowBits);
rowParities[i] = expectedParity !== parityGrid[i][gridSize];
rowCounts[i] = rowCount;
}
for (let j = 0; j < gridSize; j++) {
const colBits = parityGrid.slice(0, gridSize).map(row => row[j]);
const colCount = colBits.filter(bit => bit).length;
const expectedParity = calculateParity(colBits);
colParities[j] = expectedParity !== parityGrid[gridSize][j];
colCounts[j] = colCount;
}
setAnimationState({
@ -133,7 +143,9 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
showRowParity: false,
showColParity: false,
rowParities,
colParities
colParities,
rowCounts,
colCounts
});
// Animate through rows
@ -171,13 +183,45 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
showRowParity: false,
showColParity: false,
rowParities: [],
colParities: []
colParities: [],
rowCounts: [],
colCounts: []
});
setPhase('detect');
};
// Reset the game
// Random start - fill random cells
const randomStart = () => {
if (phase !== 'setup') return;
const newGrid = Array(gridSize).fill(null).map(() => Array(gridSize).fill(false));
// Fill about 30-50% of cells randomly
const fillPercentage = 0.3 + Math.random() * 0.2; // 30-50%
const totalCells = gridSize * gridSize;
const cellsToFill = Math.floor(totalCells * fillPercentage);
const positions: {row: number, col: number}[] = [];
for (let i = 0; i < gridSize; i++) {
for (let j = 0; j < gridSize; j++) {
positions.push({row: i, col: j});
}
}
// Shuffle and take first cellsToFill positions
for (let i = positions.length - 1; i > 0; i--) {
const j = Math.floor(Math.random() * (i + 1));
[positions[i], positions[j]] = [positions[j], positions[i]];
}
for (let i = 0; i < cellsToFill; i++) {
const {row, col} = positions[i];
newGrid[row][col] = true;
}
setGrid(newGrid);
};
const resetGame = () => {
setGrid(Array(gridSize).fill(null).map(() => Array(gridSize).fill(false)));
setParityBitsAdded(false);
@ -192,7 +236,9 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
showRowParity: false,
showColParity: false,
rowParities: [],
colParities: []
colParities: [],
rowCounts: [],
colCounts: []
});
};
@ -222,7 +268,7 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
${currentGrid[row]?.[col] ? 'bg-foreground' : 'bg-background'}
${isParityCell ? 'border-primary' : 'border-foreground'}
${isError ? 'ring-4 ring-green-500 bg-green-500/20' : ''}
${shouldHighlightForAnimation ? 'ring-4 ring-yellow-400 bg-yellow-400/30' : ''}
${shouldHighlightForAnimation ? 'ring-2 ring-yellow-400 bg-yellow-400/15' : ''}
${phase === 'setup' && !isParityCell ? 'hover:bg-accent cursor-pointer' : ''}
${phase === 'parity' ? 'hover:bg-accent cursor-pointer' : ''}
`}
@ -242,12 +288,13 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
<div className="flex flex-col gap-1">
{Array(gridSize).fill(null).map((_, row) => {
const hasOddParity = animationState.rowParities[row];
const count = animationState.rowCounts[row];
const showLabel = row === animationState.currentRow;
return (
<div key={`row-${row}`} className="w-12 h-12 flex items-center justify-center">
{showLabel && (
<span className={`text-xs font-medium ${hasOddParity ? 'text-red-500' : 'text-foreground'}`}>
{hasOddParity ? 'odd' : 'even'}
{count}
</span>
)}
</div>
@ -260,10 +307,11 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
<div className="flex flex-col gap-1">
{Array(gridSize).fill(null).map((_, row) => {
const hasOddParity = animationState.rowParities[row];
const count = animationState.rowCounts[row];
return (
<div key={`row-${row}`} className="w-12 h-12 flex items-center justify-center">
<span className={`text-xs font-medium ${hasOddParity ? 'text-red-500' : 'text-foreground'}`}>
{hasOddParity ? 'odd' : 'even'}
{count}
</span>
</div>
);
@ -278,12 +326,13 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
<div className="flex gap-1">
{Array(gridSize).fill(null).map((_, col) => {
const hasOddParity = animationState.colParities[col];
const count = animationState.colCounts[col];
const showLabel = col === animationState.currentCol;
return (
<div key={`col-${col}`} className="w-12 h-6 flex items-center justify-center">
{showLabel && (
<span className={`text-xs font-medium ${hasOddParity ? 'text-red-500' : 'text-foreground'}`}>
{hasOddParity ? 'odd' : 'even'}
{count}
</span>
)}
</div>
@ -296,10 +345,11 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
<div className="flex gap-1">
{Array(gridSize).fill(null).map((_, col) => {
const hasOddParity = animationState.colParities[col];
const count = animationState.colCounts[col];
return (
<div key={`col-${col}`} className="w-12 h-6 flex items-center justify-center">
<span className={`text-xs font-medium ${hasOddParity ? 'text-red-500' : 'text-foreground'}`}>
{hasOddParity ? 'odd' : 'even'}
{count}
</span>
</div>
);
@ -358,6 +408,14 @@ const ParityBitsGame = ({ showSocialShare = true }: ParityBitsGameProps) => {
Add Parity Bits
</Button>
<Button
onClick={randomStart}
disabled={phase !== 'setup'}
variant="outline"
>
Random Start
</Button>
<Button
onClick={identifyFlip}
disabled={phase !== 'flip' || animationState.isAnimating}