1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use crate::{Board, Color, Error, Hand, Square};
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
pub enum Action {
Move { from: Square, to: Square },
PlaceFromHand { index: usize, to: Square },
}
#[derive(PartialEq, Eq, PartialOrd, Ord, Clone, Copy, Debug)]
pub enum Status {
OnGoing,
BlackWins,
WhiteWins,
}
#[derive(Clone, Debug)]
pub struct Game {
board: Board,
hands: [Hand; Color::NUM],
turn: Color,
status: Status,
}
impl Game {
pub fn new() -> Self {
Self {
board: Board::new(),
hands: [Hand::new(Color::Black), Hand::new(Color::White)],
turn: Color::Black,
status: Status::OnGoing,
}
}
pub fn board(&self) -> &Board {
&self.board
}
pub fn hand(&self, color: Color) -> &Hand {
&self.hands[color as usize]
}
pub fn turn(&self) -> Color {
self.turn
}
pub fn status(&self) -> Status {
self.status
}
pub fn execute(&mut self, action: Action) -> Result<Status, Error> {
match self.status {
Status::OnGoing => {}
Status::BlackWins => {
return Ok(Status::BlackWins);
}
Status::WhiteWins => {
return Ok(Status::WhiteWins);
}
};
let result;
match action {
Action::Move { from, to } => match self.board.r#move(from, to) {
Ok(board) => {
self.board = board;
}
Err(err) => {
return Err(err);
}
},
Action::PlaceFromHand { index, to } => {
if let Some(&piece) = self.hands[self.turn as usize].peek(index) {
match self.board.place(piece, to) {
Ok(board) => {
self.hands[self.turn as usize].pop(index);
self.board = board;
}
Err(err) => {
return Err(err);
}
};
}
}
};
if self.board.has_won(Color::Black) {
self.status = Status::BlackWins;
}
if self.board.has_won(Color::White) {
self.status = Status::WhiteWins;
}
self.change_turn();
result = Ok(self.status);
result
}
fn change_turn(&mut self) {
self.turn = self.turn.reverse();
}
}