diff --git a/src/lib.rs b/src/lib.rs index 3e1527d..a252b4d 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -3,6 +3,7 @@ use std::{ arch::global_asm, clone, io::{ prelude::*, BufReader, BufWriter, WriterPanicked }, net::{ TcpListener, TcpStream }, usize, vec }; use rand::Rng; +const GAME_INTEGRITY_ERROR : &'static str = "game integrity compromised"; #[derive(Clone)] pub struct PlayerState<'a> { @@ -110,6 +111,19 @@ pub struct GameState<'a>{ impl GameState<'_>{ + fn has_any_moves(&self, player : PlayerState) -> bool{ + for card in player.cards{ + if GameState::check_if_legal(self.current_card.clone(), card, self.current_color.clone()){ + return true; + } + } + return false; + } + + fn add_to_trash<'a>(&mut self, card : Card){ + self.trash.push(card); + } + 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"))); @@ -143,35 +157,45 @@ impl GameState<'_>{ if !GameState::check_if_legal(self.current_card.clone(), card_to_be_played.clone(), self.current_color.clone()){ return Err(String::from("Please learn the rules at https://www.unorules.com/")); } + + if !GameState::has_any_moves(&self, self.player_states.get(self.current_turn as usize).expect(GAME_INTEGRITY_ERROR).to_owned()){ + let mut player = &mut self.player_states.clone(); + if !GameState::check_if_legal(self.current_card.clone(), 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.clone()){ + return Ok(String::from("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.clone()).expect("game integrity compromised")); + } let card = self.current_card.clone(); let card_value = card.value; if card_value == CardValue::PLUS_TWO && card_to_be_played.value != CardValue::PLUS_TWO{ - let current_turn = self.current_turn; - let plus_twos = self.plus_twos*2; let player = &mut self.player_states.clone(); - self.draw(player.get_mut(current_turn as usize).expect("game integrity compromised"), plus_twos) + self.draw(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), self.plus_twos); } else if card_value == CardValue::PLUS_TWO && card_to_be_played.value == CardValue::PLUS_TWO { self.plus_twos+=1; - if self.current_color != card_to_be_played.color{ + if self.current_color != card_to_be_played.color.clone(){ self.current_color = card_to_be_played.color; } return Ok(String::from("Next turn")); } if self.current_card.value == CardValue::PLUS_FOUR{ - let current_turn = self.current_turn as usize; let mut player = self.player_states.clone(); - self.draw(player.get_mut(current_turn).expect("game integrity compromised"), 4); + self.draw(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), 4); } - else if card_value == CardValue::CHANGE_COLOR { - self.current_color = card_to_be_played.color_change; + if card_value == CardValue::CHANGE_COLOR { + self.current_color = card_to_be_played.clone().color_change; } else if card_value == CardValue::PLUS_FOUR{ self.current_color = card_to_be_played.color; - + } else if [CardValue::EIGHT, CardValue::FIVE, CardValue::FOUR, CardValue::NINE, CardValue::ONE, CardValue::SEVEN, CardValue::SIX, CardValue::THREE, CardValue::TWO, CardValue::ZERO, CardValue::PLUS_TWO].contains(&card_value) { + if card_to_be_played.color != self.current_color{ + self.current_color = card_to_be_played.color.clone(); + } + 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.turns+=1; return Ok(String::from("Next turn")); } @@ -314,13 +338,14 @@ impl GameState<'_>{ return cards_drawn } - pub fn draw(&mut self, player : &mut PlayerState, count : u32) -> (){ + pub fn draw(&mut self, player : &mut PlayerState, count : u32) -> Vec{ if self.deck.len() <= count as usize{ let currently_held = self.get_currently_held(); self.reset_deck(currently_held); } let mut cards_drawn = self.get_cards(count); player.cards.append(&mut cards_drawn); + return cards_drawn; }