uuhhh, added more tests ;) and a bit of refactoring and logic fixes
This commit is contained in:
parent
7f99c65f0a
commit
5a0d6573db
323
src/uno_logic.rs
323
src/uno_logic.rs
|
|
@ -32,7 +32,7 @@ pub enum CardValue {
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
#[derive(Eq)]
|
#[derive(Eq)]
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
pub enum CardColors {
|
pub enum CardColor {
|
||||||
RED,
|
RED,
|
||||||
BLUE,
|
BLUE,
|
||||||
GREEN,
|
GREEN,
|
||||||
|
|
@ -44,7 +44,8 @@ pub enum Direction {
|
||||||
CLOCKWISE,
|
CLOCKWISE,
|
||||||
COUNTER_CLOCKWISE,
|
COUNTER_CLOCKWISE,
|
||||||
}
|
}
|
||||||
|
#[derive(PartialEq)]
|
||||||
|
#[derive(Debug)]
|
||||||
pub enum TURN_RESULT {
|
pub enum TURN_RESULT {
|
||||||
NEXT_TURN,
|
NEXT_TURN,
|
||||||
REPEAT_TURN,
|
REPEAT_TURN,
|
||||||
|
|
@ -67,7 +68,7 @@ pub struct PlayerConnection<'a, S> where S: Read + Write {
|
||||||
#[derive(Hash)]
|
#[derive(Hash)]
|
||||||
pub struct Card {
|
pub struct Card {
|
||||||
pub value: CardValue,
|
pub value: CardValue,
|
||||||
pub color: CardColors,
|
pub color: CardColor,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct GameState<'a, S: Read + Write> {
|
pub struct GameState<'a, S: Read + Write> {
|
||||||
|
|
@ -78,7 +79,7 @@ pub struct GameState<'a, S: Read + Write> {
|
||||||
pub current_card: Card,
|
pub current_card: Card,
|
||||||
pub player_states: Vec<PlayerState<'a>>,
|
pub player_states: Vec<PlayerState<'a>>,
|
||||||
pub player_connections: Vec<PlayerConnection<'a, S>>,
|
pub player_connections: Vec<PlayerConnection<'a, S>>,
|
||||||
pub current_color: CardColors,
|
pub current_color: CardColor,
|
||||||
pub current_direction: Direction,
|
pub current_direction: Direction,
|
||||||
plus_twos: u32,
|
plus_twos: u32,
|
||||||
}
|
}
|
||||||
|
|
@ -93,7 +94,7 @@ impl PartialEq for CardValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PartialEq for CardColors {
|
impl PartialEq for CardColor {
|
||||||
fn eq(&self, other: &Self) -> bool {
|
fn eq(&self, other: &Self) -> bool {
|
||||||
core::mem::discriminant(self) == core::mem::discriminant(other)
|
core::mem::discriminant(self) == core::mem::discriminant(other)
|
||||||
}
|
}
|
||||||
|
|
@ -122,7 +123,7 @@ impl Clone for Card {
|
||||||
//Copy trait implements
|
//Copy trait implements
|
||||||
|
|
||||||
impl Copy for Card {}
|
impl Copy for Card {}
|
||||||
impl Copy for CardColors {}
|
impl Copy for CardColor {}
|
||||||
impl Copy for CardValue {}
|
impl Copy for CardValue {}
|
||||||
|
|
||||||
//struct implementations
|
//struct implementations
|
||||||
|
|
@ -149,14 +150,14 @@ impl CardValue {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CardColors {
|
impl CardColor {
|
||||||
pub fn to_string<'a>(self) -> &'a str {
|
pub fn to_string<'a>(self) -> &'a str {
|
||||||
match self {
|
match self {
|
||||||
CardColors::BLACK => "BLACK",
|
CardColor::BLACK => "BLACK",
|
||||||
CardColors::BLUE => "BLUE",
|
CardColor::BLUE => "BLUE",
|
||||||
CardColors::GREEN => "GREEN",
|
CardColor::GREEN => "GREEN",
|
||||||
CardColors::YELLOW => "YELLOW",
|
CardColor::YELLOW => "YELLOW",
|
||||||
CardColors::RED => "RED",
|
CardColor::RED => "RED",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -280,10 +281,10 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
fn check_if_legal(
|
fn check_if_legal(
|
||||||
current_card: Card,
|
current_card: Card,
|
||||||
card_to_be_played: Card,
|
card_to_be_played: Card,
|
||||||
current_color: CardColors
|
current_color: CardColor
|
||||||
) -> bool {
|
) -> bool {
|
||||||
if
|
if
|
||||||
card_to_be_played.color == CardColors::BLACK ||
|
card_to_be_played.color == CardColor::BLACK ||
|
||||||
card_to_be_played.color == current_color ||
|
card_to_be_played.color == current_color ||
|
||||||
card_to_be_played.value == current_card.value
|
card_to_be_played.value == current_card.value
|
||||||
{
|
{
|
||||||
|
|
@ -293,41 +294,33 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn next_turn(mut self, card_to_be_played: Card) -> TURN_RESULT {
|
pub fn next_turn(&mut self, card_to_be_played: Card) -> TURN_RESULT {
|
||||||
if self.turns == 0 {
|
if self.turns == 0 {
|
||||||
self.game_init();
|
self.game_init();
|
||||||
return TURN_RESULT::NEXT_TURN;
|
return TURN_RESULT::NEXT_TURN;
|
||||||
}
|
}
|
||||||
|
|
||||||
if
|
if !GameState::has_any_moves(&self,
|
||||||
!GameState::has_any_moves(
|
|
||||||
&self,
|
|
||||||
self.player_states
|
self.player_states
|
||||||
.get(self.current_turn as usize)
|
.get(self.current_turn as usize)
|
||||||
.expect(&GAME_INTEGRITY_ERROR)
|
.expect(&GAME_INTEGRITY_ERROR)
|
||||||
.to_owned()
|
.to_owned()
|
||||||
)
|
){
|
||||||
{
|
|
||||||
let player = &mut self.player_states.clone();
|
let player = &mut self.player_states.clone();
|
||||||
if
|
if !GameState::<S>::check_if_legal(self.current_card,self
|
||||||
!GameState::<S>::check_if_legal(
|
.draw(
|
||||||
self.current_card,
|
player
|
||||||
self
|
.get_mut(self.current_turn as usize)
|
||||||
.draw(
|
.expect(&GAME_INTEGRITY_ERROR).player_name,
|
||||||
player
|
|
||||||
.get_mut(self.current_turn as usize)
|
|
||||||
.expect(&GAME_INTEGRITY_ERROR).player_name,
|
|
||||||
1
|
1
|
||||||
)
|
).get(0)
|
||||||
.get(0)
|
.expect(&GAME_INTEGRITY_ERROR)
|
||||||
.expect(&GAME_INTEGRITY_ERROR)
|
.to_owned(),
|
||||||
.to_owned(),
|
self.current_color
|
||||||
self.current_color
|
){
|
||||||
)
|
|
||||||
{
|
|
||||||
self.next_player();
|
self.next_player();
|
||||||
return TURN_RESULT::NEXT_TURN;
|
return TURN_RESULT::NEXT_TURN;
|
||||||
}
|
}
|
||||||
let mut player = self.player_states.clone();
|
let mut player = self.player_states.clone();
|
||||||
self.add_to_trash(
|
self.add_to_trash(
|
||||||
GameState::<S>
|
GameState::<S>
|
||||||
|
|
@ -391,8 +384,9 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
if self.current_card.value == CardValue::SKIP {
|
if card_to_be_played.value == CardValue::SKIP {
|
||||||
self.next_player();
|
self.current_card = card_to_be_played;
|
||||||
|
for _ in 0 .. 2 { self.next_player()};
|
||||||
self.turns += 1;
|
self.turns += 1;
|
||||||
return TURN_RESULT::NEXT_TURN;
|
return TURN_RESULT::NEXT_TURN;
|
||||||
}
|
}
|
||||||
|
|
@ -472,10 +466,10 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
current_turn: 0,
|
current_turn: 0,
|
||||||
deck: GameState::<S>::base_deck(),
|
deck: GameState::<S>::base_deck(),
|
||||||
trash: vec![],
|
trash: vec![],
|
||||||
current_card: Card { value: CardValue::ZERO, color: CardColors::RED },
|
current_card: Card { value: CardValue::ZERO, color: CardColor::RED },
|
||||||
player_states: player_states.clone(),
|
player_states: player_states.clone(),
|
||||||
player_connections: player_connections,
|
player_connections: player_connections,
|
||||||
current_color: CardColors::RED,
|
current_color: CardColor::RED,
|
||||||
current_direction: Direction::CLOCKWISE,
|
current_direction: Direction::CLOCKWISE,
|
||||||
plus_twos: 0,
|
plus_twos: 0,
|
||||||
}
|
}
|
||||||
|
|
@ -499,6 +493,7 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reset_deck(&mut self, currently_held: Vec<Card>) {
|
fn reset_deck(&mut self, currently_held: Vec<Card>) {
|
||||||
|
self.trash.clear();
|
||||||
self.deck = GameState::<S>::base_deck();
|
self.deck = GameState::<S>::base_deck();
|
||||||
for current_cart in currently_held {
|
for current_cart in currently_held {
|
||||||
self.deck.remove(
|
self.deck.remove(
|
||||||
|
|
@ -514,36 +509,36 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
let mut deck: Deck = vec![];
|
let mut deck: Deck = vec![];
|
||||||
|
|
||||||
for color in [
|
for color in [
|
||||||
CardColors::BLACK,
|
CardColor::BLACK,
|
||||||
CardColors::BLUE,
|
CardColor::BLUE,
|
||||||
CardColors::GREEN,
|
CardColor::GREEN,
|
||||||
CardColors::RED,
|
CardColor::RED,
|
||||||
CardColors::YELLOW,
|
CardColor::YELLOW,
|
||||||
] {
|
] {
|
||||||
for value in [
|
for value in [
|
||||||
CardValue::CHANGE_COLOR,
|
CardValue::CHANGE_COLOR,
|
||||||
CardValue::EIGHT,
|
|
||||||
CardValue::FIVE,
|
|
||||||
CardValue::FOUR,
|
|
||||||
CardValue::NINE,
|
|
||||||
CardValue::ONE,
|
|
||||||
CardValue::PLUS_FOUR,
|
CardValue::PLUS_FOUR,
|
||||||
|
CardValue::ONE,
|
||||||
|
CardValue::TWO,
|
||||||
|
CardValue::THREE,
|
||||||
|
CardValue::FOUR,
|
||||||
|
CardValue::FIVE,
|
||||||
|
CardValue::SIX,
|
||||||
|
CardValue::SEVEN,
|
||||||
|
CardValue::EIGHT,
|
||||||
|
CardValue::NINE,
|
||||||
|
CardValue::ZERO,
|
||||||
CardValue::PLUS_TWO,
|
CardValue::PLUS_TWO,
|
||||||
CardValue::REVERSE,
|
CardValue::REVERSE,
|
||||||
CardValue::SEVEN,
|
|
||||||
CardValue::SIX,
|
|
||||||
CardValue::SKIP,
|
CardValue::SKIP,
|
||||||
CardValue::THREE,
|
|
||||||
CardValue::TWO,
|
|
||||||
CardValue::ZERO,
|
|
||||||
] {
|
] {
|
||||||
if ![CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR, CardValue::ZERO].contains(&value) && color != CardColors::BLACK {
|
if ![CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR, CardValue::ZERO].contains(&value) && color != CardColor::BLACK {
|
||||||
for _ in 0..1 {
|
for _ in 0..2 {
|
||||||
deck.push(Card { value: value, color: color });
|
deck.push(Card { value: value, color: color });
|
||||||
}
|
}
|
||||||
} else if value == CardValue::ZERO && color != CardColors::BLACK{
|
} else if value == CardValue::ZERO && color != CardColor::BLACK{
|
||||||
deck.push(Card { value: value, color: color });
|
deck.push(Card { value: value, color: color });
|
||||||
} else {
|
} else if [CardValue::CHANGE_COLOR, CardValue::PLUS_FOUR].contains(&value) && color == CardColor::BLACK {
|
||||||
for _ in 0..4 {
|
for _ in 0..4 {
|
||||||
deck.push(Card { value: value, color: color });
|
deck.push(Card { value: value, color: color });
|
||||||
}
|
}
|
||||||
|
|
@ -551,74 +546,74 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
//CHANGE COLOR
|
//CHANGE COLOR
|
||||||
/* for _ in 0..3 {deck.push(Card {value : CardValue::CHANGE_COLOR, color : CardColors::BLACK, color_change : CardColors::BLACK})};
|
/* for _ in 0..3 {deck.push(Card {value : CardValue::CHANGE_COLOR, color : CardColor::BLACK, color_change : CardColor::BLACK})};
|
||||||
//PLUS FOUR
|
//PLUS FOUR
|
||||||
for _ in 0..3 {deck.push(Card{ value : CardValue::PLUS_FOUR, color : CardColors::BLACK, color_change : CardColors::BLACK})};
|
for _ in 0..3 {deck.push(Card{ value : CardValue::PLUS_FOUR, color : CardColor::BLACK, color_change : CardColor::BLACK})};
|
||||||
//PLUS TWO
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::PLUS_TWO, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//REVERSE
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::REVERSE, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//SKIP
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::SKIP, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//NINE
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::NINE, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//EIGHT
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::EIGHT, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//SEVEN
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::SEVEN, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//SIX
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::SIX, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//FIVE
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::FIVE, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//FOUR
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::FOUR, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//THREE
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::THREE, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//TWO
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::TWO, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//ONE
|
//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 : CardColor::RED, color_change : CardColor::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 : CardColor::BLUE, color_change : CardColor::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 : CardColor::GREEN, color_change : CardColor::BLACK})};
|
||||||
for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColors::YELLOW, color_change : CardColors::BLACK})};
|
for _ in 0..1 {deck.push(Card{ value : CardValue::ONE, color : CardColor::YELLOW, color_change : CardColor::BLACK})};
|
||||||
//ZERO
|
//ZERO
|
||||||
deck.push(Card{ value : CardValue::ZERO, color : CardColors::RED, color_change : CardColors::BLACK});
|
deck.push(Card{ value : CardValue::ZERO, color : CardColor::RED, color_change : CardColor::BLACK});
|
||||||
deck.push(Card{ value : CardValue::ZERO, color : CardColors::BLUE, color_change : CardColors::BLACK});
|
deck.push(Card{ value : CardValue::ZERO, color : CardColor::BLUE, color_change : CardColor::BLACK});
|
||||||
deck.push(Card{ value : CardValue::ZERO, color : CardColors::GREEN, color_change : CardColors::BLACK});
|
deck.push(Card{ value : CardValue::ZERO, color : CardColor::GREEN, color_change : CardColor::BLACK});
|
||||||
deck.push(Card{ value : CardValue::ZERO, color : CardColors::YELLOW, color_change : CardColors::BLACK}); */
|
deck.push(Card{ value : CardValue::ZERO, color : CardColor::YELLOW, color_change : CardColor::BLACK}); */
|
||||||
|
|
||||||
return deck;
|
return deck;
|
||||||
}
|
}
|
||||||
|
|
@ -650,7 +645,7 @@ impl<S> GameState<'_, S> where S: Read + Write {
|
||||||
|
|
||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use std::collections::{HashSet, VecDeque};
|
use std::{collections::{HashSet, VecDeque}, iter::Skip};
|
||||||
|
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
|
@ -664,13 +659,13 @@ mod tests {
|
||||||
unique_vec
|
unique_vec
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_card(card_value : CardValue, card_color : CardColors) -> Card{
|
fn get_card(card_value : CardValue, card_color : CardColor) -> Card{
|
||||||
for card in get_card_set(){
|
for card in get_card_set(){
|
||||||
if card_value == card.value && card_color == card.color {
|
if card_value == card.value && card_color == card.color {
|
||||||
return card;
|
return card;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return Card {value : CardValue::ZERO, color : CardColors::BLACK};
|
return Card {value : CardValue::ZERO, color : CardColor::BLACK};
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_test_gs<'a>() -> GameState<'a, VecDeque<u8>> {
|
fn get_test_gs<'a>() -> GameState<'a, VecDeque<u8>> {
|
||||||
|
|
@ -698,7 +693,7 @@ mod tests {
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_card_color_to_string() {
|
fn test_card_color_to_string() {
|
||||||
let cc: CardColors = CardColors::BLUE;
|
let cc: CardColor = CardColor::BLUE;
|
||||||
assert_eq!(cc.to_string(), "BLUE");
|
assert_eq!(cc.to_string(), "BLUE");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -736,8 +731,9 @@ mod tests {
|
||||||
fn test_has_any_moves_none(){
|
fn test_has_any_moves_none(){
|
||||||
let mut gs = get_test_gs();
|
let mut gs = get_test_gs();
|
||||||
//no moves
|
//no moves
|
||||||
gs.current_card = Card {value : CardValue::TWO, color : CardColors::GREEN};
|
gs.current_card = Card {value : CardValue::TWO, color : CardColor::GREEN};
|
||||||
let player = PlayerState::new("detlef", [get_card(CardValue::FOUR, CardColors::RED), get_card(CardValue::EIGHT, CardColors::YELLOW)].to_vec());
|
gs.current_color = CardColor::GREEN;
|
||||||
|
let player = PlayerState::new("detlef", [get_card(CardValue::FOUR, CardColor::RED), get_card(CardValue::EIGHT, CardColor::YELLOW)].to_vec());
|
||||||
assert_eq!(gs.has_any_moves(player), false);
|
assert_eq!(gs.has_any_moves(player), false);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -745,16 +741,95 @@ mod tests {
|
||||||
fn test_has_any_moves_some(){
|
fn test_has_any_moves_some(){
|
||||||
let mut gs = get_test_gs();
|
let mut gs = get_test_gs();
|
||||||
//has moves
|
//has moves
|
||||||
gs.current_card = Card {value : CardValue::TWO, color : CardColors::GREEN};
|
gs.current_card = Card {value : CardValue::TWO, color : CardColor::GREEN};
|
||||||
let player = PlayerState::new("detlef", [get_card(CardValue::FOUR, CardColors::RED), get_card(CardValue::EIGHT, CardColors::GREEN)].to_vec());
|
gs.current_color = CardColor::GREEN;
|
||||||
|
let player = PlayerState::new("detlef", [get_card(CardValue::FOUR, CardColor::RED), get_card(CardValue::EIGHT, CardColor::GREEN)].to_vec());
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn test_check_if_legal_false(){
|
fn test_check_if_legal_false(){
|
||||||
//illegal
|
//illegal
|
||||||
|
let current_card = Card {value : CardValue::TWO, color : CardColor::GREEN};
|
||||||
|
assert_eq!(GameState::<VecDeque<u8>>::check_if_legal(current_card, get_card(CardValue::FOUR, CardColor::RED), CardColor::GREEN), false);
|
||||||
|
assert_eq!(GameState::<VecDeque<u8>>::check_if_legal(current_card, get_card(CardValue::EIGHT, CardColor::YELLOW), CardColor::GREEN), false);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_add_to_trash(){
|
||||||
let mut gs = get_test_gs();
|
let mut gs = get_test_gs();
|
||||||
let current_card = Card {value : CardValue::TWO, color : CardColors::GREEN};
|
gs.add_to_trash(get_card(CardValue::ONE, CardColor::YELLOW));
|
||||||
assert_eq!(GameState::<VecDeque<u8>>::check_if_legal(current_card, get_card(CardValue::FOUR, CardColors::RED), CardColors::GREEN), false);
|
assert_eq!(gs.trash, vec![get_card(CardValue::ONE, CardColor::YELLOW)]);
|
||||||
assert_eq!(GameState::<VecDeque<u8>>::check_if_legal(current_card, get_card(CardValue::EIGHT, CardColors::YELLOW), CardColors::GREEN), false);
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_play_card_held(){
|
||||||
|
let mut gs = get_test_gs();
|
||||||
|
gs.player_states.get_mut(0).unwrap().cards.push(get_card(CardValue::NINE, CardColor::BLUE));
|
||||||
|
assert_eq!(GameState::<VecDeque<u8>>::play(gs.player_states.get_mut(0).unwrap(),get_card(CardValue::NINE, CardColor::BLUE)).unwrap(), get_card(CardValue::NINE, CardColor::BLUE));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_play_card_not_held(){
|
||||||
|
let mut gs = get_test_gs();
|
||||||
|
gs.player_states.get_mut(0).unwrap().cards.push(get_card(CardValue::NINE, CardColor::BLUE));
|
||||||
|
assert_eq!(GameState::<VecDeque<u8>>::play(gs.player_states.get_mut(0).unwrap(),get_card(CardValue::EIGHT, CardColor::BLUE)), Err("Card not held by player".to_owned()));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_next_turn_green_two_to_red_two(){
|
||||||
|
let mut gs = get_test_gs();
|
||||||
|
gs.game_init();
|
||||||
|
gs.current_card = get_card(CardValue::TWO, CardColor::GREEN);
|
||||||
|
gs.current_color = CardColor::GREEN;
|
||||||
|
gs.player_states.get_mut(0).unwrap().cards.push(get_card(CardValue::TWO, CardColor::RED));
|
||||||
|
assert_eq!(gs.next_turn(get_card(CardValue::TWO, CardColor::RED)), TURN_RESULT::NEXT_TURN);
|
||||||
|
assert_eq!(gs.current_color, CardColor::RED);
|
||||||
|
assert_eq!(gs.current_card, get_card(CardValue::TWO, CardColor::RED));
|
||||||
|
assert_eq!(gs.plus_twos, 0);
|
||||||
|
assert_eq!(gs.turns, 2);
|
||||||
|
assert_eq!(gs.current_turn, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_next_turn_green_two_to_yellow_four(){
|
||||||
|
let mut gs = get_test_gs();
|
||||||
|
gs.game_init();
|
||||||
|
gs.current_card = get_card(CardValue::TWO, CardColor::GREEN);
|
||||||
|
gs.current_color = CardColor::GREEN;
|
||||||
|
gs.player_states.get_mut(0).unwrap().cards.push(get_card(CardValue::FOUR, CardColor::YELLOW));
|
||||||
|
assert_eq!(gs.next_turn(get_card(CardValue::FOUR, CardColor::YELLOW)), TURN_RESULT::REPEAT_TURN);
|
||||||
|
assert_eq!(gs.current_color, CardColor::GREEN);
|
||||||
|
assert_eq!(gs.current_card, get_card(CardValue::TWO, CardColor::GREEN));
|
||||||
|
assert_eq!(gs.turns, 1);
|
||||||
|
assert_eq!(gs.current_turn, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_next_turn_green_two_to_green_skip(){
|
||||||
|
let mut gs = get_test_gs();
|
||||||
|
gs.game_init();
|
||||||
|
gs.current_card = get_card(CardValue::TWO, CardColor::GREEN);
|
||||||
|
gs.current_color = CardColor::GREEN;
|
||||||
|
gs.player_states.get_mut(0).unwrap().cards.push(get_card(CardValue::SKIP, CardColor::GREEN));
|
||||||
|
assert_eq!(gs.next_turn(get_card(CardValue::SKIP, CardColor::GREEN)), TURN_RESULT::NEXT_TURN);
|
||||||
|
assert_eq!(gs.current_color, CardColor::GREEN);
|
||||||
|
assert_eq!(gs.current_card, get_card(CardValue::SKIP, CardColor::GREEN));
|
||||||
|
assert_eq!(gs.turns, 2);
|
||||||
|
assert_eq!(gs.current_turn, 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_next_turn_green_two_to_plus_four(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_next_turn_green_two_to_green_reverse(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn test_next_turn_green_two_to_change_color(){
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,4 @@
|
||||||
use crate::uno_logic::{Card, CardValue, CardColors};
|
use crate::uno_logic::{Card, CardValue, CardColor};
|
||||||
const PROTOCOL_ERROR : &'static str = "protocol error";
|
const PROTOCOL_ERROR : &'static str = "protocol error";
|
||||||
// enums, structs, types
|
// enums, structs, types
|
||||||
struct Turn{
|
struct Turn{
|
||||||
|
|
@ -36,13 +36,13 @@ impl Turn{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn get_color(card_color_line : &str) -> Result<CardColors, String> {
|
fn get_color(card_color_line : &str) -> Result<CardColor, String> {
|
||||||
match &card_color_line.split(":").collect::<Vec<&str>>().get(1).unwrap()[..] {
|
match &card_color_line.split(":").collect::<Vec<&str>>().get(1).unwrap()[..] {
|
||||||
"BLACK" => Ok(CardColors::BLACK),
|
"BLACK" => Ok(CardColor::BLACK),
|
||||||
"BLUE" => Ok(CardColors::BLUE),
|
"BLUE" => Ok(CardColor::BLUE),
|
||||||
"GREEN" => Ok(CardColors::GREEN),
|
"GREEN" => Ok(CardColor::GREEN),
|
||||||
"YELLOW" => Ok(CardColors::YELLOW),
|
"YELLOW" => Ok(CardColor::YELLOW),
|
||||||
"RED" => Ok(CardColors::RED),
|
"RED" => Ok(CardColor::RED),
|
||||||
_ => Err(String::from(PROTOCOL_ERROR))
|
_ => Err(String::from(PROTOCOL_ERROR))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue
Block a user