Skip to content

Latest commit

 

History

7 Commits

Folders and files

NameName
Last commit message
Last commit date
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

rallye-engine

Moteur de règles d'un jeu de course en cartes, pour 2 à 6 joueurs. TypeScript strict, aucune dépendance, aucun accès au réseau, au DOM ni à un quelconque service.

Chaque joueur accumule des bornes jusqu'à 1000, gêne ses adversaires avec des attaques (feu rouge, panne d'essence, crevaison…) et s'en protège avec des parades et des bottes. La partie se joue en manches successives.

Création originale : les règles sont réimplémentées de zéro. Les mécaniques d'un jeu ne sont pas protégeables, et ce dépôt ne reprend ni nom commercial, ni illustration, ni texte d'aucune édition existante.

Ce que c'est

Un réducteur pur. On lui donne un état et une action, il rend un nouvel état — ou un refus motivé.

import { legalActions, reduce, scoreRound, startRound } from './src/index.js';

let state = startRound({
  players: [
    { id: 'p1', teamId: 't1' },
    { id: 'p2', teamId: 't2' },
  ],
  seed: 42,
});

const result = reduce(state, { type: 'draw', player: state.currentPlayer });
if (result.ok) {
  state = result.state;
} else {
  console.log(result.error.code); // par exemple 'notYourTurn'
}

Principes

  • Pureté. Aucun Math.random(), aucun Date.now(), aucune entrée-sortie. Tout l'aléatoire passe par un PRNG seedé dont l'état, un entier 32 bits, vit dans l'état de la manche. Une partie se rejoue donc à l'identique, et un serveur peut hiberner entre deux coups sans rien perdre.
  • Aucune mutation. L'état d'entrée n'est jamais modifié. Les manches de test le gèlent récursivement avant chaque appel : la moindre écriture en place lèverait une exception.
  • Aucune exception pour une action illégale. reduce rend { ok: false, error } avec un motif structuré, exploitable pour griser une carte ou afficher une explication.
  • Une seule source de vérité. legalActions et reduce partagent les mêmes prédicats. Un client qui grise les cartes et un serveur qui valide ne peuvent pas diverger.
  • Information cachée. playerView retire les mains adverses et le contenu de la pioche. Un serveur n'a jamais besoin d'envoyer autre chose sur le réseau.

Modules

Fichier Rôle
cards.ts Composition du paquet (106 cartes) et relations attaque / parade / botte
types.ts Types du domaine, tous en lecture seule
rules.ts Réducteur, prédicats de légalité, legalActions, mise en place
scoring.ts Décompte de fin de manche, barème configurable
view.ts Projection vers ce qu'un joueur a le droit de voir
rng.ts PRNG seedé (mulberry32) et mélange Fisher-Yates

Développement

pnpm install
pnpm test        # 116 tests
pnpm typecheck

Les tests couvrent la composition du paquet, chaque règle contre-intuitive prise isolément, le barème bonus par bonus, la non-fuite d'information, et des manches complètes jouées de bout en bout par deux robots déterministes — dont les invariants (conservation des 106 cartes, taille de main, immutabilité) sont vérifiés après chaque action.

Quelques règles qui méritent l'attention

Ce sont les points sur lesquels une réimplémentation se trompe le plus souvent.

  • Les deux piles sont indépendantes. Une limite de vitesse ne bloque pas : elle plafonne la valeur des bornes jouables, et coexiste avec l'état de la pile de bataille. Elle est donc jouable sur un joueur déjà arrêté par un feu rouge, ou qui n'a pas encore démarré.
  • Le Véhicule prioritaire dispense définitivement de feu vert, mais pas de parade : son détenteur reste arrêté par une panne, une crevaison ou un accident, et repart tout seul une fois l'attaque parée.
  • Parer ne fait pas repartir. Après une réparation, la pile de bataille n'est pas roulante : il faut encore un feu vert — sauf pour le détenteur du Véhicule prioritaire.
  • La fenêtre de coup-fourré ne s'ouvre que si la cible détient la botte. Une fenêtre systématique révélerait, par son absence de déclenchement, que la cible n'a rien.
  • Le total doit tomber exactement sur 1000. Toute pose qui dépasserait est refusée.

About

Deterministic rules engine for a multiplayer racing card game. Pure TypeScript, hidden-information state machine, no dependencies.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages