diff --git a/src/lib.rs b/src/lib.rs index 4fd52a1..438f5d6 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -1,401 +1 @@ -extern crate rand; -use std::{ - io::{ BufReader, BufWriter }, net::TcpStream, usize, vec -}; -use rand::Rng; -const GAME_INTEGRITY_ERROR : &'static str = "game integrity compromised"; - -#[derive(Clone)] -pub struct PlayerState<'a> { - pub player_name: &'a str, - pub cards: Vec, -} - -pub struct PlayerConnection<'a>{ - player_name : &'a str, - reader: BufReader, - writer: BufWriter, -} - -impl PlayerState<'_> { - pub fn new(player_name : &str, cards : Vec) -> PlayerState{ - PlayerState { - player_name: player_name, - cards: cards, - } - } -} - - -impl PlayerConnection<'_> { - pub fn new(player_name : &str, reader : BufReader, writer : BufWriter) -> PlayerConnection{ - PlayerConnection { - player_name : player_name, - reader : reader, - writer : writer - } - } -} - -pub struct Card { - value: CardValue, - color: CardColors, - color_change : CardColors, -} - -impl PartialEq for Card{ - fn eq(&self, other: &Self) -> bool { - self.value == other.value && self.color == other.color - } -} - -impl Copy for Card {} - -type Deck = Vec; - -#[derive(Clone)] -enum CardColors { - RED, - BLUE, - GREEN, - YELLOW, - BLACK, -} - -impl Copy for CardColors {} - -impl Copy for CardValue {} - -impl PartialEq for CardColors{ - fn eq(&self, other: &Self) -> bool { - core::mem::discriminant(self) == core::mem::discriminant(other) - } -} - -impl Clone for Card { - fn clone(&self) -> Self { - Self { value: self.value.clone(), color: self.color.clone(), color_change: self.color_change.clone() } - } -} -#[derive(Clone)] -enum CardValue { - PLUS_TWO, - PLUS_FOUR, - ZERO, - ONE, - TWO, - THREE, - FOUR, - FIVE, - SIX, - SEVEN, - EIGHT, - NINE, - REVERSE, - SKIP, - CHANGE_COLOR, -} - -impl PartialEq for CardValue{ - fn eq(&self, other: &Self) -> bool { - core::mem::discriminant(self) == core::mem::discriminant(other) - } -} - -pub struct GameState<'a>{ - pub turns : u64, - pub current_turn : u32, - deck : Deck, - trash : Deck, - pub current_card : Card, - player_states : Vec>, - player_connections : Vec>, - current_color : CardColors, - current_direction : Direction, - pub plus_twos : u32, -} - -impl GameState<'_>{ - - fn next_player(&mut self) { - if self.current_direction == Direction::CLOCKWISE{ - if self.current_turn+1 >= self.player_states.len() as u32{ - self.current_turn = 0; - return; - } - self.current_turn +=1; - } - else { - if self.current_turn == 0{ - self.current_turn = (self.player_states.len()-1) as u32; - return; - } - self.current_turn -=1; - } - } - - 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(&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"))); - } - else { - return Err(String::from("Card not held by player")); - } - } - - fn check_if_legal(current_card : Card, card_to_be_played : Card, current_color : CardColors) -> bool{ - if card_to_be_played.color == CardColors::BLACK || card_to_be_played.color == current_color || card_to_be_played.value == current_card.value { - return true; - } else { - return false; - } - } - - pub fn next_turn(mut self, card_to_be_played : Card) -> Result{ - if self.turns == 0 { - let mut players : Vec = vec![]; - for player in &self.player_states{ - players.push(player.to_owned()); - } - for mut player in &mut players{ - self.draw(&mut player, 7); - } - self.turns+=1; - - return Ok(String::from("Game initialized")); - } - 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/")); - } - - 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")); - } - 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")); - } - - let card = self.current_card; - let card_value = card.value; - if 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); - } - 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{ - 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.next_player(); - return Ok(String::from("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); - } - if self.current_card.value == CardValue::SKIP{ - self.next_player(); - self.turns+=1; - return Ok(String::from("Next turn")); - } - if card_to_be_played.value == CardValue::REVERSE{ - if self.current_direction == Direction::CLOCKWISE{ - self.current_direction = Direction::COUNTER_CLOCKWISE; - } - else { - self.current_direction = Direction::CLOCKWISE; - } - } - if [CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR].contains(&card_to_be_played.value) { - self.current_color = card_to_be_played.color_change; - } 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, CardValue::SKIP, CardValue::REVERSE, CardValue::PLUS_TWO].contains(&card_to_be_played.value) { - if card_to_be_played.color != self.current_color{ - 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.turns+=1; - self.next_player(); - return Ok(String::from("Next turn")); - } - - fn new_game_helper<'a>(player_states: Vec>, player_connections: Vec>) -> GameState<'a>{ - GameState{ - turns : 0, - current_turn : 0, - deck : GameState::base_deck(), - trash : vec![], - current_card : Card{ value : CardValue::ZERO, color : CardColors::RED, color_change: CardColors::BLACK,}, - player_states : player_states.clone(), - player_connections : player_connections, - current_color : CardColors::RED, - current_direction : Direction::CLOCKWISE, - plus_twos : 0, - } - } - - pub fn new_game<'a>(player_states : Vec>, player_connections: Vec>) -> GameState<'a>{ - let mut new_game = GameState::new_game_helper(player_states, player_connections); - new_game.current_color = new_game.current_card.color.clone(); - return new_game; - } - - fn get_currently_held(&mut self) -> Vec{ - let mut currently_held = vec![]; - for hand in &mut self.player_states{ - currently_held.append(&mut hand.cards); - } - return currently_held; - } - - 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")); - } - return vec![]; - } - - fn base_deck()-> Vec{ - let mut deck : Deck = vec![]; - - for color in [CardColors::BLACK, CardColors::BLUE, CardColors::GREEN, CardColors::RED, CardColors::YELLOW]{ - for value in [CardValue::CHANGE_COLOR, CardValue::EIGHT, CardValue::FIVE, CardValue::FOUR, CardValue::NINE, CardValue::ONE, CardValue::PLUS_FOUR, CardValue::PLUS_TWO, CardValue::REVERSE, CardValue::SEVEN, CardValue::SIX, CardValue::SKIP, CardValue::THREE, CardValue::TWO, CardValue::ZERO]{ - if ![CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR].contains(&value) { - for _ in 0..1 {deck.push(Card{value : value.clone(), color : color.clone(), color_change : CardColors::BLACK})}; - } - else if value == CardValue::ZERO - { - deck.push(Card{value : value, color : color.clone(), color_change : CardColors::BLACK}); - } - else { - for _ in 0..4 {deck.push(Card {value : value.clone(), color : color.clone(), color_change : CardColors::BLACK})}; - } - - } - } - //CHANGE COLOR - /* for _ in 0..3 {deck.push(Card {value : CardValue::CHANGE_COLOR, color : CardColors::BLACK, color_change : CardColors::BLACK})}; - //PLUS FOUR - for _ in 0..3 {deck.push(Card{ value : CardValue::PLUS_FOUR, color : CardColors::BLACK, color_change : CardColors::BLACK})}; - //PLUS TWO - for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //REVERSE - for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //SKIP - for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //NINE - for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //EIGHT - for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //SEVEN - for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //SIX - for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //FIVE - for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //FOUR - for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //THREE - for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //TWO - for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //ONE - for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::RED, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; - for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; - //ZERO - deck.push(Card{ value : CardValue::ZERO, color : CardColors::RED, color_change : CardColors::BLACK}); - deck.push(Card{ value : CardValue::ZERO, color : CardColors::BLUE, color_change : CardColors::BLACK}); - deck.push(Card{ value : CardValue::ZERO, color : CardColors::GREEN, color_change : CardColors::BLACK}); - deck.push(Card{ value : CardValue::ZERO, color : CardColors::YELLOW, color_change : CardColors::BLACK}); */ - - return deck; - } - - fn get_cards(&mut self, count : u32) -> Vec{ - let mut cards_drawn = vec![]; - for _ in 0..count{ - let mut rng = rand::thread_rng(); - let n: usize = rng.gen_range(0..self.deck.len()); - cards_drawn.push(self.deck.remove(n)); - } - return cards_drawn - } - - 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; - } - - -} - -enum Direction { - CLOCKWISE, - COUNTER_CLOCKWISE, -} - -impl PartialEq for Direction{ - fn eq(&self, other: &Self) -> bool { - core::mem::discriminant(self) == core::mem::discriminant(other) - } -} +pub mod uno_logic; \ No newline at end of file diff --git a/src/tcp_server.rs b/src/tcp_server.rs index fb64910..70557f7 100644 --- a/src/tcp_server.rs +++ b/src/tcp_server.rs @@ -1,5 +1,5 @@ use std::{ - io::{ prelude::*, BufReader, BufWriter, WriterPanicked }, + io::{ prelude::*, BufReader, BufWriter }, net::{ TcpListener, TcpStream }, }; diff --git a/src/uno_logic.rs b/src/uno_logic.rs new file mode 100644 index 0000000..f42e836 --- /dev/null +++ b/src/uno_logic.rs @@ -0,0 +1,419 @@ +extern crate rand; +use std::{ + io::{ BufReader, BufWriter }, net::TcpStream, usize, vec +}; +use rand::Rng; +const GAME_INTEGRITY_ERROR : &'static str = "game integrity compromised"; + + +//enums, structs and types + +#[derive(Clone)] +pub enum CardValue { + PLUS_TWO, + PLUS_FOUR, + ZERO, + ONE, + TWO, + THREE, + FOUR, + FIVE, + SIX, + SEVEN, + EIGHT, + NINE, + REVERSE, + SKIP, + CHANGE_COLOR, +} + +#[derive(Clone)] +pub enum CardColors { + RED, + BLUE, + GREEN, + YELLOW, + BLACK, +} + +pub enum Direction { + CLOCKWISE, + COUNTER_CLOCKWISE, +} + +#[derive(Clone)] +pub struct PlayerState<'a> { + pub player_name: &'a str, + pub cards: Vec, +} + +pub struct PlayerConnection<'a>{ + player_name : &'a str, + reader: BufReader, + writer: BufWriter, +} + +pub struct Card { + value: CardValue, + color: CardColors, + color_change : CardColors, +} + +pub struct GameState<'a>{ + pub turns : u64, + pub current_turn : u32, + deck : Deck, + trash : Deck, + pub current_card : Card, + pub player_states : Vec>, + pub player_connections : Vec>, + pub current_color : CardColors, + pub current_direction : Direction, + plus_twos : u32, +} + +type Deck = Vec; + +// PartialEq trait implements + +impl PartialEq for CardValue{ + fn eq(&self, other: &Self) -> bool { + core::mem::discriminant(self) == core::mem::discriminant(other) + } +} + +impl PartialEq for CardColors{ + fn eq(&self, other: &Self) -> bool { + core::mem::discriminant(self) == core::mem::discriminant(other) + } +} + +impl PartialEq for Direction{ + fn eq(&self, other: &Self) -> bool { + core::mem::discriminant(self) == core::mem::discriminant(other) + } +} + +impl PartialEq for Card{ + fn eq(&self, other: &Self) -> bool { + self.value == other.value && self.color == other.color + } +} + +//Clone trait implements + +impl Clone for Card { + fn clone(&self) -> Self { + Self {value: self.value.clone(), color: self.color.clone(), color_change: self.color_change.clone() } + } +} + +//Copy trait implements + +impl Copy for Card {} +impl Copy for CardColors {} +impl Copy for CardValue {} + +//struct implementations + +impl PlayerState<'_> { + pub fn new(player_name : &str, cards : Vec) -> PlayerState{ + PlayerState { + player_name: player_name, + cards: cards, + } + } +} + + +impl PlayerConnection<'_> { + pub fn new(player_name : &str, reader : BufReader, writer : BufWriter) -> PlayerConnection{ + PlayerConnection { + player_name : player_name, + reader : reader, + writer : writer + } + } +} + +impl GameState<'_>{ + + fn next_player(&mut self) { + if self.current_direction == Direction::CLOCKWISE{ + if self.current_turn+1 >= self.player_states.len() as u32{ + self.current_turn = 0; + return; + } + self.current_turn +=1; + } + else { + if self.current_turn == 0{ + self.current_turn = (self.player_states.len()-1) as u32; + return; + } + self.current_turn -=1; + } + } + + fn game_init(&mut self){ + let mut players : Vec = vec![]; + for player in &self.player_states{ + players.push(player.to_owned()); + } + for mut player in &mut players{ + self.draw(&mut player, 7); + } + self.turns+=1; + } + + 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(&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"))); + } + else { + return Err(String::from("Card not held by player")); + } + } + + fn check_if_legal(current_card : Card, card_to_be_played : Card, current_color : CardColors) -> bool{ + if card_to_be_played.color == CardColors::BLACK || card_to_be_played.color == current_color || card_to_be_played.value == current_card.value { + return true; + } else { + return false; + } + } + + pub fn next_turn(mut self, card_to_be_played : Card) -> Result{ + + if self.turns == 0 { + self.game_init(); + return Ok(String::from("Game initialized")); + } + + 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")); + } + 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")); + } + + 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/")); + } + + 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); + } + else if self.current_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{ + 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.next_player(); + return Ok(String::from("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); + } + + if self.current_card.value == CardValue::SKIP{ + self.next_player(); + self.turns+=1; + return Ok(String::from("Next turn")); + } + + if card_to_be_played.value == CardValue::REVERSE{ + if self.current_direction == Direction::CLOCKWISE{ + self.current_direction = Direction::COUNTER_CLOCKWISE; + } + else { + self.current_direction = Direction::CLOCKWISE; + } + } + + if [CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR].contains(&card_to_be_played.value) { + self.current_color = card_to_be_played.color_change; + } 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, CardValue::SKIP, CardValue::REVERSE, CardValue::PLUS_TWO].contains(&card_to_be_played.value) { + if card_to_be_played.color != self.current_color{ + 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.turns+=1; + self.next_player(); + return Ok(String::from("Next turn")); + } + + fn new_game_helper<'a>(player_states: Vec>, player_connections: Vec>) -> GameState<'a>{ + GameState{ + turns : 0, + current_turn : 0, + deck : GameState::base_deck(), + trash : vec![], + current_card : Card{ value : CardValue::ZERO, color : CardColors::RED, color_change: CardColors::BLACK,}, + player_states : player_states.clone(), + player_connections : player_connections, + current_color : CardColors::RED, + current_direction : Direction::CLOCKWISE, + plus_twos : 0, + } + } + + pub fn new_game<'a>(player_states : Vec>, player_connections: Vec>) -> GameState<'a>{ + let mut new_game = GameState::new_game_helper(player_states, player_connections); + new_game.current_color = new_game.current_card.color.clone(); + return new_game; + } + + fn get_currently_held(&mut self) -> Vec{ + let mut currently_held = vec![]; + for hand in &mut self.player_states{ + currently_held.append(&mut hand.cards); + } + return currently_held; + } + + 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")); + } + return vec![]; + } + + fn base_deck()-> Vec{ + let mut deck : Deck = vec![]; + + for color in [CardColors::BLACK, CardColors::BLUE, CardColors::GREEN, CardColors::RED, CardColors::YELLOW]{ + for value in [CardValue::CHANGE_COLOR, CardValue::EIGHT, CardValue::FIVE, CardValue::FOUR, CardValue::NINE, CardValue::ONE, CardValue::PLUS_FOUR, CardValue::PLUS_TWO, CardValue::REVERSE, CardValue::SEVEN, CardValue::SIX, CardValue::SKIP, CardValue::THREE, CardValue::TWO, CardValue::ZERO]{ + if ![CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR].contains(&value) { + for _ in 0..1 {deck.push(Card{value : value.clone(), color : color.clone(), color_change : CardColors::BLACK})}; + } + else if value == CardValue::ZERO + { + deck.push(Card{value : value, color : color.clone(), color_change : CardColors::BLACK}); + } + else { + for _ in 0..4 {deck.push(Card {value : value.clone(), color : color.clone(), color_change : CardColors::BLACK})}; + } + + } + } + //CHANGE COLOR + /* for _ in 0..3 {deck.push(Card {value : CardValue::CHANGE_COLOR, color : CardColors::BLACK, color_change : CardColors::BLACK})}; + //PLUS FOUR + for _ in 0..3 {deck.push(Card{ value : CardValue::PLUS_FOUR, color : CardColors::BLACK, color_change : CardColors::BLACK})}; + //PLUS TWO + for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //REVERSE + for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //SKIP + for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //NINE + for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //EIGHT + for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //SEVEN + for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //SIX + for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //FIVE + for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //FOUR + for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //THREE + for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //TWO + for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //ONE + for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::RED, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::BLUE, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::GREEN, color_change : CardColors::BLACK})}; + for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::YELLOW, color_change : CardColors::BLACK})}; + //ZERO + deck.push(Card{ value : CardValue::ZERO, color : CardColors::RED, color_change : CardColors::BLACK}); + deck.push(Card{ value : CardValue::ZERO, color : CardColors::BLUE, color_change : CardColors::BLACK}); + deck.push(Card{ value : CardValue::ZERO, color : CardColors::GREEN, color_change : CardColors::BLACK}); + deck.push(Card{ value : CardValue::ZERO, color : CardColors::YELLOW, color_change : CardColors::BLACK}); */ + + return deck; + } + + fn get_cards(&mut self, count : u32) -> Vec{ + let mut cards_drawn = vec![]; + for _ in 0..count{ + let mut rng = rand::thread_rng(); + let n: usize = rng.gen_range(0..self.deck.len()); + cards_drawn.push(self.deck.remove(n)); + } + return cards_drawn + } + + 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; + } + + +} \ No newline at end of file