feat: regicide code
This commit is contained in:
@@ -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}`;
|
||||
}
|
||||
Reference in New Issue
Block a user