versión inicial del juego
This commit is contained in:
109
src/engine/dungeon/DungeonDeck.js
Normal file
109
src/engine/dungeon/DungeonDeck.js
Normal file
@@ -0,0 +1,109 @@
|
||||
import { TILES } from './TileDefinitions.js';
|
||||
|
||||
export class DungeonDeck {
|
||||
|
||||
|
||||
constructor() {
|
||||
this.cards = [];
|
||||
this.discards = [];
|
||||
// We don't initialize automatically anymore
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs the deck according to the specific Warhammer Quest rules.
|
||||
* Rulebook steps:
|
||||
* 1. Take 6 random Dungeon Cards (Bottom pool).
|
||||
* 2. Add Objective Room card to Bottom pool.
|
||||
* 3. Shuffle Bottom pool (7 cards).
|
||||
* 4. Take 6 random Dungeon Cards (Top pool).
|
||||
* 5. Stack Top pool on Bottom pool.
|
||||
* Total: 13 cards.
|
||||
*
|
||||
* @param {string} objectiveTileId - ID of the objective/exit room.
|
||||
*/
|
||||
generateMissionDeck(objectiveTileId) {
|
||||
this.cards = [];
|
||||
|
||||
// 1. Create a "Pool" of standard dungeon tiles (Rooms & Corridors)
|
||||
// We replicate the physical deck distribution first
|
||||
let pool = [];
|
||||
const composition = [
|
||||
{ id: 'room_dungeon', count: 6 },
|
||||
// Objective room is special, handled separately
|
||||
{ id: 'corridor_straight', count: 7 },
|
||||
{ id: 'corridor_steps', count: 1 },
|
||||
{ id: 'corridor_corner', count: 1 },
|
||||
{ id: 'junction_t', count: 3 }
|
||||
];
|
||||
|
||||
composition.forEach(item => {
|
||||
const tileDef = TILES.find(t => t.id === item.id);
|
||||
if (tileDef) {
|
||||
for (let i = 0; i < item.count; i++) {
|
||||
pool.push(tileDef);
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
// Helper to pull random cards
|
||||
const drawRandom = (source, count) => {
|
||||
const drawn = [];
|
||||
for (let i = 0; i < count; i++) {
|
||||
if (source.length === 0) break;
|
||||
const idx = Math.floor(Math.random() * source.length);
|
||||
drawn.push(source[idx]);
|
||||
source.splice(idx, 1); // Remove from pool
|
||||
}
|
||||
return drawn;
|
||||
};
|
||||
|
||||
// --- Step 1 & 2: Bottom Pool (6 Random + Objective) ---
|
||||
const bottomPool = drawRandom(pool, 6);
|
||||
|
||||
// Add Objective Card
|
||||
const objectiveDef = TILES.find(t => t.id === objectiveTileId);
|
||||
if (objectiveDef) {
|
||||
bottomPool.push(objectiveDef);
|
||||
} else {
|
||||
console.error("Objective Tile ID not found:", objectiveTileId);
|
||||
// Fallback: Add a generic room if objective missing?
|
||||
}
|
||||
|
||||
// --- Step 3: Shuffle Bottom Pool ---
|
||||
this.shuffleArray(bottomPool);
|
||||
|
||||
// --- Step 4: Top Pool (6 Random) ---
|
||||
const topPool = drawRandom(pool, 6);
|
||||
// Note: No shuffle explicitly needed for Top Pool if drawn randomly,
|
||||
// but shuffling ensures random order of the 6 drawn.
|
||||
this.shuffleArray(topPool);
|
||||
|
||||
// --- Step 5: Stack (Top on Bottom) ---
|
||||
// Array[0] is the "Top" card (first to be drawn)
|
||||
this.cards = [...topPool, ...bottomPool];
|
||||
|
||||
console.log(`Deck Generated: ${this.cards.length} cards.`);
|
||||
}
|
||||
|
||||
shuffleArray(array) {
|
||||
for (let i = array.length - 1; i > 0; i--) {
|
||||
const j = Math.floor(Math.random() * (i + 1));
|
||||
[array[i], array[j]] = [array[j], array[i]];
|
||||
}
|
||||
}
|
||||
|
||||
draw() {
|
||||
if (this.cards.length === 0) {
|
||||
return null; // Deck empty
|
||||
}
|
||||
return this.cards.shift(); // Take from top
|
||||
}
|
||||
|
||||
// Useful for Campaign logic: Insert a specific card at position
|
||||
insertCard(tileId, position = 0) {
|
||||
const tileDef = TILES.find(t => t.id === tileId);
|
||||
if (tileDef) {
|
||||
this.cards.splice(position, 0, tileDef);
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user