5
\$\begingroup\$

Here is the chess class for my very own chess game. Everything is in this class. Generating moves, getting a move from the computer, printing the board etc etc. This is a follow up question to C++ generator function for a Chess game.

these are the values for each piece in the board, also used in the int board[8][8];

pawn = 1

bishop = 2

knight = 3

rook = 5

queen = 6

king = 10

The same values apply for black pieces too, except this time they are negative. For example; A white pawn holds a value of 1

A black pawn holds a value of -1

The move generation is done for each piece simply by adding or subtracting values to row and column , referring to the two dimensions of the array inside the class. For example if a pawn is at board[6][0], If you look at the board you can see moving up means going to the next row, In this case going up would be reducing values in row, that means 6,0 now becomes 5,0. Once I have a logic for how the pieces move I need to check whether It is a valid move, that means I am only moving to an empty square or capturing an opponent's piece. The final validation layer is from the rule in chess, which is a check in chess.

In simple words, It is a threat to your king. If your king is under a threat, that means if a piece is attacking it, you need to block that path, or move the king before you can play any other move.

Let's assume I have this position .

This is also called A pin in chess

If it is the Black player's turn, he cannot move his bishop, as my rook will give a check to his king if he does. As the bishop is blocking the king from a check. That's why before I generate the final moves. I generate pseudolegalmoves which are basically just following all the individual rules. Then I go through each move in the container, perform it. After performing, if the function bool check(int turn returns true, simply means it's an invalid move. I dump it.

#include<iostream>
#include<vector>
#include<string>

typedef std::vector<std::string> buff;
typedef std::string str;

// Pawn - 1, Knight - 3, Bishop - 2, rook - 5,queen - 6,king - 10

str push(int row,int col,int desrow,int descol){
    using std::to_string;

    str mystr = to_string(row) + to_string(col) + to_string(desrow) + to_string(descol);
    return mystr;
}


class Chess{

    public:
        short int board[8][8] = // This array represents the chess board
            {
              {-2,0,0,0,0,0,-10,0},
              {0,0,0,0,0,0,0,0},
              {0,0,0,0,-1,0,0,0},
              {0,0,0,0,0,0,0,0},
              {0,0,6,0,0,0,0,0},
              {0,10,0,0,0,0,0,0},
              {0,0,0,0,0,0,0,0},
              {0,0,0,0,0,0,0,0},
            };
        buff pseudomoves;
        buff legal_moves;
    private:
        void undomove(int original,str Move){
            board[Move[0]-48][Move[1]-48] = board[Move[2]-48][Move[3]-48];
            board[Move[2]-48][Move[3]-48] = original;
        }

        public:
        int perform(str Move){
            int original;
            original = board[Move[2]-48][Move[3]-48];
            board[Move[2]-48][Move[3]-48] = board[Move[0]-48][Move[1]-48];
            board[Move[0]-48][Move[1]-48] = 0;
            return original;
        }
        private:
        bool check(bool turn){
            if (turn == true){
                int row,col;
                //Finding the king on the board

                for (int i = 0;i < 8;i++){
                    for (int j = 0;j < 8;j++){
                        if (board[i][j] == 10){
                            row = i;
                            col = j;
                        }
                    }
                }

                //Finding the king on the board


                if (row != 0 && col != 0 && board[row-1][col-1] == -1) return true;
                else if (row != 0 && col != 7 && board[row-1][col+1] == -1) return true;
                int a,b;
                a = row;
                b = col;
                if (a != 0 && b != 0){
                        for(;;){
                        a-=1;
                        b-=1;
                        if (board[a][b] == -6 || board[a][b] == -2) return true;
                        if (board[a][b] !=  0 || a == 0 || b == 0) break;
                    }
                }
                a = row;
                b = col;
                if (a != 0 && b != 7){
                        for(;;){
                        a-=1;
                        b+=1;
                        if (board[a][b] == -6 || board[a][b] == -2) return true;
                        if (board[a][b] !=  0 || a == 0 || b == 7) break;
                    }
                }
                a = row;
                b = col;
                if (a != 7 && b != 0){
                        for(;;){
                        a+=1;
                        b-=1;
                        if (board[a][b] == -6 || board[a][b] == -2) return true;
                        if (board[a][b] !=  0 || a == 7 || b == 0) break;
                    }
                }
                a = row;
                b = col;
                if (a != 7 && b != 7){
                        for(;;){
                        a+=1;
                        b+=1;
                        if (board[a][b] == -6 || board[a][b] == -2) return true;
                        if (board[a][b] !=  0 || a == 7 || b == 7) break;
                    }
                }

                a = row;
                b = col;
                if (a != 7){
                    for(;;){
                        a+=1;
                        if (board[a][b] == -6 || board[a][b] == -5) return true;
                        if (board[a][b] !=  0 || a == 7 ) break;
                    }
                }
                a = row;
                b = col;
                if (a != 0){
                    for(;;){
                        a-=1;
                        if (board[a][b] == -6 || board[a][b] == -5) return true;
                        if (board[a][b] !=  0 || a == 0 ) break;
                    }
                }

                a = row;
                b = col;
                if (b != 7){
                    for(;;){
                        b+=1;
                        if (board[a][b] == -6 || board[a][b] == -5) return true;
                        if (board[a][b] !=  0 || b == 7 ) break;
                    }
                }
                a = row;
                b = col;
                if (b != 0){
                    for(;;){
                        b-=1;
                        if (board[a][b] == -6 || board[a][b] == -5) return true;
                        if (board[a][b] !=  0 || b == 0 ) break;
                    }
                }

                if (row > 0 && col < 6 && board[row-1][col+2] == -3)return true;
                if (row > 1 && col < 7 && board[row-2][col+1] == -3)return true;
                if (row < 7 && col < 6 && board[row+1][col+2] == -3)return true;
                if (row < 6 && col < 7 && board[row+2][col+1] == -3)return true;
                if (row < 6 && col > 0 && board[row+2][col-1] == -3)return true;
                if (row < 7 && col > 1 && board[row+1][col-2] == -3)return true;
                if (row > 1 && col > 0 && board[row-2][col-1] == -3)return true;
                if (row > 0 && col > 1 && board[row-1][col-2] == -3)return true;

                if (row != 7 && board[row+1][col] == -10)return true;
                if (row != 0 && board[row-1][col] == -10)return true;
                if (col != 7 && board[row][col+1] == -10) return true;
                if (col != 0 && board[row][col-1] == -10) return true;
                if (row != 7 && col != 7 && board[row+1][col+1] == -10)return true;
                if (row != 7 && col != 0 && board[row+1][col-1] == -10) return true;
                if (row != 0 && col != 7 && board[row-1][col+1] == -10) return true;
                if (row != 0 && col != 0 && board[row-1][col-1] == -10) return true;


            }

            else if(turn == false){
                int row,col;
                //Finding the king on the board

                for (int i = 0;i < 8;i++){
                    for (int j = 0;j < 8;j++){
                        if (board[i][j] == -10){
                            row = i;
                            col = j;
                        }
                    }
                }

                //Finding the king on the board


                if (row != 7 && col != 0 && board[row+1][col-1] == 1) return true;
                else if (row != 7 && col != 7 && board[row+1][col+1] == 1) return true;

                int a,b;
                a = row;
                b = col;
                if (a != 0 && b != 0){
                        for(;;){
                        a-=1;
                        b-=1;
                        if (board[a][b] == 6 || board[a][b] == 2) return true;
                        if (board[a][b] !=  0 || a == 0 || b == 0) break;
                    }
                }
                a = row;
                b = col;
                if (a != 0 && b != 7){
                        for(;;){
                        a-=1;
                        b+=1;
                        if (board[a][b] == 6 || board[a][b] == 2) return true;
                        if (board[a][b] !=  0 || a == 0 || b == 7) break;
                    }
                }
                a = row;
                b = col;
                if (a != 7 && b != 0){
                        for(;;){
                        a+=1;
                        b-=1;
                        if (board[a][b] == 6 || board[a][b] == 2) return true;
                        if (board[a][b] !=  0 || a == 7 || b == 0) break;
                    }
                }
                a = row;
                b = col;
                if (a != 7 && b != 7){
                        for(;;){
                        a+=1;
                        b+=1;
                        if (board[a][b] == 6 || board[a][b] == 2) return true;
                        if (board[a][b] !=  0 || a == 7 || b == 7) break;
                    }
                }

                a = row;
                b = col;
                if (a != 7){
                    for(;;){
                        a+=1;
                        if (board[a][b] == 6 || board[a][b] == 5) return true;
                        if (board[a][b] !=  0 || a == 7 ) break;
                    }
                }
                a = row;
                b = col;
                if (a != 0){
                    for(;;){
                        a-=1;
                        if (board[a][b] == 6 || board[a][b] == 5) return true;
                        if (board[a][b] !=  0 || a == 0 ) break;
                    }
                }

                a = row;
                b = col;
                if (b != 7){
                    for(;;){
                        b+=1;
                        if (board[a][b] == 6 || board[a][b] == 5) return true;
                        if (board[a][b] !=  0 || b == 7 ) break;
                    }
                }
                a = row;
                b = col;
                if (b != 0){
                    for(;;){
                        b-=1;
                        if (board[a][b] == 6 || board[a][b] == 5) return true;
                        if (board[a][b] !=  0 || b == 0 ) break;
                    }
                }

                if (row > 0 && col < 6 && board[row-1][col+2] == 3)return true;
                if (row > 1 && col < 7 && board[row-2][col+1] == 3)return true;
                if (row < 7 && col < 6 && board[row+1][col+2] == 3)return true;
                if (row < 6 && col < 7 && board[row+2][col+1] == 3)return true;
                if (row < 6 && col > 0 && board[row+2][col-1] == 3)return true;
                if (row < 7 && col > 1 && board[row+1][col-2] == 3)return true;
                if (row > 1 && col > 0 && board[row-2][col-1] == 3)return true;
                if (row > 0 && col > 1 && board[row-1][col-2] == 3)return true;

                if (row != 7 && board[row+1][col] == 10)return true;
                if (row != 0 && board[row-1][col] == 10)return true;
                if (col != 7 && board[row][col+1] == 10) return true;
                if (col != 0 && board[row][col-1] == 10) return true;
                if (row != 7 && col != 7 && board[row+1][col+1] == 10)return true;
                if (row != 7 && col != 0 && board[row+1][col-1] == 10) return true;
                if (row != 0 && col != 7 && board[row-1][col+1] == 10) return true;
                if (row != 0 && col != 0 && board[row-1][col-1] == 10) return true;

            }

            return false;
        }

        void getdiagonalmoves(bool turn,int row,int col){

            int a,b;
            if(turn){
                a = row;
                b = col;
                if (a !=  0 && b != 0){
                    for (;;){
                        a-=1;
                        b-=1;
                        if (board[a][b] > 0) break;
                        if (board[a][b] < 0 || a == 0 || b == 0){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));
                    }
                }
                a = row;
                b = col;
                if (a !=  0 && b != 7){
                    for (;;){
                        a-=1;
                        b+=1;
                        if (board[a][b] > 0) break;
                        if (board[a][b] < 0 || a == 0 || b == 7){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));

                    }
                }
                a = row;
                b = col;
                if (a !=  7 && b != 7){
                    for (;;){
                        a+=1;
                        b+=1;
                        if (board[a][b] > 0) break;
                        if (board[a][b] < 0 || a == 7 || b == 7){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));
                }
                }
                a = row;
                b = col;
                if (a !=  7 && b != 0){
                    for (;;){
                        a+=1;
                        b-=1;
                        if (board[a][b] > 0) break;
                        if (board[a][b] < 0 || a == 7 || b == 0){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));
                }
                }
            }
            else if(!turn){

                a = row;
                b = col;
                if (a !=  0 && b != 0){
                    for (;;){
                        a-=1;
                        b-=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || a == 0 || b == 0){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));
                    }
                }
                a = row;
                b = col;
                if (a !=  0 && b != 7){
                    for (;;){
                        a-=1;
                        b+=1;
                        if (board[a][b] < 0)
                            break;
                        if (board[a][b] > 0 || a == 0 || b == 7){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(board[a][b] == 0)
                            pseudomoves.push_back(push(row,col,a,b));

                    }
                }
                a = row;
                b = col;
                if (a !=  7 && b != 7){
                    for (;;){
                        a+=1;
                        b+=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || a == 7 || b == 7){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));
                }
                }
                a = row;
                b = col;
                if (a !=  7 && b != 0){
                    for (;;){
                        a+=1;
                        b-=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || a == 7 || b == 0){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b])pseudomoves.push_back(push(row,col,a,b));
                }
                }

            }
        }

        void getstraigtmoves(bool turn ,int row,int col){

            int a,b;
            if (turn) {// white player
            a = row;
            b = col;
            if (a != 0){
                for (;;){
                    a-=1;
                    if (board[a][b] > 0) break;
                    if (board[a][b] < 0 || a == 0){
                        pseudomoves.push_back(push(row,col,a,b));
                        break;
                    }
                    if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                }
            }
            a = row;
            b = col;
            if (a!=7){
                for(;;){
                    a+=1;
                    if (board[a][b] > 0) break;
                    if (board[a][b] < 0 || a == 7){
                        pseudomoves.push_back(push(row,col,a,b));
                        break;
                    }
                    if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                }
            }
            a = row;
            b = col;
            if (b!= 0){
                for(;;){
                    b-=1;
                    if (board[a][b] > 0) break;
                    if (board[a][b] < 0 || b == 0){
                        pseudomoves.push_back(push(row,col,a,b));
                        break;
                    }
                    if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                }
            }
            a  =row;
            b = col;
            if (b != 7){
                for(;;){
                    b+=1;
                    if (board[a][b] > 0) break;
                    if (board[a][b] < 0 || b == 7){
                        pseudomoves.push_back(push(row,col,a,b));
                        break;
                    }
                    if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                }
            }
            }

            else if(!turn) // black player
            {
                a = row;
                b = col;
                if (a != 0){
                    for (;;){
                        a-=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || a == 0){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                    }
                }
                a = row;
                b = col;
                if (a!=7){
                    for(;;){
                        a+=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || a == 7){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                    }
                }
                a = row;
                b = col;
                if (b!= 0){
                    for(;;){
                        b-=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || b == 0){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                    }
                }
                a  =row;
                b = col;
                if (b != 7){
                    for(;;){
                        b+=1;
                        if (board[a][b] < 0) break;
                        if (board[a][b] > 0 || b == 7){
                            pseudomoves.push_back(push(row,col,a,b));
                            break;
                        }
                        if(!board[a][b]) pseudomoves.push_back(push(row,col,a,b));
                    }
            }
                }
            //returnpseudomoves;
        }

        void getknightmoves(bool turn,int row,int col){

            if (turn) {

            if (row > 0 && col < 6 && board[row-1][col+2] <= 0) // one up two right
                pseudomoves.push_back(push(row,col,row-1,col+2));

            if (row > 1 && col < 7 && board[row-2][col+1] <= 0) // two up one right
                pseudomoves.push_back(push(row,col,row-2,col+1));

            if (row < 7 && col < 6 && board[row+1][col+2] <= 0) // one down two right
                pseudomoves.push_back(push(row,col,row+1,col+2));

            if (row < 6 && col < 7 && board[row+2][col+1] <= 0) // two down one right
                pseudomoves.push_back(push(row,col,row+2,col+1));

            if (row < 6 && col > 0 && board[row+2][col-1] <= 0) //two down one left
                pseudomoves.push_back(push(row,col,row+2,col-1));

            if (row < 7 && col > 1 && board[row+1][col-2] <= 0) // one down two left
                pseudomoves.push_back(push(row,col,row+1,col-2));

            if (row > 1 && col > 0 && board[row-2][col-1] <= 0) // two up one left
                pseudomoves.push_back(push(row,col,row-2,col-1));

            if (row > 0 && col > 1 && board[row-1][col-2] <= 0) // one up two left
                pseudomoves.push_back(push(row,col,row-1,col-2));
            }

            else if (!turn){
                if (row > 0 && col < 6 && board[row-1][col+2] >= 0)pseudomoves.push_back(push(row,col,row-1,col+2));
                if (row > 1 && col < 7 && board[row-2][col+1] >= 0)pseudomoves.push_back(push(row,col,row-2,col+1));
                if (row < 7 && col < 6 && board[row+1][col+2] >= 0)pseudomoves.push_back(push(row,col,row+1,col+2));
                if (row < 6 && col < 7 && board[row+2][col+1] >= 0)pseudomoves.push_back(push(row,col,row+2,col+1));
                if (row < 6 && col > 0 && board[row+2][col-1] >= 0)pseudomoves.push_back(push(row,col,row+2,col-1));
                if (row < 7 && col > 1 && board[row+1][col-2] >= 0)pseudomoves.push_back(push(row,col,row+1,col-2));
                if (row > 1 && col > 0 && board[row-2][col-1] >= 0)pseudomoves.push_back(push(row,col,row-2,col-1));
                if (row > 0 && col > 1 && board[row-1][col-2] >= 0)pseudomoves.push_back(push(row,col,row-1,col-2));
            }

            //returnpseudomoves;
        }

        void getpawnmoves(bool turn,int row,int col){
            if (turn) {
                if (row == 6 && board[row-1][col] == 0 && board[row-2][col] == 0)
                    pseudomoves.push_back(push(row,col,row-2,col));
                if (board[row-1][col] == 0)
                    pseudomoves.push_back(push(row,col,row-1,col));
                if (col != 0 && board[row-1][col-1] < 0)
                    pseudomoves.push_back(push(row,col,row-1,col-1));
                if (col != 7 && board[row-1][col+1] < 0)
                    pseudomoves.push_back(push(row,col,row-1,col+1));
            }

            else if(!turn){
                if (row == 7) //returnpseudomoves;

                if (row == 1 && board[row+1][col] == 0 && board[row+2][col] == 0)
                    pseudomoves.push_back(push(row,col,row+2,col));
                if (board[row+1][col] == 0)
                    pseudomoves.push_back(push(row,col,row+1,col));
                if (col != 0 && board[row+1][col-1] > 0)
                    pseudomoves.push_back(push(row,col,row+1,col-1));
                if (col != 7 && board[row+1][col+1] > 0)
                    pseudomoves.push_back(push(row,col,row+1,col+1));
            }

            //returnpseudomoves;
        }

        void getkingmoves(bool turn,int row,int col){

            if (!turn){
                if (row != 7 && board[row+1][col] >=0) pseudomoves.push_back(push(row,col,row+1,col));
                if (row != 0 && board[row-1][col] >=0) pseudomoves.push_back(push(row,col,row-1,col));
                if (col != 7 && board[row][col+1] >=0) pseudomoves.push_back(push(row,col,row,col+1));
                if (col != 0 && board[row][col-1] >=0) pseudomoves.push_back(push(row,col,row,col-1));
                if (row != 7 && col != 7 && board[row+1][col+1] >=0) pseudomoves.push_back(push(row,col,row+1,col+1));
                if (row != 7 && col != 0 && board[row+1][col-1] >=0) pseudomoves.push_back(push(row,col,row+1,col-1));
                if (row != 0 && col != 7 && board[row-1][col+1] >=0) pseudomoves.push_back(push(row,col,row-1,col+1));
                if (row != 0 && col != 0 && board[row-1][col-1] >=0) pseudomoves.push_back(push(row,col,row-1,col-1));
            }
            else if (turn){
                if (row != 7 && board[row+1][col] <=0) pseudomoves.push_back(push(row,col,row+1,col));
                if (row != 0 && board[row-1][col] <=0) pseudomoves.push_back(push(row,col,row-1,col));
                if (col != 7 && board[row][col+1] <=0) pseudomoves.push_back(push(row,col,row,col+1));
                if (col != 0 && board[row][col-1] <=0) pseudomoves.push_back(push(row,col,row,col-1));
                if (row != 7 && col != 7 && board[row+1][col+1] <=0) pseudomoves.push_back(push(row,col,row+1,col+1));
                if (row != 7 && col != 0 && board[row+1][col-1] <=0) pseudomoves.push_back(push(row,col,row+1,col-1));
                if (row != 0 && col != 7 && board[row-1][col+1] <=0) pseudomoves.push_back(push(row,col,row-1,col+1));
                if (row != 0 && col != 0 && board[row-1][col-1] <=0) pseudomoves.push_back(push(row,col,row-1,col-1));
            }
            //returnpseudomoves;
        }

        int evaluation(){
            int score;
            for (int i = 0;i < 8;i++){
                for(int j =0;j < 8;j++){
                    if(!board[i][j]) continue;
                    if (board[i][j] == 1) score-=10;
                    else if (board[i][j] == 2)score-=30;
                    else if (board[i][j] == 3)score-=30;
                    else if (board[i][j] == 5)score-=50;
                    else if (board[i][j] == 6)score-=90;
                    else if (board[i][j] == 10)score-=900;
                    else if (board[i][j] == -1)score+=10;
                    else if (board[i][j] == -2)score+=30;
                    else if (board[i][j] == -3)score+=30;
                    else if (board[i][j] == -5)score+=50;
                    else if (board[i][j] == -6)score+=60;
                    else if (board[i][j] == -10)score+=900;

                }
            }
            return score;
        }

        int miniMax(int depth,bool ismax,int alpha,int beta){
            if (depth == 0){
                return evaluation();
            }
            int maxeval = -999999;
            int mineval = 999999;
            buff possiblemoves;
            int original;
            int eval;
            if (ismax == true){
                 possiblemoves = getallmoves(false);
                 for (long unsigned int i = 0;i < possiblemoves.size();i++){
                    original = perform(possiblemoves[i]);
                    eval = miniMax(depth-1,false,alpha,beta);
                    undomove(original,possiblemoves[i]);
                    if(eval > maxeval)
                        maxeval = eval;
                    if (alpha >= eval)
                        alpha = eval;
                    if (beta <= alpha)
                        break;
                 }
                 return maxeval;
            }
            else{
                possiblemoves = getallmoves(true);
                 for (long unsigned int i = 0;i < possiblemoves.size();i++){
                    original = perform(possiblemoves[i]);
                    eval = miniMax(depth-1,true,alpha,beta);
                    undomove(original,possiblemoves[i]);
                    if (eval < mineval)
                        mineval = eval;
                    if (beta <= eval)
                        beta = eval;
                    if (beta <= alpha)
                        break;
                 }
                 return mineval;
            }

        }


        str miniMaxroot(int depth,bool turn){
            str bestmove;
            int maxeval = -9999999;
            buff allmoves = getallmoves(turn);
            int original;
            int eval;
            for (long unsigned int i = 0;i < allmoves.size();i++){
                original = perform(allmoves[i]);
                eval = miniMax(depth-1,false,-99999999,99999999);
                std::cout << "Move: " << allmoves[i] << " Points: " << eval << "\n";
                undomove(original,allmoves[i]);
                if (eval > maxeval){
                    maxeval = eval;
                    bestmove = allmoves[i];
                }
            }
            return bestmove;
        }

    public:
        void printboard(){
        for(int i = 0; i< 8;i++){
            for(int j = 0;j < 8;j++){
              if (board[i][j] == 1)
              std::cout << "P ";
              else if (board[i][j] == 5)
              std::cout << "R ";
              else if (board[i][j] == 3)
              std::cout << "K ";
              else if (board[i][j] == 2)
              std::cout << "B ";
              else if (board[i][j] == 6)
              std::cout << "Q ";
              else if(board[i][j] == 10)
              std::cout << "KI ";
              else if (board[i][j] == 0)
              std::cout << ". ";

              else if (board[i][j] == -1)
              std::cout << "p ";
              else if (board[i][j] == -5)
              std::cout << "r ";
              else if (board[i][j] == -3)
              std::cout << "k ";
              else if (board[i][j] == -2)
              std::cout << "b ";
              else if (board[i][j] == -6)
              std::cout << "q ";
              else if(board[i][j] == -10)
              std::cout << "ki ";
              else if (board[i][j] == -109)
              std::cout << "X";

            }
            std::cout << std::endl;
          }
        }

        buff getallmoves(bool turn){
            pseudomoves.clear();
            legal_moves.clear();
            int original;
            if (turn){
                for(int i = 0;i < 8;i++){
                    for(int j = 0;j < 8;j++){
                        if (!board[i][j]) continue;
                        else if(board[i][j] == 1) getpawnmoves(true,i,j);
                        else if(board[i][j] == 2) getdiagonalmoves(true,i,j);
                        else if(board[i][j] == 3) getknightmoves(true,i,j);
                        else if(board[i][j] == 5) getstraigtmoves(true,i,j);
                        else if(board[i][j] == 6){
                            getdiagonalmoves(true,i,j);
                            getstraigtmoves(true,i,j);
                        }
                        else if(board[i][j] == 10) getkingmoves(true,i,j);
                    }
                }
                return pseudomoves;
                for(long unsigned int i = 0;i < pseudomoves.size();i++){
                    original = perform(pseudomoves[i]);
                    if(check(true) == false){
                    legal_moves.push_back(pseudomoves[i]);
                    }
                    undomove(original,pseudomoves[i]);
                }
                return legal_moves;
            }


            else if(!turn){
                for(int i = 0;i < 8;i++){
                    for(int j = 0;j < 8;j++){
                        if (!board[i][j]) continue;
                        else if(board[i][j] == -1) getpawnmoves(false,i,j);
                        else if(board[i][j] == -2) getdiagonalmoves(false,i,j);
                        else if(board[i][j] == -3) getknightmoves(false,i,j);
                        else if(board[i][j] == -5) getstraigtmoves(false,i,j);
                        else if(board[i][j] == -6){
                            getdiagonalmoves(false,i,j);
                            getstraigtmoves(false,i,j);
                        }
                        else if(board[i][j] == -10) getkingmoves(false,i,j);
                    }
                }
                for(long unsigned int i = 0;i < pseudomoves.size();i++){
                    original = perform(pseudomoves[i]);
                    if(check(false) == false){
                    legal_moves.push_back(pseudomoves[i]);
                    }
                    undomove(original,pseudomoves[i]);
                }
                return legal_moves;
            }
            return legal_moves;
            }

        str computer_move(unsigned short int depth){
            str bestmove;
            bestmove = miniMaxroot(depth,false);
            std::cout << "Bestmove: " << bestmove << "\n";
            perform(bestmove);
            return bestmove;
        }
};

\$\endgroup\$
6
  • 3
    \$\begingroup\$ Using magic numbers everywhere makes it hard to understand your code. \$\endgroup\$ Aug 24, 2020 at 21:34
  • \$\begingroup\$ I added some short information in the top that should cover all of it \$\endgroup\$
    – user228914
    Aug 24, 2020 at 21:59
  • \$\begingroup\$ Is this related to this question? \$\endgroup\$ Aug 24, 2020 at 22:07
  • 4
    \$\begingroup\$ Seems so. And there the tip "Use an enum for clarity" was already given... (@Aryan if this is a follow up you should link to the previous one in your question. You may even edit the first question or link to this one via a comment) \$\endgroup\$ Aug 24, 2020 at 22:44
  • \$\begingroup\$ Yes how can I link it. It is like a follow up \$\endgroup\$
    – user228914
    Aug 25, 2020 at 8:39

1 Answer 1

6
\$\begingroup\$

General Observations

Unlike some more modern languages such as C# and Java, a C++ class is generally implemented as 2 files: a header file generally with the file extension .h and a source file generally with the files extensions .cpp or .cc. This is due primarily to the fact that C++ grew out the C programming language which had header files and source files as well.

In C++ the classes declarations are in the header file and the member function implementations are in the source file. There are or were benefits to this arrangement. As long as the declarations remained the same, the underlying member functions could be modified as needed, recompiled and shipped to the client or customer to be installed without changing a major version number. Changes to class declarations required version number changes.

The second possible benefit of separating the declarations from the source is that the entire implementation can be refactored as long as the class declarations do not change. This could allow for major changes to take place to improve performance or memory usage without the outside code needing to change.

The code in this question is all in one file and that makes it more difficult to maintain. It also means that all of the code needs to be included in whatever file needs to use it using an include statement, which leads to unnecessarily long compile and build times.

At the end of the answer I've included the possible header and source file for this code. None of the logic was changed.

Definitely follow any suggestions @Edward made in the previous review.

Put Public Declarations First

Within the header file the list of all public members starting with the constructors should go first, then the protected members and finally private members. This organization is so that the users of the class can quickly find what they need. This is not enforced by the language or the compilers but is general custom. C++ also differs from at least C# (I haven't programmed in Java so I don't know) in that public members can be grouped.

class CLASSNAME {
public:
    Public_Member_0;
    Public_Member_1;
    Public_Constructor_2(){}
    Public_Member_3(){}
protected:
    Private_Member_0;
    Private_Member_1(){}
    Private_Member_2(){}
private:
    Private_Member_0;
    Private_Member_1(){}
    Private_Member_2(){}
}

Make Items That Should Not Be Access Externally Private

There is no reason that the data representation of the board should be public, at most it should be protected so that classes that inherit for the Chess class can access it. It would be even better if it was private, and protected members provided access. It could also be declared as a static variable in the Chess.cpp file, which would allow easy change of the data representation.

Complexity!

The class as a whole as well as most of the member functions are too complex (do too much). Functions should only attempt to solve one problem and they shouldn't be larger than a screen in an editor or a sheet of paper if printed. Anything larger is very difficult to understand, write, read and thus maintain.

I suggest you read up on the Single Responsibility Principle which states:

that every module, class, or function should have responsibility over a single part of the functionality provided by the software, and that responsibility should be entirely encapsulated by that module, class or function.

This is one of the main principles of Object Oriented Programming, in fact it is the S in SOLID Programming.

In object-oriented computer programming, SOLID is a mnemonic acronym for five design principles intended to make software designs more understandable, flexible and maintainable. It is not related to the GRASP software design principles. The principles are a subset of many principles promoted by American software engineer and instructor Robert C. Martin. Though they apply to any object-oriented design, the SOLID principles can also form a core philosophy for methodologies such as agile development or adaptive software development. The theory of SOLID principles was introduced by Martin in his 2000 paper Design Principles and Design Patterns, although the SOLID acronym was introduced later by Michael Feathers.

It might be better to have multiple classes, one class to implement the board, an abstract base class for all the types of pieces with an abstract function for getting the move, each piece could then be implemented by a subclass that inherits from the base class. The board class would own the printboard() function.

Initialize All Local Variables

A best practice is to initialize each variable as it is declared. C++ does not initialize local variables to a default value and the lack of initialization can lead to undefined behavior.

The variable score in the function evaluation is not initialized.

Reformated Into 2 Files

** chess2.h **

#ifndef CHESS2_H
#define CHESS2_H
#include<vector>
#include<string>

typedef std::vector<std::string> buff;
typedef std::string str;

class Chess2
{
public:
    buff pseudomoves;
    buff legal_moves;
    short int board[8][8] = // This array represents the chess board
    {
      {-2,0,0,0,0,0,-10,0},
      {0,0,0,0,0,0,0,0},
      {0,0,0,0,-1,0,0,0},
      {0,0,0,0,0,0,0,0},
      {0,0,6,0,0,0,0,0},
      {0,10,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0},
      {0,0,0,0,0,0,0,0},
    };
    int perform(str Move);
    void printboard();
    str push(int row, int col, int desrow, int descol); 
    buff getallmoves(bool turn);
    str computer_move(unsigned short int depth);

private:
    bool check(bool turn);
    void getdiagonalmoves(bool turn, int row, int col);
    void getstraigtmoves(bool turn, int row, int col);
    void getknightmoves(bool turn, int row, int col);
    void getpawnmoves(bool turn, int row, int col);
    void getkingmoves(bool turn, int row, int col);
    int evaluation();
    int miniMax(int depth, bool ismax, int alpha, int beta);
    str miniMaxroot(int depth, bool turn);
    void undomove(int original, str Move);
};

#endif  // CHESS2_H

** chess2.cpp **

#include "Chess2.h"
#include<iostream>

int Chess2::perform(str Move) {
    int original;
    original = board[Move[2] - 48][Move[3] - 48];
    board[Move[2] - 48][Move[3] - 48] = board[Move[0] - 48][Move[1] - 48];
    board[Move[0] - 48][Move[1] - 48] = 0;
    return original;
}

void Chess2::printboard()
{
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            if (board[i][j] == 1)
                std::cout << "P ";
            else if (board[i][j] == 5)
                std::cout << "R ";
            else if (board[i][j] == 3)
                std::cout << "K ";
            else if (board[i][j] == 2)
                std::cout << "B ";
            else if (board[i][j] == 6)
                std::cout << "Q ";
            else if (board[i][j] == 10)
                std::cout << "KI ";
            else if (board[i][j] == 0)
                std::cout << ". ";

            else if (board[i][j] == -1)
                std::cout << "p ";
            else if (board[i][j] == -5)
                std::cout << "r ";
            else if (board[i][j] == -3)
                std::cout << "k ";
            else if (board[i][j] == -2)
                std::cout << "b ";
            else if (board[i][j] == -6)
                std::cout << "q ";
            else if (board[i][j] == -10)
                std::cout << "ki ";
            else if (board[i][j] == -109)
                std::cout << "X";

        }
        std::cout << std::endl;
    }
}

str Chess2::push(int row, int col, int desrow, int descol) {
    using std::to_string;

    str mystr = to_string(row) + to_string(col) + to_string(desrow) + to_string(descol);
    return mystr;
}

str Chess2::computer_move(unsigned short int depth) {
    str bestmove;
    bestmove = miniMaxroot(depth, false);
    std::cout << "Bestmove: " << bestmove << "\n";
    perform(bestmove);
    return bestmove;
}

buff Chess2::getallmoves(bool turn) {
    pseudomoves.clear();
    legal_moves.clear();
    int original;
    if (turn) {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (!board[i][j]) continue;
                else if (board[i][j] == 1) getpawnmoves(true, i, j);
                else if (board[i][j] == 2) getdiagonalmoves(true, i, j);
                else if (board[i][j] == 3) getknightmoves(true, i, j);
                else if (board[i][j] == 5) getstraigtmoves(true, i, j);
                else if (board[i][j] == 6) {
                    getdiagonalmoves(true, i, j);
                    getstraigtmoves(true, i, j);
                }
                else if (board[i][j] == 10) getkingmoves(true, i, j);
            }
        }
        return pseudomoves;
        for (long unsigned int i = 0; i < pseudomoves.size(); i++) {
            original = perform(pseudomoves[i]);
            if (check(true) == false) {
                legal_moves.push_back(pseudomoves[i]);
            }
            undomove(original, pseudomoves[i]);
        }
        return legal_moves;
    }
    else if (!turn) {
        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (!board[i][j]) continue;
                else if (board[i][j] == -1) getpawnmoves(false, i, j);
                else if (board[i][j] == -2) getdiagonalmoves(false, i, j);
                else if (board[i][j] == -3) getknightmoves(false, i, j);
                else if (board[i][j] == -5) getstraigtmoves(false, i, j);
                else if (board[i][j] == -6) {
                    getdiagonalmoves(false, i, j);
                    getstraigtmoves(false, i, j);
                }
                else if (board[i][j] == -10) getkingmoves(false, i, j);
            }
        }
        for (long unsigned int i = 0; i < pseudomoves.size(); i++) {
            original = perform(pseudomoves[i]);
            if (check(false) == false) {
                legal_moves.push_back(pseudomoves[i]);
            }
            undomove(original, pseudomoves[i]);
        }
        return legal_moves;
    }
    return legal_moves;
}

bool Chess2::check(bool turn) {
    if (turn == true) {
        int row, col;
        //Finding the king on the board

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i][j] == 10) {
                    row = i;
                    col = j;
                }
            }
        }

        //Finding the king on the board
        if (row != 0 && col != 0 && board[row - 1][col - 1] == -1) return true;
        else if (row != 0 && col != 7 && board[row - 1][col + 1] == -1) return true;
        int a, b;
        a = row;
        b = col;
        if (a != 0 && b != 0) {
            for (;;) {
                a -= 1;
                b -= 1;
                if (board[a][b] == -6 || board[a][b] == -2) return true;
                if (board[a][b] != 0 || a == 0 || b == 0) break;
            }
        }
        a = row;
        b = col;
        if (a != 0 && b != 7) {
            for (;;) {
                a -= 1;
                b += 1;
                if (board[a][b] == -6 || board[a][b] == -2) return true;
                if (board[a][b] != 0 || a == 0 || b == 7) break;
            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 0) {
            for (;;) {
                a += 1;
                b -= 1;
                if (board[a][b] == -6 || board[a][b] == -2) return true;
                if (board[a][b] != 0 || a == 7 || b == 0) break;
            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 7) {
            for (;;) {
                a += 1;
                b += 1;
                if (board[a][b] == -6 || board[a][b] == -2) return true;
                if (board[a][b] != 0 || a == 7 || b == 7) break;
            }
        }

        a = row;
        b = col;
        if (a != 7) {
            for (;;) {
                a += 1;
                if (board[a][b] == -6 || board[a][b] == -5) return true;
                if (board[a][b] != 0 || a == 7) break;
            }
        }
        a = row;
        b = col;
        if (a != 0) {
            for (;;) {
                a -= 1;
                if (board[a][b] == -6 || board[a][b] == -5) return true;
                if (board[a][b] != 0 || a == 0) break;
            }
        }

        a = row;
        b = col;
        if (b != 7) {
            for (;;) {
                b += 1;
                if (board[a][b] == -6 || board[a][b] == -5) return true;
                if (board[a][b] != 0 || b == 7) break;
            }
        }
        a = row;
        b = col;
        if (b != 0) {
            for (;;) {
                b -= 1;
                if (board[a][b] == -6 || board[a][b] == -5) return true;
                if (board[a][b] != 0 || b == 0) break;
            }
        }

        if (row > 0 && col < 6 && board[row - 1][col + 2] == -3)return true;
        if (row > 1 && col < 7 && board[row - 2][col + 1] == -3)return true;
        if (row < 7 && col < 6 && board[row + 1][col + 2] == -3)return true;
        if (row < 6 && col < 7 && board[row + 2][col + 1] == -3)return true;
        if (row < 6 && col > 0 && board[row + 2][col - 1] == -3)return true;
        if (row < 7 && col > 1 && board[row + 1][col - 2] == -3)return true;
        if (row > 1 && col > 0 && board[row - 2][col - 1] == -3)return true;
        if (row > 0 && col > 1 && board[row - 1][col - 2] == -3)return true;

        if (row != 7 && board[row + 1][col] == -10)return true;
        if (row != 0 && board[row - 1][col] == -10)return true;
        if (col != 7 && board[row][col + 1] == -10) return true;
        if (col != 0 && board[row][col - 1] == -10) return true;
        if (row != 7 && col != 7 && board[row + 1][col + 1] == -10)return true;
        if (row != 7 && col != 0 && board[row + 1][col - 1] == -10) return true;
        if (row != 0 && col != 7 && board[row - 1][col + 1] == -10) return true;
        if (row != 0 && col != 0 && board[row - 1][col - 1] == -10) return true;


    }
    else if (turn == false) {
        int row, col;
        //Finding the king on the board

        for (int i = 0; i < 8; i++) {
            for (int j = 0; j < 8; j++) {
                if (board[i][j] == -10) {
                    row = i;
                    col = j;
                }
            }
        }

        //Finding the king on the board
        if (row != 7 && col != 0 && board[row + 1][col - 1] == 1) return true;
        else if (row != 7 && col != 7 && board[row + 1][col + 1] == 1) return true;

        int a, b;
        a = row;
        b = col;
        if (a != 0 && b != 0) {
            for (;;) {
                a -= 1;
                b -= 1;
                if (board[a][b] == 6 || board[a][b] == 2) return true;
                if (board[a][b] != 0 || a == 0 || b == 0) break;
            }
        }
        a = row;
        b = col;
        if (a != 0 && b != 7) {
            for (;;) {
                a -= 1;
                b += 1;
                if (board[a][b] == 6 || board[a][b] == 2) return true;
                if (board[a][b] != 0 || a == 0 || b == 7) break;
            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 0) {
            for (;;) {
                a += 1;
                b -= 1;
                if (board[a][b] == 6 || board[a][b] == 2) return true;
                if (board[a][b] != 0 || a == 7 || b == 0) break;
            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 7) {
            for (;;) {
                a += 1;
                b += 1;
                if (board[a][b] == 6 || board[a][b] == 2) return true;
                if (board[a][b] != 0 || a == 7 || b == 7) break;
            }
        }

        a = row;
        b = col;
        if (a != 7) {
            for (;;) {
                a += 1;
                if (board[a][b] == 6 || board[a][b] == 5) return true;
                if (board[a][b] != 0 || a == 7) break;
            }
        }
        a = row;
        b = col;
        if (a != 0) {
            for (;;) {
                a -= 1;
                if (board[a][b] == 6 || board[a][b] == 5) return true;
                if (board[a][b] != 0 || a == 0) break;
            }
        }

        a = row;
        b = col;
        if (b != 7) {
            for (;;) {
                b += 1;
                if (board[a][b] == 6 || board[a][b] == 5) return true;
                if (board[a][b] != 0 || b == 7) break;
            }
        }
        a = row;
        b = col;
        if (b != 0) {
            for (;;) {
                b -= 1;
                if (board[a][b] == 6 || board[a][b] == 5) return true;
                if (board[a][b] != 0 || b == 0) break;
            }
        }

        if (row > 0 && col < 6 && board[row - 1][col + 2] == 3)return true;
        if (row > 1 && col < 7 && board[row - 2][col + 1] == 3)return true;
        if (row < 7 && col < 6 && board[row + 1][col + 2] == 3)return true;
        if (row < 6 && col < 7 && board[row + 2][col + 1] == 3)return true;
        if (row < 6 && col > 0 && board[row + 2][col - 1] == 3)return true;
        if (row < 7 && col > 1 && board[row + 1][col - 2] == 3)return true;
        if (row > 1 && col > 0 && board[row - 2][col - 1] == 3)return true;
        if (row > 0 && col > 1 && board[row - 1][col - 2] == 3)return true;

        if (row != 7 && board[row + 1][col] == 10)return true;
        if (row != 0 && board[row - 1][col] == 10)return true;
        if (col != 7 && board[row][col + 1] == 10) return true;
        if (col != 0 && board[row][col - 1] == 10) return true;
        if (row != 7 && col != 7 && board[row + 1][col + 1] == 10)return true;
        if (row != 7 && col != 0 && board[row + 1][col - 1] == 10) return true;
        if (row != 0 && col != 7 && board[row - 1][col + 1] == 10) return true;
        if (row != 0 && col != 0 && board[row - 1][col - 1] == 10) return true;

    }

    return false;
}

void Chess2::getdiagonalmoves(bool turn, int row, int col) {

    int a, b;
    if (turn) {
        a = row;
        b = col;
        if (a != 0 && b != 0) {
            for (;;) {
                a -= 1;
                b -= 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || a == 0 || b == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (a != 0 && b != 7) {
            for (;;) {
                a -= 1;
                b += 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || a == 0 || b == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));

            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 7) {
            for (;;) {
                a += 1;
                b += 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || a == 7 || b == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 0) {
            for (;;) {
                a += 1;
                b -= 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || a == 7 || b == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));
            }
        }
    }
    else if (!turn) {

        a = row;
        b = col;
        if (a != 0 && b != 0) {
            for (;;) {
                a -= 1;
                b -= 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || a == 0 || b == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (a != 0 && b != 7) {
            for (;;) {
                a -= 1;
                b += 1;
                if (board[a][b] < 0)
                    break;
                if (board[a][b] > 0 || a == 0 || b == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (board[a][b] == 0)
                    pseudomoves.push_back(push(row, col, a, b));

            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 7) {
            for (;;) {
                a += 1;
                b += 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || a == 7 || b == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (a != 7 && b != 0) {
            for (;;) {
                a += 1;
                b -= 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || a == 7 || b == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b])pseudomoves.push_back(push(row, col, a, b));
            }
        }

    }
}

void Chess2::getstraigtmoves(bool turn, int row, int col)
{
    int a, b;
    if (turn) {// white player
        a = row;
        b = col;
        if (a != 0) {
            for (;;) {
                a -= 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || a == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (a != 7) {
            for (;;) {
                a += 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || a == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (b != 0) {
            for (;;) {
                b -= 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || b == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (b != 7) {
            for (;;) {
                b += 1;
                if (board[a][b] > 0) break;
                if (board[a][b] < 0 || b == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
    }

    else if (!turn) // black player
    {
        a = row;
        b = col;
        if (a != 0) {
            for (;;) {
                a -= 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || a == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (a != 7) {
            for (;;) {
                a += 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || a == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (b != 0) {
            for (;;) {
                b -= 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || b == 0) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
        a = row;
        b = col;
        if (b != 7) {
            for (;;) {
                b += 1;
                if (board[a][b] < 0) break;
                if (board[a][b] > 0 || b == 7) {
                    pseudomoves.push_back(push(row, col, a, b));
                    break;
                }
                if (!board[a][b]) pseudomoves.push_back(push(row, col, a, b));
            }
        }
    }
    //returnpseudomoves;
}

void Chess2::getknightmoves(bool turn, int row, int col) {

    if (turn) {

        if (row > 0 && col < 6 && board[row - 1][col + 2] <= 0) // one up two right
            pseudomoves.push_back(push(row, col, row - 1, col + 2));

        if (row > 1 && col < 7 && board[row - 2][col + 1] <= 0) // two up one right
            pseudomoves.push_back(push(row, col, row - 2, col + 1));

        if (row < 7 && col < 6 && board[row + 1][col + 2] <= 0) // one down two right
            pseudomoves.push_back(push(row, col, row + 1, col + 2));

        if (row < 6 && col < 7 && board[row + 2][col + 1] <= 0) // two down one right
            pseudomoves.push_back(push(row, col, row + 2, col + 1));

        if (row < 6 && col > 0 && board[row + 2][col - 1] <= 0) //two down one left
            pseudomoves.push_back(push(row, col, row + 2, col - 1));

        if (row < 7 && col > 1 && board[row + 1][col - 2] <= 0) // one down two left
            pseudomoves.push_back(push(row, col, row + 1, col - 2));

        if (row > 1 && col > 0 && board[row - 2][col - 1] <= 0) // two up one left
            pseudomoves.push_back(push(row, col, row - 2, col - 1));

        if (row > 0 && col > 1 && board[row - 1][col - 2] <= 0) // one up two left
            pseudomoves.push_back(push(row, col, row - 1, col - 2));
    }

    else if (!turn) {
        if (row > 0 && col < 6 && board[row - 1][col + 2] >= 0)pseudomoves.push_back(push(row, col, row - 1, col + 2));
        if (row > 1 && col < 7 && board[row - 2][col + 1] >= 0)pseudomoves.push_back(push(row, col, row - 2, col + 1));
        if (row < 7 && col < 6 && board[row + 1][col + 2] >= 0)pseudomoves.push_back(push(row, col, row + 1, col + 2));
        if (row < 6 && col < 7 && board[row + 2][col + 1] >= 0)pseudomoves.push_back(push(row, col, row + 2, col + 1));
        if (row < 6 && col > 0 && board[row + 2][col - 1] >= 0)pseudomoves.push_back(push(row, col, row + 2, col - 1));
        if (row < 7 && col > 1 && board[row + 1][col - 2] >= 0)pseudomoves.push_back(push(row, col, row + 1, col - 2));
        if (row > 1 && col > 0 && board[row - 2][col - 1] >= 0)pseudomoves.push_back(push(row, col, row - 2, col - 1));
        if (row > 0 && col > 1 && board[row - 1][col - 2] >= 0)pseudomoves.push_back(push(row, col, row - 1, col - 2));
    }

    //returnpseudomoves;
}

void Chess2::getpawnmoves(bool turn, int row, int col) {
    if (turn) {
        if (row == 6 && board[row - 1][col] == 0 && board[row - 2][col] == 0)
            pseudomoves.push_back(push(row, col, row - 2, col));
        if (board[row - 1][col] == 0)
            pseudomoves.push_back(push(row, col, row - 1, col));
        if (col != 0 && board[row - 1][col - 1] < 0)
            pseudomoves.push_back(push(row, col, row - 1, col - 1));
        if (col != 7 && board[row - 1][col + 1] < 0)
            pseudomoves.push_back(push(row, col, row - 1, col + 1));
    }

    else if (!turn) {
        if (row == 7) //returnpseudomoves;

            if (row == 1 && board[row + 1][col] == 0 && board[row + 2][col] == 0)
                pseudomoves.push_back(push(row, col, row + 2, col));
        if (board[row + 1][col] == 0)
            pseudomoves.push_back(push(row, col, row + 1, col));
        if (col != 0 && board[row + 1][col - 1] > 0)
            pseudomoves.push_back(push(row, col, row + 1, col - 1));
        if (col != 7 && board[row + 1][col + 1] > 0)
            pseudomoves.push_back(push(row, col, row + 1, col + 1));
    }

    //returnpseudomoves;
}

void Chess2::getkingmoves(bool turn, int row, int col) {

    if (!turn) {
        if (row != 7 && board[row + 1][col] >= 0) pseudomoves.push_back(push(row, col, row + 1, col));
        if (row != 0 && board[row - 1][col] >= 0) pseudomoves.push_back(push(row, col, row - 1, col));
        if (col != 7 && board[row][col + 1] >= 0) pseudomoves.push_back(push(row, col, row, col + 1));
        if (col != 0 && board[row][col - 1] >= 0) pseudomoves.push_back(push(row, col, row, col - 1));
        if (row != 7 && col != 7 && board[row + 1][col + 1] >= 0) pseudomoves.push_back(push(row, col, row + 1, col + 1));
        if (row != 7 && col != 0 && board[row + 1][col - 1] >= 0) pseudomoves.push_back(push(row, col, row + 1, col - 1));
        if (row != 0 && col != 7 && board[row - 1][col + 1] >= 0) pseudomoves.push_back(push(row, col, row - 1, col + 1));
        if (row != 0 && col != 0 && board[row - 1][col - 1] >= 0) pseudomoves.push_back(push(row, col, row - 1, col - 1));
    }
    else if (turn) {
        if (row != 7 && board[row + 1][col] <= 0) pseudomoves.push_back(push(row, col, row + 1, col));
        if (row != 0 && board[row - 1][col] <= 0) pseudomoves.push_back(push(row, col, row - 1, col));
        if (col != 7 && board[row][col + 1] <= 0) pseudomoves.push_back(push(row, col, row, col + 1));
        if (col != 0 && board[row][col - 1] <= 0) pseudomoves.push_back(push(row, col, row, col - 1));
        if (row != 7 && col != 7 && board[row + 1][col + 1] <= 0) pseudomoves.push_back(push(row, col, row + 1, col + 1));
        if (row != 7 && col != 0 && board[row + 1][col - 1] <= 0) pseudomoves.push_back(push(row, col, row + 1, col - 1));
        if (row != 0 && col != 7 && board[row - 1][col + 1] <= 0) pseudomoves.push_back(push(row, col, row - 1, col + 1));
        if (row != 0 && col != 0 && board[row - 1][col - 1] <= 0) pseudomoves.push_back(push(row, col, row - 1, col - 1));
    }
    //returnpseudomoves;
}

int Chess2::evaluation() {
    int score;
    for (int i = 0; i < 8; i++) {
        for (int j = 0; j < 8; j++) {
            if (!board[i][j]) continue;
            if (board[i][j] == 1) score -= 10;
            else if (board[i][j] == 2)score -= 30;
            else if (board[i][j] == 3)score -= 30;
            else if (board[i][j] == 5)score -= 50;
            else if (board[i][j] == 6)score -= 90;
            else if (board[i][j] == 10)score -= 900;
            else if (board[i][j] == -1)score += 10;
            else if (board[i][j] == -2)score += 30;
            else if (board[i][j] == -3)score += 30;
            else if (board[i][j] == -5)score += 50;
            else if (board[i][j] == -6)score += 60;
            else if (board[i][j] == -10)score += 900;

        }
    }
    return score;
}

int Chess2::miniMax(int depth, bool ismax, int alpha, int beta) {
    if (depth == 0) {
        return evaluation();
    }
    int maxeval = -999999;
    int mineval = 999999;
    buff possiblemoves;
    int original;
    int eval;
    if (ismax == true) {
        possiblemoves = getallmoves(false);
        for (long unsigned int i = 0; i < possiblemoves.size(); i++) {
            original = perform(possiblemoves[i]);
            eval = miniMax(depth - 1, false, alpha, beta);
            undomove(original, possiblemoves[i]);
            if (eval > maxeval)
                maxeval = eval;
            if (alpha >= eval)
                alpha = eval;
            if (beta <= alpha)
                break;
        }
        return maxeval;
    }
    else {
        possiblemoves = getallmoves(true);
        for (long unsigned int i = 0; i < possiblemoves.size(); i++) {
            original = perform(possiblemoves[i]);
            eval = miniMax(depth - 1, true, alpha, beta);
            undomove(original, possiblemoves[i]);
            if (eval < mineval)
                mineval = eval;
            if (beta <= eval)
                beta = eval;
            if (beta <= alpha)
                break;
        }
        return mineval;
    }

}

str Chess2::miniMaxroot(int depth, bool turn) {
    str bestmove;
    int maxeval = -9999999;
    buff allmoves = getallmoves(turn);
    int original;
    int eval;
    for (long unsigned int i = 0; i < allmoves.size(); i++) {
        original = perform(allmoves[i]);
        eval = miniMax(depth - 1, false, -99999999, 99999999);
        std::cout << "Move: " << allmoves[i] << " Points: " << eval << "\n";
        undomove(original, allmoves[i]);
        if (eval > maxeval) {
            maxeval = eval;
            bestmove = allmoves[i];
        }
    }
    return bestmove;
}
void Chess2::undomove(int original, str Move) {
    board[Move[0] - 48][Move[1] - 48] = board[Move[2] - 48][Move[3] - 48];
    board[Move[2] - 48][Move[3] - 48] = original;
}
\$\endgroup\$
7
  • \$\begingroup\$ I really appreciate this a lot! Could you please link any articles or any information on How I can define stuff in other files and then use it somewhere else using header files ? \$\endgroup\$
    – user228914
    Aug 25, 2020 at 8:45
  • \$\begingroup\$ Also , I wasn't sure how I could link this post to the last one, As i added almost all of @edward's suggestions and improved its computer generation speed from about 20 seconds to 4 seconds!, \$\endgroup\$
    – user228914
    Aug 25, 2020 at 8:47
  • 2
    \$\begingroup\$ Minor nitpick: I'd say it is as common if not more common to use .hpp for C++ headers. I usually expect .h to be pure C. Then there's also less common .tpp for templates. \$\endgroup\$ Aug 25, 2020 at 8:50
  • \$\begingroup\$ This post is full of suggestions which I WILL implement, but still I wanted to ask, currently my data structure is a std::vector<std::string>, A move would look like this. 'vector < "0011">`, Where the first two correspond to the initial positions and the last two correspond to the desired positions, Is there a faster way I can achieve the same task? \$\endgroup\$
    – user228914
    Aug 25, 2020 at 8:55
  • \$\begingroup\$ @AryanParekh that will be pretty fast, numbers would be faster because they would be direct indexes into the board. \$\endgroup\$
    – pacmaninbw
    Aug 25, 2020 at 12:45

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.