valtech-components 4.0.423 → 4.0.425
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/esm2022/lib/components/organisms/mini-games/chessimals-engine.mjs +116 -12
- package/esm2022/lib/components/organisms/mini-games/chessimals-game.component.mjs +13 -1
- package/esm2022/lib/components/organisms/mini-games/mini-games.i18n.mjs +45 -9
- package/esm2022/lib/components/organisms/mini-games/retro-audio.service.mjs +8 -1
- package/esm2022/lib/components/organisms/mini-games/types.mjs +1 -1
- package/esm2022/lib/version.mjs +2 -2
- package/fesm2022/valtech-components.mjs +179 -20
- package/fesm2022/valtech-components.mjs.map +1 -1
- package/lib/components/organisms/mini-games/chessimals-game.component.d.ts +2 -1
- package/lib/components/organisms/mini-games/types.d.ts +1 -1
- package/lib/version.d.ts +1 -1
- package/package.json +1 -1
|
@@ -58,7 +58,7 @@ import fixWebmDuration from 'fix-webm-duration';
|
|
|
58
58
|
* Current version of valtech-components.
|
|
59
59
|
* This is automatically updated during the publish process.
|
|
60
60
|
*/
|
|
61
|
-
const VERSION = '4.0.
|
|
61
|
+
const VERSION = '4.0.425';
|
|
62
62
|
|
|
63
63
|
// Control de estado de refresco (singleton a nivel de módulo)
|
|
64
64
|
let isRefreshing = false;
|
|
@@ -61029,18 +61029,66 @@ const CHESSIMALS_BOT_PROFILES = [
|
|
|
61029
61029
|
labelKey: 'chessimalsBotSentinel',
|
|
61030
61030
|
descriptionKey: 'chessimalsBotSentinelBody',
|
|
61031
61031
|
},
|
|
61032
|
+
{
|
|
61033
|
+
id: 'oracle',
|
|
61034
|
+
difficulty: 'hard',
|
|
61035
|
+
avatar: '🔮',
|
|
61036
|
+
labelKey: 'chessimalsBotOracle',
|
|
61037
|
+
descriptionKey: 'chessimalsBotOracleBody',
|
|
61038
|
+
},
|
|
61039
|
+
{
|
|
61040
|
+
id: 'ambusher',
|
|
61041
|
+
difficulty: 'hard',
|
|
61042
|
+
avatar: '🪤',
|
|
61043
|
+
labelKey: 'chessimalsBotAmbusher',
|
|
61044
|
+
descriptionKey: 'chessimalsBotAmbusherBody',
|
|
61045
|
+
},
|
|
61046
|
+
{
|
|
61047
|
+
id: 'locksmith',
|
|
61048
|
+
difficulty: 'hard',
|
|
61049
|
+
avatar: '🔐',
|
|
61050
|
+
labelKey: 'chessimalsBotLocksmith',
|
|
61051
|
+
descriptionKey: 'chessimalsBotLocksmithBody',
|
|
61052
|
+
},
|
|
61053
|
+
{
|
|
61054
|
+
id: 'storm',
|
|
61055
|
+
difficulty: 'hard',
|
|
61056
|
+
avatar: '🌩️',
|
|
61057
|
+
labelKey: 'chessimalsBotStorm',
|
|
61058
|
+
descriptionKey: 'chessimalsBotStormBody',
|
|
61059
|
+
},
|
|
61060
|
+
{
|
|
61061
|
+
id: 'matriarch',
|
|
61062
|
+
difficulty: 'hard',
|
|
61063
|
+
avatar: '👑',
|
|
61064
|
+
labelKey: 'chessimalsBotMatriarch',
|
|
61065
|
+
descriptionKey: 'chessimalsBotMatriarchBody',
|
|
61066
|
+
},
|
|
61067
|
+
{
|
|
61068
|
+
id: 'endgame',
|
|
61069
|
+
difficulty: 'hard',
|
|
61070
|
+
avatar: '⌛',
|
|
61071
|
+
labelKey: 'chessimalsBotEndgame',
|
|
61072
|
+
descriptionKey: 'chessimalsBotEndgameBody',
|
|
61073
|
+
},
|
|
61032
61074
|
];
|
|
61033
61075
|
const BOT_STYLES = {
|
|
61034
|
-
explorer: { advancement: 1.05, capture: 0.82, safety: 0.62, power: 0.8, center: 1.15, unlock: 1.05, reply: 0.7, randomness: 260, spread: 0.68 },
|
|
61035
|
-
impulsive: { advancement: 0.9, capture: 1.45, safety: 0.48, power: 1.15, center: 0.8, unlock: 0.9, reply: 0.55, randomness: 290, spread: 0.62 },
|
|
61036
|
-
runner: { advancement: 1.55, capture: 0.78, safety: 0.5, power: 0.95, center: 0.7, unlock: 1.1, reply: 0.55, randomness: 250, spread: 0.6 },
|
|
61037
|
-
hunter: { advancement: 0.95, capture: 1.45, safety: 0.9, power: 1.05, center: 0.95, unlock: 0.95, reply: 1, randomness: 90, spread: 0.3 },
|
|
61038
|
-
guardian: { advancement: 0.88, capture: 1, safety: 1.45, power: 0.85, center: 1.05, unlock: 1, reply: 1.15, randomness: 70, spread: 0.26 },
|
|
61039
|
-
jumper: { advancement: 1.12, capture: 1, safety: 0.92, power: 1.42, center: 1.18, unlock: 1.08, reply: 0.95, randomness: 95, spread: 0.32 },
|
|
61040
|
-
strategist: { advancement: 1.05, capture: 1.08, safety: 1.22, power: 1.08, center: 1.16, unlock: 1.1, reply: 1.25, randomness: 22, spread: 0.14 },
|
|
61041
|
-
predator: { advancement: 0.98, capture: 1.68, safety: 1.02, power: 1.34, center: 1, unlock: 1, reply: 1.12, randomness: 28, spread: 0.16 },
|
|
61042
|
-
sprinter: { advancement: 1.72, capture: 0.9, safety: 0.95, power: 1.08, center: 0.86, unlock: 1.18, reply: 1, randomness: 26, spread: 0.15 },
|
|
61043
|
-
sentinel: { advancement: 0.9, capture: 1.12, safety: 1.72, power: 0.95, center: 1.28, unlock: 1.05, reply: 1.38, randomness: 18, spread: 0.12 },
|
|
61076
|
+
explorer: { advancement: 1.05, capture: 0.82, safety: 0.62, power: 0.8, center: 1.15, unlock: 1.05, reply: 0.7, randomness: 260, spread: 0.68, mobility: 0.75, trap: 0.5, endgame: 0.55 },
|
|
61077
|
+
impulsive: { advancement: 0.9, capture: 1.45, safety: 0.48, power: 1.15, center: 0.8, unlock: 0.9, reply: 0.55, randomness: 290, spread: 0.62, mobility: 0.85, trap: 0.62, endgame: 0.5 },
|
|
61078
|
+
runner: { advancement: 1.55, capture: 0.78, safety: 0.5, power: 0.95, center: 0.7, unlock: 1.1, reply: 0.55, randomness: 250, spread: 0.6, mobility: 0.72, trap: 0.45, endgame: 1.1 },
|
|
61079
|
+
hunter: { advancement: 0.95, capture: 1.45, safety: 0.9, power: 1.05, center: 0.95, unlock: 0.95, reply: 1, randomness: 90, spread: 0.3, mobility: 0.95, trap: 0.82, endgame: 0.76 },
|
|
61080
|
+
guardian: { advancement: 0.88, capture: 1, safety: 1.45, power: 0.85, center: 1.05, unlock: 1, reply: 1.15, randomness: 70, spread: 0.26, mobility: 0.82, trap: 0.72, endgame: 0.72 },
|
|
61081
|
+
jumper: { advancement: 1.12, capture: 1, safety: 0.92, power: 1.42, center: 1.18, unlock: 1.08, reply: 0.95, randomness: 95, spread: 0.32, mobility: 1.15, trap: 0.9, endgame: 0.82 },
|
|
61082
|
+
strategist: { advancement: 1.05, capture: 1.08, safety: 1.22, power: 1.08, center: 1.16, unlock: 1.1, reply: 1.25, randomness: 22, spread: 0.14, mobility: 1.08, trap: 1.06, endgame: 1 },
|
|
61083
|
+
predator: { advancement: 0.98, capture: 1.68, safety: 1.02, power: 1.34, center: 1, unlock: 1, reply: 1.12, randomness: 28, spread: 0.16, mobility: 1.02, trap: 1.18, endgame: 0.82 },
|
|
61084
|
+
sprinter: { advancement: 1.72, capture: 0.9, safety: 0.95, power: 1.08, center: 0.86, unlock: 1.18, reply: 1, randomness: 26, spread: 0.15, mobility: 0.95, trap: 0.78, endgame: 1.42 },
|
|
61085
|
+
sentinel: { advancement: 0.9, capture: 1.12, safety: 1.72, power: 0.95, center: 1.28, unlock: 1.05, reply: 1.38, randomness: 18, spread: 0.12, mobility: 0.86, trap: 1.04, endgame: 0.84 },
|
|
61086
|
+
oracle: { advancement: 1, capture: 1.12, safety: 1.42, power: 1.1, center: 1.18, unlock: 1.08, reply: 1.8, randomness: 8, spread: 0.08, mobility: 1.06, trap: 1.22, endgame: 1.08 },
|
|
61087
|
+
ambusher: { advancement: 0.9, capture: 1.48, safety: 1.08, power: 1.46, center: 1.05, unlock: 1.02, reply: 1.32, randomness: 14, spread: 0.1, mobility: 1.12, trap: 1.72, endgame: 0.92 },
|
|
61088
|
+
locksmith: { advancement: 0.88, capture: 1.04, safety: 1.55, power: 1.02, center: 1.48, unlock: 1.12, reply: 1.52, randomness: 12, spread: 0.1, mobility: 1.58, trap: 1.24, endgame: 0.86 },
|
|
61089
|
+
storm: { advancement: 1.18, capture: 1.38, safety: 0.98, power: 1.62, center: 1.08, unlock: 1.18, reply: 1.22, randomness: 18, spread: 0.13, mobility: 1.36, trap: 1.28, endgame: 1.02 },
|
|
61090
|
+
matriarch: { advancement: 0.96, capture: 1.18, safety: 1.64, power: 1.18, center: 1.22, unlock: 1.08, reply: 1.66, randomness: 10, spread: 0.08, mobility: 1.02, trap: 1.36, endgame: 1 },
|
|
61091
|
+
endgame: { advancement: 1.46, capture: 1, safety: 1.28, power: 1.04, center: 0.94, unlock: 1.08, reply: 1.44, randomness: 10, spread: 0.09, mobility: 0.98, trap: 1.02, endgame: 1.86 },
|
|
61044
61092
|
};
|
|
61045
61093
|
const DEFAULT_BOT_PROFILE_BY_DIFFICULTY = {
|
|
61046
61094
|
easy: 'explorer',
|
|
@@ -61325,7 +61373,7 @@ function getPowerMoves(state, piece, animal) {
|
|
|
61325
61373
|
const directions = getPowerDirections(animal);
|
|
61326
61374
|
const moves = [];
|
|
61327
61375
|
for (const direction of directions) {
|
|
61328
|
-
for (let distance = 1; distance
|
|
61376
|
+
for (let distance = 1; distance < state.boardSize; distance += 1) {
|
|
61329
61377
|
const target = {
|
|
61330
61378
|
row: piece.position.row + direction.row * distance,
|
|
61331
61379
|
col: piece.position.col + direction.col * distance,
|
|
@@ -61412,6 +61460,9 @@ function scoreBotMove(state, move, difficulty, style) {
|
|
|
61412
61460
|
score += 14 * style.power;
|
|
61413
61461
|
if (wouldUnlockPower(state, color, move.to))
|
|
61414
61462
|
score += 90 * style.unlock;
|
|
61463
|
+
score += countPowerReachAfterMove(state, move, color) * (difficulty === 'hard' ? 8 : 4) * style.mobility;
|
|
61464
|
+
score += countProtectedThreatsAfterMove(state, move, color) * (difficulty === 'hard' ? 36 : 18) * style.trap;
|
|
61465
|
+
score += scoreEndgamePressure(state, move, color) * style.endgame;
|
|
61415
61466
|
if (difficulty === 'hard' && isSquareVulnerableAfterMove(state, move)) {
|
|
61416
61467
|
score -= (targetPiece ? 80 : 140) * style.safety;
|
|
61417
61468
|
}
|
|
@@ -61448,12 +61499,65 @@ function scoreBotMoveWithLookahead(state, move, difficulty, style) {
|
|
|
61448
61499
|
const replyWeight = difficulty === 'easy' ? 0.12 : difficulty === 'normal' ? 0.32 : 0.48;
|
|
61449
61500
|
score -= opponentBestReply * replyWeight * style.reply;
|
|
61450
61501
|
}
|
|
61502
|
+
if (difficulty === 'hard') {
|
|
61503
|
+
score += scoreBestCounterplay(afterMove, state.currentTurn, style) * 0.28;
|
|
61504
|
+
}
|
|
61451
61505
|
}
|
|
61452
61506
|
catch {
|
|
61453
61507
|
score -= 1000;
|
|
61454
61508
|
}
|
|
61455
61509
|
return score;
|
|
61456
61510
|
}
|
|
61511
|
+
function countPowerReachAfterMove(state, move, color) {
|
|
61512
|
+
try {
|
|
61513
|
+
const afterMove = applyChessimalsMove(state, move);
|
|
61514
|
+
const evaluationState = { ...afterMove, currentTurn: color };
|
|
61515
|
+
return getChessimalsAllLegalMoves(evaluationState, color).filter((nextMove) => nextMove.kind === 'power').length;
|
|
61516
|
+
}
|
|
61517
|
+
catch {
|
|
61518
|
+
return 0;
|
|
61519
|
+
}
|
|
61520
|
+
}
|
|
61521
|
+
function countProtectedThreatsAfterMove(state, move, color) {
|
|
61522
|
+
try {
|
|
61523
|
+
const afterMove = applyChessimalsMove(state, move);
|
|
61524
|
+
const evaluationState = { ...afterMove, currentTurn: color };
|
|
61525
|
+
const ourMoves = getChessimalsAllLegalMoves(evaluationState, color);
|
|
61526
|
+
const enemyPieces = activePieces(afterMove).filter((piece) => piece.color !== color && !piece.captured);
|
|
61527
|
+
return enemyPieces.filter((piece) => ourMoves.some((nextMove) => nextMove.capturesPieceId === piece.id)).length;
|
|
61528
|
+
}
|
|
61529
|
+
catch {
|
|
61530
|
+
return 0;
|
|
61531
|
+
}
|
|
61532
|
+
}
|
|
61533
|
+
function scoreEndgamePressure(state, move, color) {
|
|
61534
|
+
const remainingEnemyPieces = activePieces(state).filter((piece) => piece.color !== color && !piece.captured).length;
|
|
61535
|
+
const urgency = remainingEnemyPieces <= Math.max(2, Math.floor(state.boardSize / 2)) ? 1.6 : 1;
|
|
61536
|
+
const distanceToPromotion = color === 'white' ? move.to.row : state.boardSize - 1 - move.to.row;
|
|
61537
|
+
return Math.max(0, state.boardSize - distanceToPromotion) * 14 * urgency;
|
|
61538
|
+
}
|
|
61539
|
+
function scoreBestCounterplay(afterMove, color, style) {
|
|
61540
|
+
const opponentMoves = getChessimalsAllLegalMoves(afterMove);
|
|
61541
|
+
if (opponentMoves.length === 0)
|
|
61542
|
+
return 900;
|
|
61543
|
+
const replies = opponentMoves.slice(0, 16).map((opponentMove) => {
|
|
61544
|
+
try {
|
|
61545
|
+
const afterReply = applyChessimalsMove(afterMove, opponentMove);
|
|
61546
|
+
if (afterReply.status === 'finished')
|
|
61547
|
+
return -6000;
|
|
61548
|
+
const counterState = { ...afterReply, currentTurn: color };
|
|
61549
|
+
const counterMoves = getChessimalsAllLegalMoves(counterState, color);
|
|
61550
|
+
const bestCounter = counterMoves
|
|
61551
|
+
.map((counterMove) => scoreBotMove(counterState, counterMove, 'hard', style))
|
|
61552
|
+
.sort((a, b) => b - a)[0] ?? 0;
|
|
61553
|
+
return bestCounter;
|
|
61554
|
+
}
|
|
61555
|
+
catch {
|
|
61556
|
+
return -1000;
|
|
61557
|
+
}
|
|
61558
|
+
});
|
|
61559
|
+
return Math.min(...replies);
|
|
61560
|
+
}
|
|
61457
61561
|
function pickNoisyBotMove(scored, spread) {
|
|
61458
61562
|
if (scored.length === 0)
|
|
61459
61563
|
return undefined;
|
|
@@ -62486,10 +62590,10 @@ const MINI_GAMES_I18N = {
|
|
|
62486
62590
|
chessimalsRulePowersTitle: 'Cuándo se activan los poderes',
|
|
62487
62591
|
chessimalsRulePowersBody: 'Tus cartas se desbloquean cuando uno de tus peones cruza la línea central o cuando un peón rival entra en tu mitad del tablero.',
|
|
62488
62592
|
chessimalsRuleCardsTitle: 'Cartas de animales',
|
|
62489
|
-
chessimalsRuleEagle: 'Águila: se mueve
|
|
62490
|
-
chessimalsRuleBull: 'Toro: se mueve
|
|
62593
|
+
chessimalsRuleEagle: 'Águila: se mueve en diagonal por todo el tablero, hacia adelante o atrás, sin entrar a la última fila.',
|
|
62594
|
+
chessimalsRuleBull: 'Toro: se mueve en línea recta por todo el tablero, incluso hacia los lados, sin entrar a la última fila.',
|
|
62491
62595
|
chessimalsRuleKangaroo: 'Canguro: salta en L, como el caballo del ajedrez. Puede saltar por encima de piezas y caer libre o capturar una pieza rival.',
|
|
62492
|
-
chessimalsRuleLion: 'León: se mueve
|
|
62596
|
+
chessimalsRuleLion: 'León: se mueve en cualquier dirección por todo el tablero, sin entrar a la última fila.',
|
|
62493
62597
|
chessimalsRuleLimitsTitle: 'Reglas de equilibrio',
|
|
62494
62598
|
chessimalsRuleLimitsBody: 'Cada carta se usa una sola vez por partida. Ningún poder puede entrar directamente a la última fila: el paso final para ganar siempre debe ser un avance normal.',
|
|
62495
62599
|
chessimalsBoardSize: 'Tamaño del tablero',
|
|
@@ -62602,6 +62706,18 @@ const MINI_GAMES_I18N = {
|
|
|
62602
62706
|
chessimalsBotSprinterBody: 'Optimiza rutas de promoción.',
|
|
62603
62707
|
chessimalsBotSentinel: 'Centinela',
|
|
62604
62708
|
chessimalsBotSentinelBody: 'Defiende sólido y castiga errores.',
|
|
62709
|
+
chessimalsBotOracle: 'Oráculo',
|
|
62710
|
+
chessimalsBotOracleBody: 'Lee respuestas y evita trampas profundas.',
|
|
62711
|
+
chessimalsBotAmbusher: 'Emboscador',
|
|
62712
|
+
chessimalsBotAmbusherBody: 'Prepara capturas dobles con poderes largos.',
|
|
62713
|
+
chessimalsBotLocksmith: 'Cerrajero',
|
|
62714
|
+
chessimalsBotLocksmithBody: 'Cierra el centro y reduce tus rutas.',
|
|
62715
|
+
chessimalsBotStorm: 'Tormenta',
|
|
62716
|
+
chessimalsBotStormBody: 'Usa poderes largos para presionar todo el tablero.',
|
|
62717
|
+
chessimalsBotMatriarch: 'Matriarca',
|
|
62718
|
+
chessimalsBotMatriarchBody: 'Protege su estructura y gana por desgaste.',
|
|
62719
|
+
chessimalsBotEndgame: 'Finalista',
|
|
62720
|
+
chessimalsBotEndgameBody: 'Convierte ventajas pequeñas en promoción.',
|
|
62605
62721
|
chessimalsBotExplorerTendency: 'Tiende a variar rutas, probar el centro y cometer errores suaves.',
|
|
62606
62722
|
chessimalsBotImpulsiveTendency: 'Tiende a capturar rápido, incluso cuando puede quedar expuesto.',
|
|
62607
62723
|
chessimalsBotRunnerTendency: 'Tiende a avanzar hacia la promoción antes que defender.',
|
|
@@ -62612,6 +62728,12 @@ const MINI_GAMES_I18N = {
|
|
|
62612
62728
|
chessimalsBotPredatorTendency: 'Tiende a forzar capturas y usar poderes agresivos.',
|
|
62613
62729
|
chessimalsBotSprinterTendency: 'Tiende a encontrar caminos rápidos de promoción.',
|
|
62614
62730
|
chessimalsBotSentinelTendency: 'Tiende a defender sólido y castigar errores.',
|
|
62731
|
+
chessimalsBotOracleTendency: 'Tiende a anticipar respuestas y elegir jugadas difíciles de refutar.',
|
|
62732
|
+
chessimalsBotAmbusherTendency: 'Tiende a dejar piezas bajo amenaza múltiple antes de capturar.',
|
|
62733
|
+
chessimalsBotLocksmithTendency: 'Tiende a cortar rutas por el centro y dejarte sin buenas casillas.',
|
|
62734
|
+
chessimalsBotStormTendency: 'Tiende a convertir poderes largos en presión desde varios ángulos.',
|
|
62735
|
+
chessimalsBotMatriarchTendency: 'Tiende a conservar piezas y cambiar solo cuando queda mejor.',
|
|
62736
|
+
chessimalsBotEndgameTendency: 'Tiende a simplificar y correr hacia la promoción cuando ve ventaja.',
|
|
62615
62737
|
chessimalsBotReportTitle: 'Reporte del bot',
|
|
62616
62738
|
chessimalsBotReportVs: 'Contra {bot}',
|
|
62617
62739
|
chessimalsBotReportBody: '{outcome}. Hizo {captures} capturas y usó {powers} poderes. {style}',
|
|
@@ -62659,7 +62781,7 @@ const MINI_GAMES_I18N = {
|
|
|
62659
62781
|
chessimalsTutorialStep4Title: 'Devuelve el turno',
|
|
62660
62782
|
chessimalsTutorialStep4Body: 'Mueve el peón negro de la columna F una casilla hacia abajo para continuar.',
|
|
62661
62783
|
chessimalsTutorialStep5Title: 'Usa el poder Canguro',
|
|
62662
|
-
chessimalsTutorialStep5Body: 'Selecciona la carta Canguro y salta en L para capturar el peón negro.',
|
|
62784
|
+
chessimalsTutorialStep5Body: 'Selecciona la carta Canguro y salta en L para capturar el peón negro. Las otras cartas pueden cruzar todo el tablero, pero ningún poder puede entrar a la última fila.',
|
|
62663
62785
|
chessimalsTutorialStep6Title: 'Prepara la llegada',
|
|
62664
62786
|
chessimalsTutorialStep6Body: 'Mueve el último peón negro hacia abajo. Después tendrás camino para ganar.',
|
|
62665
62787
|
chessimalsTutorialStep7Title: 'Llega a la última fila',
|
|
@@ -62847,10 +62969,10 @@ const MINI_GAMES_I18N = {
|
|
|
62847
62969
|
chessimalsRulePowersTitle: 'When powers unlock',
|
|
62848
62970
|
chessimalsRulePowersBody: 'Your cards unlock when one of your pawns crosses the center line, or when a rival pawn enters your half of the board.',
|
|
62849
62971
|
chessimalsRuleCardsTitle: 'Animal cards',
|
|
62850
|
-
chessimalsRuleEagle: 'Eagle: moves
|
|
62851
|
-
chessimalsRuleBull: 'Bull: moves
|
|
62972
|
+
chessimalsRuleEagle: 'Eagle: moves diagonally across the whole board, forward or backward, without entering the final row.',
|
|
62973
|
+
chessimalsRuleBull: 'Bull: moves in a straight line across the whole board, including sideways, without entering the final row.',
|
|
62852
62974
|
chessimalsRuleKangaroo: 'Kangaroo: jumps in an L shape, like a chess knight. It can jump over pieces and land on an empty square or capture a rival piece.',
|
|
62853
|
-
chessimalsRuleLion: 'Lion: moves
|
|
62975
|
+
chessimalsRuleLion: 'Lion: moves in any direction across the whole board, without entering the final row.',
|
|
62854
62976
|
chessimalsRuleLimitsTitle: 'Balance rules',
|
|
62855
62977
|
chessimalsRuleLimitsBody: 'Each card can be used once per game. No power can land directly on the final row: the winning step must always be a normal forward move.',
|
|
62856
62978
|
chessimalsBoardSize: 'Board size',
|
|
@@ -62963,6 +63085,18 @@ const MINI_GAMES_I18N = {
|
|
|
62963
63085
|
chessimalsBotSprinterBody: 'Optimizes promotion routes.',
|
|
62964
63086
|
chessimalsBotSentinel: 'Sentinel',
|
|
62965
63087
|
chessimalsBotSentinelBody: 'Defends solidly and punishes mistakes.',
|
|
63088
|
+
chessimalsBotOracle: 'Oracle',
|
|
63089
|
+
chessimalsBotOracleBody: 'Reads replies and avoids deep traps.',
|
|
63090
|
+
chessimalsBotAmbusher: 'Ambusher',
|
|
63091
|
+
chessimalsBotAmbusherBody: 'Sets up double captures with long powers.',
|
|
63092
|
+
chessimalsBotLocksmith: 'Locksmith',
|
|
63093
|
+
chessimalsBotLocksmithBody: 'Closes the center and reduces your routes.',
|
|
63094
|
+
chessimalsBotStorm: 'Storm',
|
|
63095
|
+
chessimalsBotStormBody: 'Uses long powers to pressure the whole board.',
|
|
63096
|
+
chessimalsBotMatriarch: 'Matriarch',
|
|
63097
|
+
chessimalsBotMatriarchBody: 'Protects structure and wins by attrition.',
|
|
63098
|
+
chessimalsBotEndgame: 'Endgame',
|
|
63099
|
+
chessimalsBotEndgameBody: 'Turns small edges into promotion.',
|
|
62966
63100
|
chessimalsBotExplorerTendency: 'Tends to vary routes, test the center, and make soft mistakes.',
|
|
62967
63101
|
chessimalsBotImpulsiveTendency: 'Tends to capture quickly, even when it can become exposed.',
|
|
62968
63102
|
chessimalsBotRunnerTendency: 'Tends to push toward promotion before defending.',
|
|
@@ -62973,6 +63107,12 @@ const MINI_GAMES_I18N = {
|
|
|
62973
63107
|
chessimalsBotPredatorTendency: 'Tends to force captures and use aggressive powers.',
|
|
62974
63108
|
chessimalsBotSprinterTendency: 'Tends to find fast promotion paths.',
|
|
62975
63109
|
chessimalsBotSentinelTendency: 'Tends to defend solidly and punish mistakes.',
|
|
63110
|
+
chessimalsBotOracleTendency: 'Tends to anticipate replies and choose hard-to-refute moves.',
|
|
63111
|
+
chessimalsBotAmbusherTendency: 'Tends to leave pieces under multiple threats before capturing.',
|
|
63112
|
+
chessimalsBotLocksmithTendency: 'Tends to close central routes and leave you without good squares.',
|
|
63113
|
+
chessimalsBotStormTendency: 'Tends to turn long powers into pressure from several angles.',
|
|
63114
|
+
chessimalsBotMatriarchTendency: 'Tends to preserve pieces and trade only when it improves.',
|
|
63115
|
+
chessimalsBotEndgameTendency: 'Tends to simplify and race toward promotion when ahead.',
|
|
62976
63116
|
chessimalsBotReportTitle: 'Bot report',
|
|
62977
63117
|
chessimalsBotReportVs: 'Against {bot}',
|
|
62978
63118
|
chessimalsBotReportBody: '{outcome}. It made {captures} captures and used {powers} powers. {style}',
|
|
@@ -63020,7 +63160,7 @@ const MINI_GAMES_I18N = {
|
|
|
63020
63160
|
chessimalsTutorialStep4Title: 'Return the turn',
|
|
63021
63161
|
chessimalsTutorialStep4Body: 'Move the black pawn on file F one square downward to continue.',
|
|
63022
63162
|
chessimalsTutorialStep5Title: 'Use the Kangaroo power',
|
|
63023
|
-
chessimalsTutorialStep5Body: 'Select the Kangaroo card and jump in an L shape to capture the black pawn.',
|
|
63163
|
+
chessimalsTutorialStep5Body: 'Select the Kangaroo card and jump in an L shape to capture the black pawn. The other cards can cross the whole board, but no power can enter the final row.',
|
|
63024
63164
|
chessimalsTutorialStep6Title: 'Prepare the finish',
|
|
63025
63165
|
chessimalsTutorialStep6Body: 'Move the last black pawn downward. Then your path to win is open.',
|
|
63026
63166
|
chessimalsTutorialStep7Title: 'Reach the last row',
|
|
@@ -63192,6 +63332,9 @@ class RetroAudioService {
|
|
|
63192
63332
|
Object.values(CHESSIMALS_POWER_SAMPLES).forEach((sample) => {
|
|
63193
63333
|
void this.preloadSampleBuffer(sample.src);
|
|
63194
63334
|
});
|
|
63335
|
+
Object.values(CHESSIMALS_OUTCOME_SAMPLES).forEach((sample) => {
|
|
63336
|
+
void this.preloadSampleBuffer(sample.src);
|
|
63337
|
+
});
|
|
63195
63338
|
if (typeof Audio === 'undefined')
|
|
63196
63339
|
return;
|
|
63197
63340
|
[
|
|
@@ -63505,12 +63648,16 @@ class RetroAudioService {
|
|
|
63505
63648
|
}
|
|
63506
63649
|
chessimalsVictory() {
|
|
63507
63650
|
this.stopMusic();
|
|
63651
|
+
if (this.playBufferedSample(CHESSIMALS_OUTCOME_SAMPLES.victory))
|
|
63652
|
+
return;
|
|
63508
63653
|
if (this.playSample(CHESSIMALS_OUTCOME_SAMPLES.victory, () => this.chessimalsVictoryFallback()))
|
|
63509
63654
|
return;
|
|
63510
63655
|
this.chessimalsVictoryFallback();
|
|
63511
63656
|
}
|
|
63512
63657
|
chessimalsDefeat() {
|
|
63513
63658
|
this.stopMusic();
|
|
63659
|
+
if (this.playBufferedSample(CHESSIMALS_OUTCOME_SAMPLES.defeat))
|
|
63660
|
+
return;
|
|
63514
63661
|
if (this.playSample(CHESSIMALS_OUTCOME_SAMPLES.defeat, () => this.lose()))
|
|
63515
63662
|
return;
|
|
63516
63663
|
this.lose();
|
|
@@ -64723,6 +64870,7 @@ class ChessimalsGameComponent {
|
|
|
64723
64870
|
this.tutorialMode.set(false);
|
|
64724
64871
|
this.onlineConnectionState.set('idle');
|
|
64725
64872
|
this.gameBotProfileId.set(this.selectedLocalMode() === 'bot' ? this.selectedBotProfileId() : undefined);
|
|
64873
|
+
this.lastOutcomeSoundKey = undefined;
|
|
64726
64874
|
this.audio.stopMusic();
|
|
64727
64875
|
this.game.set(createChessimalsGame(this.selectedBoardSize()));
|
|
64728
64876
|
this.clearReview();
|
|
@@ -64744,6 +64892,7 @@ class ChessimalsGameComponent {
|
|
|
64744
64892
|
this.onlineConnectionState.set('idle');
|
|
64745
64893
|
this.gameBotProfileId.set(undefined);
|
|
64746
64894
|
this.selectedLocalMode.set('one-device');
|
|
64895
|
+
this.lastOutcomeSoundKey = undefined;
|
|
64747
64896
|
this.audio.stopMusic();
|
|
64748
64897
|
this.game.set(this.createTutorialGame());
|
|
64749
64898
|
this.clearReview();
|
|
@@ -64865,6 +65014,7 @@ class ChessimalsGameComponent {
|
|
|
64865
65014
|
return;
|
|
64866
65015
|
}
|
|
64867
65016
|
this.clearBotTurn();
|
|
65017
|
+
this.lastOutcomeSoundKey = undefined;
|
|
64868
65018
|
this.game.set(this.tutorialMode() ? this.createTutorialGame() : createChessimalsGame(this.game().boardSize));
|
|
64869
65019
|
this.clearReview();
|
|
64870
65020
|
this.selectedPieceId.set(undefined);
|
|
@@ -65099,6 +65249,8 @@ class ChessimalsGameComponent {
|
|
|
65099
65249
|
const updated = applyChessimalsMove(game, move);
|
|
65100
65250
|
if (move.animal)
|
|
65101
65251
|
this.playMoveSound(move);
|
|
65252
|
+
if (updated.status === 'finished')
|
|
65253
|
+
this.playChessimalsOutcomeSound(updated);
|
|
65102
65254
|
this.animateMove(game, move, updated);
|
|
65103
65255
|
if (game.mode === 'online') {
|
|
65104
65256
|
this.moveSyncing.set(true);
|
|
@@ -65221,6 +65373,8 @@ class ChessimalsGameComponent {
|
|
|
65221
65373
|
this.botThinking.set(false);
|
|
65222
65374
|
if (move.animal)
|
|
65223
65375
|
this.playMoveSound(move, true);
|
|
65376
|
+
if (updated.status === 'finished')
|
|
65377
|
+
this.playChessimalsOutcomeSound(updated);
|
|
65224
65378
|
this.animateMove(game, move, updated);
|
|
65225
65379
|
if (!move.animal)
|
|
65226
65380
|
this.playMoveSound(move, true);
|
|
@@ -65315,6 +65469,10 @@ class ChessimalsGameComponent {
|
|
|
65315
65469
|
playChessimalsOutcomeSound(game = this.game()) {
|
|
65316
65470
|
if (game.status !== 'finished')
|
|
65317
65471
|
return;
|
|
65472
|
+
const key = `${game.id}:${game.status}:${game.winner ?? 'none'}:${game.winnerReason ?? 'none'}:${game.moveCount}`;
|
|
65473
|
+
if (this.lastOutcomeSoundKey === key)
|
|
65474
|
+
return;
|
|
65475
|
+
this.lastOutcomeSoundKey = key;
|
|
65318
65476
|
const winner = game.winner;
|
|
65319
65477
|
const side = this.currentPlayerSideForOutcome(game);
|
|
65320
65478
|
if (!winner || !side || winner === side) {
|
|
@@ -65938,6 +66096,7 @@ class ChessimalsGameComponent {
|
|
|
65938
66096
|
this.clearReview();
|
|
65939
66097
|
}
|
|
65940
66098
|
if (previous.status === 'finished' && state.status === 'in_progress') {
|
|
66099
|
+
this.lastOutcomeSoundKey = undefined;
|
|
65941
66100
|
this.selectedPieceId.set(undefined);
|
|
65942
66101
|
this.selectedAnimal.set(undefined);
|
|
65943
66102
|
this.movingPiece.set(undefined);
|