Prototype named Ghola leader Truthtrance promises
Verify and publish checkpoint container / container (push) Successful in 10m45s

This commit is contained in:
Quintine committed 2026-10-29 17:34:55 +11:00
1 parent f8078ed5e2
commit c1ffa1c28a
16 files changed
+689 -9

No files matched your search

+23
View File
@@ -21,6 +21,7 @@ import { parseBribeExpressionClaim, bribeExpressionRecipients, bribeExpressionTe
type BribeExpressionClaim } from './bribe-expression-promises';
import { parseRevivalExpressionClaim, revivalExpressionText, revivalExpressionPromiseModeSupported, type RevivalExpressionClaim } from './revival-expression-promises';
import { parseLeaderRevivalClaim, leaderRevivalClaimText, leaderRevivalPromiseModeSupported, type LeaderRevivalClaim } from './leader-revival-promises';
import { parseGholaLeaderClaim, gholaLeaderClaimText, type GholaLeaderClaim } from './ghola-leader-promises';
import { parseAllianceClaim, allianceClaimText, alliancePromiseModeSupported, type AllianceClaim } from './alliance-promises';
import { parseBribeClaim, bribeClaimText, bribePromiseModeSupported, type BribeClaim } from './bribe-promises';
import { parsePledgeClaim, type PledgeClaim } from './pledge-promises';
@@ -113,6 +114,7 @@ export type TruthQuestion =
| ({ kind: 'bribeExpression'; target: string } & BribeExpressionClaim)
| ({ kind: 'revivalExpression'; target: string } & RevivalExpressionClaim)
| ({ kind: 'leaderRevival'; target: string } & LeaderRevivalClaim)
| ({ kind: 'gholaLeader'; target: string } & GholaLeaderClaim)
| ({ kind: 'alliance'; target: string } & AllianceClaim)
| ({ kind: 'bribe'; target: string } & BribeClaim)
| ({ kind: 'pledgeAid'; target: string } & PledgeClaim)
@@ -321,6 +323,16 @@ function parseQuestion(g: Game, asker: string, value: unknown): TruthQuestion {
'Choose a supported current-turn revival expression in a quiet window.');
return { kind: 'revivalExpression', target: v.target, ...claim };
}
if (v.kind === 'gholaLeader') {
check(Object.keys(v).sort().join(',') === 'kind,leader,target,turn',
'Supply the current turn, exact named leader and respondent.');
const claim = parseGholaLeaderClaim(v);
check(leaderRevivalPromiseModeSupported(g) && g.status === 'playing' && g.phase >= 0 && g.phase <= 7 &&
!g.response && !g.decision && !g.phaseOpening && !g.pendingRevival && !g.pendingKarama &&
!g.pendingTreacheryDiscard && claim.turn === g.turn,
'Choose a supported current-turn Ghola leader question in a quiet window.');
return { kind: 'gholaLeader', target: v.target, ...claim };
}
if (v.kind === 'leaderRevival') {
check(Object.keys(v).sort().join(',') === 'kind,leader,target,turn',
'Supply the current turn, exact named leader and respondent.');
@@ -849,6 +861,7 @@ export function truthQuestionText(
if (q.kind === 'charity') return 'Will you claim Charity after this answer during this turn’s Charity phase?';
if (q.kind === 'revivalExpression') return `Will you ${revivalExpressionText(q.claim, id => id === 'kwisatz' ? 'Kwisatz Haderach' : leaderName(id))} from now until your Revival opportunity ends this turn?`;
if (q.kind === 'leaderRevival') return `Will you ${leaderRevivalClaimText(q, id => id === 'kwisatz' ? 'Kwisatz Haderach' : leaderName(id))}?`;
if (q.kind === 'gholaLeader') return `Will you ${gholaLeaderClaimText(q, id => id === 'kwisatz' ? 'Kwisatz Haderach' : leaderName(id))}?`;
if (q.kind === 'allianceExpression') return `Is it true that you ${allianceExpressionText(q.claim, playerName)}?`;
if (q.kind === 'alliance') return `Will you ${allianceClaimText(q, playerName)}?`;
if (q.kind === 'bribeExpression') return `Will you ${bribeExpressionText(q.claim, playerName)} from now until this turn ends?`;
@@ -990,6 +1003,8 @@ export function resolveTruthAction(
bindMixedRevival?: (g: Game, p: Player, claim: MixedRevivalClaim, answer: boolean, asker: string) => void;
revivalExpressionAnswers?: (g: Game, p: Player, claim: RevivalExpressionClaim) => TruthAnswer[];
bindRevivalExpression?: (g: Game, p: Player, claim: RevivalExpressionClaim, answer: boolean, asker: string) => void;
gholaLeaderAnswers?: (g: Game, p: Player, claim: GholaLeaderClaim) => TruthAnswer[];
bindGholaLeader?: (g: Game, p: Player, claim: GholaLeaderClaim, answer: boolean, asker: string) => void;
leaderRevivalAnswers?: (g: Game, p: Player, claim: LeaderRevivalClaim) => TruthAnswer[];
bindLeaderRevival?: (g: Game, p: Player, claim: LeaderRevivalClaim, answer: boolean, asker: string) => void;
revivalAnswers?: (g: Game, p: Player, claim: RevivalClaim) => TruthAnswer[];
@@ -1172,6 +1187,9 @@ export function resolveTruthAction(
if (w.question.kind === 'revivalExpression')
check(effects.revivalExpressionAnswers?.(g, g.players.find(other => other.id === w.question!.target)!, w.question).length,
'Choose a whole revival expression with a compatible native completion.');
if (w.question.kind === 'gholaLeader')
check(effects.gholaLeaderAnswers?.(g, g.players.find(other => other.id === w.question!.target)!, w.question).length,
'Choose a named Ghola leader question with a compatible owned completion.');
if (w.question.kind === 'leaderRevival')
check(effects.leaderRevivalAnswers?.(g, g.players.find(other => other.id === w.question!.target)!, w.question).length,
'Choose a named leader question with a compatible native completion.');
@@ -1303,6 +1321,11 @@ export function resolveTruthAction(
'Choose a whole revival answer compatible with native returns and earlier promises.');
if (a.answer !== 'unknown') effects.bindRevivalExpression(g, p, q, a.answer === 'yes', current.player);
}
if (q.kind === 'gholaLeader') {
check(effects.gholaLeaderAnswers && effects.bindGholaLeader && effects.gholaLeaderAnswers(g, p, q).includes(a.answer),
'Choose a named Ghola leader answer compatible with native eligibility and earlier promises.');
if (a.answer !== 'unknown') effects.bindGholaLeader(g, p, q, a.answer === 'yes', current.player);
}
if (q.kind === 'leaderRevival') {
check(effects.leaderRevivalAnswers && effects.bindLeaderRevival && effects.leaderRevivalAnswers(g, p, q).includes(a.answer),
'Choose a named leader-revival answer compatible with native eligibility and earlier promises.');