feat(SCOPONE-0005): complete iteration 0 — AI mastery levels, score bar fix, difficulty selection
This commit is contained in:
68
src/game/card-tracker.ts
Normal file
68
src/game/card-tracker.ts
Normal file
@@ -0,0 +1,68 @@
|
||||
import { Card, Suit, SUITS } from './types';
|
||||
|
||||
/**
|
||||
* Tracks which cards have been played/captured during a round.
|
||||
* Used by AI to infer opponent hands WITHOUT cheating.
|
||||
*/
|
||||
export class CardTracker {
|
||||
private played: Set<string> = new Set(); // card IDs that have been seen
|
||||
|
||||
/** Record a card being played to the table */
|
||||
trackPlay(card: Card): void {
|
||||
this.played.add(card.id);
|
||||
}
|
||||
|
||||
/** Record cards captured from the table */
|
||||
trackCapture(cards: Card[]): void {
|
||||
for (const c of cards) {
|
||||
this.played.add(c.id);
|
||||
}
|
||||
}
|
||||
|
||||
/** Reset for a new round */
|
||||
reset(): void {
|
||||
this.played.clear();
|
||||
}
|
||||
|
||||
/** Has a specific card been seen played? */
|
||||
hasBeenPlayed(cardId: string): boolean {
|
||||
return this.played.has(cardId);
|
||||
}
|
||||
|
||||
/** Is the settebello (7 of denara) still unseen (not played/captured)? */
|
||||
isSettebelloUnseen(): boolean {
|
||||
return !this.played.has('denara_7');
|
||||
}
|
||||
|
||||
/**
|
||||
* Get cards that could be in opponent hands.
|
||||
* = full 40-card deck minus: already played, my hand, currently on table
|
||||
*/
|
||||
getUnseenCards(myHand: Card[], table: Card[]): Card[] {
|
||||
const known = new Set<string>();
|
||||
for (const id of this.played) known.add(id);
|
||||
for (const c of myHand) known.add(c.id);
|
||||
for (const c of table) known.add(c.id);
|
||||
|
||||
const unseen: Card[] = [];
|
||||
for (const suit of SUITS) {
|
||||
for (let v = 1; v <= 10; v++) {
|
||||
const id = `${suit}_${v}`;
|
||||
if (!known.has(id)) {
|
||||
unseen.push({ suit, value: v, id });
|
||||
}
|
||||
}
|
||||
}
|
||||
return unseen;
|
||||
}
|
||||
|
||||
/** Count how many cards of a suit are still unseen */
|
||||
countRemainingSuit(suit: Suit, myHand: Card[], table: Card[]): number {
|
||||
return this.getUnseenCards(myHand, table).filter(c => c.suit === suit).length;
|
||||
}
|
||||
|
||||
/** Get count of all played/seen cards */
|
||||
get playedCount(): number {
|
||||
return this.played.size;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user