--- 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<std::cmp::Ordering> {
+ 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<Card>,
}
@@ -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<Card> ) {
+ fn get_pile( &mut self, cards: VecDeque<Card> ) {
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<Card>,
}
@@ -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<std::cmp::Ordering> {
+ match self.card.partial_cmp(&other.card) {
+ Some(core::cmp::Ordering::Equal) => {None}
+ ord => return ord,
+ }
+ }
+}
+
+#[derive(Debug)]
struct Table {
rows: Vec<Row>,
player_cards: Vec<PlayerCard>, // owned by a player
}
+impl Table {
+ fn new(row_cards: Vec<Card>) -> 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<i8> {
+ // 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<VecDeque<Card>> {
+ 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> = 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<Card> = 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 );
+ }
+ }
+
}
/*