diff options
| author | tslil clingman <> | 2020-01-20 23:41:44 -0800 |
|---|---|---|
| committer | tslil clingman <> | 2020-01-20 23:41:44 -0800 |
| commit | fa04cc6ecf3ac1b4b8e8561c5969ee64f09f59fa (patch) | |
| tree | d96b2cae013ba5b42b4bf4366474b65367ffd95a /src/parser.rs | |
| parent | ec4ae2a749315720cc12f3d71f0860e2a32f96d2 (diff) | |
Some bug in moving tall stacks ... ?
Diffstat (limited to 'src/parser.rs')
| -rw-r--r-- | src/parser.rs | 64 |
1 files changed, 45 insertions, 19 deletions
diff --git a/src/parser.rs b/src/parser.rs index a1d9a32..73457f0 100644 --- a/src/parser.rs +++ b/src/parser.rs @@ -1,6 +1,6 @@ use crate::game::*; -fn parse_move(player: Player, mv: &str) -> Result<Action, String> { +fn parse_move(mv: &str, game: &Game) -> Result<Action, String> { let mut chars = mv.chars(); let c = chars.next(); @@ -9,19 +9,28 @@ fn parse_move(player: Player, mv: &str) -> Result<Action, String> { } let dc = c.unwrap(); - if (dc < '1') || ('9' < dc) { - return Err(String::from( - "Moves must begin with a digit in 1-8 indicating the number of drops.", - )); - } - let sum_drops = dc.to_digit(10).unwrap(); + let sum_drops: u8; + let x; + if (dc >= 'a') && (dc <= 'h') { + // Drop number omitted, must be 1 drop. + sum_drops = 1; + x = dc; + } else { + if (dc < '1') || ('9' < dc) { + return Err(String::from( + "Moves must begin with a digit in 1-8 indicating the number of drops.", + )); + } + sum_drops = dc.to_digit(10).unwrap() as u8; - let c = chars.next(); - if c.is_none() { - return Err(String::from("Moves must specify a stack position.")); + let c = chars.next(); + if c.is_none() { + return Err(String::from("Moves must specify a stack position.")); + } + + x = c.unwrap(); } - let x = c.unwrap(); if (x < 'a') || (x > 'h') { return Err(String::from( "Moves must specify a valid position on the game board.", @@ -48,7 +57,9 @@ fn parse_move(player: Player, mv: &str) -> Result<Action, String> { } let c = c.unwrap(); - let dir; // This is so cool! Rust supports some very nice patterns! + // This is so cool! Rust supports some very nice patterns, and + // checks for uninitialised variables too! + let dir; match c { '+' => dir = Direction::Up, '-' => dir = Direction::Down, @@ -75,17 +86,28 @@ fn parse_move(player: Player, mv: &str) -> Result<Action, String> { } let sum = drops.iter().map(|&d| d as u32).sum::<u32>(); - if sum != sum_drops { + let pos = Position { x: x, y: y }; + if sum == 0 { + // Omitted all the drops, it's a total stack move + drops.push(0); + if let Some(stack) = game.query_square(&pos) { + drops.push(std::cmp::min(stack.len() as u8, game.get_size())); + } else { + return Err(String::from( + "Moves must specify a valid position on the game board.", + )); + } + } else if sum != sum_drops as u32 { return Err(format!( "The move called for {} stones, but {} were dropped.", sum_drops, sum )); } - Ok(Action::Move(player, Position { x: x, y: y }, dir, drops)) + Ok(Action::Move(game.query_stone_owner(), pos, dir, drops)) } -fn parse_place(player: Player, pl: &str) -> Result<Action, String> { +fn parse_place(pl: &str, game: &Game) -> Result<Action, String> { let mut chars = pl.chars(); let c = chars.next(); @@ -139,16 +161,20 @@ fn parse_place(player: Player, pl: &str) -> Result<Action, String> { } let y: u8 = (y.to_digit(10).unwrap() - 1) as u8; - Ok(Action::Place(player, Position { x: x, y: y }, stone)) + Ok(Action::Place( + game.query_stone_owner(), + Position { x: x, y: y }, + stone, + )) } -pub fn parse_action(player: Player, act: &str) -> Result<Action, String> { +pub fn parse_action(game: &Game, act: &str) -> Result<Action, String> { if act .chars() .any(|c| c == '+' || c == '-' || c == '>' || c == '<') { - parse_move(player, act) + parse_move(act, game) } else { - parse_place(player, act) + parse_place(act, game) } } |
