feat(rithmomachia): enhance Pyramid section with comprehensive details
Add detailed pyramid information to PiecesSection: **Content Enhancements:** - Clarified that Pyramids have 4 face values (perfect squares) - Added face values with perfect square notation: "36 (6²), 25 (5²), 16 (4²), 4 (2²)" - Added "How face selection works" section with 4 detailed rules - Added example showing multiple capture scenarios - Added visual board example demonstrating 3 different capture options from a single position **Visual Improvements:** - Cropped board showing White Pyramid at H5 with capture options - Demonstrates flexibility of face selection (64 for multiple, 49 for equality, 25 for equality) - All options clearly listed with mathematical relations **Translations:** - Added 15+ new translation keys to en.json and de.json - Full German translations for all new pyramid content This provides players with a complete understanding of how Pyramids work and why they're special pieces with multiple strategic uses. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
This commit is contained in:
@@ -1,6 +1,7 @@
|
||||
import { useTranslation } from 'react-i18next'
|
||||
import { css } from '../../../../../styled-system/css'
|
||||
import { PieceRenderer } from '../PieceRenderer'
|
||||
import { RithmomachiaBoard, } from '../RithmomachiaBoard'
|
||||
import type { PieceType } from '../../types'
|
||||
|
||||
export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) {
|
||||
@@ -145,16 +146,24 @@ export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbe
|
||||
})}
|
||||
>
|
||||
<h4 className={css({ fontSize: '18px', fontWeight: 'bold', color: '#92400e', mb: '12px' })}>
|
||||
{t('guide.pieces.pyramidTitle', '⭐ Pyramids are special')}
|
||||
{t('guide.pieces.pyramidTitle', '⭐ Pyramids: The Multi-Faced Pieces')}
|
||||
</h4>
|
||||
<p className={css({ fontSize: '14px', color: '#78350f', lineHeight: '1.6', mb: '16px' })}>
|
||||
{t(
|
||||
'guide.pieces.pyramidDescription',
|
||||
'Each side has 1 Pyramid. Pyramids have 4 face values - when capturing, you choose which value to use. They move one step in any direction.'
|
||||
'guide.pieces.pyramidIntro',
|
||||
'Unlike other pieces with a single value, Pyramids contain 4 face values representing perfect squares. When capturing an enemy piece, you choose which face to use for the mathematical relation.'
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div className={css({ display: 'flex', gap: '32px', flexWrap: 'wrap', mt: '16px' })}>
|
||||
<div
|
||||
className={css({
|
||||
display: 'flex',
|
||||
gap: '32px',
|
||||
flexWrap: 'wrap',
|
||||
mt: '16px',
|
||||
mb: '20px',
|
||||
})}
|
||||
>
|
||||
{/* Black Pyramid */}
|
||||
<div>
|
||||
<p
|
||||
@@ -166,9 +175,9 @@ export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbe
|
||||
textAlign: 'center',
|
||||
})}
|
||||
>
|
||||
{t('guide.pieces.blackPyramid', 'Black Pyramid')}
|
||||
{t('guide.pieces.blackPyramid', 'Black Pyramid Faces')}:
|
||||
</p>
|
||||
<div className={css({ width: '80px', height: '80px' })}>
|
||||
<div className={css({ width: '80px', height: '80px', margin: '0 auto' })}>
|
||||
<PieceRenderer
|
||||
type="P"
|
||||
color="B"
|
||||
@@ -179,14 +188,14 @@ export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbe
|
||||
</div>
|
||||
<p
|
||||
className={css({
|
||||
fontSize: '12px',
|
||||
fontSize: '13px',
|
||||
color: '#78350f',
|
||||
mt: '8px',
|
||||
textAlign: 'center',
|
||||
fontStyle: 'italic',
|
||||
fontWeight: 'bold',
|
||||
})}
|
||||
>
|
||||
{t('guide.pieces.pyramidValues', 'Values')}: 36, 25, 16, 4
|
||||
{t('guide.pieces.blackPyramidValues', '36 (6²), 25 (5²), 16 (4²), 4 (2²)')}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
@@ -201,9 +210,9 @@ export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbe
|
||||
textAlign: 'center',
|
||||
})}
|
||||
>
|
||||
{t('guide.pieces.whitePyramid', 'White Pyramid')}
|
||||
{t('guide.pieces.whitePyramid', 'White Pyramid Faces')}:
|
||||
</p>
|
||||
<div className={css({ width: '80px', height: '80px' })}>
|
||||
<div className={css({ width: '80px', height: '80px', margin: '0 auto' })}>
|
||||
<PieceRenderer
|
||||
type="P"
|
||||
color="W"
|
||||
@@ -214,17 +223,167 @@ export function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbe
|
||||
</div>
|
||||
<p
|
||||
className={css({
|
||||
fontSize: '12px',
|
||||
fontSize: '13px',
|
||||
color: '#78350f',
|
||||
mt: '8px',
|
||||
textAlign: 'center',
|
||||
fontStyle: 'italic',
|
||||
fontWeight: 'bold',
|
||||
})}
|
||||
>
|
||||
{t('guide.pieces.pyramidValues', 'Values')}: 64, 49, 36, 25
|
||||
{t('guide.pieces.whitePyramidValues', '64 (8²), 49 (7²), 36 (6²), 25 (5²)')}
|
||||
</p>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
{/* How face selection works */}
|
||||
<div
|
||||
className={css({
|
||||
bg: 'white',
|
||||
p: '16px',
|
||||
borderRadius: '6px',
|
||||
mb: '16px',
|
||||
border: '1px solid #fbbf24',
|
||||
})}
|
||||
>
|
||||
<p
|
||||
className={css({
|
||||
fontSize: '14px',
|
||||
fontWeight: 'bold',
|
||||
color: '#92400e',
|
||||
mb: '12px',
|
||||
})}
|
||||
>
|
||||
{t('guide.pieces.pyramidHowItWorks', 'How face selection works:')}
|
||||
</p>
|
||||
<ul
|
||||
className={css({ fontSize: '13px', color: '#78350f', lineHeight: '1.8', pl: '20px' })}
|
||||
>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidRule1',
|
||||
"When your Pyramid attempts a capture, you must declare which face value you're using before the relation is checked"
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidRule2',
|
||||
'The chosen face value becomes "your piece\'s value" for all mathematical relations (equality, multiple/divisor, sum, difference, product, ratio)'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidRule3',
|
||||
'You can choose different faces for different captures—the Pyramid doesn\'t "lock in" to one value'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidRule4',
|
||||
'This flexibility makes Pyramids excellent for creating unexpected capture opportunities and versatile helpers'
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
|
||||
{/* Example */}
|
||||
<div
|
||||
className={css({
|
||||
bg: 'rgba(146, 64, 14, 0.1)',
|
||||
p: '12px',
|
||||
borderRadius: '6px',
|
||||
mb: '20px',
|
||||
})}
|
||||
>
|
||||
<p className={css({ fontSize: '13px', color: '#78350f', lineHeight: '1.6' })}>
|
||||
<strong>{t('guide.pieces.example', 'Example:')}</strong>{' '}
|
||||
{t(
|
||||
'guide.pieces.pyramidExample',
|
||||
"White's Pyramid can capture Black's 16 using face 64 (multiple: 64÷16=4), face 36 (multiple: 36÷9=4, with Black's 9), or face 25 with equality if capturing Black's 25."
|
||||
)}
|
||||
</p>
|
||||
</div>
|
||||
|
||||
{/* Visual Example */}
|
||||
<div>
|
||||
<h5
|
||||
className={css({
|
||||
fontSize: '15px',
|
||||
fontWeight: 'bold',
|
||||
color: '#92400e',
|
||||
mb: '12px',
|
||||
})}
|
||||
>
|
||||
{t(
|
||||
'guide.pieces.pyramidVisualTitle',
|
||||
"Visual Example: Pyramid's Multiple Capture Options"
|
||||
)}
|
||||
</h5>
|
||||
<p className={css({ fontSize: '13px', color: '#78350f', mb: '12px', lineHeight: '1.6' })}>
|
||||
{t(
|
||||
'guide.pieces.pyramidVisualDesc',
|
||||
"White's Pyramid (faces: 64, 49, 36, 25) is positioned to capture Black pieces. Notice the flexibility:"
|
||||
)}
|
||||
</p>
|
||||
|
||||
<div className={css({ display: 'flex', justifyContent: 'center', mb: '12px' })}>
|
||||
<RithmomachiaBoard
|
||||
pieces={[
|
||||
// White Pyramid at H5
|
||||
{ square: 'H5', type: 'P', color: 'W', value: 'P' },
|
||||
// Black pieces that can be captured
|
||||
{ square: 'I5', type: 'T', color: 'B', value: 16 },
|
||||
{ square: 'H6', type: 'S', color: 'B', value: 49 },
|
||||
{ square: 'G5', type: 'C', color: 'B', value: 25 },
|
||||
]}
|
||||
scale={0.4}
|
||||
cropToSquares={['F4', 'J7']}
|
||||
showLabels={true}
|
||||
useNativeAbacusNumbers={useNativeAbacusNumbers}
|
||||
/>
|
||||
</div>
|
||||
|
||||
<div
|
||||
className={css({
|
||||
bg: 'white',
|
||||
p: '12px',
|
||||
borderRadius: '6px',
|
||||
border: '1px solid #fbbf24',
|
||||
})}
|
||||
>
|
||||
<p
|
||||
className={css({
|
||||
fontSize: '13px',
|
||||
fontWeight: 'bold',
|
||||
color: '#92400e',
|
||||
mb: '8px',
|
||||
})}
|
||||
>
|
||||
{t('guide.pieces.pyramidCaptureOptions', 'Capture options from H5:')}
|
||||
</p>
|
||||
<ul
|
||||
className={css({ fontSize: '13px', color: '#78350f', lineHeight: '1.8', pl: '20px' })}
|
||||
>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidOption1',
|
||||
'Move to I5: Choose face 64 → captures 16 by multiple (64÷16=4)'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidOption2',
|
||||
'Move to H6: Choose face 49 → captures 49 by equality (49=49)'
|
||||
)}
|
||||
</li>
|
||||
<li>
|
||||
{t(
|
||||
'guide.pieces.pyramidOption3',
|
||||
'Move to G5: Choose face 25 → captures 25 by equality (25=25)'
|
||||
)}
|
||||
</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
)
|
||||
|
||||
@@ -46,11 +46,25 @@
|
||||
"pyramid": "Pyramide",
|
||||
"pyramidMove": "Ein Feld in alle Richtungen (wie ein König)",
|
||||
"exampleValues": "Beispielwerte",
|
||||
"blackPyramid": "Schwarze Pyramide",
|
||||
"whitePyramid": "Weiße Pyramide",
|
||||
"pyramidValues": "Werte",
|
||||
"pyramidTitle": "⭐ Pyramiden sind besonders",
|
||||
"pyramidDescription": "Jede Seite hat 1 Pyramide. Pyramiden haben 4 Seitenwerte - beim Schlagen wählen Sie, welchen Wert Sie verwenden. Sie bewegen sich einen Schritt in jede Richtung."
|
||||
"pyramidTitle": "⭐ Pyramiden: Die mehrfach-wertige Figuren",
|
||||
"pyramidIntro": "Anders als andere Figuren mit einem einzigen Wert enthalten Pyramiden 4 Seitenwerte, die perfekte Quadrate darstellen. Beim Schlagen einer gegnerischen Figur wählen Sie, welche Seite Sie für die mathematische Beziehung verwenden.",
|
||||
"blackPyramid": "Schwarze Pyramiden-Seiten",
|
||||
"blackPyramidValues": "36 (6²), 25 (5²), 16 (4²), 4 (2²)",
|
||||
"whitePyramid": "Weiße Pyramiden-Seiten",
|
||||
"whitePyramidValues": "64 (8²), 49 (7²), 36 (6²), 25 (5²)",
|
||||
"pyramidHowItWorks": "Wie die Seitenwahl funktioniert:",
|
||||
"pyramidRule1": "Wenn Ihre Pyramide versucht zu schlagen, müssen Sie deklarieren, welchen Seitenwert Sie verwenden, bevor die Beziehung geprüft wird",
|
||||
"pyramidRule2": "Der gewählte Seitenwert wird \"der Wert Ihrer Figur\" für alle mathematischen Beziehungen (Gleichheit, Vielfaches/Teiler, Summe, Differenz, Produkt, Verhältnis)",
|
||||
"pyramidRule3": "Sie können für verschiedene Schlagzüge unterschiedliche Seiten wählen—die Pyramide \"verriegelt\" sich nicht auf einen Wert",
|
||||
"pyramidRule4": "Diese Flexibilität macht Pyramiden ausgezeichnet für unerwartete Schlagmöglichkeiten und vielseitige Helfer",
|
||||
"example": "Beispiel:",
|
||||
"pyramidExample": "Weiße Pyramide kann schwarze 16 schlagen mit Seite 64 (Vielfaches: 64÷16=4), Seite 36 (Vielfaches: 36÷9=4, mit schwarzer 9), oder Seite 25 mit Gleichheit beim Schlagen von schwarzer 25.",
|
||||
"pyramidVisualTitle": "Visuelles Beispiel: Mehrfache Schlagoptionen der Pyramide",
|
||||
"pyramidVisualDesc": "Weiße Pyramide (Seiten: 64, 49, 36, 25) ist positioniert, um schwarze Figuren zu schlagen. Beachten Sie die Flexibilität:",
|
||||
"pyramidCaptureOptions": "Schlagoptionen von H5:",
|
||||
"pyramidOption1": "Zug nach I5: Wähle Seite 64 → schlägt 16 durch Vielfaches (64÷16=4)",
|
||||
"pyramidOption2": "Zug nach H6: Wähle Seite 49 → schlägt 49 durch Gleichheit (49=49)",
|
||||
"pyramidOption3": "Zug nach G5: Wähle Seite 25 → schlägt 25 durch Gleichheit (25=25)"
|
||||
},
|
||||
"capture": {
|
||||
"title": "Wie man schlägt",
|
||||
|
||||
@@ -63,11 +63,25 @@
|
||||
"pyramid": "Pyramid",
|
||||
"pyramidMove": "One step any way (like a king)",
|
||||
"exampleValues": "Example values",
|
||||
"blackPyramid": "Black Pyramid",
|
||||
"whitePyramid": "White Pyramid",
|
||||
"pyramidValues": "Values",
|
||||
"pyramidTitle": "⭐ Pyramids are special",
|
||||
"pyramidDescription": "Each side has 1 Pyramid. Pyramids have 4 face values - when capturing, you choose which value to use. They move one step in any direction.",
|
||||
"pyramidTitle": "⭐ Pyramids: The Multi-Faced Pieces",
|
||||
"pyramidIntro": "Unlike other pieces with a single value, Pyramids contain 4 face values representing perfect squares. When capturing an enemy piece, you choose which face to use for the mathematical relation.",
|
||||
"blackPyramid": "Black Pyramid Faces",
|
||||
"blackPyramidValues": "36 (6²), 25 (5²), 16 (4²), 4 (2²)",
|
||||
"whitePyramid": "White Pyramid Faces",
|
||||
"whitePyramidValues": "64 (8²), 49 (7²), 36 (6²), 25 (5²)",
|
||||
"pyramidHowItWorks": "How face selection works:",
|
||||
"pyramidRule1": "When your Pyramid attempts a capture, you must declare which face value you're using before the relation is checked",
|
||||
"pyramidRule2": "The chosen face value becomes \"your piece's value\" for all mathematical relations (equality, multiple/divisor, sum, difference, product, ratio)",
|
||||
"pyramidRule3": "You can choose different faces for different captures—the Pyramid doesn't \"lock in\" to one value",
|
||||
"pyramidRule4": "This flexibility makes Pyramids excellent for creating unexpected capture opportunities and versatile helpers",
|
||||
"example": "Example:",
|
||||
"pyramidExample": "White's Pyramid can capture Black's 16 using face 64 (multiple: 64÷16=4), face 36 (multiple: 36÷9=4, with Black's 9), or face 25 with equality if capturing Black's 25.",
|
||||
"pyramidVisualTitle": "Visual Example: Pyramid's Multiple Capture Options",
|
||||
"pyramidVisualDesc": "White's Pyramid (faces: 64, 49, 36, 25) is positioned to capture Black pieces. Notice the flexibility:",
|
||||
"pyramidCaptureOptions": "Capture options from H5:",
|
||||
"pyramidOption1": "Move to I5: Choose face 64 → captures 16 by multiple (64÷16=4)",
|
||||
"pyramidOption2": "Move to H6: Choose face 49 → captures 49 by equality (49=49)",
|
||||
"pyramidOption3": "Move to G5: Choose face 25 → captures 25 by equality (25=25)",
|
||||
"pieceTypes": {
|
||||
"circle": {
|
||||
"name": "Circle",
|
||||
@@ -89,28 +103,6 @@
|
||||
"movement": "One step any way (like a king)",
|
||||
"count": "Count: 1"
|
||||
}
|
||||
},
|
||||
"pyramidSpecial": {
|
||||
"title": "⭐ Pyramids: The Multi-Faced Pieces",
|
||||
"intro": "Unlike other pieces with a single value, Pyramids contain <strong>4 face values</strong> representing perfect squares. When capturing an enemy piece, you choose which face to use for the mathematical relation.",
|
||||
"blackFaces": "Black Pyramid Faces:",
|
||||
"blackValues": "36 (6²), 25 (5²), 16 (4²), 4 (2²)",
|
||||
"whiteFaces": "White Pyramid Faces:",
|
||||
"whiteValues": "64 (8²), 49 (7²), 36 (6²), 25 (5²)",
|
||||
"howItWorks": "How face selection works:",
|
||||
"rules": [
|
||||
"When your Pyramid attempts a capture, you must declare which face value you're using before the relation is checked",
|
||||
"The chosen face value becomes \"your piece's value\" for all mathematical relations (equality, multiple/divisor, sum, difference, product, ratio)",
|
||||
"You can choose different faces for different captures—the Pyramid doesn't \"lock in\" to one value",
|
||||
"This flexibility makes Pyramids excellent for creating unexpected capture opportunities and versatile helpers"
|
||||
],
|
||||
"example": "<strong>Example:</strong> White's Pyramid can capture Black's 16 using face 64 (multiple: 64÷16=4), face 36 (multiple: 36÷9=4, with Black's 9), or face 25 with equality if capturing Black's 25.",
|
||||
"visualTitle": "Visual Example: Pyramid's Multiple Capture Options",
|
||||
"visualDesc": "White's Pyramid (faces: 64, 49, 36, 25) is positioned to capture Black pieces. Notice the flexibility:",
|
||||
"captureOptions": "<strong>Capture options from H5:</strong>",
|
||||
"option1": "Move to I5: Choose face <strong>64</strong> → captures 16 by multiple (64÷16=4)",
|
||||
"option2": "Move to H6: Choose face <strong>49</strong> → captures 49 by equality (49=49)",
|
||||
"option3": "Move to G5: Choose face <strong>25</strong> → captures 25 by equality (25=25)"
|
||||
}
|
||||
},
|
||||
"capture": {
|
||||
|
||||
Reference in New Issue
Block a user