feat: 12 character cards with 4 color-coded attributes (food/war/health/diplo)

This commit is contained in:
kevin.lhereec committed 2026-08-17 11:41:46 +02:00
1 parent 1db221e468
commit 38814668e7
7 files changed
+2190 -317

No files matched your search

+160 -34
View File
@@ -1,31 +1,161 @@
// Deck de base de Regnum
// Types: Royaume (points fixes), Armée (attaque), Commerce (multiplicateur), Magie (effets spéciaux)
/**
* Regnum - Définition des 12 personnages
*
* Chaque carte possède 4 attributs (valeurs de 1 à 6) :
* food (🟡 Nourriture) - coin haut gauche - jaune
* war (🔴 Guerre) - coin haut droite - rouge
* health(🟢 Santé) - coin bas gauche - vert
* diplo (🔵 Diplomatie) - coin bas droite - bleu
*
* Toutes les équipes ont exactement le même deck de 12 cartes,
* seule la couleur d'équipe change visuellement.
*/
const BASE_DECK = [
// === ROYAUME ===
{ id: 'r1', name: 'Village', type: 'Royaume', points: 2, effect: null },
{ id: 'r2', name: 'Château', type: 'Royaume', points: 5, effect: null },
{ id: 'r3', name: 'Cathédrale', type: 'Royaume', points: 4, effect: null },
{ id: 'r4', name: 'Forteresse', type: 'Royaume', points: 3, effect: null },
{ id: 'r5', name: 'Palais Royal', type: 'Royaume', points: 7, effect: null },
// === ARMÉE ===
{ id: 'a1', name: 'Chevaliers', type: 'Armée', points: 3, effect: 'steal:1' },
{ id: 'a2', name: 'Archers', type: 'Armée', points: 2, effect: 'steal:1' },
{ id: 'a3', name: 'Catapulte', type: 'Armée', points: 1, effect: 'steal:2' },
{ id: 'a4', name: 'Légion', type: 'Armée', points: 4, effect: 'steal:2' },
// === COMMERCE ===
{ id: 'c1', name: 'Marché', type: 'Commerce', points: 2, effect: 'bonus:1' },
{ id: 'c2', name: 'Port', type: 'Commerce', points: 3, effect: 'bonus:2' },
{ id: 'c3', name: 'Route de soie', type: 'Commerce', points: 5, effect: 'bonus:1' },
// === MAGIE ===
{ id: 'm1', name: 'Oracle', type: 'Magie', points: 1, effect: 'draw:1' },
{ id: 'm2', name: 'Enchanteur', type: 'Magie', points: 2, effect: 'protect' },
{ id: 'm3', name: 'Alchimiste', type: 'Magie', points: 3, effect: 'double' },
const CHARACTERS = [
{
id: 'queen',
name: 'Reine',
food: 2,
war: 2,
health: 3,
diplo: 5,
description: 'Maîtresse de la diplomatie, elle tisse des alliances avec dextérité.'
},
{
id: 'prince',
name: 'Prince',
food: 2,
war: 4,
health: 2,
diplo: 4,
description: 'Héritier du trône, équilibré entre le glaive et la parole.'
},
{
id: 'butcher',
name: 'Boucher',
food: 5,
war: 3,
health: 1,
diplo: 1,
description: 'Maître des viandes, il nourrit le peuple mais soigne peu.'
},
{
id: 'doctor',
name: 'Médecin',
food: 2,
war: 1,
health: 6,
diplo: 3,
description: 'Expert en guérison, indispensable à la survie du royaume.'
},
{
id: 'apothecary',
name: 'Apothicaire',
food: 3,
war: 1,
health: 5,
diplo: 3,
description: 'Prépare potions et remèdes, soutien précieux en temps de crise.'
},
{
id: 'jester',
name: 'Fou du Roi',
food: 1,
war: 1,
health: 2,
diplo: 6,
description: 'Sa sagesse cachée derrière la bouffonnerie fait des miracles diplomatiques.'
},
{
id: 'assassin',
name: 'Assassin',
food: 1,
war: 6,
health: 1,
diplo: 2,
description: 'Frappe dans l\'ombre, inarrêtable au combat mais inutile ailleurs.'
},
{
id: 'peasant',
name: 'Paysan',
food: 6,
war: 2,
health: 2,
diplo: 1,
description: 'Nourrit tout le royaume, force vitale de toute civilisation.'
},
{
id: 'executioner',
name: 'Bourreau',
food: 2,
war: 5,
health: 1,
diplo: 2,
description: 'Bras armé de la justice royale, redouté de tous.'
},
{
id: 'knight',
name: 'Chevalier',
food: 3,
war: 5,
health: 2,
diplo: 2,
description: 'Défenseur du royaume, vaillant sur le champ de bataille.'
},
{
id: 'merchant',
name: 'Marchand',
food: 4,
war: 1,
health: 2,
diplo: 5,
description: 'Ses routes commerciales enrichissent et lient les royaumes.'
},
{
id: 'bishop',
name: 'Évêque',
food: 2,
war: 1,
health: 4,
diplo: 5,
description: 'Voix de l\'Église, il guérit les âmes et négocie la paix.'
}
]
/**
* Couleurs des 4 équipes (teinte principale de la carte)
*/
const TEAM_COLORS = {
0: { name: 'Écarlate', hex: 0xcc2200, css: '#cc2200' },
1: { name: 'Azur', hex: 0x1155cc, css: '#1155cc' },
2: { name: 'Émeraude', hex: 0x1a7a2e, css: '#1a7a2e' },
3: { name: 'Or', hex: 0xb8860b, css: '#b8860b' }
}
/**
* Attributs visuels fixes (couleur de chaque coin)
*/
const ATTR_COLORS = {
food: { hex: 0xf0c030, css: '#f0c030', label: 'Nourriture', corner: 'topLeft' },
war: { hex: 0xdd2222, css: '#dd2222', label: 'Guerre', corner: 'topRight' },
health: { hex: 0x22aa44, css: '#22aa44', label: 'Santé', corner: 'bottomLeft' },
diplo: { hex: 0x3399ee, css: '#3399ee', label: 'Diplomatie', corner: 'bottomRight' }
}
/**
* Retourne le deck complet (les 12 personnages) pour une équipe donnée
*/
function getDeckForTeam(teamIndex) {
return CHARACTERS.map(c => ({
...c,
teamIndex,
teamColor: TEAM_COLORS[teamIndex]
}))
}
/**
* Distribue une main de N cartes par joueur depuis un deck mélangé
*/
function shuffle(arr) {
const a = [...arr]
for (let i = a.length - 1; i > 0; i--) {
@@ -35,17 +165,13 @@ function shuffle(arr) {
return a
}
function createDeck() {
return shuffle([...BASE_DECK, ...BASE_DECK]) // 2 exemplaires
}
function dealHands(playerCount, handSize = 5) {
const deck = createDeck()
function dealHands(playerCount, handSize = 4) {
const hands = []
for (let i = 0; i < playerCount; i++) {
hands.push(deck.splice(0, handSize))
const deck = shuffle(getDeckForTeam(i))
hands.push(deck.slice(0, handSize))
}
return { hands, remaining: deck }
return hands
}
module.exports = { createDeck, dealHands, BASE_DECK }
module.exports = { CHARACTERS, TEAM_COLORS, ATTR_COLORS, getDeckForTeam, dealHands }