Prototype conditional future battle Truthtrance
Verify and publish checkpoint container / container (push) Failing after 11m11s
Verify and publish checkpoint container / container (push) Failing after 11m11s
This commit is contained in:
1 parent
71009d73e3
commit
02695aea7c
15 files changed
+721
-8
No files matched your search
+27
-1
@@ -117,6 +117,7 @@ export type TruthQuestion =
|
||||
| ({ kind: 'shipment'; target: string } & ShipmentClaim)
|
||||
| { kind: 'mixedShipment'; target: string; mixed: MixedShipmentExpression }
|
||||
| { kind: 'battlePlan'; target: string; territory: string; claim: PlanClaim }
|
||||
| { kind: 'futureBattleLeader'; target: string; turn: number; leader: string }
|
||||
| { kind: 'fact'; target: string; fact: TruthFact }
|
||||
| {
|
||||
kind: 'freeform';
|
||||
@@ -269,6 +270,9 @@ function parseQuestion(g: Game, asker: string, value: unknown): TruthQuestion {
|
||||
if (v.kind !== 'charity' && v.kind !== 'fact' && v.kind !== 'freeform' &&
|
||||
g.charityPromises?.length && liveCharityPromises(g.charityPromises,v.target as string,g.turn).length)
|
||||
throw new TruthError('Finish this player’s current Charity answer before binding another action question.');
|
||||
if (v.kind !== 'fact' && v.kind !== 'freeform' && v.kind !== 'futureBattleLeader' && g.futureBattleLeaderPromises?.some(row =>
|
||||
row.player === v.target && row.turn === g.turn && (row.status === 'waiting' || row.status === 'bound')))
|
||||
throw new TruthError('Finish this player’s conditional battle answer before binding another action question.');
|
||||
if (v.kind === 'charity') {
|
||||
check(Object.keys(v).sort().join(',') === 'kind,target,turn' && v.turn === g.turn &&
|
||||
g.status === 'playing' && !g.advanced && g.phase >= 0 && g.phase <= 2 && !g.charityOrder &&
|
||||
@@ -593,6 +597,18 @@ function parseQuestion(g: Game, asker: string, value: unknown): TruthQuestion {
|
||||
return { kind: 'mixedBattlePlan', target: v.target as string, battle: g.battle.event,
|
||||
territory: g.battle.territory, mixed };
|
||||
}
|
||||
if (v.kind === 'futureBattleLeader') {
|
||||
const target = g.players.find(player => player.id === v.target)!;
|
||||
check(Object.keys(v).sort().join(',') === 'kind,leader,target,turn' &&
|
||||
v.turn === g.turn && typeof v.leader === 'string' &&
|
||||
leaders(target.faction).some(leader => leader.id === v.leader) &&
|
||||
g.status === 'playing' && !g.advanced && g.phase === 5 && !g.expansions.length &&
|
||||
!g.techTokens && !g.strongholdCards && !g.nexusCards && !g.homeworlds &&
|
||||
!g.leaderSkills && !g.discoveryEnabled && !g.ecazTreachery && !g.battle &&
|
||||
!g.response && !g.decision && !g.phaseOpening && !g.pendingKarama && !g.pendingTreacheryDiscard,
|
||||
'Choose a native leader and a quiet Basic turn before Battle.');
|
||||
return { kind: 'futureBattleLeader', target: v.target, turn: g.turn, leader: v.leader };
|
||||
}
|
||||
if (v.kind === 'battlePlan') {
|
||||
check(
|
||||
g.phase === 6 &&
|
||||
@@ -670,7 +686,8 @@ export function validateSavedTruthtrance(g: Game) {
|
||||
'The saved Truthtrance must retain each committed physical card in its holder’s hand.',
|
||||
);
|
||||
}
|
||||
if (window?.question?.kind === 'fact' || window?.question?.kind === 'movement' || window?.question?.kind === 'traitorCall') {
|
||||
if (window?.question?.kind === 'fact' || window?.question?.kind === 'movement' ||
|
||||
window?.question?.kind === 'traitorCall' || window?.question?.kind === 'futureBattleLeader') {
|
||||
check((window.stage === 'answer' || window.stage === 'unknown') && window.queue.length > 0,
|
||||
'The saved fact question must retain its asking player and answer stage.');
|
||||
check(JSON.stringify(parseQuestion(g, window.queue[0].player, window.question)) === JSON.stringify(window.question),
|
||||
@@ -794,6 +811,8 @@ export function truthQuestionText(
|
||||
return `Will you ${shipmentClaimText(q)} this turn?`;
|
||||
if (q.kind === 'battlePlan')
|
||||
return `In this battle in ${locationName(q.territory)}, will it be true that ${planClaimText(q.claim, leaderName)}?`;
|
||||
if (q.kind === 'futureBattleLeader')
|
||||
return `If you fight a battle later this turn, will you use ${leaderName(q.leader)} in your first such battle?`;
|
||||
const clause = (f: TruthFact): string => {
|
||||
if (isKnowledgeFact(f)) return knowledgeFactText(f);
|
||||
if (f.kind === 'noFieldValue') return noFieldValueFactText(f);
|
||||
@@ -941,6 +960,8 @@ export function resolveTruthAction(
|
||||
mixedBattleAnswers?: (g: Game, p: Player, claim: MixedBattleClaim) => TruthAnswer[];
|
||||
bindMixedBattle?: (g: Game, p: Player, claim: MixedBattleClaim, answer: boolean, asker: string) => void;
|
||||
battleAnswers: (g: Game, p: Player, claim: PlanClaim) => TruthAnswer[];
|
||||
futureBattleLeaderAnswers: (g: Game, p: Player, question: Extract<TruthQuestion, {kind: 'futureBattleLeader'}>) => TruthAnswer[];
|
||||
bindFutureBattleLeader: (g: Game, p: Player, question: Extract<TruthQuestion, {kind: 'futureBattleLeader'}>, answer: boolean, asker: string) => void;
|
||||
bindBattle: (
|
||||
g: Game,
|
||||
p: Player,
|
||||
@@ -1315,6 +1336,11 @@ export function resolveTruthAction(
|
||||
current.player,
|
||||
);
|
||||
}
|
||||
if (q.kind === 'futureBattleLeader') {
|
||||
check(effects.futureBattleLeaderAnswers(g, p, q).includes(a.answer),
|
||||
'Choose an answer compatible with your available native leaders and earlier commitments.');
|
||||
if (a.answer !== 'unknown') effects.bindFutureBattleLeader(g, p, q, a.answer === 'yes', current.player);
|
||||
}
|
||||
// Freeform semantics cannot be certified by a deterministic engine. AI does not invent an answer.
|
||||
if (q.kind === 'freeform' && p.bot)
|
||||
check(
|
||||
|
||||
Reference in new issue
Block a user