diff --git a/src/board/tictactoe.rs b/src/board/tictactoe.rs
index 54915a9d6f6262ee125cae434e7b2044f3604378..20957216f28b9f2e76eb3282a2debf8f1f3a11bc 100644
--- a/src/board/tictactoe.rs
+++ b/src/board/tictactoe.rs
@@ -1,3 +1,5 @@
+use std::str::FromStr;
+
 #[derive(Clone, Copy, Debug, PartialEq)]
 pub enum Player {
     Cross,
@@ -35,6 +37,7 @@ pub struct Board {
 }
 
 /// A TicTacToe Move
+#[derive(Clone, Copy, Debug, PartialEq)]
 pub enum Move {
     A1 = 0,
     B1 = 1,
@@ -47,10 +50,16 @@ pub enum Move {
     C3 = 8,
 }
 
+// impl std::fmt::FromStr for Move {
+
+// }
+
 impl Board {
     /// Creates a new empty board
     pub fn new() -> Self {
-        Self { board: [Square::Empty; 9] }
+        Self {
+            board: [Square::Empty; 9],
+        }
     }
 
     /// Display the board to standard output
@@ -79,6 +88,45 @@ impl std::fmt::Display for Board {
     }
 }
 
+// Implementations of the Board trait for Tictactoe
+impl super::Board<Move, Player> for Board {
+    /// Apply a move to the board
+    fn do_move(&mut self, turn: Player, m: &Move) {
+        let idx = *m as usize;
+        if self.board[idx] == Square::Empty {
+            self.board[idx] = Square::Full(turn);
+        }
+    }
+
+    /// Returns if a given player has won the game considering this
+    /// board
+    fn has_won(&self, player: Player) -> bool {
+        for (s1, s2, s3) in [
+            // rows
+            (0, 1, 2),
+            (3, 4, 5),
+            (6, 7, 8),
+            // columns
+            (0, 3, 6),
+            (1, 4, 7),
+            (2, 5, 8),
+            // diagonals
+            (0, 4, 8),
+            (2, 4, 6),
+        ] {
+            if (
+                Square::Full(player),
+                Square::Full(player),
+                Square::Full(player),
+            ) == (self.board[s1], self.board[s2], self.board[s3])
+            {
+                return true;
+            }
+        }
+        return false;
+    }
+}
+
 #[cfg(test)]
 mod tests {
     use super::*;