Skip to content
Snippets Groups Projects
Commit 6fc215b6 authored by Michael Hauspie's avatar Michael Hauspie
Browse files

Add a Coin flip game

parent b556719b
No related branches found
No related tags found
No related merge requests found
...@@ -5,3 +5,12 @@ version = 3 ...@@ -5,3 +5,12 @@ version = 3
[[package]] [[package]]
name = "intro-rust-game" name = "intro-rust-game"
version = "0.1.0" version = "0.1.0"
dependencies = [
"random",
]
[[package]]
name = "random"
version = "0.13.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "474c42c904f04dfe2a595a02f71e1a0e5e92ffb5761cc9a4c02140b93b8dd504"
...@@ -6,3 +6,4 @@ edition = "2021" ...@@ -6,3 +6,4 @@ edition = "2021"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html # See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies] [dependencies]
random = "0.13.2"
//! A flip a coin one player game
/// A possible move for a flip a coin game
#[derive(Clone, Copy, Debug, PartialEq)]
pub enum Move {
Heads,
Tails,
}
#[derive(Clone, Copy, Debug, PartialEq)]
/// A flip coin player (me...)
pub enum Player {
Me,
}
impl Default for Player {
fn default() -> Self {
Player::Me
}
}
impl std::fmt::Display for Player {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
write!(f, "me")
}
}
impl std::ops::Not for Player {
type Output = Self;
fn not(self) -> Self::Output {
self
}
}
impl std::str::FromStr for Move {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s {
"h" | "heads" => Ok(Move::Heads),
"t" | "tails" => Ok(Move::Tails),
_ => Err(format!("Invalid move {}", s)),
}
}
}
impl std::fmt::Display for Move {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match self {
Move::Heads => write!(f, "Heads"),
Move::Tails => write!(f, "Tails"),
}
}
}
use random::Source;
pub struct FlipCoin {
random_source: random::Default,
last_flip: Option<Move>,
guessed: Option<Move>,
}
impl FlipCoin {
/// Creates a new flipcoin game from a random seed
pub fn new(seed: u64) -> Self {
Self {
random_source: random::default(seed),
last_flip: None,
guessed: None
}
}
}
impl std::fmt::Display for FlipCoin {
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
match (self.last_flip, self.guessed) {
(Some(c), Some(g)) => write!(f, "You chose {} and flipped {}", g, c),
_ => write!(f, "Lets flip a coin!"),
}
}
}
impl super::Game<Move, Player> for FlipCoin {
fn do_move(&mut self, _turn: Player, m: &Move) {
self.guessed = Some(*m);
self.last_flip = if self.random_source.read_f64() > 0.5 {
Some(Move::Heads)
} else {
Some(Move::Tails)
}
}
fn has_won(&self, _player: Player) -> bool {
match (self.last_flip, self.guessed) {
(Some(f), Some(g)) => f == g,
_ => false,
}
}
}
//! A module that implements several board games //! A module that implements several board games
pub mod tictactoe; pub mod tictactoe;
pub mod coin_flip;
/// A trait that defines a Board for a game where we can make a player /// A trait that defines a Board for a game where we can make a player
/// play a move and check if a player has won /// play a move and check if a player has won
pub trait Board<Move, Player> { pub trait Game<Move, Player> {
/// Apply a move to the board /// Apply a move to the board
fn do_move(&mut self, turn: Player, m: &Move); fn do_move(&mut self, turn: Player, m: &Move);
......
...@@ -121,7 +121,7 @@ impl std::fmt::Display for Board { ...@@ -121,7 +121,7 @@ impl std::fmt::Display for Board {
} }
// Implementations of the Board trait for Tictactoe // Implementations of the Board trait for Tictactoe
impl super::Board<Move, Player> for Board { impl super::Game<Move, Player> for Board {
/// Apply a move to the board /// Apply a move to the board
fn do_move(&mut self, turn: Player, m: &Move) { fn do_move(&mut self, turn: Player, m: &Move) {
let idx = *m as usize; let idx = *m as usize;
......
mod board; mod board;
use board::tictactoe::Board as TicTacToe; use board::tictactoe::Board as TicTacToe;
use board::Board; use board::Game;
use std::io; use std::io;
use std::io::prelude::*; use std::io::prelude::*;
...@@ -13,9 +13,9 @@ where ...@@ -13,9 +13,9 @@ where
io::stdout().flush().unwrap(); io::stdout().flush().unwrap();
} }
fn play<Game, Move, Player>(mut board: Game) fn play<G, Move, Player>(mut board: G)
where where
Game: Board<Move, Player> + std::fmt::Display, G: Game<Move, Player> + std::fmt::Display,
Player: Copy + std::fmt::Display + Default + std::ops::Not<Output = Player>, Player: Copy + std::fmt::Display + Default + std::ops::Not<Output = Player>,
Move: std::str::FromStr, Move: std::str::FromStr,
{ {
...@@ -44,7 +44,8 @@ where ...@@ -44,7 +44,8 @@ where
} }
fn main() { fn main() {
let board = TicTacToe::new(); //let board = TicTacToe::new();
let board = board::coin_flip::FlipCoin::new(42);
play(board); play(board);
} }
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment