mirror of
https://github.com/coding-horror/basic-computer-games.git
synced 2025-12-30 06:31:46 -08:00
159 lines
4.6 KiB
Rust
159 lines
4.6 KiB
Rust
use rand::prelude::{thread_rng, SliceRandom};
|
|
use std::io;
|
|
|
|
//DATA
|
|
struct CARD {
|
|
suit: u8, //1-4 1=hearts 2=diamonds 3=clubs 4=spades
|
|
value: u8, //2-14 2,3,4,5,6,7,8,9,10,jack,queen,king,ace
|
|
}
|
|
impl CARD {
|
|
/**
|
|
* creates a new card from the passed card name
|
|
*/
|
|
fn new(suit:u8,value:u8) -> CARD {
|
|
return CARD { suit: suit, value: value };
|
|
}
|
|
}
|
|
impl ToString for CARD {
|
|
/**
|
|
* returns string representation of the Card
|
|
*/
|
|
fn to_string(&self) -> String {
|
|
let mut name: String;
|
|
//value
|
|
name = match self.value {
|
|
2..=10 => self.value.to_string() + " of ",
|
|
11 => String::from("Jack of "),
|
|
12 => String::from("Queen of "),
|
|
13 => String::from("King of "),
|
|
14 => String::from("Ace of "),
|
|
_ => panic!("card has an invalid value"),
|
|
};
|
|
//suit
|
|
name += match self.suit {
|
|
1=>"Hearts",
|
|
2=>"Diamonds",
|
|
3=>"Clubs",
|
|
4=>"Spades",
|
|
_ => panic!("card has an invalid suit"),
|
|
};
|
|
return name;
|
|
}
|
|
}
|
|
struct GAME {
|
|
deck: Vec<CARD>, //cards in the deck
|
|
player_score: usize, //human player score
|
|
computer_score:usize,//computer score
|
|
}
|
|
impl GAME {
|
|
/**
|
|
* creates a new game, filling a deck with 52 cards, and setting scores to 0
|
|
*/
|
|
fn new() -> GAME{
|
|
//DATA
|
|
let mut game = GAME{deck: Vec::new(), player_score: 0, computer_score: 0};
|
|
//fill deck
|
|
for suit in 1..=4 { //4 suits
|
|
for value in 2..=14 { //13 cards
|
|
game.deck.push( CARD::new(suit,value) );
|
|
}
|
|
}
|
|
//shuffle deck
|
|
game.deck.shuffle(&mut thread_rng());
|
|
//return game
|
|
return game;
|
|
}
|
|
|
|
/**
|
|
* fully play game
|
|
*/
|
|
fn play_game(&mut self) {
|
|
//DATA
|
|
let mut human_card: CARD;
|
|
let mut computer_card: CARD;
|
|
|
|
//game loop
|
|
while self.deck.len() >=2 {
|
|
//draw cards
|
|
human_card = self.deck.pop().expect("DECK IS EMPTY!");
|
|
computer_card = self.deck.pop().expect("DECK IS EMPTY!");
|
|
|
|
//print cards
|
|
println!("\nYou: {}\t\tComputer: {}",human_card.to_string(), computer_card.to_string());
|
|
|
|
//determine winner
|
|
if human_card.value > computer_card.value { //human wins
|
|
self.player_score += 1;
|
|
println!("You win. You have {} and the computer has {}", human_card.value, computer_card.value);
|
|
}
|
|
else if human_card.value < computer_card.value { //computer wins
|
|
self.computer_score += 1;
|
|
println!("The computer wins!!! You have {} and the computer has {}", human_card.value, computer_card.value);
|
|
}
|
|
else { //tie
|
|
println!("Tie. No score change.")
|
|
}
|
|
if !get_yes_no_from_user_input("Do you want to continue? y/n") {break;}
|
|
}
|
|
if self.deck.is_empty() {
|
|
println!("WE HAVE RUN OUT OF CARDS. FINAL SCORE: YOU: {} THE COMPUTER: {}",self.player_score, self.computer_score);
|
|
}
|
|
println!("\nThanks for playing. It was fun.");
|
|
}
|
|
}
|
|
|
|
fn main() {
|
|
//print welcome message
|
|
welcome();
|
|
|
|
//game loop
|
|
let mut game = GAME::new();
|
|
loop {
|
|
game.play_game();
|
|
if !get_yes_no_from_user_input("\nPlay again? (yes or no) ") {break;}
|
|
game = GAME::new();
|
|
}
|
|
}
|
|
|
|
/**
|
|
* print welcome message
|
|
*/
|
|
fn welcome() {
|
|
println!("
|
|
War\n
|
|
CREATIVE COMPUTING MORRISTOWN, NEW JERSEY\n
|
|
This is the card game of war. Each card is given by # of suit
|
|
ex: Ace of Spades\n
|
|
");
|
|
if get_yes_no_from_user_input("Do you want directions?") {
|
|
println!("
|
|
The computer gives you and it a 'card'. The higher card
|
|
(numerically) wins. The game ends when you choose not to
|
|
continue or when you have finished the pack.\n
|
|
");
|
|
}
|
|
}
|
|
|
|
/**
|
|
* returns true if user input starts with y or Y,
|
|
* false otherwise
|
|
*/
|
|
fn get_yes_no_from_user_input(prompt: &str) -> bool {
|
|
let mut raw_input = String::new(); // temporary variable for user input that can be parsed later
|
|
|
|
//print prompt
|
|
println!("{}", prompt);
|
|
//read user input from standard input, and store it to raw_input
|
|
//raw_input.clear(); //clear input
|
|
io::stdin().read_line(&mut raw_input).expect( "CANNOT READ INPUT!");
|
|
|
|
//from input, try to read a valid character
|
|
if let Some(i) = raw_input.trim().chars().nth(0) {
|
|
if i == 'y' || i == 'Y' {
|
|
return true;
|
|
}
|
|
}
|
|
//default case
|
|
return false;
|
|
}
|