refactored uno game logic to module uno_logic
This commit is contained in:
parent
b9dc550e72
commit
9680817601
402
src/lib.rs
402
src/lib.rs
|
|
@ -1,401 +1 @@
|
||||||
extern crate rand;
|
pub mod uno_logic;
|
||||||
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<Card>,
|
|
||||||
}
|
|
||||||
|
|
||||||
pub struct PlayerConnection<'a>{
|
|
||||||
player_name : &'a str,
|
|
||||||
reader: BufReader<TcpStream>,
|
|
||||||
writer: BufWriter<TcpStream>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PlayerState<'_> {
|
|
||||||
pub fn new(player_name : &str, cards : Vec<Card>) -> PlayerState{
|
|
||||||
PlayerState {
|
|
||||||
player_name: player_name,
|
|
||||||
cards: cards,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
impl PlayerConnection<'_> {
|
|
||||||
pub fn new(player_name : &str, reader : BufReader<TcpStream>, writer : BufWriter<TcpStream>) -> 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<Card>;
|
|
||||||
|
|
||||||
#[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<PlayerState<'a>>,
|
|
||||||
player_connections : Vec<PlayerConnection<'a>>,
|
|
||||||
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<Card, String>{
|
|
||||||
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<String, String>{
|
|
||||||
if self.turns == 0 {
|
|
||||||
let mut players : Vec<PlayerState> = 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<PlayerState<'a>>, player_connections: Vec<PlayerConnection<'a>>) -> 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<PlayerState<'a>>, player_connections: Vec<PlayerConnection<'a>>) -> 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<Card>{
|
|
||||||
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<Card>) -> 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<Card>{
|
|
||||||
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<Card>{
|
|
||||||
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<Card>{
|
|
||||||
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)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
use std::{
|
use std::{
|
||||||
io::{ prelude::*, BufReader, BufWriter, WriterPanicked },
|
io::{ prelude::*, BufReader, BufWriter },
|
||||||
net::{ TcpListener, TcpStream },
|
net::{ TcpListener, TcpStream },
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
419
src/uno_logic.rs
Normal file
419
src/uno_logic.rs
Normal file
|
|
@ -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<Card>,
|
||||||
|
}
|
||||||
|
|
||||||
|
pub struct PlayerConnection<'a>{
|
||||||
|
player_name : &'a str,
|
||||||
|
reader: BufReader<TcpStream>,
|
||||||
|
writer: BufWriter<TcpStream>,
|
||||||
|
}
|
||||||
|
|
||||||
|
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<PlayerState<'a>>,
|
||||||
|
pub player_connections : Vec<PlayerConnection<'a>>,
|
||||||
|
pub current_color : CardColors,
|
||||||
|
pub current_direction : Direction,
|
||||||
|
plus_twos : u32,
|
||||||
|
}
|
||||||
|
|
||||||
|
type Deck = Vec<Card>;
|
||||||
|
|
||||||
|
// 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<Card>) -> PlayerState{
|
||||||
|
PlayerState {
|
||||||
|
player_name: player_name,
|
||||||
|
cards: cards,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
impl PlayerConnection<'_> {
|
||||||
|
pub fn new(player_name : &str, reader : BufReader<TcpStream>, writer : BufWriter<TcpStream>) -> 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<PlayerState> = 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<Card, String>{
|
||||||
|
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<String, String>{
|
||||||
|
|
||||||
|
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<PlayerState<'a>>, player_connections: Vec<PlayerConnection<'a>>) -> 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<PlayerState<'a>>, player_connections: Vec<PlayerConnection<'a>>) -> 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<Card>{
|
||||||
|
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<Card>) -> 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<Card>{
|
||||||
|
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<Card>{
|
||||||
|
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<Card>{
|
||||||
|
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;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
}
|
||||||
Loading…
Reference in New Issue
Block a user