From 6fc215b6f7411c147a55d310d6d50700a6277afa Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Micha=C3=ABl=20Hauspie?= <michael.hauspie@univ-lille.fr>
Date: Tue, 29 Nov 2022 00:06:11 +0100
Subject: [PATCH] Add a Coin flip game
---
Cargo.lock | 9 ++++
Cargo.toml | 1 +
src/board/coin_flip.rs | 103 +++++++++++++++++++++++++++++++++++++++++
src/board/mod.rs | 3 +-
src/board/tictactoe.rs | 2 +-
src/main.rs | 9 ++--
6 files changed, 121 insertions(+), 6 deletions(-)
create mode 100644 src/board/coin_flip.rs
diff --git a/Cargo.lock b/Cargo.lock
index 52ce037..99a531b 100644
--- a/Cargo.lock
+++ b/Cargo.lock
@@ -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"
diff --git a/Cargo.toml b/Cargo.toml
index 3319a91..6f5e9a7 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -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"
diff --git a/src/board/coin_flip.rs b/src/board/coin_flip.rs
new file mode 100644
index 0000000..2d41065
--- /dev/null
+++ b/src/board/coin_flip.rs
@@ -0,0 +1,103 @@
+//! 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,
+ }
+ }
+}
diff --git a/src/board/mod.rs b/src/board/mod.rs
index 052f915..5fd06df 100644
--- a/src/board/mod.rs
+++ b/src/board/mod.rs
@@ -1,10 +1,11 @@
//! 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);
diff --git a/src/board/tictactoe.rs b/src/board/tictactoe.rs
index b5a44a3..eb656d6 100644
--- a/src/board/tictactoe.rs
+++ b/src/board/tictactoe.rs
@@ -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;
diff --git a/src/main.rs b/src/main.rs
index 6c0d36e..52dfb1c 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,7 +1,7 @@
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);
}
--
GitLab