diff --git a/src/board/mod.rs b/src/board/mod.rs
index 80b24fb8fa20d3dcc9fe3ae5d87f713cad50fe11..052f9155fe217625acc04df4c10c60e94d63bba3 100644
--- a/src/board/mod.rs
+++ b/src/board/mod.rs
@@ -1,3 +1,15 @@
 //! A module that implements several board games
 
 pub mod tictactoe;
+
+/// 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> {
+
+    /// Apply a move to the board
+    fn do_move(&mut self, turn: Player, m: &Move);
+
+    /// Returns if a given player has won the game considering this
+    /// board
+    fn has_won(&self, player: Player) -> bool;
+}
diff --git a/src/board/tictactoe.rs b/src/board/tictactoe.rs
index 2b9a6b40c4260270fa65e53895224e626e645fc1..54915a9d6f6262ee125cae434e7b2044f3604378 100644
--- a/src/board/tictactoe.rs
+++ b/src/board/tictactoe.rs
@@ -1,32 +1,56 @@
 #[derive(Clone, Copy, Debug, PartialEq)]
-/// A Tictactoe square
-pub enum Square {
-    Empty,
+pub enum Player {
     Cross,
     Circle,
 }
 
+impl std::fmt::Display for Player {
+    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
+        match self {
+            Player::Cross => write!(f, "X"),
+            Player::Circle => write!(f, "O"),
+        }
+    }
+}
+
+/// A Tictactoe square is either empty (None) or  Player
+#[derive(Clone, Copy, Debug, PartialEq)]
+enum Square {
+    Empty,
+    Full(Player),
+}
+
 impl std::fmt::Display for Square {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         match self {
             Square::Empty => write!(f, "."),
-            Square::Cross => write!(f, "X"),
-            Square::Circle => write!(f, "O"),
+            Square::Full(p) => write!(f, "{}", p),
         }
     }
 }
 
 /// A TicTacToe board
-pub struct TicTacToe {
+pub struct Board {
     board: [Square; 9],
 }
 
-impl TicTacToe {
+/// A TicTacToe Move
+pub enum Move {
+    A1 = 0,
+    B1 = 1,
+    C1 = 2,
+    A2 = 3,
+    B2 = 4,
+    C2 = 5,
+    A3 = 6,
+    B3 = 7,
+    C3 = 8,
+}
+
+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
@@ -35,7 +59,7 @@ impl TicTacToe {
     }
 }
 
-impl std::fmt::Display for TicTacToe {
+impl std::fmt::Display for Board {
     fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
         writeln!(f, " A   B   C")?;
         for row in 0..3 {
@@ -61,7 +85,7 @@ mod tests {
 
     #[test]
     fn new_board_squares_are_empty() {
-        let board = TicTacToe::new();
+        let board = Board::new();
 
         for square in board.board {
             assert_eq!(square, Square::Empty);
@@ -77,7 +101,7 @@ mod tests {
 ---+---+---
  . | . | .   3
 ";
-        assert_eq!(expected, format!("{}", TicTacToe::new()));
+        assert_eq!(expected, format!("{}", Board::new()));
     }
 
     #[test]
@@ -85,11 +109,19 @@ mod tests {
         assert_eq!(".", format!("{}", Square::Empty));
     }
     #[test]
+    fn cross_player_to_string_x() {
+        assert_eq!("X", format!("{}", Player::Cross));
+    }
+    #[test]
+    fn circle_player_to_string_big_o() {
+        assert_eq!("O", format!("{}", Player::Circle));
+    }
+    #[test]
     fn cross_square_to_string_x() {
-        assert_eq!("X", format!("{}", Square::Cross));
+        assert_eq!("X", format!("{}", Square::Full(Player::Cross)));
     }
     #[test]
     fn circle_square_to_string_big_o() {
-        assert_eq!("O", format!("{}", Square::Circle));
+        assert_eq!("O", format!("{}", Square::Full(Player::Circle)));
     }
 }
diff --git a/src/main.rs b/src/main.rs
index 3b1cd9c27fe29451846cb5d2931bd84e140fce93..4fd4a6b492981a6264ec004eac8bd7548dc03148 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -1,6 +1,6 @@
 mod board;
 
-use board::tictactoe::TicTacToe;
+use board::tictactoe::Board as TicTacToe;
     
 fn main() {
     let board = TicTacToe::new();