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
[[package]]
name = "intro-rust-game"
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"
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[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
pub mod tictactoe;
pub mod coin_flip;
/// 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
pub trait Board<Move, Player> {
pub trait Game<Move, Player> {
/// Apply a move to the board
fn do_move(&mut self, turn: Player, m: &Move);
......
......@@ -121,7 +121,7 @@ impl std::fmt::Display for Board {
}
// 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
fn do_move(&mut self, turn: Player, m: &Move) {
let idx = *m as usize;
......
mod board;
use board::tictactoe::Board as TicTacToe;
use board::Board;
use board::Game;
use std::io;
use std::io::prelude::*;
......@@ -13,9 +13,9 @@ where
io::stdout().flush().unwrap();
}
fn play<Game, Move, Player>(mut board: Game)
fn play<G, Move, Player>(mut board: G)
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>,
Move: std::str::FromStr,
{
......@@ -44,7 +44,8 @@ where
}
fn main() {
let board = TicTacToe::new();
//let board = TicTacToe::new();
let board = board::coin_flip::FlipCoin::new(42);
play(board);
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment