Go Fish/Rust
< Go Fish
Go Fish/Rust is part of Go_Fish. You may find other members of Go_Fish at Category:Go_Fish.
Rust implementation of Go Fish.
<lang Rust> use rand::thread_rng; use rand::seq::SliceRandom; use std::io::Write;
// parameters const STARTING_HAND_SIZE: usize = 9; const NUM_SUITS: usize = 4;
struct Deck {
cards: Vec<String>,
}
impl Deck {
fn new() -> Self { Self { // initializes deck with cards cards: { let mut deck = vec![]; for i in "2 3 4 5 6 7 8 9 10 J Q K A".split(" ") { for _ in 0..NUM_SUITS { deck.push(String::from(i)); } } deck } } }
fn shuffle(&mut self) { self.cards.shuffle(&mut thread_rng()); }
fn done(&self) -> bool { self.cards.len() == 0 }
fn draw(& mut self) -> String { self.cards.pop().unwrap() }
}
struct Player {
hand: Vec<String>, score: usize, name: String,
}
impl Player {
fn new(deck: &mut Deck, name: &str) -> Self { // initializes player, draws starting hand let mut p = Self { hand: vec![], score: 0, name: String::from(name), }; for _ in 0..STARTING_HAND_SIZE { p.add(deck.draw(), deck); } p }
fn done(&self) -> bool { self.hand.len() == 0 }
fn draw(&mut self, deck: &mut Deck) { self.add(deck.draw(), deck); }
fn has(&self, card: &String) -> bool { self.hand.contains(card) }
fn take(&mut self, card: &String) -> Option<String> { if self.has(card) { let mut i = 0; for c in &self.hand { if c == card { break; } i += 1; } Some(self.hand.remove(i)) } else { None } }
fn add(&mut self, card: String, deck: &mut Deck) { // adds card to hand. If you have NUM_SUITS, get a book. If you have no cards, draw. if self.hand.contains(&card) { let mut i = 0; for item in &self.hand { if item == &card { i += 1; } } if i == NUM_SUITS-1 { while self.has(&card) { self.take(&card); } self.score += 1; if self.done() && !deck.done() { self.draw(deck); } return; } } self.hand.push(card); self.hand.sort(); }
}
fn input(string: &str) -> String {
print!("{}", string); std::io::stdout().flush().unwrap(); let mut line = String::new(); std::io::stdin().read_line(&mut line).unwrap(); line.pop(); // \n\r line.pop(); line
}
fn main() {
let mut thread = thread_rng(); let mut deck = Deck::new(); deck.shuffle(); let mut user = Player::new(&mut deck, &input("Enter your name: ")); let mut npc = Player::new(&mut deck, "NPC");
let mut has_guessed = vec![];
let mut player_turn = true; // toggle
while !deck.done() { println!("\n\ndeck size: {}", deck.cards.len()); if player_turn { while !deck.done() { print!("\n== {}'s Turn ==\n{}: {}\nNPC: {}\nYOUR HAND: ", user.name, user.name, user.score, npc.score); for card in &user.hand { print!("{} ", card); }
let mut choice = input("\nYou fish for a: "); while !"2 3 4 5 6 7 8 9 10 J Q K A".split(" ").collect::<Vec<&str>>().contains(&choice.as_str()) || !user.hand.contains(&choice) { println!("invalid response, expecting 2, 3, 4, 5, ..., Q, K, A. The card must be in your hand."); choice = input("You fish for a: "); } if !has_guessed.contains(&choice) { has_guessed.push(choice.clone()); } match npc.take(&choice) { Some(thing) => { user.add(thing, &mut deck); while npc.has(&choice) { user.add(npc.take(&choice).unwrap(), &mut deck); } println!("Yes, go again"); } None => { user.draw(&mut deck); println!("Go fish!"); break; } } } } else { while !deck.done() { print!("\n== NPC's Turn ==\n{}: {}\nNPC: {}\nYOUR HAND: ", user.name, user.score, npc.score); for card in &user.hand { print!("{} ", card); }
// guess if user has guessed & you have let mut choice = String::new(); for string in &has_guessed { if npc.hand.contains(string) { choice = string.clone(); } } if &choice == "" { choice = npc.hand.choose(&mut thread).unwrap().clone(); }
println!("\nDo you have a {}?", choice); match user.take(&choice) { Some(thing) => { println!("Yes, I do."); npc.add(thing, &mut deck); while user.has(&choice) { npc.add(user.take(&choice).unwrap(), &mut deck); } input("\n..."); } None => { npc.draw(&mut deck); println!("Go fish!"); input("\n..."); break; } } } } player_turn = !player_turn; } if deck.done() { println!("Deck Empty, Game Over"); } if user.score > npc.score { println!("{} has won with a score of {}", user.name, user.score); } else if user.score == npc.score { println!("{} and {} have tied with a score of {}", user.name, npc.name, user.score); } else { println!("{} has won with a score of {}", npc.name, npc.score); }
} </lang>