feat: regicide code

This commit is contained in:
hyper
2026-04-10 13:24:29 +08:00
parent 8b271448d2
commit 28e548d3de
7 changed files with 426 additions and 0 deletions
+132
View File
@@ -0,0 +1,132 @@
import {ALL_RANKS, ALL_SUITS, CARD_VALUES, ENEMY_COUNT, FACE_CARDS} from "@/samples/regicide/constants";
import {CardRank, Enemy, RegicideCard, SuitType} from "@/samples/regicide/types";
import {RNG} from "@/utils/rng";
/**
* 获取卡牌面值
*/
export function getCardValue(rank: CardRank): number {
return CARD_VALUES[rank];
}
/**
* 创建卡牌部件
*/
export function createCard(id: string, suit: SuitType, rank: CardRank): RegicideCard {
return {
id,
regionId: '',
position: [],
suit,
rank,
value: getCardValue(rank),
};
}
/**
* 创建敌人
*/
export function createEnemy(id: string, rank: CardRank, suit: SuitType): Enemy {
const value = getCardValue(rank);
return {
id,
rank,
suit,
value,
hp: value * 2,
maxHp: value * 2,
};
}
/**
* 生成完整卡牌列表(52张,不含大小王)
*/
export function createAllCards(): Record<string, RegicideCard> {
const cards: Record<string, RegicideCard> = {};
for (const suit of ALL_SUITS) {
for (const rank of ALL_RANKS) {
const id = `${suit}_${rank}`;
cards[id] = createCard(id, suit, rank);
}
}
return cards;
}
/**
* 构建敌人牌堆(J/Q/K 共12张)
* 规则:4张K在最下,4张Q在中间,4张J在最上
*/
export function buildEnemyDeck(rng: RNG): Enemy[] {
const enemies: Enemy[] = [];
let idCounter = 0;
// 创建所有J/Q/K敌人
for (const rank of FACE_CARDS) {
for (const suit of ALL_SUITS) {
const id = `enemy_${idCounter++}`;
enemies.push(createEnemy(id, rank, suit));
}
}
// 分离J、Q、K
const jEnemies = enemies.filter(e => e.rank === 'J');
const qEnemies = enemies.filter(e => e.rank === 'Q');
const kEnemies = enemies.filter(e => e.rank === 'K');
// 分别洗牌
shuffleArray(jEnemies, rng);
shuffleArray(qEnemies, rng);
shuffleArray(kEnemies, rng);
// J在最上(先遇到),Q在中间,K在最下
return [...jEnemies, ...qEnemies, ...kEnemies];
}
/**
* 构建酒馆牌堆(移除J/Q/K后的剩余牌)
*/
export function buildTavernDeck(rng: RNG): RegicideCard[] {
const allCards = createAllCards();
const numberCards = Object.values(allCards).filter(card => !FACE_CARDS.includes(card.rank));
shuffleArray(numberCards, rng);
return numberCards;
}
/**
* 洗牌辅助函数
*/
function shuffleArray<T>(array: T[], rng: RNG): void {
for (let i = array.length - 1; i > 0; i--) {
const j = rng.nextInt(i + 1);
[array[i], array[j]] = [array[j], array[i]];
}
}
/**
* 从牌堆抽牌
*/
export function drawFromDeck(
deck: RegicideCard[],
count: number
): RegicideCard[] {
const drawn = deck.splice(0, count);
return drawn;
}
/**
* 检查敌人是否被击败
*/
export function isEnemyDefeated(enemy: Enemy | null): boolean {
return enemy !== null && enemy.hp <= 0;
}
/**
* 获取当前玩家手牌区域ID
*/
export function getPlayerHandRegionId(playerId: string): string {
return `hand_${playerId}`;
}