1use std::str::FromStr;
4
5use crate::pieces::stones::Color;
6use crate::pieces::util::coord::{Coord, Size};
7use crate::pieces::Nat;
8
9#[cfg(feature = "deadstones")]
10mod dead_stones;
11pub mod game;
12pub mod game_builder;
13mod sgf_bridge;
14
15#[derive(Debug, PartialEq, Eq, Clone, Copy)]
16pub enum GobanSizes {
17 Nineteen,
18 Nine,
19 Thirteen,
20 Custom(usize, usize),
21}
22
23impl From<GobanSizes> for Size {
24 fn from(goban_sizes: GobanSizes) -> Size {
25 match goban_sizes {
26 GobanSizes::Nine => (9, 9),
27 GobanSizes::Thirteen => (13, 13),
28 GobanSizes::Nineteen => (19, 19),
29 GobanSizes::Custom(height, width) => (height as u8, width as u8),
30 }
31 }
32}
33
34impl From<usize> for GobanSizes {
35 fn from(x: usize) -> Self {
36 match x {
37 9 => GobanSizes::Nine,
38 13 => GobanSizes::Thirteen,
39 19 => GobanSizes::Nineteen,
40 _ => panic!("Not implemented for others size than 9,13,19"),
41 }
42 }
43}
44
45#[derive(Debug, PartialEq, Eq, Clone, Copy, Hash)]
47pub enum Move {
48 Pass,
49 Resign(Color),
50 Play(Nat, Nat),
51}
52
53impl From<Coord> for Move {
54 fn from((x0, x1): Coord) -> Self {
55 Move::Play(x0, x1)
56 }
57}
58
59#[derive(Debug, Clone, PartialEq, Copy)]
60pub enum EndGame {
61 WinnerByScore(Color, f32),
62 WinnerByResign(Color),
63 WinnerByTime(Color),
64 WinnerByForfeit(Color),
65 Draw,
66}
67
68impl EndGame {
69 #[inline]
71 pub const fn get_winner(self) -> Option<Color> {
72 match self {
73 EndGame::WinnerByScore(p, _)
74 | EndGame::WinnerByResign(p)
75 | EndGame::WinnerByTime(p)
76 | EndGame::WinnerByForfeit(p) => Some(p),
77 EndGame::Draw => None,
78 }
79 }
80}
81
82#[derive(Clone, Eq, PartialEq, Debug, Copy)]
83pub enum PlayError {
84 Ko,
85 Suicide,
86 GamePaused,
87 FillEye,
88 PointNotEmpty,
89}
90
91type FlagUInt = u32;
92bitflags! {
93 pub struct IllegalRules: FlagUInt{
95 const KO = 1;
97 const SUPERKO = 1 << 1;
99 const SUICIDE = 1 << 2;
101 const FILLEYE = 1 << 3;
103 }
104}
105bitflags! {
106 pub struct ScoreRules : FlagUInt {
108 const STONES = 1;
110 const KOMI = 1 << 1;
112 const PRISONNERS = 1 << 2;
114 }
115}
116
117#[derive(Copy, Clone, Debug, PartialEq)]
118pub struct Rule {
119 pub komi: f32,
120 pub flag_illegal: IllegalRules,
121 pub flag_score: ScoreRules,
122}
123
124pub static JAPANESE: Rule = Rule {
125 komi: 6.5,
126 flag_illegal: IllegalRules::from_bits_truncate(
127 IllegalRules::KO.bits() | IllegalRules::SUICIDE.bits(),
128 ),
129 flag_score: ScoreRules::from_bits_truncate(
130 ScoreRules::KOMI.bits() | ScoreRules::PRISONNERS.bits(),
131 ),
132};
133
134pub static CHINESE: Rule = Rule {
135 komi: 7.5,
136 flag_illegal: IllegalRules::from_bits_truncate(
137 IllegalRules::KO.bits() | IllegalRules::SUPERKO.bits() | IllegalRules::SUICIDE.bits(),
138 ),
139 flag_score: ScoreRules::from_bits_truncate(ScoreRules::KOMI.bits() | ScoreRules::STONES.bits()),
140};
141
142impl FromStr for Rule {
143 type Err = String;
144
145 fn from_str(s: &str) -> Result<Self, Self::Err> {
146 match s {
147 "JAP" => Ok(JAPANESE),
148 "CHI" => Ok(CHINESE),
149 _ => Err(format!("The rule {s} is not implemented yet.")),
150 }
151 }
152}