Combine current facts with native Traitor decisions
This commit is contained in:
1 parent
812f77e348
commit
13398aa76e
22 files changed
+1512
-17
No files matched your search
@@ -1,3 +1,4 @@
|
||||
import { parseTraitorActionClaim, type MixedTraitorClaim } from './mixed-traitor-question';
|
||||
import { parseBattleActionClaim, MIXED_BATTLE_MAX_NODES, MIXED_BATTLE_MAX_TERMS, MIXED_BATTLE_MAX_DEPTH,
|
||||
MIXED_BATTLE_MAX_LEAVES, type MixedBattleClaim } from './mixed-battle-question';
|
||||
import { parseAllianceExpressionClaim, allianceExpressionText, type AllianceExpressionClaim } from './alliance-expression-promises';
|
||||
@@ -77,6 +78,7 @@ export type TruthFact =
|
||||
| { kind: 'and' | 'or'; terms: TruthFact[] };
|
||||
export type MixedMovementClaim = { turn: number; mixed: MixedActionExpression<MovementClaim> };
|
||||
export type TruthQuestion =
|
||||
| ({ kind: 'mixedTraitorCall'; target: string } & MixedTraitorClaim)
|
||||
| ({ kind: 'mixedBattlePlan'; target: string } & MixedBattleClaim)
|
||||
| ({ kind: 'allianceExpression'; target: string } & AllianceExpressionClaim)
|
||||
| ({ kind: 'mixedAlliance'; target: string } & MixedAllianceClaim)
|
||||
@@ -368,6 +370,17 @@ function parseQuestion(g: Game, asker: string, value: unknown): TruthQuestion {
|
||||
'Choose the current ordinary bid lot in a supported table and finish pending decisions.');
|
||||
return { kind: 'bid', target: v.target, ...claim };
|
||||
}
|
||||
if (v.kind === 'mixedTraitorCall') {
|
||||
check(Object.keys(v).sort().join(',') === 'battle,kind,mixed,target,territory' &&
|
||||
g.status === 'playing' && g.phase === 6 && g.battle?.revealed && typeof v.battle === 'string' &&
|
||||
v.battle.length > 0 && v.battle === g.battle.event && v.territory === g.battle.territory &&
|
||||
g.battle.traitorCalls[v.target as string] === undefined,
|
||||
'Choose the current revealed battle and an original unsubmitted Traitor decision.');
|
||||
const respondent = g.players.find(player => player.id === v.target)!;
|
||||
return { kind: 'mixedTraitorCall', target: v.target as string, battle: v.battle,
|
||||
territory: v.territory as string,
|
||||
mixed: parseMixedActionExpression(v.mixed, fact => parseFact(g, fact, respondent), parseTraitorActionClaim) };
|
||||
}
|
||||
if (v.kind === 'traitorCall') {
|
||||
check(Object.keys(v).sort().join(',') === 'battle,kind,target,territory' &&
|
||||
g.status === 'playing' && g.phase === 6 && g.battle?.revealed &&
|
||||
@@ -657,6 +670,9 @@ export function truthQuestionText(
|
||||
return `you currently hold ${f.compare === 'eq' ? 'exactly' : f.compare === 'gte' ? 'at least' : 'at most'} ${f.value} spice`;
|
||||
return `(${f.terms.map(clause).join(f.kind === 'and' ? ' AND ' : ' OR ')})`;
|
||||
};
|
||||
if (q.kind === 'mixedTraitorCall') return `Is it true that ${mixedActionExpressionText(q.mixed, clause,
|
||||
action => action.call ? 'you declare the opposing leader a Traitor in this battle'
|
||||
: 'you decline to declare the opposing leader a Traitor in this battle')}?`;
|
||||
if (q.kind === 'mixedBattlePlan') return `Is it true that ${mixedActionExpressionText(q.mixed, clause,
|
||||
action => `${planClaimText(action, leaderName)} in this battle`)}?`;
|
||||
if (q.kind === 'mixedAlliance') return `Is it true that ${mixedActionExpressionText(q.mixed, clause,
|
||||
@@ -723,6 +739,8 @@ export function resolveTruthAction(
|
||||
bindMixedBid?: (g: Game, p: Player, claim: MixedBidClaim, answer: boolean, asker: string) => void;
|
||||
bidAnswers?: (g: Game, p: Player, claim: BidClaim) => TruthAnswer[];
|
||||
bindBid?: (g: Game, p: Player, claim: BidClaim, answer: boolean, asker: string) => void;
|
||||
mixedTraitorAnswers?: (g: Game, p: Player, claim: MixedTraitorClaim) => TruthAnswer[];
|
||||
bindMixedTraitor?: (g: Game, p: Player, claim: MixedTraitorClaim, answer: boolean, asker: string) => void;
|
||||
traitorAnswers?: (g: Game, p: Player) => TruthAnswer[];
|
||||
bindTraitor?: (g: Game, p: Player, answer: boolean, asker: string) => void;
|
||||
mixedBattleAnswers?: (g: Game, p: Player, claim: MixedBattleClaim) => TruthAnswer[];
|
||||
@@ -888,6 +906,9 @@ export function resolveTruthAction(
|
||||
if (w.question.kind === 'bid')
|
||||
check(effects.bidAnswers?.(g, g.players.find(other => other.id === w.question!.target)!, w.question).length,
|
||||
'Choose a bidder with a remaining ordinary opportunity in this lot.');
|
||||
if (w.question.kind === 'mixedTraitorCall')
|
||||
check(effects.mixedTraitorAnswers?.(g, g.players.find(other => other.id === w.question!.target)!, w.question).length,
|
||||
'Choose a whole mixed Traitor question for an actual current voter.');
|
||||
if (w.question.kind === 'traitorCall')
|
||||
check(effects.traitorAnswers?.(g, g.players.find(other => other.id === w.question!.target)!).length,
|
||||
'Choose an actual unsubmitted native Traitor voter.');
|
||||
@@ -1009,6 +1030,11 @@ export function resolveTruthAction(
|
||||
'Choose an answer consistent with this lot, your legal bids and earlier answers.');
|
||||
if (a.answer !== 'unknown') effects.bindBid(g, p, q, a.answer === 'yes', current.player);
|
||||
}
|
||||
if (q.kind === 'mixedTraitorCall') {
|
||||
check(effects.mixedTraitorAnswers && effects.bindMixedTraitor && effects.mixedTraitorAnswers(g, p, q).includes(a.answer),
|
||||
'Choose an aggregate answer compatible with this mixed question and current native declaration.');
|
||||
if (a.answer !== 'unknown') effects.bindMixedTraitor(g, p, q, a.answer === 'yes', current.player);
|
||||
}
|
||||
if (q.kind === 'traitorCall') {
|
||||
check(effects.traitorAnswers && effects.bindTraitor && effects.traitorAnswers(g, p).includes(a.answer),
|
||||
'Choose an answer compatible with your current legal Traitor declaration and earlier answers.');
|
||||
|
||||
Reference in new issue
Block a user