trictrac/store/src/game_rules_points.rs

517 lines
20 KiB
Rust
Raw Normal View History

use std::cmp;
2024-05-27 19:54:58 +02:00
use std::collections::HashMap;
2024-05-26 12:00:30 +02:00
use crate::board::{Board, EMPTY_MOVE};
2024-05-20 19:04:46 +02:00
use crate::dice::Dice;
2024-05-25 19:56:38 +02:00
use crate::game_rules_moves::MoveRules;
use crate::player::Color;
use crate::CheckerMove;
use crate::Error;
2024-05-20 19:04:46 +02:00
2024-05-27 19:54:58 +02:00
#[derive(PartialEq, Eq, Hash, Clone, Debug)]
2024-05-25 19:56:38 +02:00
enum Jan {
2024-05-26 12:00:30 +02:00
FilledQuarter,
2024-06-15 19:10:01 +02:00
TrueHitSmallJan,
TrueHitBigJan,
2024-09-13 18:07:57 +02:00
TrueHitOpponentCorner,
FirstPlayerToExit,
2024-09-16 17:46:09 +02:00
SixTables,
2024-05-20 19:04:46 +02:00
}
2024-06-15 19:10:01 +02:00
impl Jan {
pub fn get_points(&self, is_double: bool) -> i8 {
match self {
Self::TrueHitBigJan => {
if is_double {
4
} else {
2
}
}
_ => {
if is_double {
6
} else {
4
}
}
}
}
}
2024-05-28 18:52:49 +02:00
type PossibleJans = HashMap<Jan, Vec<(CheckerMove, CheckerMove)>>;
2024-05-27 19:54:58 +02:00
2024-05-28 18:52:49 +02:00
trait PossibleJansMethods {
fn push(&mut self, jan: Jan, cmoves: (CheckerMove, CheckerMove));
fn merge(&mut self, other: Self);
2024-06-15 19:10:01 +02:00
// fn get_points(&self) -> u8;
2024-05-28 18:52:49 +02:00
}
2024-05-27 19:54:58 +02:00
2024-05-28 18:52:49 +02:00
impl PossibleJansMethods for PossibleJans {
fn push(&mut self, jan: Jan, cmoves: (CheckerMove, CheckerMove)) {
if let Some(ways) = self.get_mut(&jan) {
2024-05-27 19:54:58 +02:00
if !ways.contains(&cmoves) {
ways.push(cmoves);
}
} else {
2024-05-28 18:52:49 +02:00
self.insert(jan, [cmoves].into());
}
}
fn merge(&mut self, other: Self) {
for (jan, cmoves_list) in other {
for cmoves in cmoves_list {
self.push(jan.clone(), cmoves);
}
2024-05-27 19:54:58 +02:00
}
}
2024-05-25 19:56:38 +02:00
}
/// PointsRules always consider that the current player is White
/// You must use 'mirror' function on board if player is Black
#[derive(Default)]
pub struct PointsRules {
pub board: Board,
pub dice: Dice,
pub move_rules: MoveRules,
}
impl PointsRules {
/// Revert board if color is black
pub fn new(color: &Color, board: &Board, dice: Dice) -> Self {
let board = if *color == Color::Black {
board.mirror()
} else {
board.clone()
};
let move_rules = MoveRules::new(color, &board, dice);
// let move_rules = MoveRules::new(color, &self.board, dice, moves);
Self {
board,
dice,
move_rules,
}
}
2024-06-24 21:22:27 +02:00
pub fn set_dice(&mut self, dice: Dice) {
self.dice = dice;
self.move_rules.dice = dice;
}
pub fn update_positions(&mut self, positions: [i8; 24]) {
self.board.set_positions(positions);
self.move_rules.board.set_positions(positions);
}
2024-06-24 18:10:24 +02:00
2024-06-24 21:22:27 +02:00
fn get_jans(&self, board_ini: &Board) -> PossibleJans {
let dices = &vec![self.dice.values.0, self.dice.values.1];
let dices_reversed = &vec![self.dice.values.1, self.dice.values.0];
// « JAN DE RÉCOMPENSE »
// Battre à vrai une dame située dans la table des grands jans
// Battre à vrai une dame située dans la table des petits jans
2024-09-13 18:07:57 +02:00
let mut jans = self.get_jans_by_ordered_dice(board_ini, dices);
let jans_revert_dices = self.get_jans_by_ordered_dice(board_ini, dices_reversed);
2024-06-24 18:10:24 +02:00
jans.merge(jans_revert_dices);
2024-06-24 21:22:27 +02:00
2024-09-13 18:07:57 +02:00
// Battre à vrai le coin de repos de l'adversaire
let corner_field = board_ini.get_color_corner(&Color::White);
let adv_corner_field = board_ini.get_color_corner(&Color::Black);
let (adv_corner_count, _color) = board_ini.get_field_checkers(adv_corner_field).unwrap();
if adv_corner_count == 0 {
let from0 = adv_corner_field - self.dice.values.0 as usize;
let from1 = adv_corner_field - self.dice.values.1 as usize;
let (from0_count, from0_color) = board_ini.get_field_checkers(from0).unwrap();
let (from1_count, from1_color) = board_ini.get_field_checkers(from1).unwrap();
let hit_moves = vec![(
CheckerMove::new(from0, adv_corner_field).unwrap(),
CheckerMove::new(from1, adv_corner_field).unwrap(),
)];
if from0 == from1 {
// doublet
if from0_count > if from0 == corner_field { 3 } else { 0 } {
jans.insert(Jan::TrueHitOpponentCorner, hit_moves);
}
} else {
// simple
if from0_count > if from0 == corner_field { 2 } else { 0 }
&& from1_count > if from1 == corner_field { 2 } else { 0 }
{
jans.insert(Jan::TrueHitOpponentCorner, hit_moves);
}
}
}
2024-06-24 21:22:27 +02:00
// « JAN DE REMPLISSAGE »
// Faire un petit jan, un grand jan ou un jan de retour
let filling_moves_sequences = self
.move_rules
.get_scoring_quarter_filling_moves_sequences();
if !filling_moves_sequences.is_empty() {
jans.insert(Jan::FilledQuarter, filling_moves_sequences);
}
// « AUTRE »
// sortir le premier toutes ses dames
let mut checkers = board_ini.get_color_fields(Color::White);
checkers.sort_by(|a, b| b.0.cmp(&a.0));
let checkers_count = checkers.iter().fold(0, |acc, (_f, count)| acc + count);
if checkers_count < 3 {
let mut farthest = 24;
let mut next_farthest = 24;
if let Some((field, count)) = checkers.first() {
farthest = *field;
if *count > 1 {
next_farthest = *field;
} else if let Some((field, _count)) = checkers.get(1) {
next_farthest = *field;
}
}
if farthest + cmp::max(self.dice.values.0, self.dice.values.1) as usize > 23
&& next_farthest + cmp::min(self.dice.values.0, self.dice.values.1) as usize > 23
{
let exit_moves = vec![(
CheckerMove::new(farthest, 0).unwrap(),
if checkers_count > 1 {
CheckerMove::new(next_farthest, 0).unwrap()
} else {
CheckerMove::new(0, 0).unwrap()
},
)];
jans.insert(Jan::FirstPlayerToExit, exit_moves);
}
}
2024-09-16 17:46:09 +02:00
// « JANS RARES »
// Jan de 6 tables
// on devrait avoir 5 cases occupées : le talon et 4 cases parmi les cases 2 à 7
if checkers.len() == 5 {
let checkers_fields: Vec<usize> = checkers.iter().map(|(f, c)| *f).collect();
let mut missing_for_6tables: Vec<usize> = Vec::from([2, 3, 4, 5, 6, 7])
.into_iter()
.filter(|f| !checkers_fields.contains(f))
.collect();
if missing_for_6tables.len() == 2 {
println!("--j6 missing==2");
// Les dés doivent permettre le mouvement de deux dames du talon vers les 2 cases
// vides
let mut dice_to: Vec<usize> = vec![
1 + self.dice.values.0 as usize,
1 + self.dice.values.1 as usize,
];
missing_for_6tables.sort();
dice_to.sort();
if dice_to == missing_for_6tables {
let moves = vec![(
CheckerMove::new(1, missing_for_6tables[0]).unwrap(),
CheckerMove::new(1, missing_for_6tables[1]).unwrap(),
)];
jans.insert(Jan::SixTables, moves);
}
}
}
2024-06-24 18:10:24 +02:00
jans
}
2024-09-13 18:07:57 +02:00
fn get_jans_by_ordered_dice(&self, board_ini: &Board, dices: &Vec<u8>) -> PossibleJans {
2024-05-27 19:54:58 +02:00
let mut jans = PossibleJans::default();
2024-05-25 19:56:38 +02:00
let mut dices = dices.clone();
if let Some(dice) = dices.pop() {
2024-05-28 18:52:49 +02:00
let color = Color::White;
2024-06-13 21:18:49 +02:00
let mut board = board_ini.clone();
let corner_field = board.get_color_corner(&color);
let adv_corner_field = board.get_color_corner(&Color::Black);
2024-05-28 18:52:49 +02:00
for (from, _) in board.get_color_fields(color) {
2024-05-25 19:56:38 +02:00
let to = if from + dice as usize > 24 {
0
} else {
from + dice as usize
};
if let Ok(cmove) = CheckerMove::new(from, to) {
2024-06-14 19:07:33 +02:00
// let res = state.moves_allowed(&moves);
// if res.is_ok() {
// println!("dice : {:?}, res : {:?}", dice, res);
// On vérifie que le mouvement n'est pas interdit par les règles des coins de
// repos :
// - on ne va pas sur le coin de l'adversaire
// - ni sur son propre coin de repos avec une seule dame
2024-09-13 18:07:57 +02:00
// - règle non prise en compte pour le battage des dames : on ne sort pas de son coin de repos s'il n'y reste que deux dames
2024-06-13 21:18:49 +02:00
let (corner_count, _color) = board.get_field_checkers(corner_field).unwrap();
2024-06-15 19:10:01 +02:00
if to != adv_corner_field && (to != corner_field || corner_count > 1)
// && (from != corner_field || corner_count > 2)
2024-06-14 19:07:33 +02:00
{
2024-06-13 21:18:49 +02:00
// println!(
// "dice : {}, adv_corn_field : {:?}, from : {}, to : {}, corner_count : {}",
// dice, adv_corner_field, from, to, corner_count
// );
2024-06-15 19:10:01 +02:00
let mut can_try_toutdune = true;
2024-06-13 21:18:49 +02:00
match board.move_checker(&color, cmove) {
Err(Error::FieldBlockedByOne) => {
2024-06-15 19:10:01 +02:00
let jan = if Board::is_field_in_small_jan(to) {
Jan::TrueHitSmallJan
} else {
Jan::TrueHitBigJan
};
jans.push(jan, (cmove, EMPTY_MOVE));
2024-06-13 21:18:49 +02:00
}
Err(_) => {
2024-06-15 19:10:01 +02:00
can_try_toutdune = false;
2024-06-13 21:18:49 +02:00
// let next_dice_jan = self.get_jans(&board, &dices);
// jans possibles en tout d'une après un battage à vrai :
// truehit
}
2024-06-15 19:10:01 +02:00
Ok(()) => {}
}
if can_try_toutdune {
// Try tout d'une :
// - use original board before first die move
// - use a virtual dice by adding current dice to remaining dice
2024-09-13 18:07:57 +02:00
let next_dice_jan = self.get_jans_by_ordered_dice(
2024-06-24 18:10:24 +02:00
&board_ini,
&dices.iter().map(|d| d + dice).collect(),
);
2024-06-15 19:10:01 +02:00
jans.merge(next_dice_jan);
2024-05-25 19:56:38 +02:00
}
}
2024-06-13 21:18:49 +02:00
// Second die
2024-09-13 18:07:57 +02:00
let next_dice_jan = self.get_jans_by_ordered_dice(&board_ini, &dices);
2024-05-28 18:52:49 +02:00
jans.merge(next_dice_jan);
2024-05-25 19:56:38 +02:00
}
}
}
2024-05-28 18:52:49 +02:00
2024-05-25 19:56:38 +02:00
jans
}
2024-06-15 19:10:01 +02:00
pub fn get_points(&self) -> i8 {
let mut points: i8 = 0;
2024-05-25 19:56:38 +02:00
2024-06-24 21:22:27 +02:00
// « JAN DE RÉCOMPENSE »
// Battre à vrai une dame située dans la table des grands jans
// Battre à vrai une dame située dans la table des petits jans
2024-09-13 18:07:57 +02:00
// Battre le coin adverse
2024-06-24 21:22:27 +02:00
let jans = self.get_jans(&self.board);
2024-06-15 19:10:01 +02:00
points += jans.into_iter().fold(0, |acc: i8, (jan, moves)| {
2024-09-13 18:07:57 +02:00
println!("get_points : {:?}", jan);
2024-06-15 19:10:01 +02:00
acc + jan.get_points(self.dice.is_double()) * (moves.len() as i8)
});
2024-05-25 19:56:38 +02:00
2024-06-24 21:22:27 +02:00
// « JAN DE REMPLISSAGE »
// Faire un petit jan, un grand jan ou un jan de retour
// let filling_moves_sequences = self.move_rules.get_quarter_filling_moves_sequences();
// points += 4 * filling_moves_sequences.len() as i8;
2024-05-28 18:52:49 +02:00
// cf. https://fr.wikipedia.org/wiki/Trictrac
// Points par simple par moyen | Points par doublet par moyen Nombre de moyens possibles Bénéficiaire
2024-05-25 19:56:38 +02:00
// « JAN RARE »
// Jan de six tables 4 n/a 1 Joueur
// Jan de deux tables 4 6 1 Joueur
// Jan de mézéas 4 6 1 Joueur
// Contre jan de deux tables 4 6 1 Adversaire
// Contre jan de mézéas 4 6 1 Adversaire
// « JAN QUI NE PEUT »
// Battre à faux une dame
// située dans la table des grands jans 2 4 1 Adversaire
// Battre à faux une dame
// située dans la table des petits jans 4 6 1 Adversaire
// Pour chaque dé non jouable (dame impuissante) 2 2 n/a Adversaire
// Conserver un petit jan, un grand jan ou un jan de retour 4 6 1 Joueur
// « AUTRE »
// Sortir le premier toutes ses dames 4 6 n/a Joueur
2024-05-20 19:04:46 +02:00
2024-05-25 19:56:38 +02:00
points
2024-05-20 19:04:46 +02:00
}
}
2024-05-28 18:52:49 +02:00
#[cfg(test)]
mod tests {
use super::*;
#[test]
2024-06-24 18:10:24 +02:00
fn get_jans_by_dice_order() {
2024-05-28 18:52:49 +02:00
let mut rules = PointsRules::default();
rules.board.set_positions([
2, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-09-13 18:07:57 +02:00
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]);
2024-05-28 18:52:49 +02:00
assert_eq!(1, jans.len());
2024-06-15 19:10:01 +02:00
assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
2024-05-28 18:52:49 +02:00
2024-09-13 18:07:57 +02:00
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 2]);
2024-05-28 18:52:49 +02:00
assert_eq!(1, jans.len());
2024-06-15 19:10:01 +02:00
assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
2024-05-28 18:52:49 +02:00
2024-06-24 18:10:24 +02:00
// On peut passer par une dame battue pour battre une autre dame
2024-06-15 19:10:01 +02:00
// mais pas par une case remplie par l'adversaire
2024-05-28 18:52:49 +02:00
rules.board.set_positions([
2024-06-15 19:10:01 +02:00
2, 0, -1, -2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
2024-05-28 18:52:49 +02:00
]);
2024-09-13 18:07:57 +02:00
let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]);
let jans_revert_dices = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 2]);
2024-05-28 18:52:49 +02:00
assert_eq!(1, jans.len());
2024-06-15 19:10:01 +02:00
assert_eq!(1, jans_revert_dices.len());
jans.merge(jans_revert_dices);
assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
2024-05-28 18:52:49 +02:00
rules.board.set_positions([
2, 0, -1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-09-13 18:07:57 +02:00
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]);
2024-05-28 18:52:49 +02:00
assert_eq!(1, jans.len());
2024-06-15 19:10:01 +02:00
assert_eq!(2, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
2024-05-28 18:52:49 +02:00
rules.board.set_positions([
2, 0, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-09-13 18:07:57 +02:00
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]);
2024-05-28 18:52:49 +02:00
assert_eq!(1, jans.len());
2024-06-15 19:10:01 +02:00
assert_eq!(1, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
2024-05-28 18:52:49 +02:00
rules.board.set_positions([
2, 0, 1, 1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-09-13 18:07:57 +02:00
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 3]);
2024-05-28 18:52:49 +02:00
assert_eq!(1, jans.len());
2024-06-15 19:10:01 +02:00
assert_eq!(3, jans.get(&Jan::TrueHitSmallJan).unwrap().len());
2024-06-13 21:18:49 +02:00
// corners handling
// deux dés bloqués (coin de repos et coin de l'adversaire)
rules.board.set_positions([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
// le premier dé traité est le dernier du vecteur : 1
2024-09-13 18:07:57 +02:00
let jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![2, 1]);
2024-06-13 21:18:49 +02:00
// println!("jans (dés bloqués) : {:?}", jans.get(&Jan::TrueHit));
assert_eq!(0, jans.len());
2024-06-15 19:10:01 +02:00
// dé dans son coin de repos : peut tout de même battre à vrai
2024-06-14 19:07:33 +02:00
rules.board.set_positions([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-09-13 18:07:57 +02:00
let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 3]);
2024-06-15 19:10:01 +02:00
assert_eq!(1, jans.len());
2024-06-14 19:07:33 +02:00
2024-06-13 21:18:49 +02:00
// premier dé bloqué, mais tout d'une possible en commençant par le second
rules.board.set_positions([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-09-13 18:07:57 +02:00
let mut jans = rules.get_jans_by_ordered_dice(&rules.board, &vec![3, 1]);
let jans_revert_dices = rules.get_jans_by_ordered_dice(&rules.board, &vec![1, 3]);
2024-06-13 21:18:49 +02:00
assert_eq!(1, jans_revert_dices.len());
jans.merge(jans_revert_dices);
assert_eq!(1, jans.len());
2024-06-14 19:07:33 +02:00
// print!("jans (2) : {:?}", jans.get(&Jan::TrueHit));
// battage à faux : ne pas prendre en compte si en inversant l'ordre des dés il y a battage
// à vrai
2024-05-28 18:52:49 +02:00
}
2024-06-15 19:10:01 +02:00
#[test]
fn get_points() {
2024-06-24 21:22:27 +02:00
// ----- Jan de récompense
2024-09-13 18:07:57 +02:00
// Battre à vrai une dame située dans la table des petits jans : 4 + 4 + 4 = 12
2024-06-15 19:10:01 +02:00
let mut rules = PointsRules::default();
2024-06-24 21:22:27 +02:00
rules.update_positions([
2024-06-15 19:10:01 +02:00
2, 0, -1, -1, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
2024-06-24 21:22:27 +02:00
rules.set_dice(Dice { values: (2, 3) });
assert_eq!(12, rules.get_points());
2024-09-13 18:07:57 +02:00
// Battre à vrai une dame située dans la table des grands jans : 2 + 2 = 4
let mut rules = PointsRules::default();
rules.update_positions([
2, 0, 0, -1, 2, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (2, 4) });
assert_eq!(4, rules.get_points());
// Battre à vrai le coin adverse par doublet : 6
rules.update_positions([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (2, 2) });
assert_eq!(6, rules.get_points());
// Cas de battage du coin de repos adverse impossible
rules.update_positions([
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (1, 1) });
assert_eq!(0, rules.get_points());
2024-06-24 21:22:27 +02:00
// ---- Jan de remplissage
2024-09-13 18:07:57 +02:00
// Faire un petit jan : 4
2024-06-24 21:22:27 +02:00
rules.update_positions([
3, 1, 2, 2, 3, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (2, 1) });
assert_eq!(1, rules.get_jans(&rules.board).len());
assert_eq!(4, rules.get_points());
2024-09-13 18:07:57 +02:00
// Faire un petit jan avec un doublet : 6
2024-06-24 21:22:27 +02:00
rules.update_positions([
2, 3, 1, 2, 2, 3, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (1, 1) });
assert_eq!(6, rules.get_points());
2024-09-13 18:07:57 +02:00
// Faire un petit jan avec 2 moyens : 6 + 6 = 12
2024-06-24 21:22:27 +02:00
rules.update_positions([
3, 3, 1, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (1, 1) });
2024-06-15 19:10:01 +02:00
assert_eq!(12, rules.get_points());
2024-06-24 21:22:27 +02:00
2024-09-13 18:07:57 +02:00
// Conserver un jan avec un doublet : 6
2024-06-24 21:22:27 +02:00
rules.update_positions([
3, 3, 2, 2, 2, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0,
]);
rules.set_dice(Dice { values: (1, 1) });
assert_eq!(6, rules.get_points());
2024-09-16 17:46:09 +02:00
// ---- Sorties
// Sortir toutes ses dames avant l'adversaire (simple)
rules.update_positions([
0, 0, -2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1,
]);
rules.set_dice(Dice { values: (3, 1) });
assert_eq!(4, rules.get_points());
// Sortir toutes ses dames avant l'adversaire (doublet)
rules.update_positions([
0, 0, -2, 0, 0, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0,
]);
rules.set_dice(Dice { values: (2, 2) });
assert_eq!(6, rules.get_points());
2024-09-16 17:46:09 +02:00
// ---- JANS RARES
// Jan de six tables
rules.update_positions([
10, 1, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, -1, 0,
]);
rules.set_dice(Dice { values: (2, 3) });
assert_eq!(4, rules.get_points());
// Jan de deux tables
// Jan de mézéas
// Contre jan de deux tables
// Contre jan de mézéas
// ---- JANS QUI NE PEUT
// Battre à faux une dame située dans la table des grands jans
// Battre à faux une dame située dans la table des petits jans
// Pour chaque dé non jouable (dame impuissante)
2024-06-15 19:10:01 +02:00
}
2024-05-28 18:52:49 +02:00
}