Mert Us Matthew Hannay Logan Starr

Dependencies:   mbed 4DGL-uLCD-SE

Revision:
14:f390d08e5f92
Parent:
11:43c89579ac52
Child:
15:cae96e8b62a3
Child:
16:b66a720631dd
--- a/main.cpp	Thu Dec 01 05:53:57 2022 +0000
+++ b/main.cpp	Sun Dec 04 09:32:07 2022 +0000
@@ -4,6 +4,9 @@
 
 uLCD_4DGL uLCD(p28,p27,p30); // serial tx, serial rx, reset pin;
 
+DigitalOut myLed(LED1);
+Serial Blue(p13, p14);
+
 enum Piece {e, wK, bK, wQ, bQ, wR, bR, wB, bB, wN, bN, w, b};
 std::vector<Piece> whitePieces;
 std::vector<Piece> blackPieces;
@@ -81,15 +84,123 @@
     return _pins.read();
 }
 
+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};
+                                            
+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};
+
+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};
+
+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};
+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};
+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};
+
 class BoardState
 {
 private:
     Piece array[64];
+    // 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;
+    static const float BISHOP_VALUE = 30.0;
+    static const float ROOK_VALUE = 50.0;
+    static const float QUEEN_VALUE = 90.0;
+    static const float KING_VALUE = 900.0;
 public:
+    BoardState() {}
+    
     // calculates the advantage difference for the board state
     float calculateBoardState()
     {
-        return 0.0;
+        float sum = 0.0;
+        for (int i = 0; i < 64; i++) {
+            int row = i / 8;
+            int column = i % 8;
+            Piece curr = getPiece(row, column);
+            switch(curr) {
+                case wK:
+                    sum += KING_VALUE + KING_POSITION_VALUES[row*8 + column];
+                    break;
+                case bK:
+                    sum -= (KING_VALUE + KING_POSITION_VALUES[(7-row)*8 + (7-column)]);
+                    break;
+                case wQ:
+                    sum += QUEEN_VALUE + QUEEN_POSITION_VALUES[row*8 + column];
+                    break;
+                case bQ:
+                    sum -= (QUEEN_VALUE - QUEEN_POSITION_VALUES[(7-row)*8 + (7-column)]);
+                    break;
+                case wR:
+                    sum += ROOK_VALUE + ROOK_POSITION_VALUES[row*8 + column];
+                    break;
+                case bR:
+                    sum -= (ROOK_VALUE - ROOK_POSITION_VALUES[(7-row)*8 + (7-column)]);
+                    break;
+                case wB:
+                    sum += BISHOP_VALUE + BISHOP_POSITION_VALUES[row*8 + column];
+                    break;
+                case bB:
+                    sum -= (BISHOP_VALUE - BISHOP_POSITION_VALUES[(7-row)*8 + (7-column)]);
+                    break;
+                case wN:
+                    sum += KNIGHT_VALUE + KNIGHT_POSITION_VALUES[row*8 + column];
+                    break;
+                case bN:
+                    sum -= (KNIGHT_VALUE - KNIGHT_POSITION_VALUES[(7-row)*8 + (7-column)]);
+                    break;
+                case w:
+                    sum += PAWN_VALUE + PAWN_POSITION_VALUES[row*8 + column];
+                    break;
+                case b:
+                    sum -= (PAWN_VALUE - PAWN_POSITION_VALUES[(7-row)*8 + (7-column)]);
+                    break;
+                default:
+                    break;
+                }
+        }
+        return sum;
     }
 
     // returns the piece at a given location
@@ -144,44 +255,204 @@
             case bK:
                 isWhite = movingPiece == wK;
                 if (validMove(isWhite, row + 1, column)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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)) {
-                    moves.push_back((boardPos) {
+                    boardPos tPos = (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:
@@ -855,6 +1126,7 @@
 {
     3, 4
 };
+bool OnePlayer = true;
 boardPos selectedPos;
 Piece selectedPiece;
 std::vector<boardPos> possibleMoves;
@@ -926,7 +1198,11 @@
                 }
                 gameBoard.selectSquare(selectedPos);
                 // transition state
-                state = state == whiteSelecting ? whitePickedUp : blackPickedUp;
+                if (OnePlayer) {
+                    state = whitePickedUp;
+                } else {
+                    state = state == whiteSelecting ? whitePickedUp : blackPickedUp;
+                }
             } else {
                 selectedPos = (boardPos)
                 {
@@ -946,7 +1222,11 @@
                     // game end
                 }
                 // transition state
-                state = state == whitePickedUp ? blackSelecting : whiteSelecting;
+                if (OnePlayer) {
+                    state = blackAI;
+                } else {
+                    state = state == whitePickedUp ? blackSelecting : whiteSelecting;
+                }
                 // check if placing piece back down
             } else {
                 // transition state
@@ -966,9 +1246,124 @@
             break;
         }
         case whiteAI:
+            break;
         case blackAI: {
+            boardPos bestMoveSourceDepth0 = (boardPos) {
+                0, 0
+            };
+            boardPos bestMoveDestDepth0 =  (boardPos) {
+                0, 0
+            };
+            float bestMoveValueDepth0 = 100000.0;
+            for (int i = 0; i < 64; i++) {
+                boardPos currSourceDepth0 =  (boardPos) {
+                    i/8, i%8
+                };
+                Piece currPieceDepth0 = gameBoard.getBoardState().getPiece(i/8, i%8);
+                if (currPieceDepth0 == bK || currPieceDepth0 == bQ || currPieceDepth0 == bR || currPieceDepth0 == bB || currPieceDepth0 == bN || currPieceDepth0 == b) {
+                    std::vector<boardPos> possibleMovesDepth0 = gameBoard.getBoardState().getMoves(currSourceDepth0);
+                    for (std::vector<boardPos>::iterator it = possibleMovesDepth0.begin(); it != possibleMovesDepth0.end(); ++it) {
+                        BoardState bsDepth0;
+                        for (int j = 0; j < 64; j++) {
+                            bsDepth0.placePiece(gameBoard.getBoardState().getPiece(j/8, j%8), j/8, j%8);
+                        }
+                        bsDepth0.movePiece(currSourceDepth0.row, currSourceDepth0.column, (*it).row, (*it).column);
+                        float bestMoveValueDepth1 = -100000.0;
+                        for (int i2 = 0; i2 < 64; i2++) {
+                            boardPos currSourceDepth1 =  (boardPos) {
+                                i2/8, i2%8
+                            };
+                            Piece currPieceDepth1 = bsDepth0.getPiece(i2/8, i2%8);
+                            if (currPieceDepth1 == wK || currPieceDepth1 == wQ || currPieceDepth1 == wR || currPieceDepth1 == wB || currPieceDepth1 == wN || currPieceDepth1 == w) {
+                                std::vector<boardPos> possibleMovesDepth1 = bsDepth0.getMoves(currSourceDepth1);
+                                for (std::vector<boardPos>::iterator it2 = possibleMovesDepth1.begin(); it2 != possibleMovesDepth1.end(); ++it2) {
+                                    BoardState bsDepth1;
+                                    for (int j2 = 0; j2 < 64; j2++) {
+                                        bsDepth1.placePiece(bsDepth0.getPiece(j2/8, j2%8), j2/8, j2%8);
+                                    }
+                                    bsDepth1.movePiece(currSourceDepth1.row, currSourceDepth1.column, (*it2).row, (*it2).column);
+                                    float bestMoveValueDepth2 = 100000.0;
+                                    for (int i3 = 0; i3 < 64; i3++) {
+                                        boardPos currSourceDepth2 =  (boardPos) {
+                                            i3/8, i3%8
+                                        };
+                                        Piece currPieceDepth2 = bsDepth1.getPiece(i3/8, i3%8);
+                                        if (currPieceDepth2 == bK || currPieceDepth2 == bQ || currPieceDepth2 == bR || currPieceDepth2 == bB || currPieceDepth2 == bN || currPieceDepth2 == b) {
+                                            std::vector<boardPos> possibleMovesDepth2 = bsDepth1.getMoves(currSourceDepth2);
+                                            for (std::vector<boardPos>::iterator it3 = possibleMovesDepth2.begin(); it3 != possibleMovesDepth2.end(); ++it3) {
+                                                BoardState bsDepth2;
+                                                for (int j3 = 0; j3 < 64; j3++) {
+                                                    bsDepth2.placePiece(bsDepth1.getPiece(j3/8, j3%8), j3/8, j3%8);
+                                                }
+                                                bsDepth2.movePiece(currSourceDepth2.row, currSourceDepth2.column, (*it3).row, (*it3).column);
+                                                float thisMoveValueDepth2 = bsDepth2.calculateBoardState();
+                                                if (thisMoveValueDepth2 < bestMoveValueDepth2) {
+                                                    bestMoveValueDepth2 = thisMoveValueDepth2;
+                                                }
+                                            }
+                                        }
+                                    }
+                                    if (bestMoveValueDepth2 > bestMoveValueDepth1) {
+                                        bestMoveValueDepth1 = bestMoveValueDepth2;
+                                    }
+                                }
+                            }
+                        }
+                        
+                        if (bestMoveValueDepth1 < bestMoveValueDepth0) {
+                            bestMoveSourceDepth0 = currSourceDepth0;
+                            bestMoveDestDepth0 = *it;
+                            bestMoveValueDepth0 = bestMoveValueDepth1;
+                        }
+                    }
+                }
+            }
+            Piece capturedPiece = gameBoard.movePieceAndDraw(bestMoveSourceDepth0, bestMoveDestDepth0);
+            if (capturedPiece == bK) {
+                // game end
+            }
+            state = whiteSelecting;
             break;
         }
+        default: {
+            break;
+        }
+    }
+}
+
+// bluetooth
+volatile bool button_ready = 0;
+volatile int bnum = 0;
+volatile int bhit = 0;
+enum statetype {start = 0, got_exclm, got_B, got_num, got_hit};
+statetype bluetooth_state = start;
+ 
+void parse_message()
+{
+    switch (bluetooth_state) {
+        case start:
+            if (Blue.getc() == '!') bluetooth_state = got_exclm;
+            else bluetooth_state = start;
+            break;
+        case got_exclm:
+            if (Blue.getc() == 'B') bluetooth_state = got_B;
+            else bluetooth_state = start;
+            break;
+        case got_B:
+            bnum = Blue.getc();
+            bluetooth_state = got_num;
+            break;
+        case got_num:
+            bhit = Blue.getc();
+            bluetooth_state = got_hit;
+            break;
+        case got_hit:
+            if (Blue.getc() == char(~('!' + ' B' + bnum + bhit))) button_ready = 1;
+            bluetooth_state = start;
+            break;
+        default:
+            Blue.getc();
+            bluetooth_state = start;
     }
 }
 
@@ -990,7 +1385,11 @@
     blackPieces.push_back(bR);
     blackPieces.push_back(b);
     moveCursor(0, 0);
+    Blue.attach(&parse_message,Serial::RxIrq);
     while (1) {
+        if (state == blackAI) {
+            joyStickPressed();
+        }
         if (myNav.up()) {
             joyStickUp();
         } else if (myNav.down()) {
@@ -1001,7 +1400,26 @@
             joyStickRight();
         } else if (myNav.fire()) {
             joyStickPressed();
+        } else if (button_ready && bhit == '1') {
+            switch(bnum) {
+                case '1':
+                    joyStickPressed();
+                    break;
+                case '5':
+                    joyStickUp();
+                    break;
+                case '6':
+                    joyStickDown();
+                    break;
+                case '7':
+                    joyStickLeft();
+                    break;
+                case '8':
+                    joyStickRight();
+                    break;
+            }
+            button_ready = false;
         }
-        wait(0.25);
+        wait(0.2);
     }
 }
\ No newline at end of file