diff options
| author | tslil clingman <> | 2020-01-12 16:08:47 -0500 |
|---|---|---|
| committer | tslil clingman <> | 2020-01-12 16:08:47 -0500 |
| commit | 67ca3fc5f9280c8a6fa4623efc4b60ba554a2bc4 (patch) | |
| tree | cde81509dbbcbda1322a417a2f67440f2d4c47b1 /src/board.rs | |
| parent | 5ae986b316b0be692e79203f79a00a8afdd71a77 (diff) | |
Factoring and loggin
Diffstat (limited to 'src/board.rs')
| -rw-r--r-- | src/board.rs | 140 |
1 files changed, 88 insertions, 52 deletions
diff --git a/src/board.rs b/src/board.rs index 9ba89dc..bd86c12 100644 --- a/src/board.rs +++ b/src/board.rs @@ -1,5 +1,16 @@ use std::fmt; +// #[derive(Clone, Copy)] +pub struct Position { + pub x: u8, + pub y: u8, +} +impl fmt::Display for Position { + fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { + write!(f, "{:x}{}", 10 + self.x, self.y) + } +} + #[derive(PartialEq)] pub enum Player { Black, @@ -40,16 +51,7 @@ impl fmt::Display for Stone { } } -pub struct Position { - pub x: u8, - pub y: u8, -} -impl fmt::Display for Position { - fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result { - write!(f, "{:x}{}", 10 + self.x, self.y) - } -} - +// #[derive(Clone, Copy)] pub enum Direction { Up, Down, @@ -103,40 +105,68 @@ pub struct Board { board: Vec<Stack>, } -// Probably it's best to split the move and place actions into their -// own methods, they should also take an extra argument which can be -// used to log error messages - // How to solve code duplication between is_legal_action and // perform_action? // TODO: Generate all legal actions for a given player +pub type Logger = fn(&str); + impl Board { - fn lookup(&self, pos: &Position) -> Option<&Stack> { + fn remaining_pieces(&self, player: &Player, stone: &Stone) -> u8 { + match player { + Player::Black => { + if *stone == Stone::Capstone { + self.black_capstones + } else { + self.black_flats + } + } + Player::White => { + if *stone == Stone::Capstone { + self.white_capstones + } else { + self.white_flats + } + } + } + } + + fn lookup_square(&self, pos: &Position) -> Option<&Stack> { let y: u16 = pos.y as u16; let x: u16 = pos.x as u16; self.board.get((x + y * self.size) as usize) } - fn is_legal_action(&self, mov: &Action) -> bool { - match mov { - Action::Place(player, pos, piece) => match self.lookup(pos) { - Some(stack) => { - // Incomplete and incorrect, must take account of - // piece availabilty - if stack.len() == 0 { - true - } else { - false - } + fn is_legal_place(&self, player: &Player, pos: &Position, stone: &Stone, log: Logger) -> bool { + /* In order to legally place a piece: + 1. The desired square must be empty + 2. The player must have sufficient pieces + */ + match self.lookup_square(pos) { + Some(stack) => { + if (stack.len() > 0) || (self.remaining_pieces(player, stone) == 0) { + log("Not"); + false + } else { + true } - None => false, - }, - Action::Move(player, pos, direction, drops) => match self.lookup(pos) { - Some(stack) => { - /* Rules for moving a stack: - 0. There are stones + } + None => false, + } + } + + fn is_legal_move( + &self, + player: &Player, + pos: &Position, + direction: &Direction, + drops: &Vec<u8>, + ) -> bool { + match self.lookup_square(pos) { + Some(stack) => { + /* Rules for moving a stack: + 0. There are stones 1. Top stone belongs to player 2. Zero or One stones dropped on starting square 3. Total number of stones moved does not exceed the carry capacity @@ -146,28 +176,34 @@ impl Board { We check 0,1,2, and 3 first */ - if (stack.len() == 0) - || (drops.len() == 0) - || (stack[0].0 != *player) - || (drops[0] > 1) - || (drops.iter().sum::<u8>() as u16 > self.size) - { - false - } else { - let steps: usize = drops.len() - 1; - let cap: bool = stack[0].1 == Stone::Capstone; - let (dy, dx): (i8, i8) = match direction { - Direction::Up => (1, 0), - Direction::Down => (-1, 0), - Direction::Left => (0, -1), - Direction::Right => (0, 1), - }; + if (stack.len() == 0) + || (drops.len() == 0) + || (stack[0].0 != *player) + || (drops[0] > 1) + || (drops.iter().sum::<u8>() as u16 > self.size) + { + false + } else { + let steps: usize = drops.len() - 1; + let cap: bool = stack[0].1 == Stone::Capstone; + let (dy, dx): (i8, i8) = match direction { + Direction::Up => (1, 0), + Direction::Down => (-1, 0), + Direction::Left => (0, -1), + Direction::Right => (0, 1), + }; - false - } + false } - None => false, - }, + } + None => false, + } + } + + fn is_legal_action(&self, mov: &Action, log: Logger) -> bool { + match mov { + Action::Place(player, pos, stone) => self.is_legal_place(player, pos, stone, log), + Action::Move(player, pos, direction, drops) => false, } } } |
