diff -r a95b84125269 -r 5f81068a8a88 src/main.rs --- a/src/main.rs Sun Jan 29 21:41:10 2023 +0100 +++ b/src/main.rs Sun Jan 29 23:59:45 2023 +0100 @@ -1,13 +1,13 @@ // vigyazz6! autplayer // -use core::fmt; +use core::{fmt, panic}; use std::collections::VecDeque; use rand::Rng; use std::mem; fn main() { - println!("Hello, world!"); + game(); } #[derive(Debug)] @@ -61,6 +61,25 @@ } } +impl Eq for Card {} + +impl PartialOrd for Card { + fn partial_cmp(&self, other: &Self) -> Option { + match self.value.partial_cmp(&other.value) { + Some(core::cmp::Ordering::Equal) => {None} + ord => return ord, + } + } +} + +impl Ord for Card { + fn cmp(&self, other: &Self) -> std::cmp::Ordering { + self.value.cmp(&other.value) + } +} + + +#[derive(Debug)] struct Deck { content: VecDeque, } @@ -88,9 +107,9 @@ // * grin: take 1..6 from front and put at bottom // naive shuffle: exchange random cards - for _i in 1..500 { - let c1 = rng.gen_range(1 .. self.content.len()); - let c2 = rng.gen_range(1 .. self.content.len()); + for _i in 1..=500 { + let c1 = rng.gen_range(0 .. self.content.len()); + let c2 = rng.gen_range(0 .. self.content.len()); if c1 != c2 { self.content.swap(c1, c2); } @@ -120,6 +139,7 @@ } } +#[derive(Debug)] struct Player { name: String, hand: Deck, @@ -156,7 +176,7 @@ } // get a busted row of cards - fn get_pile( &mut self, cards: Vec ) { + fn get_pile( &mut self, cards: VecDeque ) { for c in cards.into_iter() { self.game_point += c.points as i32; self.pile.push(c); @@ -208,6 +228,7 @@ } // a row of cards on the table (max 5) +#[derive(Debug)] struct Row { cards: VecDeque, } @@ -243,32 +264,166 @@ } } +#[derive(Debug)] struct PlayerCard { - player_id: u32, + player_id: i32, card: Card, } +impl PlayerCard { + fn get_player(&self) -> i32 { + self.player_id + } +} + +impl PartialEq for PlayerCard { + fn eq(&self, other: &Self) -> bool { + self.card == other.card + } +} + +impl PartialOrd for PlayerCard { + fn partial_cmp(&self, other: &Self) -> Option { + match self.card.partial_cmp(&other.card) { + Some(core::cmp::Ordering::Equal) => {None} + ord => return ord, + } + } +} + +#[derive(Debug)] struct Table { rows: Vec, player_cards: Vec, // owned by a player } +impl Table { + fn new(row_cards: Vec) -> Self { + let mut rows = Vec::new(); + for card in row_cards { + // create a new row then put a card into it + let mut row = Row::new(); + if let Some(c) = row.push_or_collect(card) { + panic!("Freshly created row overflowed"); + } + rows.push( row ); + } + Table { + rows, + player_cards: Vec::new(), + } + } + + fn lay_player_card( &mut self, card: Card, player_id: i32 ) { + self.player_cards.push( PlayerCard { player_id, card } ); + } + + fn sort_cards( &mut self ) { + self.player_cards.sort_by( |a,b| b.card.cmp(&a.card) ); + } + + fn get_smallest_player_card( &mut self ) -> PlayerCard { + self.player_cards.pop().expect("out of player cards on table") + } + + fn get_closest_row( &self, pcard: &PlayerCard ) -> Option { + // get the row id with last card closest smaller to players' + todo!() + } + + fn put_card_into_row( &mut self, pcard: PlayerCard, row_id: i8 ) -> Option> { + self.rows[row_id as usize].push_or_collect(pcard.card) + } +} fn game() { -/* - let mut deck = deck_init(); - let mut players = Vec::new(); + let mut cnt_shuffle = 0; + + let mut deck = Deck::new(); + + let player_names = vec![ "grin", "moni", "icbalint", "orsi", "topi", "kgb", "zsu", "csilla" ]; + let mut players: Vec = player_names.iter().map( |n| Player::new(n.to_string()) ).collect(); + + let player_count = players.len(); // pc - 1 + + for _cnt_game in 1..=2 { + deck.shuffle(); + cnt_shuffle += 1; + + // dealing + for i in 1..=10 { + for player in 0 .. player_count { + players[player].get_card( deck.pop().expect("Deck is empty while dealing to players") ); + } + } + + // we need 5 crds from deck + let mut cards = Vec::new(); + for i in 1..=5 { + cards.push( deck.pop().expect("deck empty before starting the game") ); + } + println!("We push 5 cards to rows: {:?}\n", cards); + let mut table = Table::new(cards); + + // DEBUG + println!("Table: {:?}\n", table); + println!("PLayers: {:?}\n", players); + println!("Deck: {:?}\n", deck); + + + // playing + for turn in 1..=10 { - for cnt_game in (1..100) { + // everyone puts a card face down + for player in 0 .. player_count { + let player_id: i32 = player.try_into().unwrap(); + // get a card from the player + let topcard = players[player].throw_card(); + // put it on the table ("turned face down") + table.lay_player_card( topcard, player_id ); + } + + // process cards + table.sort_cards(); + + let smallest = table.get_smallest_player_card(); + let closest_row = table.get_closest_row(&smallest); + match closest_row { + Some(rowid) => { + let player_id: usize = smallest.player_id.try_into().unwrap(); + let overflow = table.put_card_into_row(smallest, rowid); + if let Some(cards) = overflow { + // row is full, got pile + // player gets pile, card gets into row head + players[ player_id ].get_pile( cards ); + } + }, + None => { + // card too small, need to pick row! + todo!(); + } + } + + } + + // end of round + + // recollect deck + + panic!("FInish now."); } - */ } #[cfg(test)] mod tests { + use core::panic; + use std::collections::VecDeque; + + use rand::Rng; + use crate::{Card, Player, Row}; #[test] @@ -287,11 +442,11 @@ // create a player let mut p = Player::new("bob".to_string()); // create a pile - let mut pile = Vec::new(); + let mut pile = VecDeque::new(); let mut refpile = Vec::new(); for i in 5..10 { let c = Card::new(i); - pile.push(c); + pile.push_back(c); let c = Card::new(i); refpile.push(c); } @@ -307,10 +462,10 @@ // this check is O(n^2), doesn't matter for less than 100 items assert!( pile.iter().all( |item| refpile.contains(item)) ); - let mut pile = Vec::new(); - for i in 4..9 { + let mut pile = VecDeque::new(); + for i in 4..=9 { let c = Card::new(i); - pile.push(c); + pile.push_back(c); } p.get_pile(pile); assert!( p.rows_busted == 2 ); @@ -342,6 +497,22 @@ } assert!( row.cards.len() == 2, "Row contains wrong amount of cards: {}", row.cards.len() ); } + + #[test] + fn sort_cards() { + let mut cards: Vec = Vec::new(); + let mut rng = rand::thread_rng(); + for i in 1..50 { + let n = rng.gen_range(1..104); + cards.push( Card::new(n) ); + } + cards.sort(); + + for i in 1..cards.len() { + assert!( cards[i-1].value <= cards[i].value, "Bad ordering: {} > {}", cards[i-1].value,cards[i].value ); + } + } + } /*