diff --git a/apps/web/src/arcade-games/rithmomachia/components/PlayingGuideModal.tsx b/apps/web/src/arcade-games/rithmomachia/components/PlayingGuideModal.tsx index 9ded4b2d..acef9095 100644 --- a/apps/web/src/arcade-games/rithmomachia/components/PlayingGuideModal.tsx +++ b/apps/web/src/arcade-games/rithmomachia/components/PlayingGuideModal.tsx @@ -1,39 +1,52 @@ 'use client' import { useEffect, useState, useRef } from 'react' +import { useTranslation } from 'react-i18next' import { css } from '../../../../styled-system/css' import { Z_INDEX } from '@/constants/zIndex' +import { useAbacusSettings } from '@/hooks/useAbacusSettings' import { PieceRenderer } from './PieceRenderer' +import { RithmomachiaBoard, type ExamplePiece } from './RithmomachiaBoard' import type { PieceType, Color } from '../types' +import '../i18n/config' // Initialize i18n interface PlayingGuideModalProps { isOpen: boolean onClose: () => void + standalone?: boolean // True when opened in popup window } -type Section = 'overview' | 'pieces' | 'capture' | 'harmony' | 'victory' +type Section = 'overview' | 'pieces' | 'capture' | 'strategy' | 'harmony' | 'victory' + +export function PlayingGuideModal({ isOpen, onClose, standalone = false }: PlayingGuideModalProps) { + const { t, i18n } = useTranslation() + const { data: abacusSettings } = useAbacusSettings() + const useNativeAbacusNumbers = abacusSettings?.nativeAbacusNumbers ?? false -export function PlayingGuideModal({ isOpen, onClose }: PlayingGuideModalProps) { const [activeSection, setActiveSection] = useState
('overview') const [position, setPosition] = useState({ x: 0, y: 0 }) + const [size, setSize] = useState({ width: 800, height: 600 }) const [isDragging, setIsDragging] = useState(false) const [dragStart, setDragStart] = useState({ x: 0, y: 0 }) + const [isResizing, setIsResizing] = useState(false) + const [resizeDirection, setResizeDirection] = useState('') + const [isHovered, setIsHovered] = useState(false) const modalRef = useRef(null) - // Center modal on mount + // Center modal on mount (not in standalone mode) useEffect(() => { - if (isOpen && modalRef.current) { + if (isOpen && modalRef.current && !standalone) { const rect = modalRef.current.getBoundingClientRect() setPosition({ x: (window.innerWidth - rect.width) / 2, y: Math.max(50, (window.innerHeight - rect.height) / 2), }) } - }, [isOpen]) + }, [isOpen, standalone]) // Handle dragging const handleMouseDown = (e: React.MouseEvent) => { - if (window.innerWidth < 768) return // No dragging on mobile + if (window.innerWidth < 768 || standalone) return // No dragging on mobile or standalone setIsDragging(true) setDragStart({ x: e.clientX - position.x, @@ -41,20 +54,91 @@ export function PlayingGuideModal({ isOpen, onClose }: PlayingGuideModalProps) { }) } + // Handle resize start + const handleResizeStart = (e: React.MouseEvent, direction: string) => { + if (window.innerWidth < 768 || standalone) return + e.stopPropagation() + setIsResizing(true) + setResizeDirection(direction) + setDragStart({ x: e.clientX, y: e.clientY }) + } + + // Bust-out button handler + const handleBustOut = () => { + const url = `${window.location.origin}/arcade/rithmomachia/guide` + const features = 'width=600,height=800,menubar=no,toolbar=no,location=no,status=no' + window.open(url, 'RithmomachiaGuide', features) + } + + // Mouse move effect for dragging and resizing useEffect(() => { const handleMouseMove = (e: MouseEvent) => { - if (!isDragging) return - setPosition({ - x: e.clientX - dragStart.x, - y: e.clientY - dragStart.y, - }) + if (isDragging) { + setPosition({ + x: e.clientX - dragStart.x, + y: e.clientY - dragStart.y, + }) + } else if (isResizing) { + const deltaX = e.clientX - dragStart.x + const deltaY = e.clientY - dragStart.y + + let actualDeltaX = 0 + let actualDeltaY = 0 + + setSize((prev) => { + let newWidth = prev.width + let newHeight = prev.height + let newX = position.x + let newY = position.y + + // Handle different resize directions + if (resizeDirection.includes('e')) { + const desiredWidth = prev.width + deltaX + newWidth = Math.max(450, Math.min(window.innerWidth * 0.9, desiredWidth)) + actualDeltaX = newWidth - prev.width + } + if (resizeDirection.includes('w')) { + const desiredWidth = prev.width - deltaX + newWidth = Math.max(450, Math.min(window.innerWidth * 0.9, desiredWidth)) + const widthDiff = newWidth - prev.width + newX = position.x - widthDiff + actualDeltaX = -widthDiff + } + if (resizeDirection.includes('s')) { + const desiredHeight = prev.height + deltaY + newHeight = Math.max(600, Math.min(window.innerHeight * 0.8, desiredHeight)) + actualDeltaY = newHeight - prev.height + } + if (resizeDirection.includes('n')) { + const desiredHeight = prev.height - deltaY + newHeight = Math.max(600, Math.min(window.innerHeight * 0.8, desiredHeight)) + const heightDiff = newHeight - prev.height + newY = position.y - heightDiff + actualDeltaY = -heightDiff + } + + if (newX !== position.x || newY !== position.y) { + setPosition({ x: newX, y: newY }) + } + + return { width: newWidth, height: newHeight } + }) + + // Only update dragStart by the amount that was actually applied + setDragStart({ + x: dragStart.x + actualDeltaX, + y: dragStart.y + actualDeltaY, + }) + } } const handleMouseUp = () => { setIsDragging(false) + setIsResizing(false) + setResizeDirection('') } - if (isDragging) { + if (isDragging || isResizing) { document.addEventListener('mousemove', handleMouseMove) document.addEventListener('mouseup', handleMouseUp) } @@ -63,183 +147,435 @@ export function PlayingGuideModal({ isOpen, onClose }: PlayingGuideModalProps) { document.removeEventListener('mousemove', handleMouseMove) document.removeEventListener('mouseup', handleMouseUp) } - }, [isDragging, dragStart]) + }, [isDragging, isResizing, dragStart, position, resizeDirection]) - if (!isOpen) return null + if (!isOpen && !standalone) return null const sections: { id: Section; label: string; icon: string }[] = [ - { id: 'overview', label: 'Quick Start', icon: '🎯' }, - { id: 'pieces', label: 'Pieces', icon: '♟️' }, - { id: 'capture', label: 'Capture', icon: '⚔️' }, - { id: 'harmony', label: 'Harmony', icon: '🎵' }, - { id: 'victory', label: 'Victory', icon: '👑' }, + { id: 'overview', label: t('guide.sections.overview', 'Quick Start'), icon: '🎯' }, + { id: 'pieces', label: t('guide.sections.pieces', 'Pieces'), icon: '♟️' }, + { id: 'capture', label: t('guide.sections.capture', 'Capture'), icon: '⚔️' }, + { id: 'harmony', label: t('guide.sections.harmony', 'Harmony'), icon: '🎵' }, + { id: 'victory', label: t('guide.sections.victory', 'Victory'), icon: '👑' }, ] - return ( - <> - {/* Backdrop */} -
+ const renderResizeHandles = () => { + if (!isHovered || window.innerWidth < 768 || standalone) return null - {/* Modal */} + const handleStyle = { + position: 'absolute' as const, + bg: 'transparent', + zIndex: 1, + _hover: { borderColor: '#3b82f6' }, + } + + return ( + <> + {/* North */} +
handleResizeStart(e, 'n')} + /> + {/* South */} +
handleResizeStart(e, 's')} + /> + {/* East */} +
handleResizeStart(e, 'e')} + /> + {/* West */} +
handleResizeStart(e, 'w')} + /> + {/* NorthEast */} +
handleResizeStart(e, 'ne')} + /> + {/* NorthWest */} +
handleResizeStart(e, 'nw')} + /> + {/* SouthEast */} +
handleResizeStart(e, 'se')} + /> + {/* SouthWest */} +
handleResizeStart(e, 'sw')} + /> + + ) + } + + const modalContent = ( +
setIsHovered(true)} + onMouseLeave={() => setIsHovered(false)} + > + {renderResizeHandles()} + + {/* Header */}
= 768 ? `${position.x}px` : '0', - top: window.innerWidth >= 768 ? `${position.y}px` : '0', - cursor: isDragging ? 'grabbing' : 'auto', + cursor: isDragging + ? 'grabbing' + : !standalone && window.innerWidth >= 768 + ? 'grab' + : 'default', }} > - {/* Header */} -
= 768 ? 'grab' : 'default', - }} > -
- 📖 -
-

+ +
+ {/* Language switcher */} +
+ {['en', 'de'].map((lang) => ( +

-

- Rithmomachia – The Philosopher's Game -

-
+ {lang.toUpperCase()} + + ))}
+ + {/* Bust-out button (only if not already standalone) */} + {!standalone && ( + + )} + + {/* Close button */}
- - {/* Navigation Tabs */} -
- {sections.map((section) => ( - - ))} -
- - {/* Content */} -
- {activeSection === 'overview' && } - {activeSection === 'pieces' && } - {activeSection === 'capture' && } - {activeSection === 'harmony' && } - {activeSection === 'victory' && } -
- + + {/* Navigation Tabs */} +
+ {sections.map((section) => ( + + ))} +
+ + {/* Content */} +
+ {activeSection === 'overview' && ( + + )} + {activeSection === 'pieces' && ( + + )} + {activeSection === 'capture' && ( + + )} + {activeSection === 'harmony' && ( + + )} + {activeSection === 'victory' && ( + + )} +
+
) + + // If standalone, just render the content without Dialog wrapper + if (standalone) { + return modalContent + } + + // Otherwise, just render the modal (no backdrop so game is visible) + return modalContent } -function OverviewSection() { +function OverviewSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) { + const { t } = useTranslation() + + // Initial board setup - full starting position + const initialSetup: ExamplePiece[] = [ + // BLACK - Column A + { square: 'A1', type: 'S', color: 'B', value: 28 }, + { square: 'A2', type: 'S', color: 'B', value: 66 }, + { square: 'A7', type: 'S', color: 'B', value: 225 }, + { square: 'A8', type: 'S', color: 'B', value: 361 }, + // BLACK - Column B + { square: 'B1', type: 'S', color: 'B', value: 28 }, + { square: 'B2', type: 'S', color: 'B', value: 66 }, + { square: 'B3', type: 'T', color: 'B', value: 36 }, + { square: 'B4', type: 'T', color: 'B', value: 30 }, + { square: 'B5', type: 'T', color: 'B', value: 56 }, + { square: 'B6', type: 'T', color: 'B', value: 64 }, + { square: 'B7', type: 'S', color: 'B', value: 120 }, + { square: 'B8', type: 'P', color: 'B', value: 36 }, + // BLACK - Column C + { square: 'C1', type: 'T', color: 'B', value: 16 }, + { square: 'C2', type: 'T', color: 'B', value: 12 }, + { square: 'C3', type: 'C', color: 'B', value: 9 }, + { square: 'C4', type: 'C', color: 'B', value: 25 }, + { square: 'C5', type: 'C', color: 'B', value: 49 }, + { square: 'C6', type: 'C', color: 'B', value: 81 }, + { square: 'C7', type: 'T', color: 'B', value: 90 }, + { square: 'C8', type: 'T', color: 'B', value: 100 }, + // BLACK - Column D + { square: 'D3', type: 'C', color: 'B', value: 3 }, + { square: 'D4', type: 'C', color: 'B', value: 5 }, + { square: 'D5', type: 'C', color: 'B', value: 7 }, + { square: 'D6', type: 'C', color: 'B', value: 9 }, + // WHITE - Column M + { square: 'M3', type: 'C', color: 'W', value: 8 }, + { square: 'M4', type: 'C', color: 'W', value: 6 }, + { square: 'M5', type: 'C', color: 'W', value: 4 }, + { square: 'M6', type: 'C', color: 'W', value: 2 }, + // WHITE - Column N + { square: 'N1', type: 'T', color: 'W', value: 81 }, + { square: 'N2', type: 'T', color: 'W', value: 72 }, + { square: 'N3', type: 'C', color: 'W', value: 64 }, + { square: 'N4', type: 'C', color: 'W', value: 16 }, + { square: 'N5', type: 'C', color: 'W', value: 16 }, + { square: 'N6', type: 'C', color: 'W', value: 4 }, + { square: 'N7', type: 'T', color: 'W', value: 6 }, + { square: 'N8', type: 'T', color: 'W', value: 9 }, + // WHITE - Column O + { square: 'O1', type: 'S', color: 'W', value: 153 }, + { square: 'O2', type: 'P', color: 'W', value: 64 }, + { square: 'O3', type: 'T', color: 'W', value: 72 }, + { square: 'O4', type: 'T', color: 'W', value: 20 }, + { square: 'O5', type: 'T', color: 'W', value: 20 }, + { square: 'O6', type: 'T', color: 'W', value: 25 }, + { square: 'O7', type: 'S', color: 'W', value: 45 }, + { square: 'O8', type: 'S', color: 'W', value: 15 }, + // WHITE - Column P + { square: 'P1', type: 'S', color: 'W', value: 289 }, + { square: 'P2', type: 'S', color: 'W', value: 169 }, + { square: 'P7', type: 'S', color: 'W', value: 81 }, + { square: 'P8', type: 'S', color: 'W', value: 25 }, + ] + return (

- Goal of the Game + {t('guide.overview.goalTitle', 'Goal of the Game')}

- Arrange 3 of your pieces in enemy territory to form a{' '} - mathematical progression, survive one opponent turn, and win. + {t( + 'guide.overview.goal', + 'Arrange 3 of your pieces in enemy territory to form a mathematical progression, survive one opponent turn, and win.' + )}

- The Board + {t('guide.overview.boardTitle', 'The Board')}

+ +
+ +
+ +

+ {t( + 'guide.overview.boardCaption', + 'The starting position - Black on the left, White on the right' + )} +

+
    -
  • 8 rows × 16 columns (columns A-P, rows 1-8)
  • +
  • {t('guide.overview.boardSize', '8 rows × 16 columns (columns A-P, rows 1-8)')}
  • - Your half: Black controls rows 5-8, White controls rows 1-4 + {t( + 'guide.overview.territory', + 'Your half: Black controls rows 5-8, White controls rows 1-4' + )}
  • - Enemy territory: Where you need to build your winning progression + {t( + 'guide.overview.enemyTerritory', + 'Enemy territory: Where you need to build your winning progression' + )}
@@ -295,7 +656,7 @@ function OverviewSection() { mt: '24px', })} > - How to Play + {t('guide.overview.howToPlayTitle', 'How to Play')}
    -
  1. Start by moving pieces toward the center
  2. -
  3. Look for capture opportunities using mathematical relations
  4. -
  5. Push into enemy territory (rows 1-4 for Black, rows 5-8 for White)
  6. -
  7. Watch for harmony opportunities with your forward pieces
  8. -
  9. Win by forming a progression that survives one turn!
  10. +
  11. {t('guide.overview.step1', 'Move your pieces toward the center')}
  12. +
  13. {t('guide.overview.step2', 'Look for ways to capture using math')}
  14. +
  15. {t('guide.overview.step3', 'Push into enemy territory')}
  16. +
  17. {t('guide.overview.step4', 'Watch for chances to make a progression')}
  18. +
  19. {t('guide.overview.step5', 'Win by forming a progression that survives one turn!')}
) } -function PiecesSection() { +function PiecesSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) { + const { t } = useTranslation() const pieces: { type: PieceType; name: string; movement: string; count: number }[] = [ - { type: 'C', name: 'Circle', movement: 'Diagonal (like a bishop)', count: 8 }, - { type: 'T', name: 'Triangle', movement: 'Straight lines (like a rook)', count: 8 }, - { type: 'S', name: 'Square', movement: 'Any direction (like a queen)', count: 7 }, - { type: 'P', name: 'Pyramid', movement: 'One step any way (like a king)', count: 1 }, + { + type: 'C', + name: t('guide.pieces.circle', 'Circle'), + movement: t('guide.pieces.circleMove', 'Diagonal (like a bishop)'), + count: 8, + }, + { + type: 'T', + name: t('guide.pieces.triangle', 'Triangle'), + movement: t('guide.pieces.triangleMove', 'Straight lines (like a rook)'), + count: 8, + }, + { + type: 'S', + name: t('guide.pieces.square', 'Square'), + movement: t('guide.pieces.squareMove', 'Any direction (like a queen)'), + count: 7, + }, + { + type: 'P', + name: t('guide.pieces.pyramid', 'Pyramid'), + movement: t('guide.pieces.pyramidMove', 'One step any way (like a king)'), + count: 1, + }, ] return ( @@ -333,10 +715,10 @@ function PiecesSection() { mb: '16px', })} > - Your Pieces (24 total) + {t('guide.pieces.title', 'Your Pieces (24 total)')}

- Each piece has a number value and moves differently: + {t('guide.pieces.description', 'Each piece has a number value and moves differently:')}

@@ -360,14 +742,13 @@ function PiecesSection() { flexShrink: 0, })} > - - - +

- Count: {piece.count} + {t('guide.pieces.count', 'Count')}: {piece.count}

@@ -401,17 +782,21 @@ function PiecesSection() { })} >

- ⭐ Pyramids are special + {t('guide.pieces.pyramidTitle', '⭐ Pyramids are special')}

- Pyramids have 4 face values. When capturing, you choose which face to use. + {t( + 'guide.pieces.pyramidDescription', + 'Pyramids have 4 face values. When capturing, you choose which face to use.' + )}

) } -function CaptureSection() { +function CaptureSection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) { + const { t } = useTranslation() return (

- How to Capture + {t('guide.capture.title', 'How to Capture')}

- You can capture an enemy piece{' '} - only if your piece's value relates mathematically to theirs: + {t( + 'guide.capture.description', + "You can capture an enemy piece only if your piece's value relates mathematically to theirs:" + )}

- Simple Relations (no helper needed) + {t('guide.capture.simpleTitle', 'Simple Relations (no helper needed)')}

- Equal + {t('guide.capture.equality', 'Equal')} +

+

+ {t('guide.capture.equalityExample', 'Your 25 captures their 25')}

-

Your 25 captures their 25

- Multiple / Divisor + {t('guide.capture.multiple', 'Multiple / Divisor')}

- Your 64 captures their 16 (64 ÷ 16 = 4) + {t('guide.capture.multipleExample', 'Your 64 captures their 16 (64 ÷ 16 = 4)')}

@@ -466,31 +855,31 @@ function CaptureSection() { mt: '20px', })} > - Advanced Relations (need one helper piece) + {t('guide.capture.advancedTitle', 'Advanced Relations (need one helper piece)')}

- Sum + {t('guide.capture.sum', 'Sum')}

- Your 9 + helper 16 = enemy 25 + {t('guide.capture.sumExample', 'Your 9 + helper 16 = enemy 25')}

- Difference + {t('guide.capture.difference', 'Difference')}

- Your 30 - helper 10 = enemy 20 + {t('guide.capture.differenceExample', 'Your 30 - helper 10 = enemy 20')}

- Product + {t('guide.capture.product', 'Product')}

- Your 5 × helper 5 = enemy 25 + {t('guide.capture.productExample', 'Your 5 × helper 5 = enemy 25')}

@@ -505,18 +894,21 @@ function CaptureSection() { })} >

- 💡 What are helpers? + {t('guide.capture.helpersTitle', '💡 What are helpers?')}

- Helpers are your other pieces still on the board — they don't move, just provide their - value for the math. The game will show you valid captures when you select a piece. + {t( + 'guide.capture.helpersDescription', + "Helpers are your other pieces still on the board — they don't move, just provide their value for the math. The game will show you valid captures when you select a piece." + )}

) } -function HarmonySection() { +function HarmonySection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) { + const { t } = useTranslation() return (

- Harmonies (Progressions) + {t('guide.harmony.title', 'Harmonies (Progressions)')}

- Get 3 of your pieces into enemy territory forming one of these - progressions: + {t( + 'guide.harmony.description', + 'Get 3 of your pieces into enemy territory forming one of these progressions:' + )}

@@ -546,13 +940,13 @@ function HarmonySection() {

- Arithmetic Progression + {t('guide.harmony.arithmetic', 'Arithmetic Progression')}

- Middle value is the average + {t('guide.harmony.arithmeticDesc', 'Middle value is the average')}

- Example: 6, 9, 12 (because 9 = (6+12)/2) + {t('guide.harmony.arithmeticExample', 'Example: 6, 9, 12 (because 9 = (6+12)/2)')}

@@ -567,13 +961,13 @@ function HarmonySection() {

- Geometric Progression + {t('guide.harmony.geometric', 'Geometric Progression')}

- Middle value is geometric mean + {t('guide.harmony.geometricDesc', 'Middle value is geometric mean')}

- Example: 4, 8, 16 (because 8² = 4×16) + {t('guide.harmony.geometricExample', 'Example: 4, 8, 16 (because 8² = 4×16)')}

@@ -588,13 +982,13 @@ function HarmonySection() {

- Harmonic Progression + {t('guide.harmony.harmonic', 'Harmonic Progression')}

- Special proportion (formula: 2AB = M(A+B)) + {t('guide.harmony.harmonicDesc', 'Special proportion (formula: 2AB = M(A+B))')}

- Example: 6, 8, 12 (because 2×6×12 = 8×(6+12)) + {t('guide.harmony.harmonicExample', 'Example: 6, 8, 12 (because 2×6×12 = 8×(6+12))')}

@@ -609,20 +1003,31 @@ function HarmonySection() { })} >

- ⚠️ Important Rules + {t('guide.harmony.rulesTitle', '⚠️ Important Rules')}

    -
  • Your 3 pieces must be in a straight line (row, column, or diagonal)
  • -
  • All 3 must be in enemy territory
  • -
  • When you form a harmony, your opponent gets one turn to break it
  • -
  • If it survives, you win!
  • +
  • + {t( + 'guide.harmony.rule1', + 'Your 3 pieces must be in a straight line (row, column, or diagonal)' + )} +
  • +
  • {t('guide.harmony.rule2', 'All 3 must be in enemy territory')}
  • +
  • + {t( + 'guide.harmony.rule3', + 'When you form a harmony, your opponent gets one turn to break it' + )} +
  • +
  • {t('guide.harmony.rule4', 'If it survives, you win!')}
) } -function VictorySection() { +function VictorySection({ useNativeAbacusNumbers }: { useNativeAbacusNumbers: boolean }) { + const { t } = useTranslation() return (

- How to Win + {t('guide.victory.title', 'How to Win')}

@@ -650,11 +1055,13 @@ function VictorySection() { })} > 👑 - Victory #1: Harmony (Progression) + {t('guide.victory.harmony', 'Victory #1: Harmony (Progression)')}

- Form a mathematical progression with 3 pieces in enemy territory. If it survives your - opponent's next turn, you win! + {t( + 'guide.victory.harmonyDesc', + "Form a mathematical progression with 3 pieces in enemy territory. If it survives your opponent's next turn, you win!" + )}

- This is the primary victory condition in Rithmomachia + {t( + 'guide.victory.harmonyNote', + 'This is the primary victory condition in Rithmomachia' + )}

@@ -683,10 +1093,13 @@ function VictorySection() { })} > 🚫 - Victory #2: Exhaustion + {t('guide.victory.exhaustion', 'Victory #2: Exhaustion')}

- If your opponent has no legal moves at the start of their turn, they lose. + {t( + 'guide.victory.exhaustionDesc', + 'If your opponent has no legal moves at the start of their turn, they lose.' + )}

@@ -700,7 +1113,7 @@ function VictorySection() { mt: '32px', })} > - Quick Strategy Tips + {t('guide.victory.strategyTitle', 'Quick Strategy Tips')}
    +
  • {t('guide.victory.tip1', 'Control the center — easier to invade enemy territory')}
  • - Control the center — easier to invade enemy territory + {t( + 'guide.victory.tip2', + 'Small pieces are fast — circles (3, 5, 7, 9) can slip into enemy half quickly' + )}
  • - Small pieces are fast — circles (3, 5, 7, 9) can slip into enemy half - quickly + {t( + 'guide.victory.tip3', + 'Large pieces are powerful — harder to capture due to their size' + )}
  • - Large pieces are powerful — harder to capture due to their size + {t( + 'guide.victory.tip4', + "Watch for harmony threats — don't let opponent get 3 pieces deep in your territory" + )}
  • - Watch for harmony threats — don't let opponent get 3 pieces deep in your - territory -
  • -
  • - Pyramids are flexible — choose the right face value for each situation + {t( + 'guide.victory.tip5', + 'Pyramids are flexible — choose the right face value for each situation' + )}
diff --git a/apps/web/src/arcade-games/rithmomachia/i18n/locales/de.json b/apps/web/src/arcade-games/rithmomachia/i18n/locales/de.json new file mode 100644 index 00000000..548540dd --- /dev/null +++ b/apps/web/src/arcade-games/rithmomachia/i18n/locales/de.json @@ -0,0 +1,102 @@ +{ + "guide": { + "title": "Rithmomachia Spielanleitung", + "subtitle": "Rithmomachia – Das Spiel der Philosophen", + "close": "Schließen", + "maximize": "Maximieren", + "restore": "Wiederherstellen", + "bustOut": "In neuem Fenster öffnen", + "sections": { + "overview": "Schnellstart", + "pieces": "Spielfiguren", + "capture": "Schlagen", + "strategy": "Strategie", + "harmony": "Harmonie", + "victory": "Sieg" + }, + "languageSelector": { + "label": "Sprache", + "en": "English", + "de": "Deutsch" + }, + "overview": { + "goalTitle": "Spielziel", + "goal": "Bringen Sie 3 Ihrer Steine ins gegnerische Gebiet, um eine mathematische Progression zu bilden, überstehen Sie eine Runde des Gegners und gewinnen Sie.", + "boardTitle": "Das Spielbrett", + "boardSize": "8 Reihen × 16 Spalten (Spalten A-P, Reihen 1-8)", + "territory": "Ihre Hälfte: Schwarz kontrolliert Reihen 5-8, Weiß kontrolliert Reihen 1-4", + "enemyTerritory": "Gegnerisches Gebiet: Wo Sie Ihre Siegprogression aufbauen müssen", + "howToPlayTitle": "Spielablauf", + "step1": "Bewegen Sie Steine zunächst zur Mitte", + "step2": "Suchen Sie nach Schlagmöglichkeiten durch mathematische Beziehungen", + "step3": "Dringen Sie ins gegnerische Gebiet vor (Reihen 1-4 für Schwarz, Reihen 5-8 für Weiß)", + "step4": "Achten Sie auf Harmoniemöglichkeiten mit Ihren vorderen Steinen", + "step5": "Gewinnen Sie durch eine Progression, die eine Runde übersteht!" + }, + "pieces": { + "title": "Ihre Spielfiguren (24 insgesamt)", + "description": "Jede Figur hat einen Zahlenwert und bewegt sich anders:", + "count": "Anzahl", + "circle": "Kreis", + "circleMove": "Diagonal (wie ein Läufer)", + "triangle": "Dreieck", + "triangleMove": "Geradeaus (wie ein Turm)", + "square": "Quadrat", + "squareMove": "In alle Richtungen (wie eine Dame)", + "pyramid": "Pyramide", + "pyramidMove": "Ein Feld in alle Richtungen (wie ein König)", + "pyramidTitle": "⭐ Pyramiden sind besonders", + "pyramidDescription": "Pyramiden haben 4 Seitenwerte. Beim Schlagen wählen Sie, welche Seite Sie verwenden." + }, + "capture": { + "title": "Wie man schlägt", + "description": "Sie können einen gegnerischen Stein nur schlagen, wenn der Wert Ihres Steins in einer mathematischen Beziehung zu ihm steht:", + "simpleTitle": "Einfache Beziehungen (kein Helfer nötig)", + "equality": "Gleich", + "equalityExample": "Ihre 25 schlägt deren 25", + "multiple": "Vielfaches / Teiler", + "multipleExample": "Ihre 64 schlägt deren 16 (64 ÷ 16 = 4)", + "advancedTitle": "Erweiterte Beziehungen (ein Helferstein nötig)", + "sum": "Summe", + "sumExample": "Ihre 9 + Helfer 16 = Gegner 25", + "difference": "Differenz", + "differenceExample": "Ihre 30 - Helfer 10 = Gegner 20", + "product": "Produkt", + "productExample": "Ihre 5 × Helfer 5 = Gegner 25", + "helpersTitle": "💡 Was sind Helfer?", + "helpersDescription": "Helfer sind Ihre anderen Steine, die noch auf dem Brett sind – sie bewegen sich nicht, sondern stellen nur ihren Wert für die Mathematik zur Verfügung. Das Spiel zeigt Ihnen gültige Schlagzüge, wenn Sie einen Stein auswählen." + }, + "harmony": { + "title": "Harmonien (Progressionen)", + "description": "Bringen Sie 3 Ihrer Steine ins gegnerische Gebiet und bilden Sie eine dieser Progressionen:", + "arithmetic": "Arithmetische Progression", + "arithmeticDesc": "Mittlerer Wert ist der Durchschnitt", + "arithmeticExample": "Beispiel: 6, 9, 12 (weil 9 = (6+12)/2)", + "geometric": "Geometrische Progression", + "geometricDesc": "Mittlerer Wert ist das geometrische Mittel", + "geometricExample": "Beispiel: 4, 8, 16 (weil 8² = 4×16)", + "harmonic": "Harmonische Progression", + "harmonicDesc": "Spezielle Proportion (Formel: 2AB = M(A+B))", + "harmonicExample": "Beispiel: 6, 8, 12 (weil 2×6×12 = 8×(6+12))", + "rulesTitle": "⚠️ Wichtige Regeln", + "rule1": "Ihre 3 Steine müssen in einer geraden Linie stehen (Reihe, Spalte oder Diagonale)", + "rule2": "Alle 3 müssen im gegnerischen Gebiet sein", + "rule3": "Wenn Sie eine Harmonie bilden, hat Ihr Gegner einen Zug, um sie zu zerstören", + "rule4": "Wenn sie übersteht, gewinnen Sie!" + }, + "victory": { + "title": "Wie man gewinnt", + "harmony": "Sieg #1: Harmonie (Progression)", + "harmonyDesc": "Bilden Sie eine mathematische Progression mit 3 Steinen im gegnerischen Gebiet. Wenn sie den nächsten Zug Ihres Gegners übersteht, gewinnen Sie!", + "harmonyNote": "Dies ist die primäre Siegbedingung in Rithmomachia", + "exhaustion": "Sieg #2: Erschöpfung", + "exhaustionDesc": "Wenn Ihr Gegner zu Beginn seines Zuges keine legalen Züge hat, verliert er.", + "strategyTitle": "Schnelle Strategietipps", + "tip1": "Kontrollieren Sie die Mitte – leichter ins gegnerische Gebiet vorzudringen", + "tip2": "Kleine Steine sind schnell – Kreise (3, 5, 7, 9) können schnell in die gegnerische Hälfte schlüpfen", + "tip3": "Große Steine sind mächtig – schwerer zu schlagen aufgrund ihrer Größe", + "tip4": "Achten Sie auf Harmoniebedrohungen – lassen Sie den Gegner nicht 3 Steine tief in Ihr Gebiet bringen", + "tip5": "Pyramiden sind flexibel – wählen Sie den richtigen Seitenwert für jede Situation" + } + } +} diff --git a/apps/web/src/arcade-games/rithmomachia/i18n/locales/en.json b/apps/web/src/arcade-games/rithmomachia/i18n/locales/en.json new file mode 100644 index 00000000..40c38f3f --- /dev/null +++ b/apps/web/src/arcade-games/rithmomachia/i18n/locales/en.json @@ -0,0 +1,369 @@ +{ + "guide": { + "title": "Rithmomachia Playing Guide", + "subtitle": "Rithmomachia – The Philosopher's Game", + "close": "Close", + "maximize": "Maximize", + "restore": "Restore", + "bustOut": "Open in new window", + "sections": { + "overview": "Quick Start", + "pieces": "Pieces", + "capture": "Capture", + "strategy": "Strategy", + "harmony": "Harmony", + "victory": "Victory" + }, + "languageSelector": { + "label": "Language", + "en": "English", + "de": "Deutsch", + "ja": "日本語", + "hi": "हिन्दी", + "es": "Español" + }, + "overview": { + "goalTitle": "Goal of the Game", + "goal": "Arrange 3 of your pieces in enemy territory to form a mathematical progression, survive one opponent turn, and win.", + "goalDesc": "Arrange 3 of your pieces in enemy territory to form a mathematical progression, survive one opponent turn, and win.", + "boardTitle": "The Board", + "boardSize": "8 rows × 16 columns (columns A-P, rows 1-8)", + "territory": "Your half: Black controls rows 5-8, White controls rows 1-4", + "enemyTerritory": "Enemy territory: Where you need to build your winning progression", + "boardItems": [ + "8 rows × 16 columns (columns A-P, rows 1-8)", + "Your half: Black controls rows 5-8, White controls rows 1-4", + "Enemy territory: Where you need to build your winning progression" + ], + "howToPlayTitle": "How to Play", + "step1": "Start by moving pieces toward the center", + "step2": "Look for capture opportunities using mathematical relations", + "step3": "Push into enemy territory (rows 1-4 for Black, rows 5-8 for White)", + "step4": "Watch for harmony opportunities with your forward pieces", + "step5": "Win by forming a progression that survives one turn!", + "howToPlayItems": [ + "Start by moving pieces toward the center", + "Look for capture opportunities using mathematical relations", + "Push into enemy territory (rows 1-4 for Black, rows 5-8 for White)", + "Watch for harmony opportunities with your forward pieces", + "Win by forming a progression that survives one turn!" + ] + }, + "pieces": { + "title": "Your Pieces (24 total)", + "description": "Each piece has a number value and moves differently:", + "intro": "Each piece has a number value and moves differently:", + "count": "Count", + "circle": "Circle", + "circleMove": "Diagonal (like a bishop)", + "triangle": "Triangle", + "triangleMove": "Straight lines (like a rook)", + "square": "Square", + "squareMove": "Any direction (like a queen)", + "pyramid": "Pyramid", + "pyramidMove": "One step any way (like a king)", + "pyramidTitle": "⭐ Pyramids are special", + "pyramidDescription": "Pyramids have 4 face values. When capturing, you choose which face to use.", + "pieceTypes": { + "circle": { + "name": "Circle", + "movement": "Diagonal (like a bishop)", + "count": "Count: 8" + }, + "triangle": { + "name": "Triangle", + "movement": "Straight lines (like a rook)", + "count": "Count: 8" + }, + "square": { + "name": "Square", + "movement": "Any direction (like a queen)", + "count": "Count: 7" + }, + "pyramid": { + "name": "Pyramid", + "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 4 face values 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": "Example: 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": "Capture options from H5:", + "option1": "Move to I5: Choose face 64 → captures 16 by multiple (64÷16=4)", + "option2": "Move to H6: Choose face 49 → captures 49 by equality (49=49)", + "option3": "Move to G5: Choose face 25 → captures 25 by equality (25=25)" + } + }, + "capture": { + "title": "How to Capture", + "description": "You can capture an enemy piece only if your piece's value relates mathematically to theirs:", + "intro": "You can capture an enemy piece only if your piece's value relates mathematically to theirs:", + "simpleTitle": "Simple Relations (no helper needed)", + "equality": "Equal", + "equalityExample": "Your 25 captures their 25", + "multiple": "Multiple / Divisor", + "multipleExample": "Your 64 captures their 16 (64 ÷ 16 = 4)", + "simpleEqual": { + "name": "Equal", + "desc": "Your 25 captures their 25" + }, + "simpleMultiple": { + "name": "Multiple / Divisor", + "desc": "Your 64 captures their 16 (64 ÷ 16 = 4)" + }, + "advancedTitle": "Advanced Relations (need one helper piece)", + "sum": "Sum", + "sumExample": "Your 9 + helper 16 = enemy 25", + "difference": "Difference", + "differenceExample": "Your 30 - helper 10 = enemy 20", + "product": "Product", + "productExample": "Your 5 × helper 5 = enemy 25", + "advancedSum": { + "name": "Sum", + "desc": "Your 9 + helper 16 = enemy 25" + }, + "advancedDifference": { + "name": "Difference", + "desc": "Your 30 - helper 10 = enemy 20" + }, + "advancedProduct": { + "name": "Product", + "desc": "Your 5 × helper 5 = enemy 25" + }, + "helpersTitle": "💡 What are helpers?", + "helpersDescription": "Helpers are your other pieces still on the board — they don't move, just provide their value for the math. The game will show you valid captures when you select a piece.", + "helpersDesc": "Helpers are your other pieces still on the board — they don't move, just provide their value for the math. The game will show you valid captures when you select a piece.", + "example1Title": "Example: Multiple/Divisor Capture", + "example1Desc": "White's 64 (square) can capture Black's 16 (triangle) because 64 is a multiple of 16", + "example2Title": "Example: Sum Capture with Helper", + "example2Desc": "White's 9 + helper 16 = Black's 25 (9 + 16 = 25)", + "example3Title": "Example: Difference Capture with Helper", + "example3Desc": "White's 30 - helper 10 = Black's 20 (30 - 10 = 20)", + "example4Title": "Example: Product Capture with Helper", + "example4Desc": "White's 4 × helper 5 = Black's 20 (4 × 5 = 20)", + "example5Title": "Example: Ratio Capture with Helper", + "example5Desc": "White's 20 ÷ helper 4 = Black's 5 (20 ÷ 4 = 5)", + "pyramidTitle": "Special: Pyramid Captures", + "pyramidIntro": "Pyramids have 4 face values, making them incredibly versatile. You choose which face to use when attempting a capture, allowing one Pyramid to threaten multiple enemy pieces.", + "pyramidEx1Title": "Example: Pyramid Face Selection (Equality)", + "pyramidEx1Desc": "White's Pyramid (faces: 64, 49, 36, 25) can capture Black's 49 by choosing face 49 for equality (49 = 49)", + "pyramidEx1Note": "Face selection: White declares face 49 → 49 = 49 (equality) → Capture succeeds! The Pyramid could also capture pieces valued 64, 36, or 25 using the corresponding faces.", + "pyramidEx2Title": "Example: Pyramid with Helper (Sum)", + "pyramidEx2Desc": "White's Pyramid uses face 25 + helper 20 = Black's 45 (25 + 20 = 45)", + "pyramidEx2Note": "Face selection: White chooses face 25 and declares helper at D4 (value 20) → 25 + 20 = 45 (sum) → Capture succeeds! By selecting different faces, the same Pyramid could capture other values using various helpers.", + "pyramidEx3Title": "Example: Pyramid Flexibility (Multiple/Divisor)", + "pyramidEx3Desc": "Black's Pyramid (faces: 36, 25, 16, 4) can capture White's 9 using face 36 (multiple: 36 ÷ 9 = 4)", + "pyramidEx3Note": "Face selection: Black chooses face 36 → 36 ÷ 9 = 4 (multiple) → Capture succeeds! Note: Black could also use face 4 with a helper 5 for sum (4 + 5 = 9), showing multiple valid approaches." + }, + "harmony": { + "title": "Harmonies (Progressions)", + "description": "Get 3 of your pieces into enemy territory forming one of these progressions:", + "intro1": "A Harmony (also called a \"Proper Victory\") is the most sophisticated way to win. Get 3 of your pieces into enemy territory arranged in a straight line where their values form a mathematical pattern.", + "intro2": "Think of it like getting three numbers in a sequence—but the sequences follow special mathematical rules from ancient philosophy and music theory.", + "typesTitle": "The Three Types of Harmony", + "arithmetic": "Arithmetic Progression", + "arithmeticDesc": "Middle value is the average", + "arithmeticExample": "Example: 6, 9, 12 (because 9 = (6+12)/2)", + "geometric": "Geometric Progression", + "geometricDesc": "Middle value is geometric mean", + "geometricExample": "Example: 4, 8, 16 (because 8² = 4×16)", + "harmonic": "Harmonic Progression", + "harmonicDesc": "Special proportion (formula: 2AB = M(A+B))", + "harmonicExample": "Example: 6, 8, 12 (because 2×6×12 = 8×(6+12))", + "rulesTitle": "⚠️ Important Rules", + "rule1": "Your 3 pieces must be in a straight line (row, column, or diagonal)", + "rule2": "All 3 must be in enemy territory", + "rule3": "When you form a harmony, your opponent gets one turn to break it", + "rule4": "If it survives, you win!", + "arithmeticOld": { + "title": "1. Arithmetic Progression (Easiest to Understand)", + "desc": "The middle number is exactly halfway between the other two. In other words, the differences are equal.", + "formula": "How to check: Middle × 2 = First + Last", + "ex1": "Example 1: 6, 9, 12", + "ex1Check": "Differences: 9−6=3, 12−9=3 (equal!) • Check: 9×2 = 18 = 6+12 ✓", + "ex2": "Example 2: 5, 7, 9", + "ex2Check": "Differences: 7−5=2, 9−7=2 • Check: 7×2 = 14 = 5+9 ✓", + "ex3": "Example 3: 8, 12, 16", + "ex3Check": "Differences: 12−8=4, 16−12=4 • Check: 12×2 = 24 = 8+16 ✓", + "tip": "Strategy tip: Your small circles (2-9) and many triangles naturally form arithmetic progressions. Look for three pieces where the gaps are equal!" + }, + "geometricOld": { + "title": "2. Geometric Progression (Powers and Multiples)", + "desc": "Each number is multiplied by the same amount to get the next. The ratios are equal.", + "formula": "How to check: Middle² = First × Last", + "ex1": "Example 1: 4, 8, 16", + "ex1Check": "Ratios: 8÷4=2, 16÷8=2 (equal!) • Check: 8² = 64 = 4×16 ✓", + "ex2": "Example 2: 3, 9, 27", + "ex2Check": "Ratios: 9÷3=3, 27÷9=3 • Check: 9² = 81 = 3×27 ✓", + "ex3": "Example 3: 2, 8, 32", + "ex3Check": "Ratios: 8÷2=4, 32÷8=4 • Check: 8² = 64 = 2×32 ✓", + "tip": "Strategy tip: Square values (4, 9, 16, 25, 36, 49, 64, 81) work great here! For example, 4-16-64 (squares of 2, 4, 8)." + }, + "harmonicOld": { + "title": "3. Harmonic Progression (Music-Based, Trickiest)", + "desc": "Named after musical harmonies. The pattern is: the ratio of the outer numbers equals the ratio of their differences from the middle.", + "formula": "How to check: 2 × First × Last = Middle × (First + Last)", + "ex1": "Example 1: 6, 8, 12", + "ex1Check": "Check: 2×6×12 = 144 = 8×(6+12) = 8×18 ✓", + "ex2": "Example 2: 10, 12, 15", + "ex2Check": "Check: 2×10×15 = 300 = 12×(10+15) = 12×25 ✓", + "ex3": "Example 3: 6, 10, 15", + "ex3Check": "Check: 2×6×15 = 180 = 10×(6+15) = 10×18 ✓", + "tip": "Strategy tip: Harmonic progressions are rarer. Memorize common triads: (3,4,6), (4,6,12), (6,8,12), (6,10,15), (8,12,24)." + }, + "rulesOld": [ + "Enemy Territory Only: All 3 pieces must be in your opponent's half (White needs rows 5-8, Black needs rows 1-4)", + "Straight Line: The 3 pieces must form a row, column, or diagonal—no scattered formations", + "Adjacent Placement: In this implementation, the 3 pieces must be next to each other (no gaps)", + "Survival Rule: When you declare a harmony, your opponent gets ONE turn to break it by capturing or moving a piece", + "Victory: If your harmony survives until your next turn starts—you win!" + ], + "strategyTitle": "Strategy: How to Build Harmonies", + "strategy1Title": "Start with 2, Add the Third", + "strategy1Desc": "Get two pieces into enemy territory first. Calculate which third piece would complete a progression, then advance that piece. Your opponent may not notice the threat until it's too late!", + "strategy2Title": "Use Common Values", + "strategy2Desc": "Pieces like 6, 8, 9, 12, 16 appear in multiple progressions. If you have these in enemy territory, calculate all possible third pieces that would complete a pattern.", + "strategy3Title": "Protect the Line", + "strategy3Desc": "While building your harmony, position other pieces to defend your advancing pieces. One capture breaks the progression!", + "strategy4Title": "Block Opponent's Harmonies", + "strategy4Desc": "If your opponent has 2 pieces in your territory forming part of a progression, identify which third piece would complete it. Block that square or capture one of the two pieces immediately.", + "strategy5Title": "Calculate Before You Declare", + "strategy5Desc": "Before declaring harmony, examine if your opponent can capture any of the 3 pieces on their turn. If they can, either protect those pieces first or wait for a safer moment.", + "quickRefTitle": "💡 Quick Reference: Common Harmonies in Your Army", + "exampleTitle": "Example: Arithmetic Progression Victory", + "exampleDesc": "White has formed 6, 9, 12 in a row in Black's territory (rows 5-8). Since 9 = (6+12)/2, this is an arithmetic progression. If it survives Black's next turn, White wins!", + "exampleNote": "The highlighted pieces form the winning progression in enemy territory" + }, + "victory": { + "title": "How to Win", + "harmony": "Victory #1: Harmony (Progression)", + "harmonyDesc": "Form a mathematical progression with 3 pieces in enemy territory. If it survives your opponent's next turn, you win!", + "harmonyNote": "This is the primary victory condition in Rithmomachia", + "exhaustion": "Victory #2: Exhaustion", + "exhaustionDesc": "If your opponent has no legal moves at the start of their turn, they lose.", + "strategyTitle": "Quick Strategy Tips", + "tip1": "Control the center — easier to invade enemy territory", + "tip2": "Small pieces are fast — circles (3, 5, 7, 9) can slip into enemy half quickly", + "tip3": "Large pieces are powerful — harder to capture due to their size", + "tip4": "Watch for harmony threats — don't let opponent get 3 pieces deep in your territory", + "tip5": "Pyramids are flexible — choose the right face value for each situation", + "harmonyOld": { + "title": "Victory #1: Harmony (Progression)", + "desc": "Form a mathematical progression with 3 pieces in enemy territory. If it survives your opponent's next turn, you win!", + "note": "This is the primary victory condition in Rithmomachia" + }, + "exhaustionOld": { + "title": "Victory #2: Exhaustion", + "desc": "If your opponent has no legal moves at the start of their turn, they lose." + }, + "exampleTitle": "Visual Example: Winning by Harmony", + "exampleDesc": "White's pieces at E6, F6, G6 form 6, 9, 12 - an arithmetic progression in Black's territory. If Black cannot break this on their next turn, White wins!", + "exampleNote": "✓ All 3 highlighted pieces are in enemy territory (rows 5-8 for White)\n✓ They form a straight line (horizontal row 6)\n✓ They satisfy arithmetic progression: 9 = (6+12)/2", + "tipsTitle": "Quick Strategy Tips", + "tips": [ + "Control the center — easier to invade enemy territory", + "Small pieces are fast — circles (3, 5, 7, 9) can slip into enemy half quickly", + "Large pieces are powerful — harder to capture due to their size", + "Watch for harmony threats — don't let opponent get 3 pieces deep in your territory", + "Pyramids are flexible — choose the right face value for each situation" + ] + }, + "strategy": { + "title": "Strategy & Tactics", + "intro": "Rithmomachia rewards both mathematical insight and strategic planning. Success requires balancing territorial control, piece preservation, and mathematical opportunities.", + "openingPrinciples": { + "title": "Opening Principles", + "controlCenter": { + "title": "Control the Center", + "desc": "Advance pieces toward the 8-column empty center (columns E–L). This provides mobility and creates capturing opportunities from multiple angles." + }, + "developCircles": { + "title": "Develop Small Circles First", + "desc": "Your small circles (2–9) in columns D and M are mobile and versatile. Move them toward the center early to establish presence and create helper networks." + }, + "protectPyramid": { + "title": "Protect Your Pyramid", + "desc": "The Pyramid is your most flexible piece (4 face values) but moves only 1 square. Keep it behind advancing lines until mid-game when mathematical threats are clear." + }, + "knowNumbers": { + "title": "Know Your Numbers", + "desc": "Memorize key mathematical relationships in your army. Identify which pieces form factors, multiples, and sums—this speeds up tactical calculation." + } + }, + "midGame": { + "title": "Mid-Game Tactics", + "helperNetworks": { + "title": "Build Helper Networks", + "desc": "Position pieces so multiple helpers can support captures. For example, if you have pieces valued 5 and 10, you can capture 15 (sum), 5 (difference), or 50 (product) when your mover is positioned correctly." + }, + "createThreats": { + "title": "Create Capture Threats", + "desc": "Force your opponent to defend multiple pieces simultaneously. Even if you can't execute all captures, the threat constrains their options and controls the tempo." + }, + "thinkDefensively": { + "title": "Think Defensively", + "desc": "After each move, check which of your pieces can be captured. High-value pieces like squares (169, 225, 289, 361) are vulnerable to many relations—position them behind defenders or in protected squares." + }, + "exchangeWhenAhead": { + "title": "Exchange When Ahead", + "desc": "If you've captured more pieces or higher values, simplify the position by trading pieces. This reduces your opponent's attacking options and brings you closer to exhaustion victory." + } + }, + "victoryPaths": { + "title": "Paths to Victory", + "harmony": { + "title": "Harmony Victory (Most Elegant)", + "desc": "Place 3 pieces in enemy territory forming an arithmetic, geometric, or harmonic progression. Common triads:", + "arithmetic": "Arithmetic: (6, 9, 12), (5, 7, 9), (8, 12, 16)", + "geometric": "Geometric: (4, 8, 16), (3, 9, 27), (2, 8, 32)", + "harmonic": "Harmonic: (6, 8, 12), (10, 12, 15), (6, 10, 15)" + }, + "exhaustion": { + "title": "Exhaustion Victory (Attrition)", + "desc": "Capture pieces systematically until your opponent has no legal moves. Focus on: eliminating mobile pieces (Squares and Triangles), blocking diagonals and ranks, and forcing the Pyramid into a corner." + }, + "points": { + "title": "Point Victory (Optional Rule)", + "desc": "If enabled, capture 30 points worth of pieces (C=1, T=2, S=3, P=5). Hunt high-value targets and preserve your own heavy pieces. Trade advantageously." + } + }, + "commonMistakes": { + "title": "⚠️ Common Mistakes to Avoid", + "movingWithoutCalc": "Moving without calculation: Always check if your destination square is capturable by enemy pieces", + "ignoringGeometry": "Ignoring helper geometry: Helpers can be anywhere, but you still need a legal move path to capture", + "neglectingHarmony": "Neglecting harmony threats: If your opponent has 2 pieces in your territory forming part of a progression, block their third", + "exposingPyramid": "Leaving the Pyramid exposed: It moves only 1 square and has limited escape options—protect it early" + }, + "advanced": { + "title": "Advanced Concepts", + "sacrifices": { + "title": "Positional Sacrifices", + "desc": "Sometimes sacrificing a piece opens lines for your other pieces or forces your opponent into a worse position. Calculate the resulting imbalance before sacrificing." + }, + "pyramidFaces": { + "title": "Pyramid Face Selection", + "desc": "Your Pyramid has 4 face values. In captures, choose the face that maximizes future flexibility. In harmony declarations, choose the face that completes the most valuable progression type." + }, + "tempo": { + "title": "Tempo and Initiative", + "desc": "Each move that forces a defensive response gains tempo. String together forcing moves (captures, threats) to dictate the pace and prevent your opponent from executing their plan." + } + } + } + } +}