Compare commits

...

8 Commits

Author SHA1 Message Date
semantic-release-bot
214b9077ab chore(release): 4.6.6 [skip ci]
## [4.6.6](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.5...v4.6.6) (2025-10-18)

### Bug Fixes

* **complement-race:** use local player emoji instead of first active player ([76eb051](76eb0517c2))
2025-10-18 13:58:33 +00:00
Thomas Hallock
76eb0517c2 fix(complement-race): use local player emoji instead of first active player
Fixed a bug where both LinearTrack and CircularTrack were displaying
the first active player's emoji instead of the current user's (local)
player emoji. This would cause incorrect avatar display in multi-player
arcade rooms.

Changed from:
- Getting first element of activePlayers array
- Would show wrong player in multi-player scenarios

To:
- Finding player with isLocal === true
- Correctly shows current user's avatar
- Matches pattern used throughout Provider.tsx

Files changed:
- LinearTrack.tsx: Use local player for emoji
- CircularTrack.tsx: Use local player for emoji

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 08:57:45 -05:00
semantic-release-bot
820000f93b chore(release): 4.6.5 [skip ci]
## [4.6.5](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.4...v4.6.5) (2025-10-18)

### Bug Fixes

* **complement-race:** flip player avatar to face right in practice mode ([fa6b3b6](fa6b3b69d5))
2025-10-18 13:48:07 +00:00
Thomas Hallock
fa6b3b69d5 fix(complement-race): flip player avatar to face right in practice mode
Adds scaleX(-1) to player racer icon so it faces the same direction as AI racers (racing to the right).

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 08:47:11 -05:00
semantic-release-bot
ca4ba6e2d7 chore(release): 4.6.4 [skip ci]
## [4.6.4](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.3...v4.6.4) (2025-10-18)

### Bug Fixes

* **complement-race:** flip AI racers to face right in practice mode ([ebfff1a](ebfff1a62f))
2025-10-18 13:39:34 +00:00
Thomas Hallock
ebfff1a62f fix(complement-race): flip AI racers to face right in practice mode
Adds horizontal flip (scaleX(-1)) to AI racer icons in LinearTrack so they face the correct direction (right) when racing.

CircularTrack doesn't need this fix as racers are already rotated to face the direction they're traveling around the track.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 08:38:38 -05:00
semantic-release-bot
ba04d7f491 chore(release): 4.6.3 [skip ci]
## [4.6.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.2...v4.6.3) (2025-10-18)

### Bug Fixes

* **complement-race:** balance AI speeds to match original implementation ([054f0c0](054f0c0d23))
2025-10-18 13:32:32 +00:00
Thomas Hallock
054f0c0d23 fix(complement-race): balance AI speeds to match original implementation
Fixes AI opponents racing away too fast and ending the game in 2 seconds by restoring the original balanced speeds and mode-specific multipliers.

Changes:
- Reduce AI base speeds from 0.8-1.2 to 0.32 (Swift AI) and 0.2 (Math Bot)
- Add mode-specific speedMultipliers: practice (0.7), sprint (0.9), survival (1.0)
- Update AI names to match original: "Swift AI" and "Math Bot"

The original system uses much lower base speeds combined with:
- Random variance (0.6-1.4x per update)
- Rubber-banding (2x speed when >10 units behind)
- Adaptive difficulty adjustments based on player performance

This makes AI opponents challenging but fair, adapting to player skill rather than just racing ahead at fixed high speeds.

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

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-18 08:31:38 -05:00
5 changed files with 47 additions and 14 deletions

View File

@@ -1,3 +1,31 @@
## [4.6.6](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.5...v4.6.6) (2025-10-18)
### Bug Fixes
* **complement-race:** use local player emoji instead of first active player ([76eb051](https://github.com/antialias/soroban-abacus-flashcards/commit/76eb0517c202d1b9160b49dec0b99ff4972daff2))
## [4.6.5](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.4...v4.6.5) (2025-10-18)
### Bug Fixes
* **complement-race:** flip player avatar to face right in practice mode ([fa6b3b6](https://github.com/antialias/soroban-abacus-flashcards/commit/fa6b3b69d5a4a7eb70f8c18fc8c122c54c4d504a))
## [4.6.4](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.3...v4.6.4) (2025-10-18)
### Bug Fixes
* **complement-race:** flip AI racers to face right in practice mode ([ebfff1a](https://github.com/antialias/soroban-abacus-flashcards/commit/ebfff1a62fd104d531a8158345c8c012ec8a55d3))
## [4.6.3](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.2...v4.6.3) (2025-10-18)
### Bug Fixes
* **complement-race:** balance AI speeds to match original implementation ([054f0c0](https://github.com/antialias/soroban-abacus-flashcards/commit/054f0c0d235dc2b0042a0f6af48840d23a4c5ff8))
## [4.6.2](https://github.com/antialias/soroban-abacus-flashcards/compare/v4.6.1...v4.6.2) (2025-10-18)

View File

@@ -22,10 +22,9 @@ export function CircularTrack({ playerProgress, playerLap, aiRacers, aiLaps }: C
const { playSound } = useSoundEffects()
const [celebrationCooldown, setCelebrationCooldown] = useState<Set<string>>(new Set())
// Get the first active player's emoji
const activePlayers = Array.from(players.values()).filter((p) => p.id)
const firstActivePlayer = activePlayers[0]
const playerEmoji = firstActivePlayer?.emoji ?? '👤'
// Get the local player's emoji
const localPlayer = Array.from(players.values()).find((p) => p.isLocal)
const playerEmoji = localPlayer?.emoji ?? '👤'
const [dimensions, setDimensions] = useState({ width: 600, height: 400 })
// Update dimensions on mount and resize

View File

@@ -23,10 +23,9 @@ export function LinearTrack({
const { players } = useGameMode()
const { profile: _profile } = useUserProfile()
// Get the first active player's emoji
const activePlayers = Array.from(players.values()).filter((p) => p.id)
const firstActivePlayer = activePlayers[0]
const playerEmoji = firstActivePlayer?.emoji ?? '👤'
// Get the local player's emoji
const localPlayer = Array.from(players.values()).find((p) => p.isLocal)
const playerEmoji = localPlayer?.emoji ?? '👤'
// Position calculation: leftPercent = Math.min(98, (progress / raceGoal) * 96 + 2)
// 2% minimum (start), 98% maximum (near finish), 96% range for race
@@ -110,7 +109,7 @@ export function LinearTrack({
position: 'absolute',
left: `${playerPosition}%`,
top: '50%',
transform: 'translate(-50%, -50%)',
transform: 'translate(-50%, -50%) scaleX(-1)',
fontSize: '32px',
transition: 'left 0.3s ease-out',
filter: 'drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2))',
@@ -132,7 +131,7 @@ export function LinearTrack({
position: 'absolute',
left: `${aiPosition}%`,
top: `${35 + index * 15}%`,
transform: 'translate(-50%, -50%)',
transform: 'translate(-50%, -50%) scaleX(-1)',
fontSize: '28px',
transition: 'left 0.2s linear',
filter: 'drop-shadow(0 2px 4px rgba(0, 0, 0, 0.2))',

View File

@@ -400,7 +400,12 @@ export function ComplementRaceProvider({ children }: { children: ReactNode }) {
// Race mechanics
raceGoal: multiplayerState.config.raceGoal,
timeLimit: multiplayerState.config.timeLimit ?? null,
speedMultiplier: 1.0,
speedMultiplier:
multiplayerState.config.style === 'practice'
? 0.7
: multiplayerState.config.style === 'sprint'
? 0.9
: 1.0, // Base speed multipliers by mode
aiRacers: clientAIRacers, // Use client-side AI state
// Sprint mode specific (all client-side for smooth movement)
@@ -460,17 +465,19 @@ export function ComplementRaceProvider({ children }: { children: ReactNode }) {
if (compatibleState.isGameActive && multiplayerState.config.enableAI) {
const count = multiplayerState.config.aiOpponentCount
if (count > 0 && clientAIRacers.length === 0) {
const aiNames = ['Robo-Racer', 'Calculator', 'Speed Demon', 'Brain Bot']
const aiNames = ['Swift AI', 'Math Bot', 'Speed Demon', 'Brain Bot']
const personalities: Array<'competitive' | 'analytical'> = ['competitive', 'analytical']
const newAI = []
for (let i = 0; i < Math.min(count, aiNames.length); i++) {
// Use original balanced speeds: 0.32 for Swift AI, 0.2 for Math Bot
const baseSpeed = i === 0 ? 0.32 : 0.2
newAI.push({
id: `ai-${i}`,
name: aiNames[i],
personality: personalities[i % personalities.length] as 'competitive' | 'analytical',
position: 0,
speed: 0.8 + Math.random() * 0.4, // Speed multiplier 0.8-1.2
speed: baseSpeed, // Balanced speed from original single-player version
icon: personalities[i % personalities.length] === 'competitive' ? '🏃‍♂️' : '🏃',
lastComment: 0,
commentCooldown: 0,

View File

@@ -1,6 +1,6 @@
{
"name": "soroban-monorepo",
"version": "4.6.2",
"version": "4.6.6",
"private": true,
"description": "Beautiful Soroban Flashcard Generator - Monorepo",
"workspaces": [