src/main.rs
changeset 1 5f81068a8a88
parent 0 a95b84125269
child 2 950660fddec0
equal deleted inserted replaced
0:a95b84125269 1:5f81068a8a88
     1 // vigyazz6! autplayer
     1 // vigyazz6! autplayer
     2 //
     2 //
     3 
     3 
     4 use core::fmt;
     4 use core::{fmt, panic};
     5 use std::collections::VecDeque;
     5 use std::collections::VecDeque;
     6 use rand::Rng;
     6 use rand::Rng;
     7 use std::mem;
     7 use std::mem;
     8 
     8 
     9 fn main() {
     9 fn main() {
    10     println!("Hello, world!");
    10     game();
    11 }
    11 }
    12 
    12 
    13 #[derive(Debug)]
    13 #[derive(Debug)]
    14 struct Card {
    14 struct Card {
    15     value: i8,
    15     value: i8,
    59     fn eq(&self, other: &Self) -> bool {
    59     fn eq(&self, other: &Self) -> bool {
    60         self.value == other.value
    60         self.value == other.value
    61     }
    61     }
    62 }
    62 }
    63 
    63 
       
    64 impl Eq for Card {} 
       
    65 
       
    66 impl PartialOrd for Card {
       
    67     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
       
    68         match self.value.partial_cmp(&other.value) {
       
    69             Some(core::cmp::Ordering::Equal) => {None}
       
    70             ord => return ord,
       
    71         }
       
    72     }
       
    73 }
       
    74 
       
    75 impl Ord for Card {
       
    76     fn cmp(&self, other: &Self) -> std::cmp::Ordering {
       
    77         self.value.cmp(&other.value)
       
    78     }
       
    79 }
       
    80 
       
    81 
       
    82 #[derive(Debug)]
    64 struct Deck {
    83 struct Deck {
    65     content: VecDeque<Card>,
    84     content: VecDeque<Card>,
    66 }
    85 }
    67 
    86 
    68 impl Deck {
    87 impl Deck {
    86         // * naive: swap cards n times
   105         // * naive: swap cards n times
    87         // * kgb: half the deck, take 1..4 cards sequentially from each
   106         // * kgb: half the deck, take 1..4 cards sequentially from each
    88         // * grin: take 1..6 from front and put at bottom
   107         // * grin: take 1..6 from front and put at bottom
    89 
   108 
    90         // naive shuffle: exchange random cards
   109         // naive shuffle: exchange random cards
    91         for _i in 1..500 {
   110         for _i in 1..=500 {
    92             let c1 = rng.gen_range(1 .. self.content.len());
   111             let c1 = rng.gen_range(0 .. self.content.len());
    93             let c2 = rng.gen_range(1 .. self.content.len());
   112             let c2 = rng.gen_range(0 .. self.content.len());
    94             if c1 != c2 {
   113             if c1 != c2 {
    95                 self.content.swap(c1, c2);
   114                 self.content.swap(c1, c2);
    96             }
   115             }
    97         }
   116         }
    98     }
   117     }
   118             panic!("get_nth: index {} out of bounds ({})!", n, self.content.len());
   137             panic!("get_nth: index {} out of bounds ({})!", n, self.content.len());
   119         }
   138         }
   120     }
   139     }
   121 }
   140 }
   122 
   141 
       
   142 #[derive(Debug)]
   123 struct Player {
   143 struct Player {
   124     name: String,
   144     name: String,
   125     hand: Deck,
   145     hand: Deck,
   126     pile: Vec<Card>,
   146     pile: Vec<Card>,
   127     game_point: i32,
   147     game_point: i32,
   154             panic!("throw_card: Player {} has no card in hand!", self.name);
   174             panic!("throw_card: Player {} has no card in hand!", self.name);
   155         }
   175         }
   156     }
   176     }
   157 
   177 
   158     // get a busted row of cards
   178     // get a busted row of cards
   159     fn get_pile( &mut self, cards: Vec<Card> ) {
   179     fn get_pile( &mut self, cards: VecDeque<Card> ) {
   160         for c in cards.into_iter() {
   180         for c in cards.into_iter() {
   161             self.game_point += c.points as i32;
   181             self.game_point += c.points as i32;
   162             self.pile.push(c);
   182             self.pile.push(c);
   163         }
   183         }
   164         self.rows_busted += 1;
   184         self.rows_busted += 1;
   206         self.game_point = 0;
   226         self.game_point = 0;
   207     }
   227     }
   208 }
   228 }
   209 
   229 
   210 // a row of cards on the table (max 5)
   230 // a row of cards on the table (max 5)
       
   231 #[derive(Debug)]
   211 struct Row {
   232 struct Row {
   212     cards: VecDeque<Card>,
   233     cards: VecDeque<Card>,
   213 }
   234 }
   214 
   235 
   215 impl Row {
   236 impl Row {
   241         println!("last_card_value: cards {:?}, len {}", self.cards, self.cards.len());
   262         println!("last_card_value: cards {:?}, len {}", self.cards, self.cards.len());
   242         self.cards.get( self.cards.len()-1 ).unwrap().value
   263         self.cards.get( self.cards.len()-1 ).unwrap().value
   243     }
   264     }
   244 }
   265 }
   245 
   266 
       
   267 #[derive(Debug)]
   246 struct PlayerCard {
   268 struct PlayerCard {
   247     player_id: u32,
   269     player_id: i32,
   248     card: Card,
   270     card: Card,
   249 }
   271 }
   250 
   272 
       
   273 impl PlayerCard {
       
   274     fn get_player(&self) -> i32 {
       
   275         self.player_id
       
   276     }
       
   277 }
       
   278 
       
   279 impl PartialEq for PlayerCard {
       
   280     fn eq(&self, other: &Self) -> bool {
       
   281         self.card == other.card
       
   282     }
       
   283 }
       
   284 
       
   285 impl PartialOrd for PlayerCard {
       
   286     fn partial_cmp(&self, other: &Self) -> Option<std::cmp::Ordering> {
       
   287         match self.card.partial_cmp(&other.card) {
       
   288             Some(core::cmp::Ordering::Equal) => {None}
       
   289             ord => return ord,
       
   290         }
       
   291     }
       
   292 }
       
   293 
       
   294 #[derive(Debug)]
   251 struct Table {
   295 struct Table {
   252     rows: Vec<Row>,
   296     rows: Vec<Row>,
   253     player_cards: Vec<PlayerCard>, // owned by a player
   297     player_cards: Vec<PlayerCard>, // owned by a player
   254 }
   298 }
   255 
   299 
   256 
   300 impl Table {
       
   301     fn new(row_cards: Vec<Card>) -> Self {
       
   302         let mut rows = Vec::new();
       
   303         for card in row_cards {
       
   304             // create a new row then put a card into it
       
   305             let mut row = Row::new();
       
   306             if let Some(c) = row.push_or_collect(card) {
       
   307                 panic!("Freshly created row overflowed");
       
   308             }
       
   309             rows.push( row );
       
   310         }
       
   311 
       
   312         Table {
       
   313             rows,
       
   314             player_cards: Vec::new(),
       
   315         }
       
   316     }
       
   317 
       
   318     fn lay_player_card( &mut self, card: Card, player_id: i32 ) {
       
   319         self.player_cards.push( PlayerCard { player_id, card } );
       
   320     }
       
   321 
       
   322     fn sort_cards( &mut self ) {
       
   323         self.player_cards.sort_by( |a,b| b.card.cmp(&a.card) );
       
   324     }
       
   325 
       
   326     fn get_smallest_player_card( &mut self ) -> PlayerCard {
       
   327         self.player_cards.pop().expect("out of player cards on table")
       
   328     }
       
   329 
       
   330     fn get_closest_row( &self, pcard: &PlayerCard ) -> Option<i8> {
       
   331         // get the row id with last card closest smaller to players'
       
   332         todo!()
       
   333     }
       
   334 
       
   335     fn put_card_into_row( &mut self, pcard: PlayerCard, row_id: i8 ) -> Option<VecDeque<Card>> {
       
   336         self.rows[row_id as usize].push_or_collect(pcard.card)
       
   337     }
       
   338 }
   257 
   339 
   258 
   340 
   259 fn game() {
   341 fn game() {
   260 /*
   342     let mut cnt_shuffle = 0;
   261     let mut deck = deck_init();
   343 
   262     let mut players = Vec::new();
   344     let mut deck = Deck::new();
   263 
   345 
   264     for cnt_game in (1..100) {
   346     let player_names = vec![ "grin", "moni", "icbalint", "orsi", "topi", "kgb", "zsu", "csilla" ];
   265 
   347     let mut players: Vec<Player> = player_names.iter().map( |n| Player::new(n.to_string()) ).collect();
   266     }
   348 
   267      */
   349     let player_count = players.len(); // pc - 1
       
   350 
       
   351     for _cnt_game in 1..=2 {
       
   352         deck.shuffle();
       
   353         cnt_shuffle += 1;
       
   354 
       
   355         // dealing
       
   356         for i in 1..=10 {
       
   357             for player in 0 .. player_count {
       
   358                 players[player].get_card( deck.pop().expect("Deck is empty while dealing to players") );
       
   359             }
       
   360         }
       
   361 
       
   362         // we need 5 crds from deck
       
   363         let mut cards = Vec::new();
       
   364         for i in 1..=5 {
       
   365             cards.push( deck.pop().expect("deck empty before starting the game") );
       
   366         }
       
   367         println!("We push 5 cards to rows: {:?}\n", cards);
       
   368         let mut table = Table::new(cards);
       
   369 
       
   370         // DEBUG
       
   371         println!("Table: {:?}\n", table);
       
   372         println!("PLayers: {:?}\n", players);
       
   373         println!("Deck: {:?}\n", deck);
       
   374         
       
   375 
       
   376         // playing
       
   377         for turn in 1..=10 {
       
   378 
       
   379             // everyone puts a card face down
       
   380             for player in 0 .. player_count {
       
   381                 let player_id: i32 = player.try_into().unwrap();
       
   382                 // get a card from the player
       
   383                 let topcard = players[player].throw_card();
       
   384                 // put it on the table ("turned face down")
       
   385                 table.lay_player_card( topcard, player_id );
       
   386             }
       
   387 
       
   388             // process cards
       
   389             table.sort_cards();
       
   390 
       
   391             let smallest = table.get_smallest_player_card();
       
   392 
       
   393             let closest_row = table.get_closest_row(&smallest);
       
   394             match closest_row {
       
   395                 Some(rowid) => {
       
   396                     let player_id: usize = smallest.player_id.try_into().unwrap();
       
   397                     let overflow = table.put_card_into_row(smallest, rowid);
       
   398                     if let Some(cards) = overflow {
       
   399                         // row is full, got pile
       
   400                         // player gets pile, card gets into row head
       
   401                         players[ player_id ].get_pile( cards );
       
   402                     }
       
   403                 },
       
   404                 None => {
       
   405                     // card too small, need to pick row!
       
   406                     todo!();
       
   407                 }
       
   408             }
       
   409 
       
   410         }
       
   411 
       
   412         // end of round
       
   413 
       
   414         // recollect deck
       
   415 
       
   416         panic!("FInish now.");
       
   417     }
   268 }
   418 }
   269 
   419 
   270 #[cfg(test)]
   420 #[cfg(test)]
   271 mod tests {
   421 mod tests {
       
   422     use core::panic;
       
   423     use std::collections::VecDeque;
       
   424 
       
   425     use rand::Rng;
       
   426 
   272     use crate::{Card, Player, Row};
   427     use crate::{Card, Player, Row};
   273 
   428 
   274     #[test]
   429     #[test]
   275     fn card_values() {
   430     fn card_values() {
   276         let card_values = vec![1,2,5,10,33,55,77];
   431         let card_values = vec![1,2,5,10,33,55,77];
   285     #[test]
   440     #[test]
   286     fn player_take_pile() {
   441     fn player_take_pile() {
   287         // create a player
   442         // create a player
   288         let mut p = Player::new("bob".to_string());
   443         let mut p = Player::new("bob".to_string());
   289         // create a pile
   444         // create a pile
   290         let mut pile = Vec::new();
   445         let mut pile = VecDeque::new();
   291         let mut refpile = Vec::new();
   446         let mut refpile = Vec::new();
   292         for i in 5..10 {
   447         for i in 5..10 {
   293             let c = Card::new(i);
   448             let c = Card::new(i);
   294             pile.push(c);
   449             pile.push_back(c);
   295             let c = Card::new(i);
   450             let c = Card::new(i);
   296             refpile.push(c);
   451             refpile.push(c);
   297         }
   452         }
   298         // add the pile to player
   453         // add the pile to player
   299         p.get_pile(pile);
   454         p.get_pile(pile);
   305         
   460         
   306         // the pile we got shall be same as the pile we gave
   461         // the pile we got shall be same as the pile we gave
   307         // this check is O(n^2), doesn't matter for less than 100 items
   462         // this check is O(n^2), doesn't matter for less than 100 items
   308         assert!( pile.iter().all( |item| refpile.contains(item)) );
   463         assert!( pile.iter().all( |item| refpile.contains(item)) );
   309 
   464 
   310         let mut pile = Vec::new();
   465         let mut pile = VecDeque::new();
   311         for i in 4..9 {
   466         for i in 4..=9 {
   312             let c = Card::new(i);
   467             let c = Card::new(i);
   313             pile.push(c);
   468             pile.push_back(c);
   314         }
   469         }
   315         p.get_pile(pile);
   470         p.get_pile(pile);
   316         assert!( p.rows_busted == 2 );
   471         assert!( p.rows_busted == 2 );
   317     }
   472     }
   318 
   473 
   340             // check card value
   495             // check card value
   341             assert!( row.last_card_value() == cval, "Last card value mismatch: got {} vs expected {}", row.last_card_value(), cval );
   496             assert!( row.last_card_value() == cval, "Last card value mismatch: got {} vs expected {}", row.last_card_value(), cval );
   342         }
   497         }
   343         assert!( row.cards.len() == 2, "Row contains wrong amount of cards: {}", row.cards.len() );
   498         assert!( row.cards.len() == 2, "Row contains wrong amount of cards: {}", row.cards.len() );
   344     }
   499     }
       
   500 
       
   501     #[test]
       
   502     fn sort_cards() {
       
   503         let mut cards: Vec<Card> = Vec::new();
       
   504         let mut rng = rand::thread_rng();
       
   505         for i in 1..50 {
       
   506             let n = rng.gen_range(1..104);
       
   507             cards.push( Card::new(n) );
       
   508         }
       
   509         cards.sort();
       
   510 
       
   511         for i in 1..cards.len() {
       
   512             assert!( cards[i-1].value <= cards[i].value, "Bad ordering: {} > {}", cards[i-1].value,cards[i].value );
       
   513         }
       
   514     }
       
   515 
   345 }
   516 }
   346 
   517 
   347 /*
   518 /*
   348 
   519 
   349 - 1-104 lap, 
   520 - 1-104 lap,