use crate::GameState;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub struct Game {
pub now_turn: bool,
pub turns: u8,
pub game_board: [SquareState; 64],
pub game_state: GameState,
}
impl Game {
pub fn new(nt: bool, t: u8, gb: [SquareState; 64], sf: GameState) -> Self {
Game {
now_turn: nt,
turns: t,
game_board: gb,
game_state: sf,
}
}
pub fn proceed_one_turn(&mut self, x: isize, y: isize) {
if self.game_state == GameState::NonePutPoint {
self.game_state = GameState::Running;
}
if self.can_put_stone(x, y) {
self.put_stone(x, y);
self.turns += 1;
self.now_turn = !self.now_turn;
} else {
println!("You can't put there");
return;
}
if self.should_be_pass() {
self.turns += 1;
self.now_turn = !self.now_turn;
self.game_state = GameState::NonePutPoint;
if self.should_be_pass() {
let game_result = self.count_stone();
if game_result.0 > game_result.1 {
self.game_state = GameState::BlackWin;
} else {
self.game_state = GameState::WhiteWin;
}
}
}
}
fn can_put_stone(&self, x: isize, y: isize) -> bool {
let di_num: [(isize, isize); 8] =
[(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)];
let mut now_result: bool = false;
if self.get_index(x, y).unwrap() == SquareState::NoneSquare {
let enemy_color: SquareState = self.now_color().get_reversed();
for dn in di_num.iter() {
let mut x_sub = x.clone();
let mut y_sub = y.clone();
if self.get_index(x_sub+dn.0, y_sub+dn.1).is_err() {
continue;
}
if self.get_index(x_sub+dn.0, y_sub+dn.1).unwrap() == enemy_color {
x_sub += dn.0;
y_sub += dn.1;
if self.get_index(x_sub, y_sub).is_err() {
continue;
}
while self.get_index(x_sub, y_sub).unwrap() == enemy_color {
x_sub += dn.0;
y_sub += dn.1;
if self.get_index(x_sub, y_sub).is_err() {
break;
}
}
if self.get_index(x_sub, y_sub).unwrap() == self.now_color() {
now_result |= true;
} else {
now_result |= false;
}
} else {
now_result = false || now_result;
continue;
}
}
} else {
now_result = false && now_result;
}
now_result
}
fn put_stone(&mut self, x: isize, y: isize) {
if !self.can_put_stone(x, y) {
panic!("You can't put there");
}
let list_change_stone: Vec<(isize, isize)> = self.enum_change_stone(x, y);
let index: isize = x + 8 * y - 9;
self.game_board[index as usize] = self.now_color();
for lcs in list_change_stone.into_iter() {
self.reverse_square(lcs.0, lcs.1);
}
}
fn enum_change_stone(&self, x: isize, y: isize) -> Vec<(isize, isize)> {
let mut change_point: Vec<(isize, isize)> = Vec::new();
let mut chp: Vec<(isize, isize)> = Vec::new();
let di_num: [(isize, isize); 8] =
[(0, -1), (1, -1), (1, 0), (1, 1), (0, 1), (-1, 1), (-1, 0), (-1, -1)];
if self.get_index(x, y).unwrap() == SquareState::NoneSquare {
let enemy_color: SquareState = self.now_color().get_reversed();
for dn in di_num.iter() {
let mut x_sub = x.clone();
let mut y_sub = y.clone();
if self.get_index(x_sub+dn.0, y_sub+dn.1).is_err() {
continue;
}
if self.get_index(x_sub+dn.0, y_sub+dn.1).unwrap() == enemy_color {
x_sub += dn.0;
y_sub += dn.1;
if self.get_index(x_sub, y_sub).is_err() {
continue;
}
while self.get_index(x_sub, y_sub).unwrap() == enemy_color {
chp.push((x_sub, y_sub));
x_sub += dn.0;
y_sub += dn.1;
if self.get_index(x_sub, y_sub).is_err() {
chp.clear();
break;
}
}
if self.get_index(x_sub, y_sub).unwrap() == self.now_color() {
change_point.append(&mut chp);
} else {
chp.clear();
}
} else {
continue;
}
}
} else {
panic!("you select square where not none");
}
change_point
}
fn reverse_square(&mut self, x: isize, y: isize) {
let t: isize = x + 8 * y - 9;
if self.game_board[t as usize] == SquareState::White {
self.game_board[t as usize] = SquareState::Black;
} else {
self.game_board[t as usize] = SquareState::White;
}
}
fn should_be_pass(&mut self) -> bool {
let mut result = true;
for y in 1..8 {
for x in 1..8 {
if self.can_put_stone(x, y) {
result = false;
break;
}
}
}
result
}
fn code_to_board(code: &str) -> [SquareState; 64] {
let mut result_board: [SquareState; 64] = [SquareState::NoneSquare; 64];
let mut i: usize = 0;
for c in code.chars() {
if c.to_string() == "/" {
continue;
}
if c.to_digit(10).is_some() {
let blank_zone: u32 = c.to_digit(10).unwrap();
for b in 0..blank_zone {
result_board[i] = SquareState::NoneSquare;
i = i + 1;
}
continue;
}
let cs: String = c.to_string();
let ctoken: &str = &cs;
result_board[i] = Game::char_to_square(ctoken);
i = i + 1;
}
result_board
}
fn char_to_square(w: &str) -> SquareState {
let mut result: SquareState = SquareState::NoneSquare;
match w {
"n" => result = SquareState::NoneSquare,
"b" => result = SquareState::Black,
"w" => result = SquareState::White,
_ => result = SquareState::NoneSquare,
}
result
}
fn get_index(&self, x: isize, y: isize) -> Result<SquareState, &str> {
if x < 1 || x > 8 || y < 1 || y > 8 {
return Err("Illegal number");
}
let i: isize = x + 8 * y - 9;
Ok(self.game_board[i as usize])
}
fn now_color(&self) -> SquareState {
if self.now_turn {
SquareState::Black
} else {
SquareState::White
}
}
fn count_stone(&self) -> (usize, usize) {
let mut black: usize = 0;
let mut white: usize = 0;
for y in 1..8 {
for x in 1..8 {
match self.get_index(x, y).unwrap() {
SquareState::Black => black += 1,
SquareState::White => white += 1,
_ => black += 0
}
}
}
(black, white)
}
pub fn print_now_board(&self) -> String {
let mut now_board_string = String::from("\n a b c d e f g h \n |-----------------|\n");
let mut board_char = " ";
let mut line_string = String::from("");
let mut square_counter = 0;
let mut line_counter = 0;
for s in self.game_board.iter() {
if (square_counter+1) % 8 == 1 {
line_string += &(format!("{}", line_counter+1) + " |");
}
match s {
SquareState::NoneSquare => board_char = " ",
SquareState::White => board_char = "⚫",
SquareState::Black => board_char = "⚪"
}
line_string += board_char;
if (square_counter+1) % 8 == 0 {
line_string += "|\n";
line_counter += 1;
now_board_string = format!("{}{}", now_board_string, line_string);
line_string = String::from("");
}
square_counter += 1;
}
now_board_string + " |-----------------\n"
}
}
impl Default for Game {
fn default() -> Self {
let g_board = [
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::White, SquareState::Black,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::Black, SquareState::White,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare, SquareState::NoneSquare,
];
Game {
now_turn: true,
turns: 0,
game_board: g_board,
game_state: GameState::Neutral,
}
}
}
#[derive(PartialEq, Eq, Clone, Copy, Debug)]
pub enum SquareState {
NoneSquare,
Black,
White,
}
impl SquareState {
pub fn get_reversed(&self) -> Self {
let mut result: SquareState = SquareState::NoneSquare;
match self {
SquareState::Black => SquareState::White,
SquareState::White => SquareState::Black,
_ => SquareState::NoneSquare,
}
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_char_to_square() {
assert_eq!(SquareState::NoneSquare, Game::char_to_square("n"));
assert_eq!(SquareState::Black, Game::char_to_square("b"));
assert_eq!(SquareState::White, Game::char_to_square("w"));
}
#[test]
fn test_code_to_board() {
assert_eq!(Game::default(), Game::new(true, 0, Game::code_to_board("/8/8/8/3wb3/3bw3/8/8/8/"), GameState::Neutral));
}
#[test]
fn test_get_index() {
let sample_game = Game::default();
assert_eq!(SquareState::NoneSquare, sample_game.get_index(1, 1).unwrap());
assert_eq!(SquareState::White, sample_game.get_index(4, 4).unwrap());
}
#[test]
fn test_can_put_stone() {
let example_default_game = Game::default();
let example_ellegal_game = Game::new(true, 0,
Game::code_to_board("/wwww4/8/8/bwww1wwb/3b4/2b5/1b6/8/"), 0);
let check_diagonal_game = Game::new(true, 1,
Game::code_to_board("/8/8/8/3bb3/3ww3/8/8/8"), 0);
assert_eq!(true, example_default_game.can_put_stone(3, 4));
assert_eq!(true, example_ellegal_game.can_put_stone(5, 4));
assert_eq!(true, check_diagonal_game.can_put_stone(3, 6));
}
#[test]
#[should_panic]
fn test_can_put_stone_should_panic() {
let example_ellegal_game = Game::new(true, 0, Game::code_to_board("/wwww4/8/8/bwww1wwb/8/8/8/8/"), GameState::Running);
let x = example_ellegal_game.can_put_stone(5, 1);
}
#[test]
fn test_count_stone() {
let default_game = Game::default();
assert_eq!((2, 2), default_game.count_stone());
}
#[test]
fn test_enum_change_stone() {
let default_game = Game::default();
assert_eq!(vec![(5, 5)], default_game.enum_change_stone(5, 6));
}
#[test]
fn test_enum_change_stone_part2() {
let sample_game = Game::new(true, 0, Game::code_to_board("/bwwww3/8/8/8/8/8/8/8/"), GameState::Running);
assert_eq!(vec![(5, 1), (4, 1), (3, 1), (2, 1)], sample_game.enum_change_stone(6, 1));
}
#[test]
fn test_put_stone() {
let mut sample_game = Game::new(true, 0, Game::code_to_board("/bwwww3/8/8/8/8/8/8/8/"), GameState::Running);
sample_game.put_stone(6, 1);
assert_eq!(Game::new(true, 0, Game::code_to_board("/bbbbbb2/8/8/8/8/8/8/8/"), GameState::Running), sample_game);
}
#[test]
fn test_print_now_board() {
let default_game = Game::default();
assert_eq!(
"
a b c d e f g h
|-----------------|
1 | |
2 | |
3 | |
4 | ⚫⚪ |
5 | ⚪⚫ |
6 | |
7 | |
8 | |
|-----------------\n"
,
default_game.print_now_board()
);
}
}