Repository: thomas-mauran/chess-tui (language: rust)

Issue:
feat: board turn
## Problem

Be able to play as black

## Solution

Implement it and be sure to remove all the hardcoded white values



Discussion / hints:

Fix patch:
diff --git a/README.md b/README.md
index 14a8257..77563bc 100644
--- a/README.md
+++ b/README.md
@@ -3,7 +3,7 @@
 A chess TUI implementation in rust 🦀
 </div>
 
-![board](./examples/demo.gif)
+![board](./examples/play_against_white_bot.gif)
 
 ![GitHub CI](https://github.com/thomas-mauran/chess-tui/actions/workflows/flow_test_build_push.yml/badge.svg)
 [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
@@ -55,9 +55,8 @@ pacman -S chess-tui
   <summary>Helper menu</summary>
   <img src="./examples/helper.gif" alt="Helper menu" />
 </details>
-
 <details>
-  <summary>Piece moves and checkmate</summary>
+  <summary>Local 2 player mode</summary>
   <img src="./examples/demo.gif" alt="Helper menu" />
 </details>
 <details>
@@ -73,17 +72,13 @@ pacman -S chess-tui
   no demo available yet
 </details>
 <details>
-  <summary>Play against a chess engine</summary>
-  <img src="./examples/play_against_bot.gif" alt="Play against a chess engine" />
-</details>
-
-### Roadmap
-
-You can find the roadmap of the project [here](https://github.com/users/thomas-mauran/projects/4) if you want to contribute.
-
-### Crates.io
+  <summary>Play against any UCI chess engine as black or white</summary>
+  <h3>Play the white pieces</h3>
+  <img src="./examples/play_against_white_bot.gif" alt="Play against a chess engine as white" />
 
-The project is also available on crates.io [here](https://crates.io/crates/chess-tui)
+  <h3>Play the black pieces</h3>
+  <img src="./examples/play_against_black_bot.gif" alt="Play against a chess engine as black" />
+</details>
 
 ### Connect a chess engine
 
@@ -97,3 +92,11 @@ chess-tui -e /your/bin/path
 
 Here I installed stockfish using homebrew and gave chess-tui the path the the engine binary.
 This command will store in your home directory the chess engine path so you don't have to relink it everytime !
+
+### Roadmap
+
+You can find the roadmap of the project [here](https://github.com/users/thomas-mauran/projects/4) if you want to contribute.
+
+### Crates.io
+
+The project is also available on crates.io [here](https://crates.io/crates/chess-tui)
\ No newline at end of file
diff --git a/examples/demo-two-player.gif b/examples/demo-two-player.gif
new file mode 100644
index 0000000..e788df6
Binary files /dev/null and b/examples/demo-two-player.gif differ
diff --git a/examples/demo-two-player.tape b/examples/demo-two-player.tape
new file mode 100644
index 0000000..1cb3dac
--- /dev/null
+++ b/examples/demo-two-player.tape
@@ -0,0 +1,78 @@
+Output examples/demo-two-player.gif
+
+Require echo
+
+Set Margin 100
+Set MarginFill "#674EBB"
+
+Set BorderRadius 10
+Set Shell zsh
+
+Set FontSize 14
+Set Width 1920
+Set Height 1080
+
+Set WindowBar Colorful
+Set WindowBarSize 40
+
+Type "cargo run" Sleep 500ms  Enter
+
+Sleep 0.5s
+Down @0.8s
+Down @0.8s
+Down @0.8s
+Down @0.8s
+Down @0.8s
+Space @0.8s
+Sleep 1.5s
+
+Down @0.8s
+Down @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+
+Sleep 0.8s
+Left @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+
+Down @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+Sleep 0.8s
+
+Right @0.8s
+Right @0.8s
+Right @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+Sleep 0.8s
+
+Left @0.8s
+Space @0.8s
+Sleep 0.8s
+Right @0.8s
+Right @0.8s
+Space @0.8s
+Sleep 0.8s
+
+Up @0.8s
+Right @0.8s
+Right @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+Sleep 0.8s
+
+
+Up @0.8s
+Up @0.8s
+Up @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+Sleep 0.8s
diff --git a/examples/demo.gif b/examples/demo.gif
index b14afb8..3344c78 100644
Binary files a/examples/demo.gif and b/examples/demo.gif differ
diff --git a/examples/demo.tape b/examples/demo.tape
deleted file mode 100644
index 7dff9d8..0000000
--- a/examples/demo.tape
+++ /dev/null
@@ -1,109 +0,0 @@
-Output examples/demo.gif
-
-Require echo
-
-Set Margin 100
-Set MarginFill "#674EBB"
-
-Set BorderRadius 10
-Set Shell zsh
-
-Set FontSize 14
-Set Width 1920
-Set Height 1080
-
-Set WindowBar Colorful
-Set WindowBarSize 40
-
-Type "cargo run" Sleep 500ms  Enter
-
-Sleep 1s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Space @0.3s
-Sleep 3s
-
-Down @0.3s
-Down @0.3s
-Space @0.3s
-Sleep 0.3s
-Space @0.3s
-
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Space @0.3s
-Sleep 0.3s
-Down @0.3s
-Space @0.3s
-
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Right @0.3s
-Space @0.3s
-
-Right @0.3s
-Right @0.3s
-Space @0.3s
-Sleep 0.3s
-
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Space @0.3s
-Sleep 0.3s
-
-Space @0.3s
-Sleep 0.3s
-
-
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Down @0.3s
-Left @0.3s
-Left @0.3s
-Space @0.3s
-Space @0.3s
-
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Up @0.3s
-Left @0.3s
-Left @0.3s
-Space @0.3s
-Sleep 0.3s
-Space @0.3s
-
-Right @0.3s
-Down @0.3s
-Right @0.3s
-Down @0.3s
-Right @0.3s
-Down @0.3s
-Right @0.3s
-Right @0.3s
-Right @0.3s
-Space @0.3s
-Sleep 0.3s
-Space @0.3s
-Sleep 3s
\ No newline at end of file
diff --git a/examples/helper.gif b/examples/helper.gif
index 4838e43..673f32c 100644
Binary files a/examples/helper.gif and b/examples/helper.gif differ
diff --git a/examples/helper.tape b/examples/helper.tape
index 4010e76..6311b41 100644
--- a/examples/helper.tape
+++ b/examples/helper.tape
@@ -20,6 +20,7 @@ Type "cargo run" Sleep 500ms  Enter
 Sleep 2s
 Down @0.3s
 Down @0.3s
+Down @0.3s
 Space @0.3s
 Sleep 1s
 
diff --git a/examples/play_against_black_bot.gif b/examples/play_against_black_bot.gif
new file mode 100644
index 0000000..c36067c
Binary files /dev/null and b/examples/play_against_black_bot.gif differ
diff --git a/examples/play_against_black_bot.tape b/examples/play_against_black_bot.tape
new file mode 100644
index 0000000..73508d7
--- /dev/null
+++ b/examples/play_against_black_bot.tape
@@ -0,0 +1,54 @@
+Output examples/play_against_black_bot.gif
+
+Require echo
+
+Set Margin 100
+Set MarginFill "#674EBB"
+
+Set BorderRadius 10
+Set Shell zsh
+
+Set FontSize 14
+Set Width 1920
+Set Height 1080
+
+Set WindowBar Colorful
+Set WindowBarSize 40
+
+Type "cargo run" Sleep 500ms  Enter
+
+Sleep 2s
+Down @0.8s
+Space @0.8s
+Sleep 1s
+
+Right @0.8s
+Space @0.8s
+Sleep 0.3s
+
+Down @0.8s
+Down @0.8s
+Space @0.8s
+Sleep 0.3s
+Space @0.8s
+
+Right @0.8s
+Space @0.8s
+Sleep 0.3s
+Space @0.8s
+
+Right @0.8s
+Space @0.8s
+Sleep 0.3s
+Space @0.8s
+
+Left @0.8s
+Left @0.8s
+Left @0.8s
+Left @0.8s
+Left @0.8s
+Space @0.8s
+Sleep 0.8s
+Space @0.8s
+Sleep 0.8s
+
diff --git a/examples/play_against_bot.gif b/examples/play_against_bot.gif
deleted file mode 100644
index 318014a..0000000
Binary files a/examples/play_against_bot.gif and /dev/null differ
diff --git a/examples/play_against_bot.tape b/examples/play_against_bot.tape
deleted file mode 100644
index 910d408..0000000
--- a/examples/play_against_bot.tape
+++ /dev/null
@@ -1,57 +0,0 @@
-Output examples/play_against_bot.gif
-
-Require echo
-
-Set Margin 100
-Set MarginFill "#674EBB"
-
-Set BorderRadius 10
-Set Shell zsh
-
-Set FontSize 14
-Set Width 1920
-Set Height 1080
-
-Set WindowBar Colorful
-Set WindowBarSize 40
-
-Type "cargo run" Sleep 500ms  Enter
-
-Sleep 2s
-Down @0.3s
-Space @0.3s
-Sleep 1s
-
-Down @0.3s
-Down @0.3s
-Space @0.3s
-Space @0.3s
-
-Down @0.3s
-Space @0.3s
-Space @0.3s
-
-Up @0.3s
-Space @0.3s
-Space @0.3s
-
-Up @0.3s
-Left @0.3s
-Space @0.3s
-Space @0.3s
-
-Up @0.3s
-Left @0.3s
-Space @0.3s
-Right @0.3s
-Space @0.3s
-
-Up @0.3s
-Space @0.3s
-Right @0.3s
-Space @0.3s
-Right @0.3s
-Space @0.3s
-
-
-Sleep 5s
diff --git a/examples/play_against_white_bot.gif b/examples/play_against_white_bot.gif
new file mode 100644
index 0000000..bcf373b
Binary files /dev/null and b/examples/play_against_white_bot.gif differ
diff --git a/examples/play_against_white_bot.tape b/examples/play_against_white_bot.tape
new file mode 100644
index 0000000..be14f82
--- /dev/null
+++ b/examples/play_against_white_bot.tape
@@ -0,0 +1,57 @@
+Output examples/play_against_white_bot.gif
+
+Require echo
+
+Set Margin 100
+Set MarginFill "#674EBB"
+
+Set BorderRadius 10
+Set Shell zsh
+
+Set FontSize 14
+Set Width 1920
+Set Height 1080
+
+Set WindowBar Colorful
+Set WindowBarSize 40
+
+Type "cargo run" Sleep 500ms  Enter
+
+Sleep 2s
+Down @0.8s
+Space @0.8s
+Sleep 0.5s
+Space @0.8s
+Sleep 0.5s
+
+Down @0.8s
+Down @0.8s
+Space @0.8s
+Space @0.8s
+
+Down @0.8s
+Space @0.8s
+Space @0.8s
+
+Up @0.8s
+Space @0.8s
+Space @0.8s
+
+Up @0.8s
+Left @0.8s
+Space @0.8s
+Space @0.8s
+
+Up @0.8s
+Left @0.8s
+Space @0.8s
+Right @0.8s
+Space @0.8s
+
+Left @0.8s
+Down @0.8s
+Space @0.8s
+Sleep 0.5s
+Space @0.8s
+
+Sleep 5s
\ No newline at end of file
diff --git a/src/app.rs b/src/app.rs
index 1676315..6b0659f 100644
--- a/src/app.rs
+++ b/src/app.rs
@@ -1,7 +1,11 @@
 use dirs::home_dir;
 use toml::Value;
 
-use crate::{board::Board, constants::DisplayMode, constants::Pages};
+use crate::{
+    board::Board,
+    constants::{DisplayMode, Pages},
+    pieces::PieceColor,
+};
 use std::{
     error,
     fs::{self, File},
@@ -21,6 +25,10 @@ pub struct App {
     pub current_page: Pages,
     /// Used to show the help popup during the game or in the home menu
     pub show_help_popup: bool,
+    /// Used to show the side selection popup when playing against the bot
+    pub show_color_popup: bool,
+    // Selected color when playing against the bot
+    pub selected_color: Option<PieceColor>,
     /// menu current cursor
     pub menu_cursor: u8,
     /// path of the chess engine
@@ -34,6 +42,8 @@ impl Default for App {
             board: Board::default(),
             current_page: Pages::Home,
             show_help_popup: false,
+            show_color_popup: false,
+            selected_color: None,
             menu_cursor: 0,
             chess_engine_path: None,
         }
@@ -65,32 +75,78 @@ impl App {
         self.running = false;
     }
 
-    pub fn menu_cursor_up(&mut self) {
+    pub fn menu_cursor_up(&mut self, l: u8) {
         if self.menu_cursor > 0 {
             self.menu_cursor -= 1;
         } else {
-            self.menu_cursor = 4;
+            self.menu_cursor = l - 1;
         }
     }
-
-    pub fn menu_cursor_down(&mut self) {
-        if self.menu_cursor < 4 {
+    pub fn menu_cursor_right(&mut self, l: u8) {
+        if self.menu_cursor < l - 1 {
             self.menu_cursor += 1;
         } else {
             self.menu_cursor = 0;
         }
     }
+    pub fn menu_cursor_left(&mut self, l: u8) {
+        if self.menu_cursor > 0 {
+            self.menu_cursor -= 1;
+        } else {
+            self.menu_cursor = l - 1;
+        }
+    }
+    pub fn menu_cursor_down(&mut self, l: u8) {
+        if self.menu_cursor < l - 1 {
+            self.menu_cursor += 1;
+        } else {
+            self.menu_cursor = 0;
+        }
+    }
+
+    pub fn color_selection(&mut self) {
+        self.show_color_popup = false;
+
+        let color = match self.menu_cursor {
+            0 => PieceColor::White,
+            1 => PieceColor::Black,
+            _ => unreachable!("Invalid color selection"),
+        };
+        self.selected_color = Some(color);
+
+        // if the selected Color is Black, we need to switch the board
+        if let Some(color) = self.selected_color {
+            if color == PieceColor::Black {
+                self.board.is_bot_starting = true;
+                self.board.bot_move();
+                self.board.player_turn = PieceColor::Black;
+            }
+        }
+    }
 
     pub fn restart(&mut self) {
         if self.board.is_draw || self.board.is_checkmate {
+            let is_bot_starting = self.board.is_bot_starting;
+            let engine = self.board.engine.clone();
+            let game_is_against_bot = self.board.is_game_against_bot;
             self.board = Board::default();
+            self.board.engine = engine;
+            self.board.is_game_against_bot = game_is_against_bot;
+            if is_bot_starting {
+                self.board.is_bot_starting = true;
+                self.board.bot_move();
+                self.board.player_turn = PieceColor::Black;
+            }
         }
     }
 
     pub fn menu_select(&mut self) {
         match self.menu_cursor {
             0 => self.current_page = Pages::Solo,
-            1 => self.current_page = Pages::Bot,
+            1 => {
+                self.menu_cursor = 0;
+                self.current_page = Pages::Bot
+            }
             2 => {
                 self.board.display_mode = match self.board.display_mode {
                     DisplayMode::ASCII => DisplayMode::DEFAULT,
diff --git a/src/board.rs b/src/board.rs
index 69ca480..6d2c2c4 100644
--- a/src/board.rs
+++ b/src/board.rs
@@ -4,7 +4,7 @@ use crate::{
     utils::{
         col_to_letter, convert_notation_into_position, convert_position_into_notation,
         did_piece_already_move, get_cell_paragraph, get_int_from_char, get_king_coordinates,
-        get_piece_color, get_piece_type, is_getting_checked,
+        get_piece_color, get_piece_type, invert_position, is_getting_checked,
     },
 };
 use ratatui::{
@@ -100,24 +100,43 @@ impl std::ops::IndexMut<&Coord> for GameBoard {
 /// 1 ♜ ♞ ♝ ♛ ♚ ♝ ♞ ♜ 1
 /// . a b c d e f g h .
 pub struct Board {
+    // the actual board
     pub board: GameBoard,
-    pub board_history: Vec<GameBoard>,
+    // the cursor position
     pub cursor_coordinates: Coord,
+    // the selected cell
     pub selected_coordinates: Coord,
+    // the selected piece cursor when we already selected a piece
     pub selected_piece_cursor: i8,
+    // the old cursor position used when unslecting a cell
     pub old_cursor_position: Coord,
+    // the player turn
     pub player_turn: PieceColor,
+    // the move history
     pub move_history: Vec<PieceMove>,
+    // historic of the past position of the board
+    pub board_history: Vec<GameBoard>,
+    // if the game is a draw
     pub is_draw: bool,
+    // if the game is a checkmate
     pub is_checkmate: bool,
+    // if we are doing a promotion
     pub is_promotion: bool,
+    // the cursor for the promotion popup
     pub promotion_cursor: i8,
+    // the number of consecutive non pawn or capture moves
     pub consecutive_non_pawn_or_capture: i32,
+    // the chess engine
     pub engine: Option<Engine>,
+    // if the game is against a bot
     pub is_game_against_bot: bool,
+    // the display mode
     pub display_mode: DisplayMode,
-
+    // if the bot is starting, meaning the player is black
+    pub is_bot_starting: bool,
+    // The white piece that got taken
     pub white_taken_pieces: Vec<PieceType>,
+    // The black piece that got taken
     pub black_taken_pieces: Vec<PieceType>,
 }
 
@@ -189,6 +208,7 @@ impl Default for Board {
             engine: None,
             is_game_against_bot: false,
             display_mode: DisplayMode::DEFAULT,
+            is_bot_starting: false,
             white_taken_pieces: vec![],
             black_taken_pieces: vec![],
         }
@@ -214,6 +234,7 @@ impl Board {
             engine: None,
             is_game_against_bot: false,
             display_mode: DisplayMode::DEFAULT,
+            is_bot_starting: false,
             white_taken_pieces: vec![],
             black_taken_pieces: vec![],
         }
@@ -268,6 +289,19 @@ impl Board {
         }
     }
 
+    pub fn flip_the_board(&mut self) {
+        let mut flipped_board = [[None; 8]; 8]; // Create a new empty board of the same type
+
+        for (i, row) in self.board.iter().enumerate() {
+            for (j, &square) in row.iter().enumerate() {
+                // Place each square in the mirrored position
+                flipped_board[7 - i][7 - j] = square;
+            }
+        }
+
+        self.board = flipped_board;
+    }
+
     // Cursor movement methods
     pub fn cursor_up(&mut self) {
         if !self.is_checkmate && !self.is_draw && !self.is_promotion {
@@ -365,13 +399,21 @@ impl Board {
             self.promote_piece();
         } else if !self.is_checkmate && !self.is_draw {
             if self.is_cell_selected() {
-                // We already selected a piece
+                // We already selected a piece so we apply the move
                 if self.cursor_coordinates.is_valid() {
                     let selected_coords_usize = &self.selected_coordinates.clone();
                     let cursor_coords_usize = &self.cursor_coordinates.clone();
                     self.move_piece_on_the_board(selected_coords_usize, cursor_coords_usize);
                     self.unselect_cell();
                     self.switch_player_turn();
+                    self.is_draw = self.is_draw();
+                    if (!self.is_game_against_bot || self.is_bot_starting)
+                        && (!self.is_latest_move_promotion()
+                            || self.is_draw()
+                            || self.is_checkmate())
+                    {
+                        self.flip_the_board();
+                    }
                     // If we play against a bot we will play his move and switch the player turn again
                     if self.is_game_against_bot {
                         self.is_promotion = self.is_latest_move_promotion();
@@ -384,7 +426,6 @@ impl Board {
                             }
                         }
                     }
-                    self.is_draw = self.is_draw();
                 }
             } else {
                 // Check if the piece on the cell can move before selecting it
@@ -408,6 +449,7 @@ impl Board {
         }
         self.is_checkmate = self.is_checkmate();
         self.is_promotion = self.is_latest_move_promotion();
+        self.is_draw = self.is_draw();
     }
 
     // Check if the king has already moved (used for castling)
@@ -426,12 +468,10 @@ impl Board {
        We use the UCI protocol to communicate with the chess engine
     */
     pub fn bot_move(&mut self) {
-        let Some(engine) = &self.engine else {
-            panic!("Missing the chess engine")
-        };
-
-        engine.set_position(&self.fen_position()).unwrap();
+        let engine = self.engine.clone().expect("Missing the chess engine");
+        let fen_position = self.fen_position();
 
+        engine.set_position(&(fen_position as String)).unwrap();
         let best_move = engine.bestmove();
         let Ok(movement) = best_move else {
             panic!("An error has occured")
@@ -447,11 +487,19 @@ impl Board {
             &Coord::new(from_y as u8, from_x as u8),
             &Coord::new(to_y as u8, to_x as u8),
         );
+        if self.is_bot_starting {
+            self.flip_the_board();
+        }
     }
 
     // Convert the history and game status to a FEN string
-    pub fn fen_position(&self) -> String {
+    pub fn fen_position(&mut self) -> String {
         let mut result = String::new();
+        let bot_color = if self.is_bot_starting {
+            PieceColor::White
+        } else {
+            PieceColor::Black
+        };
 
         // We loop through the board and convert it to a FEN string
         for i in 0..8u8 {
@@ -494,25 +542,41 @@ impl Board {
         result.pop();
 
         // We say it is blacks turn to play
-        result.push_str(" b");
+        result.push_str(if bot_color == PieceColor::Black {
+            " b"
+        } else {
+            " w"
+        });
 
         // We add the castles availabilities for black
         if !did_piece_already_move(
             &self.move_history,
-            (Some(PieceType::King), Coord::new(0, 4)),
+            (
+                Some(PieceType::King),
+                Some(self.player_turn),
+                Coord::new(0, 4),
+            ),
         ) && !is_getting_checked(self.board, PieceColor::Black, &self.move_history)
         {
             // king side black castle availability
             if !did_piece_already_move(
                 &self.move_history,
-                (Some(PieceType::Rook), Coord::new(0, 7)),
+                (
+                    Some(PieceType::Rook),
+                    Some(self.player_turn),
+                    Coord::new(0, 7),
+                ),
             ) {
                 result.push_str(" k");
             }
             // queen side black castle availability
             if !did_piece_already_move(
                 &self.move_history,
-                (Some(PieceType::Rook), Coord::new(0, 0)),
+                (
+                    Some(PieceType::Rook),
+                    Some(self.player_turn),
+                    Coord::new(0, 0),
+                ),
             ) {
                 result.push('q');
             }
@@ -583,6 +647,9 @@ impl Board {
         }
         self.is_promotion = false;
         self.promotion_cursor = 0;
+        if !self.is_draw() && !self.is_checkmate() {
+            self.flip_the_board();
+        }
     }
 
     // Move a piece from a cell to another
@@ -645,43 +712,39 @@ impl Board {
         // We check for castling as the latest move
         if self.is_latest_move_castling(*from, *to) {
             // we set the king 2 cells on where it came from
-
             let from_x: i32 = from.col as i32;
-            let mut to_x: i32 = to.col as i32;
+            let mut new_to = to;
+            let to_x: i32 = to.col as i32;
 
             let distance = from_x - to_x;
+            // We set the direction of the rook > 0 meaning he went on the left else on the right
             let direction_x = if distance > 0 { -1 } else { 1 };
 
-            let row_index_rook;
-
-            let row_index = from_x + direction_x * 2;
+            let col_king = from_x + direction_x * 2;
 
             // We put move the king 2 cells
-            self.board[to.row as usize][row_index as usize] = self.board[from];
+            self.board[to.row as usize][col_king as usize] = self.board[from];
 
             // We put the rook 3 cells from it's position if it's a big castling else 2 cells
             // If it is playing against a bot we will receive 4 -> 6  and 4 -> 2 for to_x instead of 4 -> 7 and 4 -> 0
-            // big castling
-            match distance {
-                distance if distance > 0 => {
-                    row_index_rook = 3;
-                    if self.is_game_against_bot && self.player_turn == PieceColor::Black {
-                        to_x = 0;
-                    }
-                }
-                distance if distance < 0 => {
-                    row_index_rook = 5;
-                    if self.is_game_against_bot && self.player_turn == PieceColor::Black {
-                        to_x = 7;
-                    }
-                }
-                _ => unreachable!("Undefined distance for castling"),
+            if self.is_game_against_bot && to_x == 6 && to.row == 0 {
+                new_to = &Coord { row: 0, col: 7 };
             }
-            let new_to = Coord::new(to.row, to_x as u8);
-            self.board[to.row as usize][row_index_rook as usize] = self.board[&new_to];
+            if self.is_game_against_bot && to_x == 2 && to.row == 0 {
+                new_to = &Coord { row: 0, col: 0 };
+            }
+
+            let col_rook = if distance > 0 {
+                col_king + 1
+            } else {
+                col_king - 1
+            };
+
+            self.board[new_to.row as usize][col_rook as usize] =
+                Some((PieceType::Rook, self.player_turn));
 
             // We remove the latest rook
-            self.board[&new_to] = None;
+            self.board[new_to] = None;
         } else {
             self.board[to] = self.board[from];
         }
@@ -691,9 +754,12 @@ impl Board {
         // We store it in the history
         self.move_history.push(PieceMove {
             piece_type: piece_type_from,
+            piece_color: self.player_turn,
             from: *from,
             to: *to,
         });
+        // We store the current position of the board
+        self.board_history.push(self.board);
     }
 
     // Method to get the number of authorized positions for the current player (used for the end condition)
@@ -756,18 +822,9 @@ impl Board {
             if let Some(piece_type_to) =
                 get_piece_type(self.board, &Coord::new(last_move.to.row, last_move.to.col))
             {
-                if let Some(piece_color) =
-                    get_piece_color(self.board, &Coord::new(last_move.to.row, last_move.to.col))
-                {
-                    let last_row = if piece_color == PieceColor::White {
-                        0
-                    } else {
-                        7
-                    };
-
-                    if last_move.to.row == last_row && piece_type_to == PieceType::Pawn {
-                        return true;
-                    }
+                let last_row = 0;
+                if last_move.to.row == last_row && piece_type_to == PieceType::Pawn {
+                    return true;
                 }
             }
         }
@@ -792,9 +849,6 @@ impl Board {
             return false;
         }
 
-        // Add the new move
-        self.board_history.push(self.board);
-
         // Index mapping
         let mut position_counts = std::collections::HashMap::new();
         for board in self.board_history.iter() {
@@ -865,15 +919,33 @@ impl Board {
                 .split(columns[i as usize + 1]);
             for j in 0..8u8 {
                 // Color of the cell to draw the board
-                let mut cell_color: Color = if (i + j) % 2 == 0 { WHITE } else { BLACK };
+                let cell_color: Color = if (i + j) % 2 == 0 { WHITE } else { BLACK };
+
+                let last_move;
+                let mut last_move_from = Coord::undefined();
+                let mut last_move_to = Coord::undefined();
+                if !self.move_history.is_empty() {
+                    last_move = self.move_history.last();
+                    if self.is_game_against_bot && !self.is_bot_starting {
+                        last_move_from = last_move.map(|m| m.from).unwrap();
+                        last_move_to = last_move.map(|m| m.to).unwrap();
+                    } else {
+                        last_move_from = invert_position(&last_move.map(|m| m.from).unwrap());
+                        last_move_to = invert_position(&last_move.map(|m| m.to).unwrap());
+                    }
+                }
 
+                let mut positions: Vec<Coord> = vec![];
+                let is_cell_in_positions = |positions: &Vec<Coord>, i: u8, j: u8| {
+                    positions.iter().any(|&coord| coord == Coord::new(i, j))
+                };
                 // Draw the available moves for the selected piece
                 if self.is_cell_selected() {
                     let selected_piece_type =
                         get_piece_type(self.board, &self.selected_coordinates);
                     let selected_piece_color: Option<PieceColor> =
                         get_piece_color(self.board, &self.selected_coordinates);
-                    let positions = self.get_authorized_positions(
+                    positions = self.get_authorized_positions(
                         selected_piece_type,
                         selected_piece_color,
                         self.selected_coordinates,
@@ -882,29 +954,42 @@ impl Board {
                     // Draw grey if the color is in the authorized positions
                     for coords in positions.clone() {
                         if i == coords.row && j == coords.col {
-                            cell_color = Color::Rgb(100, 100, 100);
+                            // cell_color = Color::Rgb(100, 100, 100);
                         }
                     }
                 }
 
                 let square = lines[j as usize + 1];
+                // Here we have all the possibilities for a cell:
+                // - selected cell: green
+                // - cursor cell: blue
+                // - available move cell: grey
+                // - checked king cell: magenta
+                // - last move cell: green
+                // - default cell: white or black
                 // Draw the cell blue if this is the current cursor cell
                 if i == self.cursor_coordinates.row && j == self.cursor_coordinates.col {
-                    let cell = Block::default().bg(Color::LightBlue);
-                    frame.render_widget(cell.clone(), square);
-                } else if is_getting_checked(self.board, self.player_turn, &self.move_history)
+                    Board::render_cell(frame, square, Color::LightBlue, None);
+                }
+                // Draw the cell magenta if the king is getting checked
+                else if is_getting_checked(self.board, self.player_turn, &self.move_history)
                     && Coord::new(i, j) == get_king_coordinates(self.board, self.player_turn)
                 {
-                    let cell = Block::default()
-                        .bg(Color::Magenta)
-                        .add_modifier(Modifier::SLOW_BLINK);
-                    frame.render_widget(cell.clone(), square);
+                    Board::render_cell(frame, square, Color::Magenta, Some(Modifier::SLOW_BLINK));
                 }
-                // Draw the cell green if this is the selected cell
-                else if i == self.selected_coordinates.row && j == self.selected_coordinates.col {
-                    let cell = Block::default().bg(Color::LightGreen);
-                    frame.render_widget(cell.clone(), square);
-                } else {
+                // Draw the cell green if this is the selected cell or if the cell is part of the last move
+                else if (i == self.selected_coordinates.row && j == self.selected_coordinates.col)
+                    || (last_move_from == Coord::new(i, j) // If the last move from 
+                        || (last_move_to == Coord::new(i, j) // If last move to
+                            && !is_cell_in_positions(&positions, i, j)))
+                // and not in the authorized positions (grey instead of green)
+                {
+                    Board::render_cell(frame, square, Color::LightGreen, None);
+                } else if is_cell_in_positions(&positions, i, j) {
+                    Board::render_cell(frame, square, Color::Rgb(100, 100, 100), None);
+                }
+                // else as a last resort we draw the cell with the default color either white or black
+                else {
                     let mut cell = Block::default();
                     cell = match self.display_mode {
                         DisplayMode::DEFAULT => cell.bg(cell_color),
@@ -914,7 +999,6 @@ impl Board {
                             _ => cell.bg(cell_color),
                         },
                     };
-
                     frame.render_widget(cell.clone(), square);
                 }
 
@@ -926,6 +1010,13 @@ impl Board {
             }
         }
     }
+    fn render_cell(frame: &mut Frame, square: Rect, color: Color, modifier: Option<Modifier>) {
+        let mut cell = Block::default().bg(color);
+        if let Some(modifier) = modifier {
+            cell = cell.add_modifier(modifier);
+        }
+        frame.render_widget(cell, square);
+    }
 
     // Method to render the right panel history
     pub fn history_render(&self, area: Rect, frame: &mut Frame) {
@@ -1561,6 +1652,7 @@ mod tests {
             vec![
                 (PieceMove {
                     piece_type: PieceType::Pawn,
+                    piece_color: PieceColor::White,
                     from: Coord::new(7, 3),
                     to: Coord::new(6, 3),
                 }),
@@ -1614,6 +1706,7 @@ mod tests {
             vec![
                 (PieceMove {
                     piece_type: PieceType::Pawn,
+                    piece_color: PieceColor::White,
                     from: Coord::new(1, 4),
                     to: Coord::new(0, 4),
                 }),
@@ -1681,20 +1774,15 @@ mod tests {
     #[test]
     fn is_promote_true_black() {
         let custom_board = [
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
             [
-                None,
-                Some((PieceType::King, PieceColor::Black)),
                 None,
                 None,
                 None,
                 None,
+                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
                 None,
+                Some((PieceType::King, PieceColor::White)),
             ],
             [
                 None,
@@ -1707,15 +1795,20 @@ mod tests {
                 None,
             ],
             [
+                None,
+                Some((PieceType::King, PieceColor::Black)),
                 None,
                 None,
                 None,
                 None,
-                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
                 None,
-                Some((PieceType::King, PieceColor::White)),
             ],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
         ];
         let board = Board::new(
             custom_board,
@@ -1723,8 +1816,9 @@ mod tests {
             vec![
                 (PieceMove {
                     piece_type: PieceType::Pawn,
-                    from: Coord::new(6, 4),
-                    to: Coord::new(7, 4),
+                    piece_color: PieceColor::Black,
+                    from: Coord::new(1, 4),
+                    to: Coord::new(0, 4),
                 }),
             ],
         );
@@ -1742,13 +1836,10 @@ mod tests {
                 None,
                 None,
                 None,
+                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
-                Some((PieceType::Rook, PieceColor::Black)),
-                None,
+                Some((PieceType::King, PieceColor::White)),
             ],
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
             [
                 None,
                 Some((PieceType::King, PieceColor::Black)),
@@ -1759,24 +1850,27 @@ mod tests {
                 None,
                 None,
             ],
+            [None, None, None, None, None, None, None, None],
             [
                 None,
                 None,
                 None,
                 None,
                 None,
-                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
-                Some((PieceType::King, PieceColor::White)),
+                Some((PieceType::Rook, PieceColor::Black)),
+                None,
             ],
             [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
         ];
         // We setup the board
         let mut board = Board::new(custom_board, PieceColor::Black, vec![]);
         assert!(!board.is_latest_move_promotion());
 
         // Move the pawn to a promote cell
-        board.move_piece_on_the_board(&Coord::new(6, 5), &Coord::new(7, 5));
+        board.move_piece_on_the_board(&Coord::new(1, 5), &Coord::new(0, 5));
         assert!(board.is_latest_move_promotion());
 
         // Promote the pawn
@@ -1853,41 +1947,49 @@ mod tests {
             vec![
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::White,
                     from: Coord::new(0, 2),
                     to: Coord::new(0, 1),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::Black,
                     from: Coord::new(0, 6),
                     to: Coord::new(0, 5),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::White,
                     from: Coord::new(0, 1),
                     to: Coord::new(0, 2),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::Black,
                     from: Coord::new(0, 5),
                     to: Coord::new(0, 6),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::White,
                     from: Coord::new(0, 2),
                     to: Coord::new(0, 1),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::Black,
                     from: Coord::new(0, 6),
                     to: Coord::new(0, 5),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::White,
                     from: Coord::new(0, 1),
                     to: Coord::new(0, 2),
                 }),
                 (PieceMove {
                     piece_type: PieceType::King,
+                    piece_color: PieceColor::Black,
                     from: Coord::new(0, 5),
                     to: Coord::new(0, 6),
                 }),
@@ -1939,7 +2041,7 @@ mod tests {
             [None, None, None, None, None, None, None, None],
         ];
         // We setup the board
-        let board = Board::new(custom_board, PieceColor::White, vec![]);
+        let mut board = Board::new(custom_board, PieceColor::White, vec![]);
 
         // Move the king to replicate a third time the same position
         assert_eq!(board.fen_position(), "2k4R/8/4K3/8/8/8/8/8 b - - 0 0");
@@ -1985,12 +2087,13 @@ mod tests {
             [None, None, None, None, None, None, None, None],
         ];
         // We setup the board
-        let board = Board::new(
+        let mut board = Board::new(
             custom_board,
             PieceColor::White,
             vec![
                 (PieceMove {
                     piece_type: PieceType::Pawn,
+                    piece_color: PieceColor::White,
                     from: Coord::new(6, 2),
                     to: Coord::new(4, 2),
                 }),
@@ -2049,7 +2152,7 @@ mod tests {
             ],
         ];
         // We setup the board
-        let board = Board::new(custom_board, PieceColor::White, vec![]);
+        let mut board = Board::new(custom_board, PieceColor::White, vec![]);
 
         // Move the king to replicate a third time the same position
         assert_eq!(
diff --git a/src/constants.rs b/src/constants.rs
index eb9cc0f..2bdb29c 100644
--- a/src/constants.rs
+++ b/src/constants.rs
@@ -44,3 +44,8 @@ pub enum Pages {
     Bot,
     Credit,
 }
+impl Pages {
+    pub fn variant_count() -> usize {
+        5
+    }
+}
diff --git a/src/handler.rs b/src/handler.rs
index b09853f..128417e 100644
--- a/src/handler.rs
+++ b/src/handler.rs
@@ -22,24 +22,40 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
             }
         }
         // Counter handlers
-        KeyCode::Right | KeyCode::Char('l') => app.board.cursor_right(),
-        KeyCode::Left | KeyCode::Char('h') => app.board.cursor_left(),
+        KeyCode::Right | KeyCode::Char('l') => {
+            // When we are in the color selection menu
+            if app.current_page == Pages::Bot && app.selected_color.is_none() {
+                app.menu_cursor_right(2);
+            } else {
+                app.board.cursor_right();
+            }
+        }
+        KeyCode::Left | KeyCode::Char('h') => {
+            // When we are in the color selection menu
+            if app.current_page == Pages::Bot && app.selected_color.is_none() {
+                app.menu_cursor_left(2);
+            } else {
+                app.board.cursor_left();
+            }
+        }
         KeyCode::Up | KeyCode::Char('k') => {
             if app.current_page == Pages::Home {
-                app.menu_cursor_up();
+                app.menu_cursor_up(Pages::variant_count() as u8);
             } else {
                 app.board.cursor_up();
             }
         }
         KeyCode::Down | KeyCode::Char('j') => {
             if app.current_page == Pages::Home {
-                app.menu_cursor_down();
+                app.menu_cursor_down(Pages::variant_count() as u8);
             } else {
                 app.board.cursor_down();
             }
         }
         KeyCode::Char(' ') | KeyCode::Enter => {
-            if app.current_page == Pages::Home {
+            if app.current_page == Pages::Bot && app.selected_color.is_none() {
+                app.color_selection();
+            } else if app.current_page == Pages::Home {
                 app.menu_select();
             } else {
                 app.board.select_cell();
@@ -56,6 +72,10 @@ pub fn handle_key_events(key_event: KeyEvent, app: &mut App) -> AppResult<()> {
                 app.show_help_popup = false;
             } else if app.current_page == Pages::Credit {
                 app.current_page = Pages::Home;
+            } else if app.current_page == Pages::Bot && app.selected_color.is_none() {
+                app.current_page = Pages::Home;
+                app.show_color_popup = false;
+                app.menu_cursor = 0;
             }
             app.board.unselect_cell();
         }
diff --git a/src/pieces/king.rs b/src/pieces/king.rs
index 3eb8420..74a1e0d 100644
--- a/src/pieces/king.rs
+++ b/src/pieces/king.rs
@@ -55,37 +55,43 @@ impl Position for King {
         let rook_big_castle_x = 0;
         let rook_small_castle_x = 7;
         let king_x = 4;
-        let king_line = if color == PieceColor::White { 7 } else { 0 };
+        let king_row = 7;
+        let king_col = if color == PieceColor::White { 4 } else { 3 };
 
         // We check the condition for small and big castling
         if !did_piece_already_move(
             move_history,
-            (Some(PieceType::King), Coord::new(king_line, king_x)),
+            (
+                Some(PieceType::King),
+                Some(color),
+                Coord::new(king_row, king_x),
+            ),
         ) && !is_king_checked
         {
             // We check if there is no pieces between tower and king
-
             // Big castle check
             if !did_piece_already_move(
                 move_history,
                 (
                     Some(PieceType::Rook),
-                    Coord::new(king_line, rook_big_castle_x),
+                    Some(color),
+                    Coord::new(king_row, rook_big_castle_x),
                 ),
-            ) && King::check_castling_condition(board, color, 0, 3, &checked_cells)
+            ) && King::check_castling_condition(board, color, 0, king_col - 1, &checked_cells)
             {
-                positions.push(Coord::new(king_line, 0));
+                positions.push(Coord::new(king_row, 0));
             }
             // Small castle check
             if !did_piece_already_move(
                 move_history,
                 (
                     Some(PieceType::Rook),
-                    Coord::new(king_line, rook_small_castle_x),
+                    Some(color),
+                    Coord::new(king_row, rook_small_castle_x),
                 ),
-            ) && King::check_castling_condition(board, color, 5, 7, &checked_cells)
+            ) && King::check_castling_condition(board, color, king_col + 1, 7, &checked_cells)
             {
-                positions.push(Coord::new(king_line, 7));
+                positions.push(Coord::new(king_row, 7));
             }
         }
 
@@ -136,12 +142,12 @@ impl King {
         end: i8,
         checked_cells: &[Coord],
     ) -> bool {
-        let king_line = if color == PieceColor::White { 7 } else { 0 };
+        let king_row = 7;
 
         let mut valid_for_castling = true;
 
         for i in start..=end {
-            let new_coordinates = Coord::new(king_line, i as u8);
+            let new_coordinates = Coord::new(king_row, i as u8);
 
             if checked_cells.contains(&new_coordinates) {
                 valid_for_castling = false;
@@ -432,7 +438,7 @@ mod tests {
     }
 
     #[test]
-    fn small_castle_black() {
+    fn small_castle_white() {
         let custom_board = [
             [
                 Some((PieceType::Rook, PieceColor::Black)),
@@ -440,8 +446,8 @@ mod tests {
                 Some((PieceType::Bishop, PieceColor::Black)),
                 Some((PieceType::Queen, PieceColor::Black)),
                 Some((PieceType::King, PieceColor::Black)),
-                None,
-                None,
+                Some((PieceType::Bishop, PieceColor::Black)),
+                Some((PieceType::Knight, PieceColor::Black)),
                 Some((PieceType::Rook, PieceColor::Black)),
             ],
             [
@@ -468,25 +474,156 @@ mod tests {
                 Some((PieceType::Pawn, PieceColor::White)),
                 Some((PieceType::Pawn, PieceColor::White)),
             ],
+            [
+                Some((PieceType::Rook, PieceColor::White)),
+                Some((PieceType::Bishop, PieceColor::White)),
+                Some((PieceType::Bishop, PieceColor::White)),
+                Some((PieceType::Queen, PieceColor::White)),
+                Some((PieceType::King, PieceColor::White)),
+                None,
+                None,
+                Some((PieceType::Rook, PieceColor::White)),
+            ],
+        ];
+        let mut board = Board::default();
+        board.set_board(custom_board);
+
+        let mut right_positions = vec![Coord::new(7, 5), Coord::new(7, 7)];
+        right_positions.sort();
+
+        let mut positions = King::authorized_positions(
+            &Coord::new(7, 4),
+            PieceColor::White,
+            board.board,
+            &[],
+            false,
+        );
+        positions.sort();
+
+        assert_eq!(right_positions, positions);
+    }
+
+    #[test]
+    fn big_castle_black() {
+        let custom_board = [
             [
                 Some((PieceType::Rook, PieceColor::White)),
                 Some((PieceType::Knight, PieceColor::White)),
                 Some((PieceType::Bishop, PieceColor::White)),
+                Some((PieceType::King, PieceColor::White)),
                 Some((PieceType::Queen, PieceColor::White)),
+                Some((PieceType::Bishop, PieceColor::White)),
+                Some((PieceType::Knight, PieceColor::White)),
+                Some((PieceType::Rook, PieceColor::White)),
+            ],
+            [
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+            ],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+            ],
+            [
+                Some((PieceType::Rook, PieceColor::Black)),
+                Some((PieceType::Knight, PieceColor::Black)),
+                Some((PieceType::Bishop, PieceColor::Black)),
+                Some((PieceType::King, PieceColor::Black)),
+                None,
+                None,
+                None,
+                Some((PieceType::Rook, PieceColor::Black)),
+            ],
+        ];
+        let mut board = Board::default();
+        board.set_board(custom_board);
+
+        let mut right_positions = vec![Coord::new(7, 4), Coord::new(7, 7)];
+        right_positions.sort();
+
+        let mut positions = King::authorized_positions(
+            &Coord::new(7, 3),
+            PieceColor::Black,
+            board.board,
+            &[],
+            false,
+        );
+        positions.sort();
+
+        assert_eq!(right_positions, positions);
+    }
+    #[test]
+    fn small_castle_black() {
+        let custom_board = [
+            [
+                Some((PieceType::Rook, PieceColor::White)),
+                Some((PieceType::Knight, PieceColor::White)),
+                Some((PieceType::Bishop, PieceColor::White)),
                 Some((PieceType::King, PieceColor::White)),
+                Some((PieceType::Queen, PieceColor::White)),
                 Some((PieceType::Bishop, PieceColor::White)),
                 Some((PieceType::Knight, PieceColor::White)),
                 Some((PieceType::Rook, PieceColor::White)),
             ],
+            [
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+            ],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+            ],
+            [
+                Some((PieceType::Rook, PieceColor::Black)),
+                None,
+                None,
+                Some((PieceType::King, PieceColor::Black)),
+                Some((PieceType::Queen, PieceColor::Black)),
+                Some((PieceType::Bishop, PieceColor::Black)),
+                Some((PieceType::Knight, PieceColor::Black)),
+                Some((PieceType::Rook, PieceColor::Black)),
+            ],
         ];
         let mut board = Board::default();
         board.set_board(custom_board);
 
-        let mut right_positions = vec![Coord::new(0, 5), Coord::new(0, 7)];
+        let mut right_positions = vec![Coord::new(7, 0), Coord::new(7, 2)];
         right_positions.sort();
 
         let mut positions = King::authorized_positions(
-            &Coord::new(0, 4),
+            &Coord::new(7, 3),
             PieceColor::Black,
             board.board,
             &[],
@@ -693,16 +830,19 @@ mod tests {
             &[
                 (PieceMove {
                     piece_type: PieceType::Rook,
+                    piece_color: PieceColor::White,
                     from: Coord::new(0, 7),
                     to: Coord::new(4, 7),
                 }),
                 (PieceMove {
                     piece_type: PieceType::Pawn,
+                    piece_color: PieceColor::Black,
                     from: Coord::new(6, 2),
                     to: Coord::new(5, 2),
                 }),
                 (PieceMove {
                     piece_type: PieceType::Rook,
+                    piece_color: PieceColor::White,
                     from: Coord::new(4, 7),
                     to: Coord::new(0, 7),
                 }),
@@ -713,4 +853,90 @@ mod tests {
 
         assert_eq!(right_positions, positions);
     }
+
+    #[test]
+    fn castle_both_sides() {
+        let custom_board = [
+            [
+                Some((PieceType::Rook, PieceColor::Black)),
+                None,
+                None,
+                None,
+                Some((PieceType::King, PieceColor::Black)),
+                Some((PieceType::Bishop, PieceColor::Black)),
+                Some((PieceType::Knight, PieceColor::Black)),
+                Some((PieceType::Rook, PieceColor::Black)),
+            ],
+            [
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+            ],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+            ],
+            [
+                Some((PieceType::Rook, PieceColor::White)),
+                Some((PieceType::Knight, PieceColor::White)),
+                Some((PieceType::Bishop, PieceColor::White)),
+                Some((PieceType::Queen, PieceColor::White)),
+                Some((PieceType::King, PieceColor::White)),
+                None,
+                None,
+                Some((PieceType::Rook, PieceColor::White)),
+            ],
+        ];
+        let mut board = Board::new(custom_board, PieceColor::White, vec![]);
+        board.set_board(custom_board);
+
+        let is_king_checked =
+            is_getting_checked(board.board, board.player_turn, &board.move_history);
+
+        let mut white_right_positions = vec![Coord::new(7, 5), Coord::new(7, 7)];
+        white_right_positions.sort();
+
+        let mut positions = King::authorized_positions(
+            &Coord::new(7, 4),
+            PieceColor::White,
+            board.board,
+            &[],
+            is_king_checked,
+        );
+        positions.sort();
+
+        assert_eq!(white_right_positions, positions);
+
+        board.move_piece_on_the_board(&Coord::new(7, 4), &Coord::new(7, 7));
+        board.flip_the_board();
+
+        let mut black_right_positions = vec![Coord::new(7, 4), Coord::new(7, 7)];
+        black_right_positions.sort();
+
+        let mut positions = King::authorized_positions(
+            &Coord::new(7, 3),
+            PieceColor::Black,
+            board.board,
+            &[],
+            is_king_checked,
+        );
+        positions.sort();
+
+        assert_eq!(black_right_positions, positions);
+    }
 }
diff --git a/src/pieces/mod.rs b/src/pieces/mod.rs
index 63a0f11..8bfee54 100644
--- a/src/pieces/mod.rs
+++ b/src/pieces/mod.rs
@@ -185,6 +185,7 @@ impl Eq for PieceType {}
 #[derive(Debug, Copy, Clone, PartialEq)]
 pub struct PieceMove {
     pub piece_type: PieceType,
+    pub piece_color: PieceColor,
     pub from: Coord,
     pub to: Coord,
 }
diff --git a/src/pieces/pawn.rs b/src/pieces/pawn.rs
index bbe6f00..72ae709 100644
--- a/src/pieces/pawn.rs
+++ b/src/pieces/pawn.rs
@@ -1,8 +1,9 @@
-use super::{Movable, PieceColor, PieceMove, Position};
+use super::{Movable, PieceColor, PieceMove, PieceType, Position};
 use crate::board::{Coord, GameBoard};
 use crate::constants::DisplayMode;
 use crate::utils::{
-    cleaned_positions, get_piece_color, impossible_positions_king_checked, is_cell_color_ally,
+    cleaned_positions, get_piece_color, impossible_positions_king_checked, invert_position,
+    is_cell_color_ally,
 };
 
 pub struct Pawn;
@@ -16,8 +17,8 @@ impl Movable for Pawn {
         move_history: &[PieceMove],
     ) -> Vec<Coord> {
         // Pawns can only move in one direction depending of their color
-        // -1 if they are white (go up) +1 if they are black (go down)
-        let direction: i8 = if color == PieceColor::White { -1 } else { 1 };
+        // -1 we go up
+        let direction: i8 = if allow_move_on_ally_positions { 1 } else { -1 };
 
         let mut positions: Vec<Coord> = vec![];
 
@@ -42,8 +43,7 @@ impl Movable for Pawn {
 
             if new_coordinates_front_two.is_valid()
                 && get_piece_color(board, &new_coordinates_front_two).is_none()
-                && ((color == PieceColor::White && y == 6)
-                    || (color == PieceColor::Black && y == 1))
+                && (y == 6)
             {
                 positions.push(new_coordinates_front_two);
             }
@@ -95,31 +95,22 @@ impl Movable for Pawn {
 
         // We check for en passant
         if let Some(latest_move) = move_history.last() {
-            let valid_y_start: i8;
-            let number_of_cells_move: i8;
-
-            if color == PieceColor::White {
-                valid_y_start = 1;
-                number_of_cells_move = latest_move.to.row as i8 - latest_move.from.row as i8;
-            } else {
-                valid_y_start = 6;
-                number_of_cells_move = latest_move.from.row as i8 - latest_move.to.row as i8;
-            };
+            let number_of_cells_move = latest_move.to.row as i8 - latest_move.from.row as i8;
 
+            let last_coords = invert_position(&Coord::new(latest_move.to.row, latest_move.to.col));
             // We check if the latest move was on the right start cell
             // if it moved 2 cells
             // and if the current pawn is next to this pawn latest position
-            if latest_move.from.row as i8 == valid_y_start
-                && number_of_cells_move == 2
-                && y == latest_move.to.row
-                && (x as i8 == latest_move.to.col as i8 - 1 || x == latest_move.to.col + 1)
+            if latest_move.piece_type == PieceType::Pawn
+                && number_of_cells_move == -2
+                && y == last_coords.row
+                && (x as i8 == (last_coords.col as i8) - 1 || x == last_coords.col + 1)
             {
-                let new_y = latest_move.from.row as i8 + -direction;
-                let new_x = latest_move.from.col;
-                positions.push(Coord::new(new_y as u8, new_x));
+                let new_y = y - 1;
+                let new_x = last_coords.col;
+                positions.push(Coord::new(new_y, new_x));
             }
         }
-
         cleaned_positions(&positions)
     }
 }
@@ -257,13 +248,17 @@ mod tests {
     #[test]
     fn piece_move_one_cell_enemy_left_right() {
         let custom_board = [
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
             [
                 None,
                 None,
+                Some((PieceType::Pawn, PieceColor::White)),
                 None,
-                Some((PieceType::Pawn, PieceColor::Black)),
-                None,
+                Some((PieceType::Pawn, PieceColor::White)),
                 None,
                 None,
                 None,
@@ -271,32 +266,75 @@ mod tests {
             [
                 None,
                 None,
-                Some((PieceType::Pawn, PieceColor::White)),
                 None,
-                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::Black)),
+                None,
                 None,
                 None,
                 None,
             ],
             [None, None, None, None, None, None, None, None],
+        ];
+        let mut board = Board::default();
+        board.set_board(custom_board);
+
+        let mut right_positions = vec![
+            Coord::new(5, 3),
+            Coord::new(4, 3),
+            Coord::new(5, 4),
+            Coord::new(5, 2),
+        ];
+        right_positions.sort();
+
+        let mut positions = Pawn::authorized_positions(
+            &Coord::new(6, 3),
+            PieceColor::Black,
+            board.board,
+            &[],
+            false,
+        );
+        positions.sort();
+        assert_eq!(right_positions, positions);
+    }
+
+    #[test]
+    fn piece_move_one_pawn_3_enemies() {
+        let custom_board = [
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
+            [
+                None,
+                None,
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::White)),
+                None,
+                None,
+                None,
+            ],
+            [
+                None,
+                None,
+                None,
+                Some((PieceType::Pawn, PieceColor::Black)),
+                None,
+                None,
+                None,
+                None,
+            ],
             [None, None, None, None, None, None, None, None],
         ];
         let mut board = Board::default();
         board.set_board(custom_board);
 
-        let mut right_positions = vec![
-            Coord::new(2, 3),
-            Coord::new(3, 3),
-            Coord::new(2, 4),
-            Coord::new(2, 2),
-        ];
+        let mut right_positions = vec![Coord::new(5, 4), Coord::new(5, 2)];
         right_positions.sort();
 
         let mut positions = Pawn::authorized_positions(
-            &Coord::new(1, 3),
+            &Coord::new(6, 3),
             PieceColor::Black,
             board.board,
             &[],
@@ -307,7 +345,7 @@ mod tests {
     }
 
     #[test]
-    fn piece_move_one_cell_3_enemies() {
+    fn piece_move_3_enemies_one_pawn() {
         let custom_board = [
             [None, None, None, None, None, None, None, None],
             [
@@ -339,18 +377,47 @@ mod tests {
         let mut board = Board::default();
         board.set_board(custom_board);
 
-        let mut right_positions = vec![Coord::new(2, 4), Coord::new(2, 2)];
-        right_positions.sort();
+        // First pawn on the left
+        let mut right_positions_first_pawn = vec![Coord::new(1, 2), Coord::new(1, 3)];
+        right_positions_first_pawn.sort();
 
         let mut positions = Pawn::authorized_positions(
-            &Coord::new(1, 3),
-            PieceColor::Black,
+            &Coord::new(2, 2),
+            PieceColor::White,
             board.board,
             &[],
             false,
         );
         positions.sort();
-        assert_eq!(right_positions, positions);
+        assert_eq!(right_positions_first_pawn, positions);
+
+        // Middle pawn
+        let mut right_positions_second_pawn: Vec<Coord> = vec![];
+        right_positions_second_pawn.sort();
+
+        let mut positions = Pawn::authorized_positions(
+            &Coord::new(2, 3),
+            PieceColor::White,
+            board.board,
+            &[],
+            false,
+        );
+        positions.sort();
+        assert_eq!(right_positions_second_pawn, positions);
+
+        // Third pawn on the right
+        let mut right_positions_third_pawn: Vec<Coord> = vec![Coord::new(1, 3), Coord::new(1, 4)];
+        right_positions_third_pawn.sort();
+
+        let mut positions = Pawn::authorized_positions(
+            &Coord::new(2, 4),
+            PieceColor::White,
+            board.board,
+            &[],
+            false,
+        );
+        positions.sort();
+        assert_eq!(right_positions_third_pawn, positions);
     }
 
     #[test]
@@ -362,8 +429,8 @@ mod tests {
             [
                 None,
                 None,
-                Some((PieceType::Pawn, PieceColor::Black)),
                 Some((PieceType::Pawn, PieceColor::White)),
+                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
                 None,
                 None,
@@ -381,13 +448,14 @@ mod tests {
         right_positions.sort();
 
         let mut positions = Pawn::authorized_positions(
-            &Coord::new(3, 3),
+            &Coord::new(3, 2),
             PieceColor::White,
             board.board,
             &[(PieceMove {
                 piece_type: PieceType::Pawn,
-                from: Coord::new(1, 2),
-                to: Coord::new(3, 2),
+                piece_color: PieceColor::Black,
+                from: Coord::new(6, 4),
+                to: Coord::new(4, 4),
             })],
             false,
         );
@@ -401,7 +469,6 @@ mod tests {
             [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
             [
                 None,
                 None,
@@ -415,21 +482,23 @@ mod tests {
             [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
         ];
         let mut board = Board::default();
         board.set_board(custom_board);
 
-        let mut right_positions = vec![Coord::new(5, 2), Coord::new(5, 3)];
+        let mut right_positions = vec![Coord::new(2, 2), Coord::new(2, 3)];
         right_positions.sort();
 
         let mut positions = Pawn::authorized_positions(
-            &Coord::new(4, 2),
+            &Coord::new(3, 2),
             PieceColor::Black,
             board.board,
             &[(PieceMove {
                 piece_type: PieceType::Pawn,
-                from: Coord::new(6, 3),
-                to: Coord::new(4, 3),
+                piece_color: PieceColor::White,
+                from: Coord::new(6, 4),
+                to: Coord::new(4, 4),
             })],
             false,
         );
@@ -440,12 +509,14 @@ mod tests {
     #[test]
     fn pawn_not_en_passant() {
         let custom_board = [
+            [None, None, None, None, None, None, None, None],
+            [None, None, None, None, None, None, None, None],
             [None, None, None, None, None, None, None, None],
             [
                 None,
-                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
                 None,
+                Some((PieceType::Pawn, PieceColor::White)),
                 None,
                 None,
                 None,
@@ -455,32 +526,31 @@ mod tests {
             [None, None, None, None, None, None, None, None],
             [
                 None,
+                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
                 None,
-                Some((PieceType::Pawn, PieceColor::White)),
                 None,
                 None,
                 None,
                 None,
             ],
             [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
-            [None, None, None, None, None, None, None, None],
         ];
         let mut board = Board::default();
         board.set_board(custom_board);
 
-        let mut right_positions = vec![Coord::new(2, 1), Coord::new(3, 1)];
+        let mut right_positions = vec![Coord::new(5, 1), Coord::new(4, 1)];
         right_positions.sort();
 
         let mut positions = Pawn::authorized_positions(
-            &Coord::new(1, 1),
+            &Coord::new(6, 1),
             PieceColor::Black,
             board.board,
             &[(PieceMove {
                 piece_type: PieceType::Pawn,
-                from: Coord::new(6, 3),
-                to: Coord::new(4, 3),
+                piece_color: PieceColor::White,
+                from: Coord::new(6, 4),
+                to: Coord::new(4, 4),
             })],
             false,
         );
@@ -496,8 +566,8 @@ mod tests {
             [
                 None,
                 None,
-                Some((PieceType::King, PieceColor::Black)),
-                Some((PieceType::Pawn, PieceColor::Black)),
+                Some((PieceType::Queen, PieceColor::White)),
+                None,
                 None,
                 None,
                 None,
@@ -506,8 +576,8 @@ mod tests {
             [
                 None,
                 None,
-                Some((PieceType::Queen, PieceColor::White)),
-                None,
+                Some((PieceType::King, PieceColor::Black)),
+                Some((PieceType::Pawn, PieceColor::Black)),
                 None,
                 None,
                 None,
@@ -524,11 +594,11 @@ mod tests {
         let is_king_checked =
             is_getting_checked(board.board, board.player_turn, &board.move_history);
 
-        let mut right_positions = vec![Coord::new(3, 2)];
+        let mut right_positions = vec![Coord::new(2, 2)];
         right_positions.sort();
 
         let mut positions = Pawn::authorized_positions(
-            &Coord::new(2, 3),
+            &Coord::new(3, 3),
             PieceColor::Black,
             board.board,
             &[],
diff --git a/src/popups.rs b/src/popups.rs
index e1ebaf0..5da22c8 100644
--- a/src/popups.rs
+++ b/src/popups.rs
@@ -1,7 +1,7 @@
 use crate::{
     app::App,
     constants::WHITE,
-    pieces::{bishop::Bishop, knight::Knight, queen::Queen, rook::Rook},
+    pieces::{bishop::Bishop, knight::Knight, pawn::Pawn, queen::Queen, rook::Rook},
     ui::centered_rect,
 };
 use ratatui::{
@@ -168,7 +168,7 @@ pub fn render_credit_popup(frame: &mut Frame) {
 
     let credits_text = vec![
         Line::from(""),
-        Line::from("Hi 👋, I'm Thomas, a 21-year-old French computer science student."),
+        Line::from("Hi 👋, I'm Thomas, a 22 years old French computer science student."),
         Line::from("Thank you for playing Chess-tui! This project started as a personal journey to improve my algorithmic skills and learn Rust."),
         Line::from(""),
         Line::from("The entire source code is available on GitHub at https://github.com/thomas-mauran/chess-tui"),
@@ -251,3 +251,82 @@ pub fn render_help_popup(frame: &mut Frame) {
     frame.render_widget(block, area);
     frame.render_widget(paragraph, area);
 }
+
+// This renders a popup for the color selection
+pub fn render_color_selection_popup(frame: &mut Frame, app: &App) {
+    let block = Block::default()
+        .title("Color selection")
+        .borders(Borders::ALL)
+        .border_type(BorderType::Rounded)
+        .padding(Padding::horizontal(1))
+        .border_style(Style::default().fg(WHITE));
+    let area = centered_rect(40, 40, frame.area());
+
+    let text = vec![
+        Line::from(""),
+        Line::from("-- Choose your color --").alignment(Alignment::Center),
+        Line::from(""),
+    ];
+
+    let paragraph = Paragraph::new(text)
+        .block(Block::default())
+        .alignment(Alignment::Left)
+        .wrap(Wrap { trim: true });
+    frame.render_widget(Clear, area);
+    frame.render_widget(block, area);
+    frame.render_widget(paragraph, area);
+
+    let inner_popup_layout_vertical = Layout::default()
+        .direction(Direction::Vertical)
+        .constraints(
+            [
+                Constraint::Ratio(1, 3),
+                Constraint::Ratio(1, 3),
+                Constraint::Ratio(1, 3),
+            ]
+            .as_ref(),
+        )
+        .split(area);
+
+    let inner_popup_layout_horizontal = Layout::default()
+        .direction(Direction::Horizontal)
+        .constraints(
+            [
+                Constraint::Ratio(1, 3),
+                Constraint::Ratio(1, 3),
+                Constraint::Ratio(1, 3),
+            ]
+            .as_ref(),
+        )
+        .split(inner_popup_layout_vertical[1]);
+
+    let display_mode = &app.board.display_mode;
+
+    let white_pawn = Paragraph::new(Pawn::to_string(display_mode))
+        .block(Block::default())
+        .alignment(Alignment::Center)
+        .style(
+            Style::default()
+                .fg(Color::White)
+                .bg(if app.menu_cursor == 0 {
+                    Color::Blue
+                } else {
+                    Color::Reset // Set to the default background color when the condition is false
+                }),
+        );
+    frame.render_widget(white_pawn, inner_popup_layout_horizontal[0]);
+
+    let black_pawn = Paragraph::new(Pawn::to_string(display_mode))
+        .block(Block::default())
+        .alignment(Alignment::Center)
+        .style(
+            Style::default()
+                .fg(Color::Black)
+                .bg(if app.menu_cursor == 1 {
+                    Color::Blue
+                } else {
+                    Color::Reset // Set to the default background color when the condition is false
+                }),
+        );
+    frame.render_widget(black_pawn, inner_popup_layout_horizontal[2]);
+}
diff --git a/src/ui.rs b/src/ui.rs
index 1512dc7..a7d1bf0 100644
--- a/src/ui.rs
+++ b/src/ui.rs
@@ -12,8 +12,8 @@ use crate::{
     constants::{DisplayMode, Pages, TITLE},
     pieces::PieceColor,
     popups::{
-        render_credit_popup, render_end_popup, render_engine_path_error_popup, render_help_popup,
-        render_promotion_popup,
+        render_color_selection_popup, render_credit_popup, render_end_popup,
+        render_engine_path_error_popup, render_help_popup, render_promotion_popup,
     },
 };
 
@@ -28,16 +28,25 @@ pub fn render(app: &mut App, frame: &mut Frame) {
             match &app.chess_engine_path {
                 Some(path) => {
                     app.board.set_engine(path);
-                    render_game_ui(frame, app, main_area);
+                    if app.selected_color.is_none() {
+                        app.show_color_popup = true;
+                    } else {
+                        render_game_ui(frame, app, main_area);
+                    }
                 }
                 None => render_engine_path_error_popup(frame),
             }
+        } else if app.selected_color.is_none() {
+            app.show_color_popup = true;
         } else {
             render_game_ui(frame, app, main_area);
         }
     } else {
         render_menu_ui(frame, app, main_area);
     }
+    if app.show_color_popup {
+        render_color_selection_popup(frame, app);
+    }
 
     if app.show_help_popup {
         render_help_popup(frame);
diff --git a/src/utils.rs b/src/utils.rs
index 4540b25..9e40ada 100644
--- a/src/utils.rs
+++ b/src/utils.rs
@@ -128,10 +128,13 @@ pub fn get_int_from_char(ch: Option<char>) -> u8 {
 
 pub fn did_piece_already_move(
     move_history: &[PieceMove],
-    original_piece: (Option<PieceType>, Coord),
+    original_piece: (Option<PieceType>, Option<PieceColor>, Coord),
 ) -> bool {
     for entry in move_history {
-        if Some(entry.piece_type) == original_piece.0 && entry.from == original_piece.1 {
+        if Some(entry.piece_type) == original_piece.0
+            && Some(entry.piece_color) == original_piece.1
+            && entry.from == original_piece.2
+        {
             return true;
         }
     }
@@ -245,6 +248,10 @@ pub fn get_cell_paragraph<'a>(
     paragraph.alignment(Alignment::Center)
 }
 
+pub fn invert_position(coord: &Coord) -> Coord {
+    Coord::new(7 - coord.row, 7 - coord.col)
+}
+
 #[cfg(test)]
 mod tests {
     use crate::utils::{convert_notation_into_position, convert_position_into_notation};


Test patch: