fix(SCOPONE-0012): complete iteration 3 - pass ai quality gate
This commit is contained in:
@@ -11,6 +11,10 @@ export type AIBenchmarkCriticalConcept =
|
||||
| 'partner-scopa-setup'
|
||||
| 'settebello-capture'
|
||||
| 'anti-scopa-defense'
|
||||
| 'cards-majority-conversion'
|
||||
| 'denari-denial'
|
||||
| 'primiera-denial'
|
||||
| 'partner-preserving-quiet-release'
|
||||
| 'dealer-rank-residue-preservation'
|
||||
| 'exact-endgame-resolution';
|
||||
|
||||
@@ -90,7 +94,7 @@ const RAW_FIXTURES: RawFixture[] = [
|
||||
{
|
||||
id: 'anti-scopa-safe-dump',
|
||||
name: 'Anti-Scopa Safe Dump',
|
||||
description: 'The root player should prefer the safe high dump instead of taking a flashy but dangerous capture.',
|
||||
description: 'The root player should take the clean five capture that removes the only cheap concession, rather than floating a tenth card into the same anti-scopa race.',
|
||||
tags: ['critical-anti-scopa', 'table-control'],
|
||||
criticalConcept: 'anti-scopa-defense',
|
||||
dealer: 0,
|
||||
@@ -107,27 +111,34 @@ const RAW_FIXTURES: RawFixture[] = [
|
||||
piles: PILES_TEMPLATE_A,
|
||||
totalPoints: [8, 8],
|
||||
expectedMove: {
|
||||
cardId: 'spade_10',
|
||||
cardId: 'denara_5',
|
||||
captureIds: ['coppe_5'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'dealer-rank-residue-preserve-pair',
|
||||
name: 'Dealer Rank Residue Preserve Pair',
|
||||
description: 'The dealer should keep the double-nine structure intact and release the harmless low card.',
|
||||
description: 'The dealer should keep the double-nine structure intact and release the harmless three into the heavy 6+8+8 table instead of breaking higher-rank control.',
|
||||
tags: ['critical-dealer-rank-residue', 'dealer-side-control'],
|
||||
criticalConcept: 'dealer-rank-residue-preservation',
|
||||
dealer: 3,
|
||||
currentPlayer: 3,
|
||||
handSizes: [5, 5, 5, 5],
|
||||
hands: [undefined, undefined, undefined, [
|
||||
hands: [[
|
||||
'bastoni_1',
|
||||
'bastoni_2',
|
||||
'bastoni_4',
|
||||
'bastoni_5',
|
||||
'spade_5',
|
||||
], undefined, undefined, [
|
||||
'spade_3',
|
||||
'denara_9',
|
||||
'coppe_9',
|
||||
'bastoni_10',
|
||||
'denara_5',
|
||||
]],
|
||||
table: ['denara_2', 'coppe_5', 'bastoni_4', 'spade_8'],
|
||||
piles: PILES_TEMPLATE_A,
|
||||
table: ['bastoni_6', 'spade_8', 'coppe_8'],
|
||||
pileCardCounts: [5, 4, 4, 4],
|
||||
scopes: [0, 1, 0, 1],
|
||||
totalPoints: [9, 7],
|
||||
expectedMove: {
|
||||
@@ -180,8 +191,8 @@ const RAW_FIXTURES: RawFixture[] = [
|
||||
},
|
||||
{
|
||||
id: 'partner-scopa-setup',
|
||||
name: 'Partner Scopa Setup',
|
||||
description: 'When there is no safe immediate sweep, the root player should prefer the quiet partner invitation that preserves table pressure for the partner line instead of cashing a smaller material capture.',
|
||||
name: 'Partner Pressure Setup',
|
||||
description: 'Instead of floating a sterile ten, the root player should take the low five capture that strips the loose 1+4 total and leaves a heavy 7+8 table the next opponent cannot immediately cash, preserving team pressure into the partner rotation.',
|
||||
tags: ['critical-partner-setup', 'partner-window', 'table-control'],
|
||||
criticalConcept: 'partner-scopa-setup',
|
||||
dealer: 0,
|
||||
@@ -190,7 +201,7 @@ const RAW_FIXTURES: RawFixture[] = [
|
||||
hands: [
|
||||
undefined,
|
||||
['coppe_10', 'spade_6', 'bastoni_3', 'denara_5', 'coppe_2'],
|
||||
['spade_10', 'denara_6', 'bastoni_4', 'coppe_9', 'denara_8'],
|
||||
['spade_10', 'denara_6', 'bastoni_4', 'coppe_9', 'spade_3'],
|
||||
undefined,
|
||||
],
|
||||
table: ['denara_1', 'coppe_4', 'bastoni_7', 'spade_8'],
|
||||
@@ -198,7 +209,8 @@ const RAW_FIXTURES: RawFixture[] = [
|
||||
scopes: [0, 1, 0, 1],
|
||||
totalPoints: [8, 9],
|
||||
expectedMove: {
|
||||
cardId: 'coppe_10',
|
||||
cardId: 'denara_5',
|
||||
captureIds: ['denara_1', 'coppe_4'],
|
||||
},
|
||||
},
|
||||
{
|
||||
@@ -360,6 +372,115 @@ const RAW_FIXTURES: RawFixture[] = [
|
||||
cardId: 'coppe_8',
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'cards-majority-conversion',
|
||||
name: 'Cards Majority Conversion',
|
||||
description: 'With the cards race on a knife edge, the search should take the two-card conversion that secures team majority instead of the single-card direct grab.',
|
||||
tags: ['critical-cards-majority-conversion', 'team-race', 'material-margin'],
|
||||
criticalConcept: 'cards-majority-conversion',
|
||||
dealer: 1,
|
||||
currentPlayer: 0,
|
||||
handSizes: [5, 5, 5, 5],
|
||||
hands: [[
|
||||
'bastoni_9',
|
||||
'spade_8',
|
||||
'denara_2',
|
||||
'coppe_3',
|
||||
'spade_6',
|
||||
], undefined, undefined, undefined],
|
||||
table: ['coppe_4', 'spade_5', 'denara_8', 'bastoni_10'],
|
||||
pileCardCounts: [5, 3, 5, 3],
|
||||
scopes: [1, 0, 1, 0],
|
||||
totalPoints: [9, 9],
|
||||
expectedMove: {
|
||||
cardId: 'bastoni_9',
|
||||
captureIds: ['coppe_4', 'spade_5'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'denari-denial-window',
|
||||
name: 'Denari Denial Window',
|
||||
description: 'The root player should strip the exposed denari immediately, before the heavier table turns into a generic control race, because the team denari count is still live.',
|
||||
tags: ['critical-denari-denial', 'denari-race', 'team-defense'],
|
||||
criticalConcept: 'denari-denial',
|
||||
dealer: 2,
|
||||
currentPlayer: 1,
|
||||
handSizes: [5, 5, 5, 5],
|
||||
hands: [undefined, [
|
||||
'spade_6',
|
||||
'bastoni_5',
|
||||
'coppe_3',
|
||||
'spade_10',
|
||||
'spade_2',
|
||||
], undefined, undefined],
|
||||
table: ['denara_6', 'coppe_7', 'bastoni_8', 'spade_9'],
|
||||
pileCardCounts: [4, 4, 4, 4],
|
||||
totalPoints: [9, 9],
|
||||
expectedMove: {
|
||||
cardId: 'spade_6',
|
||||
captureIds: ['denara_6'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'primiera-denial-window',
|
||||
name: 'Primiera Denial Window',
|
||||
description: 'The benchmark should prefer removing the exposed seven that swings primiera control instead of banking the larger but strategically softer material capture.',
|
||||
tags: ['critical-primiera-denial', 'primiera-pressure', 'team-defense'],
|
||||
criticalConcept: 'primiera-denial',
|
||||
dealer: 3,
|
||||
currentPlayer: 2,
|
||||
handSizes: [5, 5, 5, 5],
|
||||
hands: [undefined, undefined, [
|
||||
'spade_7',
|
||||
'coppe_8',
|
||||
'denara_2',
|
||||
'bastoni_6',
|
||||
'spade_9',
|
||||
], undefined],
|
||||
table: ['coppe_7', 'denara_4', 'spade_1', 'bastoni_3'],
|
||||
pileCardCounts: [4, 4, 4, 4],
|
||||
totalPoints: [8, 8],
|
||||
expectedMove: {
|
||||
cardId: 'spade_7',
|
||||
captureIds: ['coppe_7'],
|
||||
},
|
||||
},
|
||||
{
|
||||
id: 'partner-preserving-quiet-release',
|
||||
name: 'Partner Preserving Quiet Release',
|
||||
description: 'Rather than breaking the paired sevens or the denari structure, the root player should release the quiet two that keeps the 2+8 ten line alive for the partner while the intervening opponent still has no immediate capture.',
|
||||
tags: ['critical-partner-preserving-quiet-release', 'partner-window', 'quiet-release', 'table-control'],
|
||||
criticalConcept: 'partner-preserving-quiet-release',
|
||||
dealer: 0,
|
||||
currentPlayer: 0,
|
||||
handSizes: [5, 5, 5, 5],
|
||||
hands: [[
|
||||
'coppe_2',
|
||||
'denara_7',
|
||||
'coppe_7',
|
||||
'denara_5',
|
||||
'bastoni_4',
|
||||
], [
|
||||
'bastoni_1',
|
||||
'bastoni_3',
|
||||
'bastoni_5',
|
||||
'bastoni_7',
|
||||
'coppe_1',
|
||||
], [
|
||||
'spade_10',
|
||||
'denara_8',
|
||||
'coppe_9',
|
||||
'bastoni_2',
|
||||
'spade_6',
|
||||
], undefined],
|
||||
table: ['bastoni_8', 'spade_9', 'coppe_6'],
|
||||
pileCardCounts: [5, 4, 4, 4],
|
||||
scopes: [0, 1, 0, 1],
|
||||
totalPoints: [8, 9],
|
||||
expectedMove: {
|
||||
cardId: 'coppe_2',
|
||||
},
|
||||
},
|
||||
];
|
||||
|
||||
function cloneCard(card: Card): Card {
|
||||
|
||||
Reference in New Issue
Block a user