fix(rithmomachia): implement proper board cropping and highlighting in guide

Fixed all guide section board visualizations to use correct props:
- Replaced non-existent `cropToSquares` prop with `cropArea` object
- Added `highlightSquares` prop for yellow highlighting of piece squares
- Created `squaresToCropArea()` helper function in each section
- Updated all examples in CaptureSection (6 examples)
- Updated all examples in HarmonySection (3 examples)
- Updated pyramid example in PiecesSection
- Updated victory example in VictorySection

Board examples now properly display:
✓ Cropped to relevant squares only
✓ Yellow highlighting on squares with pieces
✓ Proper coordinate labels

This matches the original guide design shown in the reference image.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
Thomas Hallock
2025-10-31 17:55:13 -05:00
parent 24896957d0
commit d0a8fcdea6
4 changed files with 75 additions and 12 deletions

View File

@@ -2,6 +2,19 @@ import { useTranslation } from 'react-i18next'
import { css } from '../../../../../styled-system/css'
import { RithmomachiaBoard, type ExamplePiece } from '../RithmomachiaBoard'
/**
* Helper to convert square names to crop area coordinates
* @param topLeft - e.g. 'D3'
* @param bottomRight - e.g. 'H6'
*/
function squaresToCropArea(topLeft: string, bottomRight: string) {
const minCol = topLeft.charCodeAt(0) - 65 // A=0
const maxCol = bottomRight.charCodeAt(0) - 65
const maxRow = Number.parseInt(topLeft.slice(1), 10)
const minRow = Number.parseInt(bottomRight.slice(1), 10)
return { minCol, maxCol, minRow, maxRow }
}
export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) {
const { t } = useTranslation()
@@ -91,7 +104,8 @@ export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={equalityExample}
scale={0.4}
cropToSquares={['F3', 'I5']}
cropArea={squaresToCropArea('F5', 'I3')}
highlightSquares={['G4', 'H4']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -132,7 +146,8 @@ export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={multipleExample}
scale={0.4}
cropToSquares={['D4', 'G6']}
cropArea={squaresToCropArea('D6', 'G4')}
highlightSquares={['E5', 'F5']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -185,7 +200,8 @@ export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={sumExample}
scale={0.4}
cropToSquares={['D3', 'H6']}
cropArea={squaresToCropArea('D6', 'H3')}
highlightSquares={['F4', 'E5', 'G4']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -226,7 +242,8 @@ export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={differenceExample}
scale={0.4}
cropToSquares={['D3', 'H6']}
cropArea={squaresToCropArea('D6', 'H3')}
highlightSquares={['F4', 'E5', 'G4']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -267,7 +284,8 @@ export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={productExample}
scale={0.4}
cropToSquares={['D3', 'H6']}
cropArea={squaresToCropArea('D6', 'H3')}
highlightSquares={['F4', 'E5', 'G4']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -308,7 +326,8 @@ export function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={ratioExample}
scale={0.4}
cropToSquares={['D3', 'H6']}
cropArea={squaresToCropArea('D6', 'H3')}
highlightSquares={['F4', 'E5', 'G4']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>

View File

@@ -2,6 +2,19 @@ import { useTranslation } from 'react-i18next'
import { css } from '../../../../../styled-system/css'
import { RithmomachiaBoard, type ExamplePiece } from '../RithmomachiaBoard'
/**
* Helper to convert square names to crop area coordinates
* @param topLeft - e.g. 'D3'
* @param bottomRight - e.g. 'H6'
*/
function squaresToCropArea(topLeft: string, bottomRight: string) {
const minCol = topLeft.charCodeAt(0) - 65 // A=0
const maxCol = bottomRight.charCodeAt(0) - 65
const maxRow = Number.parseInt(topLeft.slice(1), 10)
const minRow = Number.parseInt(bottomRight.slice(1), 10)
return { minCol, maxCol, minRow, maxRow }
}
export function HarmonySection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) {
const { t } = useTranslation()
@@ -118,7 +131,8 @@ export function HarmonySection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={arithmeticExample}
scale={0.4}
cropToSquares={['D5', 'H7']}
cropArea={squaresToCropArea('D7', 'H5')}
highlightSquares={['E6', 'F6', 'G6']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -224,7 +238,8 @@ export function HarmonySection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={geometricExample}
scale={0.4}
cropToSquares={['D5', 'H7']}
cropArea={squaresToCropArea('D7', 'H5')}
highlightSquares={['E6', 'F6', 'G6']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>
@@ -326,7 +341,8 @@ export function HarmonySection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={harmonicExample}
scale={0.4}
cropToSquares={['D5', 'H7']}
cropArea={squaresToCropArea('D7', 'H5')}
highlightSquares={['E6', 'F6', 'G6']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>

View File

@@ -1,9 +1,22 @@
import { useTranslation } from 'react-i18next'
import { css } from '../../../../../styled-system/css'
import { PieceRenderer } from '../PieceRenderer'
import { RithmomachiaBoard, } from '../RithmomachiaBoard'
import { RithmomachiaBoard } from '../RithmomachiaBoard'
import type { PieceType } from '../../types'
/**
* Helper to convert square names to crop area coordinates
* @param topLeft - e.g. 'D3'
* @param bottomRight - e.g. 'H6'
*/
function squaresToCropArea(topLeft: string, bottomRight: string) {
const minCol = topLeft.charCodeAt(0) - 65 // A=0
const maxCol = bottomRight.charCodeAt(0) - 65
const maxRow = Number.parseInt(topLeft.slice(1), 10)
const minRow = Number.parseInt(bottomRight.slice(1), 10)
return { minCol, maxCol, minRow, maxRow }
}
export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) {
const { t } = useTranslation()
const pieces: {
@@ -336,7 +349,8 @@ export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbe
{ square: 'G5', type: 'C', color: 'B', value: 25 },
]}
scale={0.4}
cropToSquares={['F4', 'J7']}
cropArea={squaresToCropArea('F7', 'J4')}
highlightSquares={['H5', 'I5', 'H6', 'G5']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>

View File

@@ -2,6 +2,19 @@ import { useTranslation } from 'react-i18next'
import { css } from '../../../../../styled-system/css'
import { RithmomachiaBoard, type ExamplePiece } from '../RithmomachiaBoard'
/**
* Helper to convert square names to crop area coordinates
* @param topLeft - e.g. 'D3'
* @param bottomRight - e.g. 'H6'
*/
function squaresToCropArea(topLeft: string, bottomRight: string) {
const minCol = topLeft.charCodeAt(0) - 65 // A=0
const maxCol = bottomRight.charCodeAt(0) - 65
const maxRow = Number.parseInt(topLeft.slice(1), 10)
const minRow = Number.parseInt(bottomRight.slice(1), 10)
return { minCol, maxCol, minRow, maxRow }
}
export function VictorySection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) {
const { t } = useTranslation()
@@ -77,7 +90,8 @@ export function VictorySection({ useNativeAbacusNumbers }: { useNativeAbacusNumb
<RithmomachiaBoard
pieces={winningExample}
scale={0.4}
cropToSquares={['B5', 'K8']}
cropArea={squaresToCropArea('B8', 'K5')}
highlightSquares={['E6', 'F6', 'G6']}
showLabels={true}
useNativeAbacusNumbers={useNativeAbacusNumbers}
/>