game logic fertig, (hoff ich zumindest)

This commit is contained in:
mux 2024-08-15 20:30:23 +02:00
parent 0c9f3a99c4
commit b9dc550e72

View File

@ -1,6 +1,6 @@
extern crate rand; extern crate rand;
use std::{ use std::{
arch::global_asm, clone, io::{ prelude::*, BufReader, BufWriter, WriterPanicked }, net::{ TcpListener, TcpStream }, usize, vec io::{ BufReader, BufWriter }, net::TcpStream, usize, vec
}; };
use rand::Rng; use rand::Rng;
const GAME_INTEGRITY_ERROR : &'static str = "game integrity compromised"; const GAME_INTEGRITY_ERROR : &'static str = "game integrity compromised";
@ -11,7 +11,7 @@ pub struct PlayerState<'a> {
pub cards: Vec<Card>, pub cards: Vec<Card>,
} }
struct PlayerConnection<'a>{ pub struct PlayerConnection<'a>{
player_name : &'a str, player_name : &'a str,
reader: BufReader<TcpStream>, reader: BufReader<TcpStream>,
writer: BufWriter<TcpStream>, writer: BufWriter<TcpStream>,
@ -37,7 +37,7 @@ impl PlayerConnection<'_> {
} }
} }
struct Card { pub struct Card {
value: CardValue, value: CardValue,
color: CardColors, color: CardColors,
color_change : CardColors, color_change : CardColors,
@ -49,6 +49,8 @@ impl PartialEq for Card{
} }
} }
impl Copy for Card {}
type Deck = Vec<Card>; type Deck = Vec<Card>;
#[derive(Clone)] #[derive(Clone)]
@ -60,6 +62,10 @@ enum CardColors {
BLACK, BLACK,
} }
impl Copy for CardColors {}
impl Copy for CardValue {}
impl PartialEq for CardColors{ impl PartialEq for CardColors{
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)
@ -104,13 +110,30 @@ pub struct GameState<'a>{
pub current_card : Card, pub current_card : Card,
player_states : Vec<PlayerState<'a>>, player_states : Vec<PlayerState<'a>>,
player_connections : Vec<PlayerConnection<'a>>, player_connections : Vec<PlayerConnection<'a>>,
pub current_color : CardColors, current_color : CardColors,
pub current_direction : Direction, current_direction : Direction,
pub plus_twos : u32, pub plus_twos : u32,
} }
impl GameState<'_>{ 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{ fn has_any_moves(&self, player : PlayerState) -> bool{
for card in player.cards{ for card in player.cards{
if GameState::check_if_legal(self.current_card.clone(), card, self.current_color.clone()){ if GameState::check_if_legal(self.current_card.clone(), card, self.current_color.clone()){
@ -120,7 +143,7 @@ impl GameState<'_>{
return false; return false;
} }
fn add_to_trash<'a>(&mut self, card : Card){ fn add_to_trash(&mut self, card : Card){
self.trash.push(card); self.trash.push(card);
} }
@ -141,11 +164,11 @@ impl GameState<'_>{
} }
} }
pub fn next_turn<'a>(mut self, card_to_be_played : Card) -> Result<String, String>{ pub fn next_turn(mut self, card_to_be_played : Card) -> Result<String, String>{
if self.turns == 0 { if self.turns == 0 {
let mut players : Vec<PlayerState> = vec![]; let mut players : Vec<PlayerState> = vec![];
for player in &self.player_states{ for player in &self.player_states{
&mut players.push(player.to_owned()); players.push(player.to_owned());
} }
for mut player in &mut players{ for mut player in &mut players{
self.draw(&mut player, 7); self.draw(&mut player, 7);
@ -154,20 +177,21 @@ impl GameState<'_>{
return Ok(String::from("Game initialized")); return Ok(String::from("Game initialized"));
} }
if !GameState::check_if_legal(self.current_card.clone(), card_to_be_played.clone(), self.current_color.clone()){ if !GameState::check_if_legal(self.current_card, card_to_be_played, self.current_color){
return Err(String::from("Please learn the rules at https://www.unorules.com/")); return 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()){ if !GameState::has_any_moves(&self, self.player_states.get(self.current_turn as usize).expect(GAME_INTEGRITY_ERROR).to_owned()){
let mut player = &mut self.player_states.clone(); let player = &mut self.player_states.clone();
if !GameState::check_if_legal(self.current_card.clone(), self.draw(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), 1).get(0).expect(&GAME_INTEGRITY_ERROR).to_owned(), self.current_color.clone()){ if !GameState::check_if_legal(self.current_card, self.draw(player.get_mut(self.current_turn as usize).expect(&GAME_INTEGRITY_ERROR), 1).get(0).expect(&GAME_INTEGRITY_ERROR).to_owned(), self.current_color){
self.next_player();
return Ok(String::from("Next turn")); return Ok(String::from("Next turn"));
} }
let mut player = self.player_states.clone(); let mut player = self.player_states.clone();
self.add_to_trash(GameState::play(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), card_to_be_played.clone()).expect("game integrity compromised")); 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.clone(); let card = self.current_card;
let card_value = card.value; let card_value = card.value;
if card_value == CardValue::PLUS_TWO && card_to_be_played.value != CardValue::PLUS_TWO{ if card_value == CardValue::PLUS_TWO && card_to_be_played.value != CardValue::PLUS_TWO{
let player = &mut self.player_states.clone(); let player = &mut self.player_states.clone();
@ -175,28 +199,42 @@ impl GameState<'_>{
} }
else if card_value == CardValue::PLUS_TWO && card_to_be_played.value == CardValue::PLUS_TWO { else if card_value == CardValue::PLUS_TWO && card_to_be_played.value == CardValue::PLUS_TWO {
self.plus_twos+=1; self.plus_twos+=1;
if self.current_color != card_to_be_played.color.clone(){ if self.current_color != card_to_be_played.color{
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")); return Ok(String::from("Next turn"));
} }
if self.current_card.value == CardValue::PLUS_FOUR{ if self.current_card.value == CardValue::PLUS_FOUR{
let mut player = self.player_states.clone(); let mut player = self.player_states.clone();
self.draw(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), 4); self.draw(player.get_mut(self.current_turn as usize).expect("game integrity compromised"), 4);
} }
if card_value == CardValue::CHANGE_COLOR { if self.current_card.value == CardValue::SKIP{
self.current_color = card_to_be_played.clone().color_change; self.next_player();
self.turns+=1;
return Ok(String::from("Next turn"));
} }
else if card_value == CardValue::PLUS_FOUR{ if card_to_be_played.value == CardValue::REVERSE{
self.current_color = card_to_be_played.color; if self.current_direction == Direction::CLOCKWISE{
} else if [CardValue::EIGHT, CardValue::FIVE, CardValue::FOUR, CardValue::NINE, CardValue::ONE, CardValue::SEVEN, CardValue::SIX, CardValue::THREE, CardValue::TWO, CardValue::ZERO, CardValue::PLUS_TWO].contains(&card_value) { self.current_direction = Direction::COUNTER_CLOCKWISE;
if card_to_be_played.color != self.current_color{ }
self.current_color = card_to_be_played.color.clone(); else {
self.current_direction = Direction::CLOCKWISE;
} }
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 [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.turns+=1;
self.next_player();
return Ok(String::from("Next turn")); return Ok(String::from("Next turn"));
} }
@ -229,7 +267,7 @@ impl GameState<'_>{
return currently_held; return currently_held;
} }
pub fn reset_deck(&mut self, currently_held : Vec<Card>) -> Deck{ fn reset_deck(&mut self, currently_held : Vec<Card>) -> Deck{
self.deck = GameState::base_deck(); self.deck = GameState::base_deck();
for current_cart in currently_held{ for current_cart in currently_held{
self.deck.remove(self.deck.iter().position(|x| *x == current_cart).expect("game integrity compromised")); self.deck.remove(self.deck.iter().position(|x| *x == current_cart).expect("game integrity compromised"));
@ -328,7 +366,7 @@ impl GameState<'_>{
return deck; return deck;
} }
pub fn get_cards(&mut self, count : u32) -> Vec<Card>{ fn get_cards(&mut self, count : u32) -> Vec<Card>{
let mut cards_drawn = vec![]; let mut cards_drawn = vec![];
for _ in 0..count{ for _ in 0..count{
let mut rng = rand::thread_rng(); let mut rng = rand::thread_rng();
@ -338,7 +376,7 @@ impl GameState<'_>{
return cards_drawn return cards_drawn
} }
pub fn draw(&mut self, player : &mut PlayerState, count : u32) -> Vec<Card>{ fn draw(&mut self, player : &mut PlayerState, count : u32) -> Vec<Card>{
if self.deck.len() <= count as usize{ if self.deck.len() <= count as usize{
let currently_held = self.get_currently_held(); let currently_held = self.get_currently_held();
self.reset_deck(currently_held); self.reset_deck(currently_held);
@ -355,3 +393,9 @@ enum Direction {
CLOCKWISE, CLOCKWISE,
COUNTER_CLOCKWISE, COUNTER_CLOCKWISE,
} }
impl PartialEq for Direction{
fn eq(&self, other: &Self) -> bool {
core::mem::discriminant(self) == core::mem::discriminant(other)
}
}