Mert Us Matthew Hannay Logan Starr

Dependencies:   mbed 4DGL-uLCD-SE

Revision:
16:b66a720631dd
Parent:
14:f390d08e5f92
Child:
17:4d74a661d6a0
diff -r f390d08e5f92 -r b66a720631dd main.cpp
--- a/main.cpp	Sun Dec 04 09:32:07 2022 +0000
+++ b/main.cpp	Mon Dec 05 12:10:50 2022 +0000
@@ -1,33 +1,34 @@
 #include "mbed.h"
 #include "uLCD_4DGL.h"
 #include <vector>
-
+ 
 uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
-
-DigitalOut myLed(LED1);
 Serial Blue(p13, p14);
-
+DigitalOut bad_move(p18);
+DigitalIn reset_button(p19);
+DigitalIn game_mode_switch(p20);
+ 
 enum Piece {e, wK, bK, wQ, bQ, wR, bR, wB, bB, wN, bN, w, b};
 std::vector<Piece> whitePieces;
 std::vector<Piece> blackPieces;
-
+ 
 enum GameState {whiteSelecting, whitePickedUp, whiteAI, blackSelecting, blackPickedUp, blackAI};
-
+ 
 struct pixelCoord {
     uint8_t x;
     uint8_t y;
 };
-
+ 
 struct boardPos {
     uint8_t row;
     uint8_t column;
-
+ 
     bool operator==(const boardPos &other) const
     {
         return row == other.row && column == other.column;
     }
 };
-
+ 
 class Nav_Switch
 {
 public:
@@ -42,12 +43,13 @@
 //automatic read on RHS
     operator int ();
 //index to any switch array style
-    bool operator[](int index) {
+    bool operator[](int index)
+    {
         return _pins[index];
     };
 private:
     BusIn _pins;
-
+ 
 };
 Nav_Switch::Nav_Switch (PinName up,PinName down,PinName left,PinName right,PinName fire):
     _pins(up, down, left, right, fire)
@@ -84,63 +86,72 @@
     return _pins.read();
 }
 
+const int BOARD_DARK_COLOR = 0x769656;
+const int BOARD_LIGHT_COLOR = 0xbaca44;
+ 
 const float KING_POSITION_VALUES[] = {2.0, 3.0, 1.0, 0.0, 0.0, 1.0, 3.0, 2,0,
-                                            2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0,
-                                            -1.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -1.0,
-                                            -2.0, -3.0, -3.0, -4.0, -4.0, -3.0, -3.0, -2,0,
-                                            -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0,
-                                            -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0,
-                                            -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0,
-                                            -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0};
-                                            
+                                      2.0, 2.0, 0.0, 0.0, 0.0, 0.0, 2.0, 2.0,
+                                      -1.0, -2.0, -2.0, -2.0, -2.0, -2.0, -2.0, -1.0,
+                                      -2.0, -3.0, -3.0, -4.0, -4.0, -3.0, -3.0, -2,0,
+                                      -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0,
+                                      -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0,
+                                      -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0,
+                                      -3.0, -4.0, -4.0, -5.0, -5.0, -4.0, -4.0, -3.0
+                                     };
+ 
 const float QUEEN_POSITION_VALUES[] = {-2.0, -1.0, -1.0, -0.5, -0.5, -1.0, -1.0, -2.0,
-                                                        -1.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, -1.0,
-                                                        -1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0, -1.0,
-                                                        0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, -0.5,
-                                                        -0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, -0.5,
-                                                        -1.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, -1.0,
-                                                        -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
-                                                        -2.0, -1.0, -1.0, -0.5, -0.5, -1.0, -1.0, -2.0};
-
+                                       -1.0, 0.0, 0.5, 0.0, 0.0, 0.0, 0.0, -1.0,
+                                       -1.0, 0.5, 0.5, 0.5, 0.5, 0.5, 0.0, -1.0,
+                                       0.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, -0.5,
+                                       -0.5, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, -0.5,
+                                       -1.0, 0.0, 0.5, 0.5, 0.5, 0.5, 0.0, -1.0,
+                                       -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
+                                       -2.0, -1.0, -1.0, -0.5, -0.5, -1.0, -1.0, -2.0
+                                      };
+ 
 const float ROOK_POSITION_VALUES[] = {0.0, 0.0, 0.0, 0.5, 0.5, 0.0, 0.0, 0.0,
-                                                       -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
-                                                       -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
-                                                       -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
-                                                       -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
-                                                       -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
-                                                       0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5,
-                                                       0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
-
+                                      -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
+                                      -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
+                                      -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
+                                      -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
+                                      -0.5, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -0.5,
+                                      0.5, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 0.5,
+                                      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
+                                     };
+ 
 const float BISHOP_POSITION_VALUES[] = {-2.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -2.0,
-                                                         -1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, -1.0,
-                                                         -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,
-                                                         -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0,
-                                                         -1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, -1.0,
-                                                         -1.0, 0.0, 0.5, 1.0, 1.0, 0.5, 0.0, -1.0,
-                                                         -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
-                                                         -2.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -2.0};
+                                        -1.0, 0.5, 0.0, 0.0, 0.0, 0.0, 0.5, -1.0,
+                                        -1.0, 1.0, 1.0, 1.0, 1.0, 1.0, 1.0, -1.0,
+                                        -1.0, 0.0, 1.0, 1.0, 1.0, 1.0, 0.0, -1.0,
+                                        -1.0, 0.5, 0.5, 1.0, 1.0, 0.5, 0.5, -1.0,
+                                        -1.0, 0.0, 0.5, 1.0, 1.0, 0.5, 0.0, -1.0,
+                                        -1.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, -1.0,
+                                        -2.0, -1.0, -1.0, -1.0, -1.0, -1.0, -1.0, -2.0
+                                       };
 const float KNIGHT_POSITION_VALUES[] = {-5.0, -4.0, -3.0, -3.0, -3.0, -3.0, -4.0, -5.0,
-                                                         -4.0, -2.0, 0.0, 0.5, 0.5, 0.0, -2.0, -4.0,
-                                                         -3.0, 0.5, 1.0, 1.5, 1.5, 1.0, 0.5, -3.0,
-                                                         -3.0, 0.0, 1.5, 2.0, 2.0, 1.5, 0.0, -3.0,
-                                                         -3.0, 0.5, 1.5, 2.0, 2.0, 1.5, 0.5, -3.0,
-                                                         -3.0, 0.0, 1.0, 1.5, 1.5, 1.0, 0.0, -3.0,
-                                                         -4.0, -2.0, 0.0, 0.0, 0.0, 0.0, -2.0, -4.0,
-                                                         -5.0, -4.0, -3.0, -3.0, -3.0, -3.0, -4.0, -5.0};
+                                        -4.0, -2.0, 0.0, 0.5, 0.5, 0.0, -2.0, -4.0,
+                                        -3.0, 0.5, 1.0, 1.5, 1.5, 1.0, 0.5, -3.0,
+                                        -3.0, 0.0, 1.5, 2.0, 2.0, 1.5, 0.0, -3.0,
+                                        -3.0, 0.5, 1.5, 2.0, 2.0, 1.5, 0.5, -3.0,
+                                        -3.0, 0.0, 1.0, 1.5, 1.5, 1.0, 0.0, -3.0,
+                                        -4.0, -2.0, 0.0, 0.0, 0.0, 0.0, -2.0, -4.0,
+                                        -5.0, -4.0, -3.0, -3.0, -3.0, -3.0, -4.0, -5.0
+                                       };
 const float PAWN_POSITION_VALUES[] = {0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0,
-                                                       0.5, 1.0, 1.0, -2.0, -2.0, 1.0, 1.0, 0.5,
-                                                       0.5, -0.5, -1.0, 0.0, 0.0, -1.0, -0.5, 0.5,
-                                                       0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0,
-                                                       0.5, 0.5, 1.0, 2.5, 2.5, 1.0, 0.5, 0.5,
-                                                       1.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0,
-                                                       5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
-                                                       0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0};
-
+                                      0.5, 1.0, 1.0, -2.0, -2.0, 1.0, 1.0, 0.5,
+                                      0.5, -0.5, -1.0, 0.0, 0.0, -1.0, -0.5, 0.5,
+                                      0.0, 0.0, 0.0, 2.0, 2.0, 0.0, 0.0, 0.0,
+                                      0.5, 0.5, 1.0, 2.5, 2.5, 1.0, 0.5, 0.5,
+                                      1.0, 1.0, 2.0, 3.0, 3.0, 2.0, 1.0, 1.0,
+                                      5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0, 5.0,
+                                      0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0
+                                     };
+ 
 class BoardState
 {
 private:
     Piece array[64];
-    // These values are for white pieces, need to be inverted 
+    // These values are for white pieces, need to be inverted
     // when making calculations for black pieces.
     static const float PAWN_VALUE = 10.0;
     static const float KNIGHT_VALUE = 30.0;
@@ -150,7 +161,7 @@
     static const float KING_VALUE = 900.0;
 public:
     BoardState() {}
-    
+ 
     // calculates the advantage difference for the board state
     float calculateBoardState()
     {
@@ -198,23 +209,30 @@
                     break;
                 default:
                     break;
-                }
+            }
         }
         return sum;
     }
-
+ 
     // returns the piece at a given location
     Piece getPiece(int row, int column)
     {
         return array[column + 8 * row];
     }
-
+ 
     // puts a piece at a given location
     void placePiece(Piece piece, int row, int column)
     {
-        array[column + 8 * row] = piece;
+        // pawn promotion handling
+        if (piece == w && row == 7) {
+            array[column + 8 * row] = wQ;
+        } else if (piece == b && row == 0) {
+            array[column + 8 * row] = bQ;
+        } else {
+            array[column + 8 * row] = piece;
+        }
     }
-
+ 
     /*  removes a piece from the set position of the board
         returns the bit representation of the piece
     */
@@ -224,7 +242,7 @@
         array[column + 8 * row] = e;
         return removedPiece;
     }
-
+ 
     /*  moves a piece from one position to another
         returns the captured piece
     */
@@ -235,7 +253,7 @@
         placePiece(movingPiece, endRow, endColumn);
         return capturedPiece;
     }
-
+ 
     // generates a list of possible moves for a piece
     // returns moves
     std::vector<boardPos> getMoves(boardPos pos)
@@ -255,204 +273,44 @@
             case bK:
                 isWhite = movingPiece == wK;
                 if (validMove(isWhite, row + 1, column)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row + 1, column
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row, column + 1)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row, column + 1
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row - 1, column)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row - 1, column
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row, column - 1)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row, column - 1
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row + 1, column + 1)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row + 1, column + 1
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row - 1, column + 1)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row - 1, column + 1
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row - 1, column - 1)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row - 1, column - 1
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 if (validMove(isWhite, row + 1, column - 1)) {
-                    boardPos tPos = (boardPos) {
+                    moves.push_back((boardPos) {
                         row + 1, column - 1
-                    };
-                    bool possibleKingMove = true;
-                    for (int i = 0; i < 64; i++) {
-                        Piece possibleThreat = getPiece(i/8, i%8);
-                        if (isWhite && (possibleThreat == bK || possibleThreat == bQ || possibleThreat == bR || possibleThreat == bN || possibleThreat == bB || possibleThreat == b)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        } else if (!isWhite && (possibleThreat == wK || possibleThreat == wQ || possibleThreat == wR || possibleThreat == wN || possibleThreat == wB || possibleThreat == w)) {
-                            std::vector<boardPos> possibleThreatMoves = getMoves(i/8, i%8);
-                            if (std::find(possibleThreatMoves.begin(), possibleThreatMoves.end(), tPos) != possibleThreatMoves.end()) {
-                                possibleKingMove = false;
-                                break;
-                            }
-                        }
-                    }
-                    if (possibleKingMove) {
-                        moves.push_back(tPos);
-                    }
+                    });
                 }
                 break;
             case wQ:
@@ -726,7 +584,7 @@
         }
         return moves;
     }
-
+ 
     // returns a vector of board positions that a piece can move in a line
     std::vector<boardPos> movesInLine(bool isMovingPieceWhite, int row, int column, int rowChange, int columnChange)
     {
@@ -748,7 +606,7 @@
         }
         return moves;
     }
-
+ 
     // returns if a piece can move to a given location
     bool validMove(bool isMovingPieceWhite, int row, int column)
     {
@@ -777,163 +635,153 @@
         return false;
     }
 };
-
+ 
 class GameBoard
 {
 private:
     BoardState boardState;
-    static const int BOARD_DARK_COLOR = 0x769656;
-    static const int BOARD_LIGHT_COLOR = 0xbaca44;
     static const int HOVER_COLOR = 0x0000ff;
     static const int SELECTED_COLOR = 0xff8800;
     static const int MOVE_COLOR = 0xff00ff;
-    
-    // gets the pixel coordinates of the top left of the square 
-    static pixelCoord getTopLeftOfSquare(boardPos pos)  
-    {   
-        return getTopLeftOfSquare(pos.row, pos.column); 
-    }   
-    static pixelCoord getTopLeftOfSquare(int row, int column)   
-    {   
-        pixelCoord topLeft; 
-        topLeft.x = 16 * column;    
-        topLeft.y = 112 - 16 * row; 
-        return topLeft; 
+ 
+    // piece sprites (12 x 12)
+    static void drawPawn(int row, int column, bool white, bool light)
+    {
+        int X = white ? 0xffffff : 0x000000;
+        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;
+        int sprite[144] = {_, _, _, _, _, _, _, _, _, _, _, _,
+                           _, _, _, _, _, _, _, _, _, _, _, _,
+                           _, _, _, _, _, _, _, _, _, _, _, _,
+                           _, _, _, _, _, _, _, _, _, _, _, _,
+                           _, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, _, X, X, X, X, _, _, _, _,
+                           _, _, _, _, X, X, X, X, _, _, _, _,
+                           _, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, _, X, X, X, X, _, _, _, _,
+                           _, _, X, X, X, X, X, X, X, X, _, _,
+                           _, _, X, X, X, X, X, X, X, X, _, _
+                          };
+        pixelCoord tl = getTopLeftOfSquare(row, column);
+        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);
+    }
+ 
+    static void drawRook(int row, int column, bool white, bool light)
+    {
+        int X = white ? 0xffffff : 0x000000;
+        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;
+        int sprite[144] = {X, X, _, X, X, _, _, X, X, _, X, X,
+                           X, X, _, X, X, _, _, X, X, _, X, X,
+                           X, X, X, X, X, X, X, X, X, X, X, X,
+                           X, X, X, X, X, X, X, X, X, X, X, X,
+                           _, X, X, X, _, X, X, _, X, X, X, _,
+                           _, X, X, X, _, X, X, _, X, X, X, _,
+                           _, _, X, X, _, X, X, _, X, X, _, _,
+                           _, _, X, X, _, X, X, _, X, X, _, _,
+                           _, _, X, X, _, X, X, _, X, X, _, _,
+                           _, X, X, X, X, X, X, X, X, X, X, _,
+                           X, X, X, X, X, X, X, X, X, X, X, X,
+                           X, X, X, X, X, X, X, X, X, X, X, X
+                          };
+        pixelCoord tl = getTopLeftOfSquare(row, column);
+        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);
+    }
+ 
+    static void drawKnight(int row, int column, bool white, bool light)
+    {
+        int X = white ? 0xffffff : 0x000000;
+        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;
+        int sprite[144] = {_, _, _, _, _, _, _, _, _, _, _, _,
+                           _, _, _, _, _, X, X, _, X, X, _, _,
+                           _, _, _, _, _, X, X, _, X, X, _, _,
+                           _, _, _, X, X, X, X, X, X, _, _, _,
+                           _, _, X, X, X, X, X, _, X, _, _, _,
+                           _, _, X, X, X, X, X, X, X, _, _, _,
+                           _, _, _, _, _, X, X, X, X, _, _, _,
+                           _, _, _, _, X, X, X, X, X, _, _, _,
+                           _, _, _, X, X, X, X, X, X, X, _, _,
+                           _, _, X, X, X, X, X, X, X, X, _, _,
+                           _, X, X, X, X, X, X, X, X, X, X, _,
+                           _, X, X, X, X, X, X, X, X, X, X, _
+                          };
+        pixelCoord tl = getTopLeftOfSquare(row, column);
+        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);
     }
-
-    // piece sprites (12 x 12)  
-    static void drawPawn(int row, int column, bool white, bool light)   
-    {   
-        int X = white ? 0xffffff : 0x000000;    
-        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;   
-        int sprite[144] = {_, _, _, _, _, _, _, _, _, _, _, _,  
-                           _, _, _, _, _, _, _, _, _, _, _, _,  
-                           _, _, _, _, _, _, _, _, _, _, _, _,  
-                           _, _, _, _, _, _, _, _, _, _, _, _,  
-                           _, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, _, X, X, X, X, _, _, _, _,  
-                           _, _, _, _, X, X, X, X, _, _, _, _,  
-                           _, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, _, X, X, X, X, _, _, _, _,  
-                           _, _, X, X, X, X, X, X, X, X, _, _,  
-                           _, _, X, X, X, X, X, X, X, X, _, _   
-                          };    
-        pixelCoord tl = getTopLeftOfSquare(row, column);    
-        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);  
-    }   
-    static void drawRook(int row, int column, bool white, bool light)   
-    {   
-        int X = white ? 0xffffff : 0x000000;    
-        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;   
-        int sprite[144] = {X, X, _, X, X, _, _, X, X, _, X, X,  
-                           X, X, _, X, X, _, _, X, X, _, X, X,  
-                           X, X, X, X, X, X, X, X, X, X, X, X,  
-                           X, X, X, X, X, X, X, X, X, X, X, X,  
-                           _, X, X, X, _, X, X, _, X, X, X, _,  
-                           _, X, X, X, _, X, X, _, X, X, X, _,  
-                           _, _, X, X, _, X, X, _, X, X, _, _,  
-                           _, _, X, X, _, X, X, _, X, X, _, _,  
-                           _, _, X, X, _, X, X, _, X, X, _, _,  
-                           _, X, X, X, X, X, X, X, X, X, X, _,  
-                           X, X, X, X, X, X, X, X, X, X, X, X,  
-                           X, X, X, X, X, X, X, X, X, X, X, X   
-                          };    
-        pixelCoord tl = getTopLeftOfSquare(row, column);    
-        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);  
-    }   
-    static void drawKnight(int row, int column, bool white, bool light) 
-    {   
-        int X = white ? 0xffffff : 0x000000;    
-        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;   
-        int sprite[144] = {_, _, _, _, _, _, _, _, _, _, _, _,  
-                           _, _, _, _, _, X, X, _, X, X, _, _,  
-                           _, _, _, _, _, X, X, _, X, X, _, _,  
-                           _, _, _, X, X, X, X, X, X, _, _, _,  
-                           _, _, X, X, X, X, X, _, X, _, _, _,  
-                           _, _, X, X, X, X, X, X, X, _, _, _,  
-                           _, _, _, _, _, X, X, X, X, _, _, _,  
-                           _, _, _, _, X, X, X, X, X, _, _, _,  
-                           _, _, _, X, X, X, X, X, X, X, _, _,  
-                           _, _, X, X, X, X, X, X, X, X, _, _,  
-                           _, X, X, X, X, X, X, X, X, X, X, _,  
-                           _, X, X, X, X, X, X, X, X, X, X, _   
-                          };    
-        pixelCoord tl = getTopLeftOfSquare(row, column);    
-        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);  
-    }   
-    static void drawBishop(int row, int column, bool white, bool light) 
-    {   
-        int X = white ? 0xffffff : 0x000000;    
-        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;   
-        int sprite[144] = {_, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, _, X, X, X, _, _, _, _, _,  
-                           _, _, _, X, X, X, _, _, X, _, _, _,  
-                           _, _, _, X, X, _, _, X, X, _, _, _,  
-                           _, _, _, X, X, X, X, X, X, _, _, _,  
-                           _, _, _, _, X, X, X, X, _, _, _, _,  
-                           _, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, _, X, X, X, X, _, _, _, _,  
-                           _, _, _, X, X, X, X, X, X, _, _, _,  
-                           _, _, _, X, X, X, X, X, X, _, _, _,  
-                           _, _, X, X, X, X, X, X, X, X, _, _,  
-                           _, _, X, X, X, X, X, X, X, X, _, _   
-                          };    
-        pixelCoord tl = getTopLeftOfSquare(row, column);    
-        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);  
-    }   
-    static void drawQueen(int row, int column, bool white, bool light)  
-    {   
-        int X = white ? 0xffffff : 0x000000;    
-        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;   
-        int sprite[144] = {_, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, X, _, _, X, X, _, _, X, _, _,  
-                           X, _, X, X, _, X, X, _, X, X, _, X,  
-                           X, _, X, X, _, X, X, _, X, X, _, X,  
-                           X, _, X, X, _, X, X, _, X, X, _, X,  
-                           X, X, X, X, X, X, X, X, X, X, X, X,  
-                           X, X, X, X, X, X, X, X, X, X, X, X,  
-                           X, X, _, X, X, X, X, X, X, _, X, X,  
-                           X, X, X, X, _, X, X, _, X, X, X, X,  
-                           _, X, X, X, X, X, X, X, X, X, X, _,  
-                           _, _, X, X, X, X, X, X, X, X, _, _,  
-                           _, X, X, X, X, X, X, X, X, X, X, _   
-                          };    
-        pixelCoord tl = getTopLeftOfSquare(row, column);    
-        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);  
-    }   
-    static void drawKing(int row, int column, bool white, bool light)   
-    {   
-        int X = white ? 0xffffff : 0x000000;    
-        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;   
-        int sprite[144] = {_, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, _, _, X, X, _, _, _, _, _,  
-                           _, _, _, X, X, X, X, X, X, _, _, _,  
-                           _, _, _, X, X, X, X, X, X, _, _, _,  
-                           X, X, _, _, _, X, X, _, _, _, X, X,  
-                           X, X, X, X, _, X, X, _, X, X, X, X,  
-                           X, _, X, X, X, X, X, X, X, X, _, X,  
-                           X, X, X, X, X, X, X, X, X, X, X, X,  
-                           X, X, X, _, X, X, X, X, _, X, X, X,  
-                           _, X, X, X, X, X, X, X, X, X, X, _,  
-                           _, _, X, X, X, _, _, X, X, X, _, _,  
-                           _, X, X, X, X, X, X, X, X, X, X, _   
-                          };    
-        pixelCoord tl = getTopLeftOfSquare(row, column);    
-        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);  
+ 
+    static void drawBishop(int row, int column, bool white, bool light)
+    {
+        int X = white ? 0xffffff : 0x000000;
+        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;
+        int sprite[144] = {_, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, _, X, X, X, _, _, _, _, _,
+                           _, _, _, X, X, X, _, _, X, _, _, _,
+                           _, _, _, X, X, _, _, X, X, _, _, _,
+                           _, _, _, X, X, X, X, X, X, _, _, _,
+                           _, _, _, _, X, X, X, X, _, _, _, _,
+                           _, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, _, X, X, X, X, _, _, _, _,
+                           _, _, _, X, X, X, X, X, X, _, _, _,
+                           _, _, _, X, X, X, X, X, X, _, _, _,
+                           _, _, X, X, X, X, X, X, X, X, _, _,
+                           _, _, X, X, X, X, X, X, X, X, _, _
+                          };
+        pixelCoord tl = getTopLeftOfSquare(row, column);
+        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);
     }
-
+ 
+    static void drawQueen(int row, int column, bool white, bool light)
+    {
+        int X = white ? 0xffffff : 0x000000;
+        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;
+        int sprite[144] = {_, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, X, _, _, X, X, _, _, X, _, _,
+                           X, _, X, X, _, X, X, _, X, X, _, X,
+                           X, _, X, X, _, X, X, _, X, X, _, X,
+                           X, _, X, X, _, X, X, _, X, X, _, X,
+                           X, X, X, X, X, X, X, X, X, X, X, X,
+                           X, X, X, X, X, X, X, X, X, X, X, X,
+                           X, X, _, X, X, X, X, X, X, _, X, X,
+                           X, X, X, X, _, X, X, _, X, X, X, X,
+                           _, X, X, X, X, X, X, X, X, X, X, _,
+                           _, _, X, X, X, X, X, X, X, X, _, _,
+                           _, X, X, X, X, X, X, X, X, X, X, _
+                          };
+        pixelCoord tl = getTopLeftOfSquare(row, column);
+        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);
+    }
+ 
+    static void drawKing(int row, int column, bool white, bool light)
+    {
+        int X = white ? 0xffffff : 0x000000;
+        int _ = light ? BOARD_LIGHT_COLOR : BOARD_DARK_COLOR;
+        int sprite[144] = {_, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, _, _, X, X, _, _, _, _, _,
+                           _, _, _, X, X, X, X, X, X, _, _, _,
+                           _, _, _, X, X, X, X, X, X, _, _, _,
+                           X, X, _, _, _, X, X, _, _, _, X, X,
+                           X, X, X, X, _, X, X, _, X, X, X, X,
+                           X, _, X, X, X, X, X, X, X, X, _, X,
+                           X, X, X, X, X, X, X, X, X, X, X, X,
+                           X, X, X, _, X, X, X, X, _, X, X, X,
+                           _, X, X, X, X, X, X, X, X, X, X, _,
+                           _, _, X, X, X, _, _, X, X, X, _, _,
+                           _, X, X, X, X, X, X, X, X, X, X, _
+                          };
+        pixelCoord tl = getTopLeftOfSquare(row, column);
+        uLCD.BLIT(tl.x + 2, tl.y + 2, 12, 12, sprite);
+    }
+ 
 public:
     BoardState getBoardState()
     {
         return boardState;
     }
-
+ 
     void setBoardState(BoardState newBoardState)
     {
         boardState = newBoardState;
     }
-
+ 
     // initializes the starting board state
     GameBoard()
     {
@@ -972,9 +820,22 @@
             placePieceAndDraw(b, 6, i);
         }
     }
-
+    
+    // gets the pixel coordinates of the top left of the square
+    static pixelCoord getTopLeftOfSquare(boardPos pos)
+    {
+        return getTopLeftOfSquare(pos.row, pos.column);
+    }
+    static pixelCoord getTopLeftOfSquare(int row, int column)
+    {
+        pixelCoord topLeft;
+        topLeft.x = 16 * column;
+        topLeft.y = 112 - 16 * row;
+        return topLeft;
+    }
+ 
     // PIECE MOVEMENT AND GRAPHICS FUNCTIONS
-
+ 
     // returns the piece at a given location
     Piece getPiece(boardPos pos)
     {
@@ -984,7 +845,7 @@
     {
         return boardState.getPiece(row, column);
     }
-
+ 
     /*  puts the bit representation of a piece at the set position of the board
         assumes that the position of the board is emptied beforehand
     */
@@ -996,34 +857,41 @@
     {
         boardState.placePiece(piece, row, column);
         pixelCoord tl = getTopLeftOfSquare(row, column);
-        switch(piece) { 
-            case wK:    
-            case bK:    
-                drawKing(row, column, piece==wK, (row+column)%2);   
-                break;  
-            case wQ:    
-            case bQ:    
-                drawQueen(row, column, piece==wQ, (row+column)%2);  
-                break;  
-            case wB:    
-            case bB:    
-                drawBishop(row, column, piece==wB, (row+column)%2); 
-                break;  
-            case wN:    
-            case bN:    
-                drawKnight(row, column, piece==wN, (row+column)%2); 
-                break;  
-            case wR:    
-            case bR:    
-                drawRook(row, column, piece==wR, (row+column)%2);   
-                break;  
-            case w: 
-            case b: 
-                drawPawn(row, column, piece==w, (row+column)%2);    
-                break;  
+        switch(piece) {
+            case wK:
+            case bK:
+                drawKing(row, column, piece==wK, (row+column)%2);
+                break;
+            case wQ:
+            case bQ:
+                drawQueen(row, column, piece==wQ, (row+column)%2);
+                break;
+            case wB:
+            case bB:
+                drawBishop(row, column, piece==wB, (row+column)%2);
+                break;
+            case wN:
+            case bN:
+                drawKnight(row, column, piece==wN, (row+column)%2);
+                break;
+            case wR:
+            case bR:
+                drawRook(row, column, piece==wR, (row+column)%2);
+                break;
+            case w:
+            case b:
+                if (piece == w && row == 7) {
+                    drawQueen(row, column, true, (row+column)%2);
+                } else if (piece == b && row == 0) {
+                    drawQueen(row, column, false, (row+column)%2);
+                } else {
+                    drawPawn(row, column, piece==w, (row+column)%2);
+                }
+                break;
+ 
         }
     }
-
+ 
     /*  removes a piece from the set position of the board
         returns the bit representation of the piece
     */
@@ -1044,7 +912,7 @@
         uLCD.filled_rectangle(tl.x+2, tl.y+2, tl.x + 13, tl.y + 13, color);
         return removedPiece;
     }
-
+ 
     /*  moves a piece from one position to another
         returns the captured piece
     */
@@ -1059,9 +927,9 @@
         placePieceAndDraw(movingPiece, endRow, endColumn);
         return capturedPiece;
     }
-
+ 
     // SQUARE BORDER GRAPHICS FUNCTIONS
-
+ 
     // removes selection border around square
     void unselectSquare(boardPos pos)
     {
@@ -1081,7 +949,7 @@
         }
         uLCD.rectangle(tl.x, tl.y, tl.x + 15, tl.y + 15, color);
     }
-
+ 
     // draws the hover border around square
     void hoverSquare(boardPos pos)
     {
@@ -1092,7 +960,7 @@
         pixelCoord tl = getTopLeftOfSquare(row, column);
         uLCD.rectangle(tl.x, tl.y, tl.x + 15, tl.y + 15, HOVER_COLOR);
     }
-
+ 
     // draws selection border around square
     void selectSquare(boardPos pos)
     {
@@ -1106,7 +974,7 @@
         pixelCoord tl = getTopLeftOfSquare(row, column);
         uLCD.rectangle(tl.x, tl.y, tl.x + 15, tl.y + 15, SELECTED_COLOR);
     }
-
+ 
     // draws the movement border around square
     void movementSquare(boardPos pos)
     {
@@ -1118,7 +986,7 @@
         uLCD.rectangle(tl.x, tl.y, tl.x + 15, tl.y + 15, MOVE_COLOR);
     }
 };
-
+ 
 // game variables
 GameBoard gameBoard;
 GameState state = whiteSelecting;
@@ -1130,21 +998,27 @@
 boardPos selectedPos;
 Piece selectedPiece;
 std::vector<boardPos> possibleMoves;
-
+ 
 // callbacks
 void moveCursor(int rowChange, int columnChange)
 {
     // calculate new positoin that is within board bounds
     int newRow = cursorPos.row + rowChange;
+    int newColumn = cursorPos.column + columnChange;
+    if (newRow > 7 || newRow < 0 || newColumn > 7 || newColumn < 0) {
+        bad_move = 1;
+        wait(0.2);
+        bad_move = 0;
+        wait(0.02);
+    }
     newRow = newRow <= 7 ? newRow : 7;
     newRow = newRow >= 0 ? newRow : 0;
-    int newColumn = cursorPos.column + columnChange;
     newColumn = newColumn <= 7 ? newColumn : 7;
     newColumn = newColumn >= 0 ? newColumn : 0;
     boardPos newPos = (boardPos) {
         newRow, newColumn
     };
-
+ 
     // draw border around square that should be there after moving cursor off
     if (cursorPos == selectedPos) {
         gameBoard.selectSquare(cursorPos);
@@ -1153,32 +1027,91 @@
     } else {
         gameBoard.unselectSquare(cursorPos);
     }
-
+ 
     // draw hover rectangle over new square
     cursorPos = newPos;
     gameBoard.hoverSquare(cursorPos);
 }
 
+void reset_game(void) {
+    BoardState newBS;
+    for (int i = 0; i < 64; i++) {
+        newBS.placePiece(e, i/8, i%8);
+    }
+    gameBoard.setBoardState(newBS);
+    // draw board
+    for (int row = 0; row < 8; row++) {
+        for (int column = 0; column < 8; column++) {
+            uint64_t color;
+            if ((row + column) % 2 == 0) {
+                color = BOARD_DARK_COLOR;
+            } else {
+                color = BOARD_LIGHT_COLOR;
+            }
+            pixelCoord tl = gameBoard.getTopLeftOfSquare(row, column);
+            uLCD.filled_rectangle(tl.x, tl.y, tl.x + 15, tl.y + 15, color);
+        }
+    }
+    // draw pieces
+    gameBoard.placePieceAndDraw(wR, 0, 0);
+    gameBoard.placePieceAndDraw(wN, 0, 1);
+    gameBoard.placePieceAndDraw(wB, 0, 2);
+    gameBoard.placePieceAndDraw(wQ, 0, 3);
+    gameBoard.placePieceAndDraw(wK, 0, 4);
+    gameBoard.placePieceAndDraw(wB, 0, 5);
+    gameBoard.placePieceAndDraw(wN, 0, 6);
+    gameBoard.placePieceAndDraw(wR, 0, 7);
+    gameBoard.placePieceAndDraw(bR, 7, 0);
+    gameBoard.placePieceAndDraw(bN, 7, 1);
+    gameBoard.placePieceAndDraw(bB, 7, 2);
+    gameBoard.placePieceAndDraw(bQ, 7, 3);
+    gameBoard.placePieceAndDraw(bK, 7, 4);
+    gameBoard.placePieceAndDraw(bB, 7, 5);
+    gameBoard.placePieceAndDraw(bN, 7, 6);
+    gameBoard.placePieceAndDraw(bR, 7, 7);
+    for (int i = 0; i < 8; i++) {
+        gameBoard.placePieceAndDraw(w, 1, i);
+        gameBoard.placePieceAndDraw(b, 6, i);
+    }
+    
+    state = whiteSelecting;
+    cursorPos = (boardPos)
+    {
+        3, 4
+    };
+    if (game_mode_switch) {
+        OnePlayer = true;
+    } else {
+        OnePlayer = false;
+    }
+    selectedPos = (boardPos)
+    {
+        10, 10
+    };
+    possibleMoves.clear();
+    moveCursor(0, 0);
+}
+ 
 void joyStickUp()
 {
     moveCursor(1, 0);
 }
-
+ 
 void joyStickDown()
 {
     moveCursor(-1, 0);
 }
-
+ 
 void joyStickLeft()
 {
     moveCursor(0, -1);
 }
-
+ 
 void joyStickRight()
 {
     moveCursor(0, 1);
 }
-
+ 
 void joyStickPressed()
 {
     switch(state) {
@@ -1204,10 +1137,13 @@
                     state = state == whiteSelecting ? whitePickedUp : blackPickedUp;
                 }
             } else {
-                selectedPos = (boardPos)
-                {
+                selectedPos = (boardPos) {
                     10, 10
                 };
+                bad_move = 1;
+                wait(0.1);
+                bad_move = 0;
+                wait(0.02);
             }
             break;
         }
@@ -1218,8 +1154,38 @@
                 // move the piece
                 Piece capturedPiece = gameBoard.movePieceAndDraw(selectedPos, cursorPos);
                 // check for king capture
-                if (state == whitePickedUp && capturedPiece == bK || state == blackPickedUp && capturedPiece == wK) {
-                    // game end
+                if (state == whitePickedUp && capturedPiece == bK) {
+                    uLCD.cls();
+                    uLCD.text_height(2);
+                    uLCD.text_width(2);
+                    uLCD.color(WHITE);
+                    uLCD.locate(2,2);
+                    uLCD.printf("WHITE");
+                    uLCD.locate(2,4);
+                    uLCD.printf("WINS");
+                    while(1) {
+                        if (!reset_button) {
+                            reset_game();
+                            break;
+                        }
+                    }
+                    break;
+                } else if (state == blackPickedUp && capturedPiece == wK) {
+                    uLCD.cls();
+                    uLCD.text_height(2);
+                    uLCD.text_width(2);
+                    uLCD.color(WHITE);
+                    uLCD.locate(2,2);
+                    uLCD.printf("BLACK");
+                    uLCD.locate(2,4);
+                    uLCD.printf("WINS");
+                    while(1) {
+                        if (!reset_button) {
+                            reset_game();
+                            break;
+                        }
+                    }
+                    break;
                 }
                 // transition state
                 if (OnePlayer) {
@@ -1239,8 +1205,7 @@
             gameBoard.unselectSquare(selectedPos);
             gameBoard.hoverSquare(cursorPos);
             possibleMoves.clear();
-            selectedPos = (boardPos)
-            {
+            selectedPos = (boardPos) {
                 10, 10
             };
             break;
@@ -1309,7 +1274,7 @@
                                 }
                             }
                         }
-                        
+ 
                         if (bestMoveValueDepth1 < bestMoveValueDepth0) {
                             bestMoveSourceDepth0 = currSourceDepth0;
                             bestMoveDestDepth0 = *it;
@@ -1319,8 +1284,22 @@
                 }
             }
             Piece capturedPiece = gameBoard.movePieceAndDraw(bestMoveSourceDepth0, bestMoveDestDepth0);
-            if (capturedPiece == bK) {
-                // game end
+            if (capturedPiece == wK) {
+                uLCD.cls();
+                uLCD.text_height(2);
+                uLCD.text_width(2);
+                uLCD.color(WHITE);
+                uLCD.locate(2,2);
+                uLCD.printf("BLACK");
+                uLCD.locate(2,4);
+                uLCD.printf("WINS");
+                while(1) {
+                    if (!reset_button) {
+                        reset_game();
+                        break;
+                    }
+                }
+                break;
             }
             state = whiteSelecting;
             break;
@@ -1330,7 +1309,7 @@
         }
     }
 }
-
+ 
 // bluetooth
 volatile bool button_ready = 0;
 volatile int bnum = 0;
@@ -1366,12 +1345,14 @@
             bluetooth_state = start;
     }
 }
-
+ 
 Nav_Switch myNav(p9, p6, p7, p5, p8); //pin order on Sparkfun breakout
-
+ 
 int main()
 {
-    //gameBoard = GameBoard();
+    reset_button.mode(PullUp);
+    game_mode_switch.mode(PullUp);
+    wait(0.01);
     whitePieces.push_back(wK);
     whitePieces.push_back(wQ);
     whitePieces.push_back(wB);
@@ -1384,13 +1365,22 @@
     blackPieces.push_back(bN);
     blackPieces.push_back(bR);
     blackPieces.push_back(b);
+ 
+    if (game_mode_switch) {
+        OnePlayer = true;
+    } else {
+        OnePlayer = false;
+    }
+    
     moveCursor(0, 0);
     Blue.attach(&parse_message,Serial::RxIrq);
+ 
     while (1) {
-        if (state == blackAI) {
+        if (!reset_button) {
+            reset_game();
+        } else if (state == blackAI) {
             joyStickPressed();
-        }
-        if (myNav.up()) {
+        } else if (myNav.up()) {
             joyStickUp();
         } else if (myNav.down()) {
             joyStickDown();