diff --git a/src/agent.rs b/src/agent.rs index ef63bdd..8c8db00 100644 --- a/src/agent.rs +++ b/src/agent.rs @@ -17,10 +17,14 @@ impl Agent for ManualAgent { fn next_move(&mut self, _: &Board) -> Option<(usize, usize)> { let stdin = io::stdin(); let mut input = String::new(); - println!("Your turn!"); + println!("Your turn! ('Skip' to skip)"); loop { input.clear(); stdin.lock().read_line(&mut input).ok()?; + if input.to_lowercase().trim() == "skip" { + // skips move + return None; + } let got = input .split_whitespace() diff --git a/src/board.rs b/src/board.rs index 678ea37..f69baa7 100644 --- a/src/board.rs +++ b/src/board.rs @@ -196,7 +196,10 @@ impl Board { } pub fn game_winner(&self, turn: Piece) -> Option { - if self.possible_moves(turn).count() > 0 { + // Wikipedia: `Players take alternate turns. If one player cannot make a valid move, play passes back to the other player. The game ends when the grid has filled up or if neither player can make a valid move.` + + if self.possible_moves(turn).next().is_some() || self.possible_moves(!turn).next().is_some() + { // player can still make a move, there is no winner return None; } diff --git a/src/complexagent.rs b/src/complexagent.rs index db2929a..80895fb 100644 --- a/src/complexagent.rs +++ b/src/complexagent.rs @@ -226,9 +226,9 @@ impl FutureMoves { let mut new_arena = Vec::new(); let mut index_map = vec![None; self.arena.len()]; - for (old_idx, _) in retain.iter().enumerate().filter(|(_, a)| **a) { + for (old_idx, _) in retain.iter().enumerate().rev().filter(|(_, a)| **a) { index_map[old_idx] = Some(new_arena.len()); - let mut node = self.arena[old_idx].clone(); + let mut node = self.arena.remove(old_idx); node.parent = node.parent.and_then(|p| index_map[p]); node.children = node.children.iter().filter_map(|&c| index_map[c]).collect(); new_arena.push(node); diff --git a/src/game.rs b/src/game.rs index b2c0cbb..cbe23e5 100644 --- a/src/game.rs +++ b/src/game.rs @@ -53,7 +53,11 @@ impl Game { } } else { println!("Player {} did not make a move!", player_i); - // TODO! break, player should not be able to skip a move + // players are able to skip a move if they have no valid moves to make + assert!( + !self.board.possible_moves(player_color).any(|_| true), + "Player skipped a move, but they had a possible move to make" + ); return; // No valid move available } } diff --git a/src/main.rs b/src/main.rs index 6506e54..5c9bb14 100644 --- a/src/main.rs +++ b/src/main.rs @@ -11,8 +11,8 @@ mod piece; fn main() { let player1 = complexagent::ComplexAgent::new(Piece::Black); // let player2 = complexagent::ComplexAgent::new(Piece::White); - // let player2 = agent::ManualAgent::new(Piece::White); - let player2 = agent::RandomAgent::new(Piece::White); + let player2 = agent::ManualAgent::new(Piece::White); + // let player2 = agent::RandomAgent::new(Piece::White); let mut game = Game::new(Box::new(player1), Box::new(player2)); game.game_loop(); }