diff --git a/src/uno_logic.rs b/src/uno_logic.rs index f42e836..edca3a7 100644 --- a/src/uno_logic.rs +++ b/src/uno_logic.rs @@ -41,10 +41,17 @@ pub enum Direction { COUNTER_CLOCKWISE, } +pub enum TURN_RESULT{ + NEXT_TURN, + REPEAT_TURN, + GAME_OVER +} + #[derive(Clone)] pub struct PlayerState<'a> { pub player_name: &'a str, pub cards: Vec, + pub said_uno : bool, } pub struct PlayerConnection<'a>{ @@ -121,6 +128,7 @@ impl PlayerState<'_> { PlayerState { player_name: player_name, cards: cards, + said_uno : false, } } } @@ -138,6 +146,10 @@ impl PlayerConnection<'_> { impl GameState<'_>{ + fn cards_left(player : &PlayerState) -> usize{ + return player.cards.len(); + } + fn next_player(&mut self) { if self.current_direction == Direction::CLOCKWISE{ if self.current_turn+1 >= self.player_states.len() as u32{ @@ -181,7 +193,7 @@ impl GameState<'_>{ fn play(player : &mut PlayerState, card_to_be_played : Card) -> Result{ if player.cards.contains(&card_to_be_played){ - return Ok(player.cards.remove(player.cards.iter().position(|x| *x == card_to_be_played).expect("game integrity compromised"))); + return Ok(player.cards.remove(player.cards.iter().position(|x| *x == card_to_be_played).expect(&GAME_INTEGRITY_ERROR))); } else { return Err(String::from("Card not held by player")); @@ -196,30 +208,30 @@ impl GameState<'_>{ } } - pub fn next_turn(mut self, card_to_be_played : Card) -> Result{ + pub fn next_turn(mut self, card_to_be_played : Card) -> TURN_RESULT{ if self.turns == 0 { self.game_init(); - return Ok(String::from("Game initialized")); + return TURN_RESULT::NEXT_TURN; } - if !GameState::has_any_moves(&self, self.player_states.get(self.current_turn as usize).expect(GAME_INTEGRITY_ERROR).to_owned()){ + if !GameState::has_any_moves(&self, self.player_states.get(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR).to_owned()){ let player = &mut self.player_states.clone(); if !GameState::check_if_legal(self.current_card, self.draw(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), 1).get(0).expect(&GAME_INTEGRITY_ERROR).to_owned(), self.current_color){ self.next_player(); - return Ok(String::from("Next turn")); + return TURN_RESULT::NEXT_TURN; } let mut player = self.player_states.clone(); - self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), card_to_be_played).expect("game integrity compromised")); + self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), card_to_be_played).expect(&GAME_INTEGRITY_ERROR)); } if !GameState::check_if_legal(self.current_card, card_to_be_played, self.current_color){ - return Err(String::from("Please learn the rules at https://www.unorules.com/")); + return TURN_RESULT::REPEAT_TURN; } if self.current_card.value == CardValue::PLUS_TWO && card_to_be_played.value != CardValue::PLUS_TWO{ let player = &mut self.player_states.clone(); - self.draw(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), self.plus_twos); + self.draw(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), self.plus_twos); } else if self.current_card.value == CardValue::PLUS_TWO && card_to_be_played.value == CardValue::PLUS_TWO { self.plus_twos+=1; @@ -227,20 +239,26 @@ impl GameState<'_>{ self.current_color = card_to_be_played.color; } let mut player = self.player_states.clone(); - self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), card_to_be_played).expect("game integrity compromised")); + self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), card_to_be_played).expect(&GAME_INTEGRITY_ERROR)); self.next_player(); - return Ok(String::from("Next turn")); + return TURN_RESULT::NEXT_TURN; } if self.current_card.value == CardValue::PLUS_FOUR{ let mut player = self.player_states.clone(); - self.draw(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), 4); + self.draw(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), 4); } if self.current_card.value == CardValue::SKIP{ self.next_player(); self.turns+=1; - return Ok(String::from("Next turn")); + return TURN_RESULT::NEXT_TURN + } + let mut player = self.player_states.clone(); + if player.get(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR).said_uno == true && GameState::cards_left(player.get(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR)) == 1{ + self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), card_to_be_played).expect(&GAME_INTEGRITY_ERROR)); + self.turns+=1; + return TURN_RESULT::GAME_OVER; } if card_to_be_played.value == CardValue::REVERSE{ @@ -261,10 +279,11 @@ impl GameState<'_>{ } let mut player = self.player_states.clone(); - self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), card_to_be_played).expect("game integrity compromised")); + self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), card_to_be_played).expect(&GAME_INTEGRITY_ERROR)); + self.current_card = card_to_be_played; self.turns+=1; self.next_player(); - return Ok(String::from("Next turn")); + return TURN_RESULT::NEXT_TURN; } fn new_game_helper<'a>(player_states: Vec>, player_connections: Vec>) -> GameState<'a>{ @@ -299,7 +318,7 @@ impl GameState<'_>{ fn reset_deck(&mut self, currently_held : Vec) -> Deck{ self.deck = GameState::base_deck(); for current_cart in currently_held{ - self.deck.remove(self.deck.iter().position(|x| *x == current_cart).expect("game integrity compromised")); + self.deck.remove(self.deck.iter().position(|x| *x == current_cart).expect(&GAME_INTEGRITY_ERROR)); } return vec![]; }