Finished version, might have memory leaks
This commit is contained in:
		
							parent
							
								
									e6e567e734
								
							
						
					
					
						commit
						cbdf377c86
					
				
							
								
								
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										3
									
								
								.gitignore
									
									
									
									
										vendored
									
									
								
							@ -1 +1,4 @@
 | 
			
		||||
chess
 | 
			
		||||
chess.exe
 | 
			
		||||
SDL2.dll
 | 
			
		||||
SDL2/
 | 
			
		||||
							
								
								
									
										51
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							
							
						
						
									
										51
									
								
								.vscode/settings.json
									
									
									
									
										vendored
									
									
										Normal file
									
								
							@ -0,0 +1,51 @@
 | 
			
		||||
{
 | 
			
		||||
    "files.associations": {
 | 
			
		||||
        "array": "cpp",
 | 
			
		||||
        "atomic": "cpp",
 | 
			
		||||
        "bit": "cpp",
 | 
			
		||||
        "*.tcc": "cpp",
 | 
			
		||||
        "cctype": "cpp",
 | 
			
		||||
        "chrono": "cpp",
 | 
			
		||||
        "clocale": "cpp",
 | 
			
		||||
        "cmath": "cpp",
 | 
			
		||||
        "cstdarg": "cpp",
 | 
			
		||||
        "cstddef": "cpp",
 | 
			
		||||
        "cstdint": "cpp",
 | 
			
		||||
        "cstdio": "cpp",
 | 
			
		||||
        "cstdlib": "cpp",
 | 
			
		||||
        "ctime": "cpp",
 | 
			
		||||
        "cwchar": "cpp",
 | 
			
		||||
        "cwctype": "cpp",
 | 
			
		||||
        "deque": "cpp",
 | 
			
		||||
        "unordered_map": "cpp",
 | 
			
		||||
        "vector": "cpp",
 | 
			
		||||
        "exception": "cpp",
 | 
			
		||||
        "algorithm": "cpp",
 | 
			
		||||
        "functional": "cpp",
 | 
			
		||||
        "iterator": "cpp",
 | 
			
		||||
        "memory": "cpp",
 | 
			
		||||
        "memory_resource": "cpp",
 | 
			
		||||
        "numeric": "cpp",
 | 
			
		||||
        "optional": "cpp",
 | 
			
		||||
        "random": "cpp",
 | 
			
		||||
        "ratio": "cpp",
 | 
			
		||||
        "string": "cpp",
 | 
			
		||||
        "string_view": "cpp",
 | 
			
		||||
        "system_error": "cpp",
 | 
			
		||||
        "tuple": "cpp",
 | 
			
		||||
        "type_traits": "cpp",
 | 
			
		||||
        "utility": "cpp",
 | 
			
		||||
        "fstream": "cpp",
 | 
			
		||||
        "initializer_list": "cpp",
 | 
			
		||||
        "iosfwd": "cpp",
 | 
			
		||||
        "istream": "cpp",
 | 
			
		||||
        "limits": "cpp",
 | 
			
		||||
        "new": "cpp",
 | 
			
		||||
        "ostream": "cpp",
 | 
			
		||||
        "sstream": "cpp",
 | 
			
		||||
        "stdexcept": "cpp",
 | 
			
		||||
        "streambuf": "cpp",
 | 
			
		||||
        "cinttypes": "cpp",
 | 
			
		||||
        "typeinfo": "cpp"
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										36
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										36
									
								
								.vscode/tasks.json
									
									
									
									
										vendored
									
									
								
							@ -6,6 +6,10 @@
 | 
			
		||||
            "command": "/usr/bin/g++",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "*.cpp",
 | 
			
		||||
                "-Wall",
 | 
			
		||||
                "-Wextra",
 | 
			
		||||
                "-pedantic",
 | 
			
		||||
                "-fsanitize=address",
 | 
			
		||||
                "-std=c++1z",
 | 
			
		||||
                "-fdiagnostics-color=always",
 | 
			
		||||
                "-g",
 | 
			
		||||
@ -21,9 +25,39 @@
 | 
			
		||||
            ],
 | 
			
		||||
            "group": {
 | 
			
		||||
                "kind": "build",
 | 
			
		||||
                "isDefault": true
 | 
			
		||||
                "isDefault": false
 | 
			
		||||
            },
 | 
			
		||||
            "detail": "Task generated by Debugger."
 | 
			
		||||
        },
 | 
			
		||||
        {
 | 
			
		||||
            "type": "cppbuild",
 | 
			
		||||
            "label": "C/C++: mingw build project",
 | 
			
		||||
            "command": "/usr/bin/x86_64-w64-mingw32-g++",
 | 
			
		||||
            "args": [
 | 
			
		||||
                "-std=gnu++17",
 | 
			
		||||
                "-g",
 | 
			
		||||
                "-static-libstdc++",
 | 
			
		||||
                "-static-libgcc",
 | 
			
		||||
                "-o",
 | 
			
		||||
                "./chess.exe",
 | 
			
		||||
                "*.cpp",
 | 
			
		||||
                "-ISDL2/include/",
 | 
			
		||||
                "-LSDL2/lib/",
 | 
			
		||||
                "-lmingw32",
 | 
			
		||||
                "-lSDL2main",
 | 
			
		||||
                "-lSDL2"
 | 
			
		||||
            ],
 | 
			
		||||
            "options": {
 | 
			
		||||
                "cwd": "${fileDirname}"
 | 
			
		||||
            },
 | 
			
		||||
            "problemMatcher": [
 | 
			
		||||
                "$gcc"
 | 
			
		||||
            ],
 | 
			
		||||
            "group": {
 | 
			
		||||
                "kind": "build",
 | 
			
		||||
                "isDefault": true
 | 
			
		||||
            },
 | 
			
		||||
            "detail": ""
 | 
			
		||||
        }
 | 
			
		||||
    ],
 | 
			
		||||
    "version": "2.0.0"
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										320
									
								
								board.cpp
									
									
									
									
									
								
							
							
						
						
									
										320
									
								
								board.cpp
									
									
									
									
									
								
							@ -9,6 +9,7 @@
 | 
			
		||||
Board::Board()
 | 
			
		||||
{
 | 
			
		||||
    load_FEN(std::string("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1"));
 | 
			
		||||
    //load_FEN(std::string("socqkcos/pppppppp/8/8/8/8/PPPPPPPP/SOCQKCOS w KQkq - 0 1"));
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Board::Board(std::string board_fen)
 | 
			
		||||
@ -31,7 +32,7 @@ void Board::load_FEN(std::string board_fen)
 | 
			
		||||
    int x=0,y=0;
 | 
			
		||||
    std::string black_team("kqbnrpcos");
 | 
			
		||||
    std::string white_team("KQBNRPCOS");
 | 
			
		||||
    for(int i = 0; i < board_fen.size() && !(x==BOARD_SIZE-1 && y==BOARD_SIZE); i++)
 | 
			
		||||
    for(unsigned int i = 0; i < board_fen.size() && board_fen[i] != ' '; i++)
 | 
			
		||||
    {
 | 
			
		||||
        if (board_fen[i] == '/')
 | 
			
		||||
        {
 | 
			
		||||
@ -135,11 +136,125 @@ void Board::load_FEN(std::string board_fen)
 | 
			
		||||
    full_turn_count = strtol(full_turn_count_loc, nullptr, 10);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::string Board::make_FEN()
 | 
			
		||||
{
 | 
			
		||||
    std::string str_out = "";
 | 
			
		||||
    
 | 
			
		||||
    std::string black_team("kqbnrpcos");
 | 
			
		||||
    std::string white_team("KQBNRPCOS");
 | 
			
		||||
 | 
			
		||||
    for (int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
    {
 | 
			
		||||
        int skipped_count = 0;
 | 
			
		||||
        for (int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
        {
 | 
			
		||||
            Piece cur_piece = game_board[x][y];
 | 
			
		||||
            if (cur_piece.get_type() != NO_TYPE)
 | 
			
		||||
            {
 | 
			
		||||
                if (skipped_count != 0)
 | 
			
		||||
                {
 | 
			
		||||
                    str_out += skipped_count+'0';
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (cur_piece.get_vis() == HIDDEN)
 | 
			
		||||
                {
 | 
			
		||||
                    cur_piece = Piece((Type)(cur_piece.get_type()+UNKNOWN-BISHOP), cur_piece.get_team(), SHOWN);
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                if (cur_piece.get_team() == WHITE)
 | 
			
		||||
                {
 | 
			
		||||
                    str_out+=white_team[cur_piece.get_type()];
 | 
			
		||||
                }
 | 
			
		||||
                else if (cur_piece.get_team() == BLACK)
 | 
			
		||||
                {
 | 
			
		||||
                    str_out+=black_team[cur_piece.get_type()];
 | 
			
		||||
                }
 | 
			
		||||
 | 
			
		||||
                skipped_count = 0;
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                skipped_count++;
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (skipped_count != 0)
 | 
			
		||||
        {
 | 
			
		||||
            str_out += skipped_count+'0';
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        str_out += "/";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    str_out += " ";
 | 
			
		||||
 | 
			
		||||
    if (active_color == WHITE)
 | 
			
		||||
    {
 | 
			
		||||
        str_out += "w ";
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        str_out += "b ";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (able_to_castle[0][0] || able_to_castle[0][1] || able_to_castle[1][0] || able_to_castle[1][1])
 | 
			
		||||
    {
 | 
			
		||||
        if (able_to_castle[WHITE][KING])
 | 
			
		||||
        {
 | 
			
		||||
            str_out += "K";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (able_to_castle[WHITE][QUEEN])
 | 
			
		||||
        {
 | 
			
		||||
            str_out += "Q";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (able_to_castle[BLACK][KING])
 | 
			
		||||
        {
 | 
			
		||||
            str_out += "k";
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (able_to_castle[BLACK][QUEEN])
 | 
			
		||||
        {
 | 
			
		||||
            str_out += "q";
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        str_out += "-";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    str_out += " ";
 | 
			
		||||
 | 
			
		||||
    if (en_passant == -1)
 | 
			
		||||
    {
 | 
			
		||||
        str_out += "- ";
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        int ep_x = en_passant%BOARD_SIZE;
 | 
			
		||||
        int ep_y = en_passant/BOARD_SIZE;
 | 
			
		||||
 | 
			
		||||
        str_out += ep_x+'a';
 | 
			
		||||
        str_out += ep_y+'0';
 | 
			
		||||
 | 
			
		||||
        str_out += " ";
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    str_out += std::to_string(half_turn_count);
 | 
			
		||||
 | 
			
		||||
    str_out += " ";
 | 
			
		||||
 | 
			
		||||
    str_out += std::to_string(full_turn_count);
 | 
			
		||||
 | 
			
		||||
    return str_out;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Board::draw_board(SDL_Surface* dest_surface)
 | 
			
		||||
{
 | 
			
		||||
    bool light_tile = true;
 | 
			
		||||
 | 
			
		||||
    std::vector<int> target_spaces = get_moves_for_space(selected_space);
 | 
			
		||||
    std::vector<int> target_spaces = get_moves_for_space(selected_space, true);
 | 
			
		||||
 | 
			
		||||
    for (int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
    {
 | 
			
		||||
@ -205,7 +320,13 @@ void Board::draw_board(SDL_Surface* dest_surface)
 | 
			
		||||
            SDL_FillRect(piece_surface, nullptr, SDL_MapRGB(piece_surface->format, 0xFF, 0x00, 0xFF));
 | 
			
		||||
            SDL_SetColorKey(piece_surface, SDL_TRUE, SDL_MapRGB(piece_surface->format, 0xFF, 0x00, 0xFF));
 | 
			
		||||
 | 
			
		||||
            if (0 == Sprite::get(game_board[x][y], piece_surface))
 | 
			
		||||
            Piece cur_piece = game_board[x][y];
 | 
			
		||||
            if (cur_piece.get_vis() == HIDDEN && cur_piece.get_team() == BLACK)
 | 
			
		||||
            {
 | 
			
		||||
                cur_piece = Piece(UNKNOWN, BLACK, SHOWN);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (0 == Sprite::get(cur_piece, piece_surface))
 | 
			
		||||
            {
 | 
			
		||||
                SDL_BlitSurface(piece_surface, nullptr, dest_surface, &dest_rect);
 | 
			
		||||
            }
 | 
			
		||||
@ -262,14 +383,20 @@ int Board::get_full_turn_count()
 | 
			
		||||
void Board::set_selected_space(int x, int y)
 | 
			
		||||
{
 | 
			
		||||
    if (game_board[x][y].get_team() != WHITE)
 | 
			
		||||
    {
 | 
			
		||||
        selected_space = -1;
 | 
			
		||||
        return;
 | 
			
		||||
    }        
 | 
			
		||||
    selected_space = x+y*BOARD_SIZE;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Board::set_selected_space(int space)
 | 
			
		||||
{
 | 
			
		||||
    if (game_board[space%BOARD_SIZE][space/BOARD_SIZE].get_team() != WHITE)
 | 
			
		||||
    {
 | 
			
		||||
        selected_space = -1;
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
    selected_space = space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@ -286,16 +413,18 @@ int Board::get_selected_space()
 | 
			
		||||
    return selected_space;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
std::vector<int> Board::get_moves_for_space(int x, int y, bool check_for_check)
 | 
			
		||||
{
 | 
			
		||||
    if (x < 0 || x >= BOARD_SIZE || y < 0 || y >= BOARD_SIZE || game_board[x][y].get_type() == NO_TYPE)
 | 
			
		||||
        return std::vector<int>();
 | 
			
		||||
 | 
			
		||||
    int forward_direction = (game_board[x][y].get_team() == WHITE)?-1:1;
 | 
			
		||||
 | 
			
		||||
    bool is_team_in_check = (check_for_check && is_check(game_board[x][y].get_team()));
 | 
			
		||||
 | 
			
		||||
    std::vector<int> out_spaces;
 | 
			
		||||
 | 
			
		||||
    Type piece_type = (game_board[x][y].get_vis() == VIS_NONE)?UNKNOWN:game_board[x][y].get_type();
 | 
			
		||||
    Type piece_type = (game_board[x][y].get_vis() == HIDDEN)?UNKNOWN:game_board[x][y].get_type();
 | 
			
		||||
 | 
			
		||||
    if (PAWN == piece_type)
 | 
			
		||||
    {
 | 
			
		||||
@ -327,7 +456,7 @@ std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
 | 
			
		||||
    if (QUEEN == piece_type || ROOK == piece_type)
 | 
			
		||||
    {
 | 
			
		||||
        for (int x1 = x-1; x1 > 0; x1--)
 | 
			
		||||
        for (int x1 = x-1; x1 >= 0; x1--)
 | 
			
		||||
        {
 | 
			
		||||
            MoveType result = can_move(x+y*BOARD_SIZE, x1+y*BOARD_SIZE);
 | 
			
		||||
            if (BLOCKED == result)
 | 
			
		||||
@ -347,7 +476,7 @@ std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int y1 = y-1; y1 > 0; y1--)
 | 
			
		||||
        for (int y1 = y-1; y1 >= 0; y1--)
 | 
			
		||||
        {
 | 
			
		||||
            MoveType result = can_move(x+y*BOARD_SIZE, x+y1*BOARD_SIZE);
 | 
			
		||||
            if (BLOCKED == result)
 | 
			
		||||
@ -357,7 +486,7 @@ std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
                break;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        for (int y1 = y+1; y1 > 0; y1++)
 | 
			
		||||
        for (int y1 = y+1; y1 < BOARD_SIZE; y1++)
 | 
			
		||||
        {
 | 
			
		||||
            MoveType result = can_move(x+y*BOARD_SIZE, x+y1*BOARD_SIZE);
 | 
			
		||||
            if (BLOCKED == result)
 | 
			
		||||
@ -441,19 +570,7 @@ std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            Piece old_piece = game_board[x1][y1];
 | 
			
		||||
            game_board[x1][y1] = game_board[x][y];
 | 
			
		||||
            game_board[x][y] = Piece();
 | 
			
		||||
 | 
			
		||||
            bool was_check = is_check(game_board[x1][y1].get_team());
 | 
			
		||||
            
 | 
			
		||||
            game_board[x][y] = game_board[x1][y1];
 | 
			
		||||
            game_board[x1][y1] = old_piece;
 | 
			
		||||
 | 
			
		||||
            if (!was_check)
 | 
			
		||||
            {
 | 
			
		||||
                out_spaces.push_back(x1+y1*BOARD_SIZE);
 | 
			
		||||
            }
 | 
			
		||||
            out_spaces.push_back(x1+y1*BOARD_SIZE);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (able_to_castle[game_board[x][y].get_team()][KING] &&
 | 
			
		||||
@ -511,10 +628,10 @@ std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
 | 
			
		||||
                if (CAPTURE != result)
 | 
			
		||||
                {
 | 
			
		||||
                    int x1 = x+2*unknown_offsets[i][0];
 | 
			
		||||
                    int y1 = y+2*unknown_offsets[i][1];
 | 
			
		||||
                    x1 = x+2*unknown_offsets[i][0];
 | 
			
		||||
                    y1 = y+2*unknown_offsets[i][1];
 | 
			
		||||
 | 
			
		||||
                    if (x1 >= 0 && x1 < BOARD_SIZE && y1 >= 0 && y1 < BOARD_SIZE || BLOCKED == can_move(x+y*BOARD_SIZE, x1+y1*BOARD_SIZE))
 | 
			
		||||
                    if (x1 >= 0 && x1 < BOARD_SIZE && y1 >= 0 && y1 < BOARD_SIZE && BLOCKED != can_move(x+y*BOARD_SIZE, x1+y1*BOARD_SIZE))
 | 
			
		||||
                    {
 | 
			
		||||
                        out_spaces.push_back(x1+y1*BOARD_SIZE);
 | 
			
		||||
                    }
 | 
			
		||||
@ -525,14 +642,20 @@ std::vector<int> Board::get_moves_for_space(int x, int y)
 | 
			
		||||
        out_spaces.push_back(x+y*BOARD_SIZE);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (is_team_in_check)
 | 
			
		||||
    {
 | 
			
		||||
        std::vector<int>::iterator new_end = std::remove_if(out_spaces.begin(), out_spaces.end(), [this, x, y](const int& target_space){ return !this->does_move_solve_check(x+y*BOARD_SIZE, target_space); });
 | 
			
		||||
        out_spaces.erase(new_end, out_spaces.end());
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return out_spaces;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::vector<int> Board::get_moves_for_space(int space)
 | 
			
		||||
std::vector<int> Board::get_moves_for_space(int space, bool check_for_check)
 | 
			
		||||
{
 | 
			
		||||
    if (space < 0 || space >= BOARD_SIZE*BOARD_SIZE)
 | 
			
		||||
        return std::vector<int>();
 | 
			
		||||
    return get_moves_for_space(space%BOARD_SIZE, space/BOARD_SIZE);
 | 
			
		||||
    return get_moves_for_space(space%BOARD_SIZE, space/BOARD_SIZE, check_for_check);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Board::is_check(Team team)
 | 
			
		||||
@ -557,13 +680,13 @@ bool Board::is_check(Team team)
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(int x = 0; x < BOARD_SIZE && king_space == -1; x++)
 | 
			
		||||
    for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
    {
 | 
			
		||||
        for(int y = 0; y < BOARD_SIZE && king_space == -1; y++)
 | 
			
		||||
        for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
        {
 | 
			
		||||
            if (game_board[x][y].get_team() == enemy_team)
 | 
			
		||||
            {
 | 
			
		||||
                std::vector<int> possible_moves = get_moves_for_space(x,y);
 | 
			
		||||
                std::vector<int> possible_moves = get_moves_for_space(x,y, false);
 | 
			
		||||
                if (possible_moves.end() != std::find(possible_moves.begin(), possible_moves.end(), king_space))
 | 
			
		||||
                {
 | 
			
		||||
                    return true;
 | 
			
		||||
@ -575,6 +698,121 @@ bool Board::is_check(Team team)
 | 
			
		||||
    return false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Board::is_mate(Team team)
 | 
			
		||||
{
 | 
			
		||||
    if (!is_check(team))
 | 
			
		||||
    {
 | 
			
		||||
        return false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
    {
 | 
			
		||||
        for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
        {
 | 
			
		||||
            if (game_board[x][y].get_team() == team)
 | 
			
		||||
            {
 | 
			
		||||
                std::vector<int> possible_moves = get_moves_for_space(x,y,false);
 | 
			
		||||
                if (possible_moves.end() != std::find_if(possible_moves.begin(), possible_moves.end(), [this, x, y](const int& target_space){ return this->does_move_solve_check(x+y*BOARD_SIZE, target_space); }))
 | 
			
		||||
                {
 | 
			
		||||
                    return false;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
    
 | 
			
		||||
    return true;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Board::do_move(int space_from, int space_to, bool holding_k)
 | 
			
		||||
{
 | 
			
		||||
    if (space_from < 0 || space_to < 0 || space_from >= BOARD_SIZE*BOARD_SIZE || space_to >= BOARD_SIZE*BOARD_SIZE)
 | 
			
		||||
    {
 | 
			
		||||
        return;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    int xf=space_from%BOARD_SIZE,yf=space_from/BOARD_SIZE,xt=space_to%BOARD_SIZE,yt=space_to/BOARD_SIZE;
 | 
			
		||||
 | 
			
		||||
    Piece cur_piece = game_board[xf][yf];
 | 
			
		||||
    Piece target_piece = game_board[xt][yt];
 | 
			
		||||
    Team enemy_team = (cur_piece.get_team() == WHITE)?BLACK:WHITE;
 | 
			
		||||
    
 | 
			
		||||
    en_passant = -1;
 | 
			
		||||
 | 
			
		||||
    if (cur_piece.get_team() == BLACK)
 | 
			
		||||
    {
 | 
			
		||||
        full_turn_count++;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (cur_piece.get_type() == PAWN)
 | 
			
		||||
    {
 | 
			
		||||
        half_turn_count = 0;
 | 
			
		||||
        if (yf-yt == 2 || yt-yf == 2)
 | 
			
		||||
        {
 | 
			
		||||
            int ep_y = (yt+yf)/2;
 | 
			
		||||
            en_passant = xf+ep_y*BOARD_SIZE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (yt == 7 && cur_piece.get_team() == BLACK)
 | 
			
		||||
        {
 | 
			
		||||
            cur_piece = Piece((holding_k)?KNIGHT:QUEEN, BLACK, SHOWN);
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (yt == 0 && cur_piece.get_team() == WHITE)
 | 
			
		||||
        {
 | 
			
		||||
            cur_piece = Piece((holding_k)?KNIGHT:QUEEN, WHITE, SHOWN);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (cur_piece.get_type() == ROOK && cur_piece.get_vis() == SHOWN)
 | 
			
		||||
    {
 | 
			
		||||
        if (xf == 7)
 | 
			
		||||
        {
 | 
			
		||||
            able_to_castle[cur_piece.get_team()][KING] = false;
 | 
			
		||||
        }
 | 
			
		||||
        if (xf == 0)
 | 
			
		||||
        {
 | 
			
		||||
            able_to_castle[cur_piece.get_team()][QUEEN] = false;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    bool castling = false;
 | 
			
		||||
    if (cur_piece.get_type() == KING)
 | 
			
		||||
    {
 | 
			
		||||
        if (target_piece.get_type() == ROOK && target_piece.get_team() == cur_piece.get_team() && target_piece.get_vis() == SHOWN)
 | 
			
		||||
        {
 | 
			
		||||
            castling = true;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        able_to_castle[cur_piece.get_team()][KING] = false;
 | 
			
		||||
        able_to_castle[cur_piece.get_team()][QUEEN] = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (xf == xt && yf == yt && cur_piece.get_vis() == HIDDEN)
 | 
			
		||||
    {
 | 
			
		||||
        cur_piece = Piece(cur_piece.get_type(), cur_piece.get_team(), SHOWN);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (castling)
 | 
			
		||||
    {
 | 
			
		||||
        game_board[xf][yf] = target_piece;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        game_board[xf][yf] = Piece();
 | 
			
		||||
    }
 | 
			
		||||
    game_board[xt][yt] = cur_piece;
 | 
			
		||||
 | 
			
		||||
    if(is_check(enemy_team))
 | 
			
		||||
    {
 | 
			
		||||
        able_to_castle[enemy_team][KING] = false;
 | 
			
		||||
        able_to_castle[enemy_team][QUEEN] = false;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    active_color = (active_color == WHITE)?BLACK:WHITE;
 | 
			
		||||
 | 
			
		||||
    selected_space = -1;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
MoveType Board::can_move(int space_from, int space_to)
 | 
			
		||||
{
 | 
			
		||||
    if (space_from < 0 || space_to < 0 || space_from >= BOARD_SIZE*BOARD_SIZE || space_to >= BOARD_SIZE*BOARD_SIZE)
 | 
			
		||||
@ -602,5 +840,29 @@ MoveType Board::can_move(int space_from, int space_to)
 | 
			
		||||
        return CAPTURE;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (game_board[xf][yf].get_type() == KING)
 | 
			
		||||
    {
 | 
			
		||||
        if (able_to_castle[game_board[xf][yf].get_team()][KING] &&
 | 
			
		||||
            game_board[7][yf].get_team() == game_board[xf][yf].get_team() && game_board[7][yf].get_type() == ROOK && game_board[7][yf].get_vis() == SHOWN &&
 | 
			
		||||
            game_board[6][yf].get_type() == NO_TYPE && game_board[5][yf].get_type() == NO_TYPE)
 | 
			
		||||
        {
 | 
			
		||||
            return FREE;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (able_to_castle[game_board[xf][yf].get_team()][QUEEN] &&
 | 
			
		||||
            game_board[0][yf].get_team() == game_board[xf][yf].get_team() && game_board[0][yf].get_type() == ROOK && game_board[0][yf].get_vis() == SHOWN &&
 | 
			
		||||
            game_board[1][yf].get_type() == NO_TYPE && game_board[2][yf].get_type() == NO_TYPE && game_board[3][yf].get_type() == NO_TYPE)
 | 
			
		||||
        {
 | 
			
		||||
            return FREE;
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return BLOCKED;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
bool Board::does_move_solve_check(int space_from, int space_to)
 | 
			
		||||
{
 | 
			
		||||
    Board test_board(make_FEN());
 | 
			
		||||
    test_board.do_move(space_from, space_to, false);
 | 
			
		||||
    return !test_board.is_check(game_board[space_from%BOARD_SIZE][space_from/BOARD_SIZE].get_team());
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								board.hpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								board.hpp
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <SDL2/SDL.h>
 | 
			
		||||
#include "SDL2/SDL.h"
 | 
			
		||||
#include <string>
 | 
			
		||||
#include <vector>
 | 
			
		||||
 | 
			
		||||
@ -32,10 +32,13 @@ public:
 | 
			
		||||
    void get_selected_space(int* x, int* y);
 | 
			
		||||
    int get_selected_space();
 | 
			
		||||
 | 
			
		||||
    std::vector<int> get_moves_for_space(int x, int y);
 | 
			
		||||
    std::vector<int> get_moves_for_space(int space);
 | 
			
		||||
    std::vector<int> get_moves_for_space(int x, int y, bool check_for_check);
 | 
			
		||||
    std::vector<int> get_moves_for_space(int space, bool check_for_check);
 | 
			
		||||
 | 
			
		||||
    bool is_check(Team team);
 | 
			
		||||
    bool is_mate(Team team);
 | 
			
		||||
 | 
			
		||||
    void do_move(int space_from, int space_to, bool holding_k);
 | 
			
		||||
private:
 | 
			
		||||
    Piece game_board[BOARD_SIZE][BOARD_SIZE];
 | 
			
		||||
    Team active_color;
 | 
			
		||||
@ -45,4 +48,5 @@ private:
 | 
			
		||||
    int selected_space;
 | 
			
		||||
 | 
			
		||||
    MoveType can_move(int space_from, int space_to);
 | 
			
		||||
    bool does_move_solve_check(int space_from, int space_to);
 | 
			
		||||
};
 | 
			
		||||
 | 
			
		||||
							
								
								
									
										306
									
								
								game.cpp
									
									
									
									
									
								
							
							
						
						
									
										306
									
								
								game.cpp
									
									
									
									
									
								
							@ -1,6 +1,10 @@
 | 
			
		||||
#include "game.hpp"
 | 
			
		||||
 | 
			
		||||
#include <chrono>
 | 
			
		||||
#include <vector>
 | 
			
		||||
#include <algorithm>
 | 
			
		||||
#include <cstdlib>
 | 
			
		||||
#include <limits>
 | 
			
		||||
 | 
			
		||||
uint64_t time_milli() {
 | 
			
		||||
    using namespace std::chrono;
 | 
			
		||||
@ -12,6 +16,7 @@ Game::Game(SDL_Window* window, SDL_Surface* surface)
 | 
			
		||||
    this->window = window;
 | 
			
		||||
    this->surface = surface;
 | 
			
		||||
    running = false;
 | 
			
		||||
    holding_k = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Game::Game(SDL_Window* window, SDL_Surface* surface, std::string board_fen)
 | 
			
		||||
@ -20,6 +25,7 @@ Game::Game(SDL_Window* window, SDL_Surface* surface, std::string board_fen)
 | 
			
		||||
    this->surface = surface;
 | 
			
		||||
    board = Board(board_fen);
 | 
			
		||||
    running = false;
 | 
			
		||||
    holding_k = false;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Game::run()
 | 
			
		||||
@ -44,22 +50,34 @@ void Game::run()
 | 
			
		||||
void Game::tick()
 | 
			
		||||
{
 | 
			
		||||
    SDL_Event e;
 | 
			
		||||
    while(SDL_PollEvent(&e) != 0)
 | 
			
		||||
    while(running && SDL_PollEvent(&e) != 0)
 | 
			
		||||
    {
 | 
			
		||||
        if (e.type == SDL_QUIT || (e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_q))
 | 
			
		||||
        {
 | 
			
		||||
            running = false;
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        if (e.type == SDL_MOUSEBUTTONDOWN)
 | 
			
		||||
        else if (e.type == SDL_KEYUP && e.key.keysym.sym == SDLK_k)
 | 
			
		||||
        {
 | 
			
		||||
            holding_k = false;
 | 
			
		||||
        }
 | 
			
		||||
        else if (e.type == SDL_KEYDOWN && e.key.keysym.sym == SDLK_k)
 | 
			
		||||
        {
 | 
			
		||||
            holding_k = true;
 | 
			
		||||
        }
 | 
			
		||||
        else if (e.type == SDL_MOUSEBUTTONDOWN)
 | 
			
		||||
        {
 | 
			
		||||
            int x,y;
 | 
			
		||||
            SDL_GetMouseState(&x, &y);
 | 
			
		||||
            x/=SPRITE_SIZE;
 | 
			
		||||
            y/=SPRITE_SIZE;
 | 
			
		||||
            board.set_selected_space(x,y);
 | 
			
		||||
            process_click(x,y);
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (BLACK == board.get_active_color())
 | 
			
		||||
    {
 | 
			
		||||
        do_ai_move();
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Game::draw()
 | 
			
		||||
@ -68,3 +86,283 @@ void Game::draw()
 | 
			
		||||
 | 
			
		||||
    SDL_UpdateWindowSurface(window);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Game::process_click(int x, int y)
 | 
			
		||||
{
 | 
			
		||||
    if (WHITE == board.get_active_color())
 | 
			
		||||
    {
 | 
			
		||||
        int current_selected_space = board.get_selected_space();
 | 
			
		||||
        int target_selected_space = x+y*BOARD_SIZE;
 | 
			
		||||
        if (current_selected_space == -1)
 | 
			
		||||
        {
 | 
			
		||||
            board.set_selected_space(x,y);
 | 
			
		||||
        }
 | 
			
		||||
        else
 | 
			
		||||
        {
 | 
			
		||||
            std::vector<int> target_spaces = board.get_moves_for_space(current_selected_space, true);
 | 
			
		||||
 | 
			
		||||
            if (target_spaces.end() != std::find(target_spaces.begin(), target_spaces.end(), target_selected_space))
 | 
			
		||||
            {
 | 
			
		||||
                board.do_move(current_selected_space, target_selected_space, holding_k);
 | 
			
		||||
            }
 | 
			
		||||
            else
 | 
			
		||||
            {
 | 
			
		||||
                board.set_selected_space(target_selected_space);
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Game::do_ai_move()
 | 
			
		||||
{
 | 
			
		||||
    int best_move_weight = std::numeric_limits<int>::min();
 | 
			
		||||
    int best_move_from = -1;
 | 
			
		||||
    int best_move_to = -1;
 | 
			
		||||
    bool best_move_makes_queen = false;
 | 
			
		||||
    for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
    {
 | 
			
		||||
        for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
        {
 | 
			
		||||
            Piece cur_piece = board.get_piece(x,y);
 | 
			
		||||
            if (cur_piece.get_team() == BLACK)
 | 
			
		||||
            {
 | 
			
		||||
                std::vector<int> piece_moves = board.get_moves_for_space(x,y, true);
 | 
			
		||||
                for (unsigned int i = 0; i < piece_moves.size(); i++)
 | 
			
		||||
                {
 | 
			
		||||
                    Board test_board(board.make_FEN());
 | 
			
		||||
                    test_board.do_move(x+y*BOARD_SIZE, piece_moves[i], false);
 | 
			
		||||
 | 
			
		||||
                    int board_value = minimax(test_board, 3, std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), false);
 | 
			
		||||
 | 
			
		||||
                    if (board_value > best_move_weight)
 | 
			
		||||
                    {
 | 
			
		||||
                        best_move_weight = board_value;
 | 
			
		||||
                        best_move_from = x+y*BOARD_SIZE;
 | 
			
		||||
                        best_move_to = piece_moves[i];
 | 
			
		||||
                        best_move_makes_queen = false;
 | 
			
		||||
                    }
 | 
			
		||||
 | 
			
		||||
                    if (cur_piece.get_type() == PAWN || (piece_moves[i]/BOARD_SIZE) == 7)
 | 
			
		||||
                    {
 | 
			
		||||
                        Board test_board1 = Board(board.make_FEN());
 | 
			
		||||
                        test_board1.do_move(x+y*BOARD_SIZE, piece_moves[i], true);
 | 
			
		||||
 | 
			
		||||
                        if (test_board1.make_FEN().compare(test_board.make_FEN()) != 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            board_value = minimax(test_board1, 3, std::numeric_limits<int>::min(), std::numeric_limits<int>::max(), false);
 | 
			
		||||
 | 
			
		||||
                            if (board_value > best_move_weight)
 | 
			
		||||
                            {
 | 
			
		||||
                                best_move_weight = board_value;
 | 
			
		||||
                                best_move_from = x+y*BOARD_SIZE;
 | 
			
		||||
                                best_move_to = piece_moves[i];
 | 
			
		||||
                                best_move_makes_queen = true;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    board.do_move(best_move_from, best_move_to, best_move_makes_queen);
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Game::minimax(Board current_board, int depth, int a, int b, bool maximizing)
 | 
			
		||||
{
 | 
			
		||||
    if (depth == 0 || current_board.is_mate(current_board.get_active_color()))
 | 
			
		||||
    {
 | 
			
		||||
        return board_heuristic(current_board);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (maximizing)
 | 
			
		||||
    {
 | 
			
		||||
        int best_move_weight = std::numeric_limits<int>::min();
 | 
			
		||||
        for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
        {
 | 
			
		||||
            for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
            {
 | 
			
		||||
                Piece cur_piece = current_board.get_piece(x,y);
 | 
			
		||||
                if (cur_piece.get_team() == BLACK)
 | 
			
		||||
                {
 | 
			
		||||
                    std::vector<int> piece_moves = current_board.get_moves_for_space(x,y, true);
 | 
			
		||||
                    for (unsigned int i = 0; i < piece_moves.size(); i++)
 | 
			
		||||
                    {
 | 
			
		||||
                        Board test_board(current_board.make_FEN());
 | 
			
		||||
                        test_board.do_move(x+y*BOARD_SIZE, piece_moves[i], false);
 | 
			
		||||
 | 
			
		||||
                        int board_value = minimax(test_board, depth-1, a, b, false);
 | 
			
		||||
 | 
			
		||||
                        if (board_value > best_move_weight)
 | 
			
		||||
                        {
 | 
			
		||||
                            best_move_weight = board_value;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (best_move_weight >= b)
 | 
			
		||||
                        {
 | 
			
		||||
                            return best_move_weight;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (best_move_weight > a)
 | 
			
		||||
                        {
 | 
			
		||||
                            a = best_move_weight;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (cur_piece.get_type() == PAWN || (piece_moves[i]/BOARD_SIZE) == 7)
 | 
			
		||||
                        {
 | 
			
		||||
                            test_board = Board(current_board.make_FEN());
 | 
			
		||||
                            test_board.do_move(x+y*BOARD_SIZE, piece_moves[i], true);
 | 
			
		||||
 | 
			
		||||
                            board_value = minimax(test_board, depth-1, a, b, false);
 | 
			
		||||
 | 
			
		||||
                            if (board_value > best_move_weight)
 | 
			
		||||
                            {
 | 
			
		||||
                                best_move_weight = board_value;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (best_move_weight >= b)
 | 
			
		||||
                            {
 | 
			
		||||
                                return best_move_weight;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (best_move_weight > a)
 | 
			
		||||
                            {
 | 
			
		||||
                                a = best_move_weight;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return best_move_weight;
 | 
			
		||||
    }
 | 
			
		||||
    else
 | 
			
		||||
    {
 | 
			
		||||
        int best_move_weight = std::numeric_limits<int>::max();
 | 
			
		||||
        for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
        {
 | 
			
		||||
            for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
            {
 | 
			
		||||
                Piece cur_piece = current_board.get_piece(x,y);
 | 
			
		||||
                if (cur_piece.get_team() == WHITE)
 | 
			
		||||
                {
 | 
			
		||||
                    std::vector<int> piece_moves = current_board.get_moves_for_space(x,y, true);
 | 
			
		||||
                    for (unsigned int i = 0; i < piece_moves.size(); i++)
 | 
			
		||||
                    {
 | 
			
		||||
                        Board test_board(current_board.make_FEN());
 | 
			
		||||
                        test_board.do_move(x+y*BOARD_SIZE, piece_moves[i], false);
 | 
			
		||||
 | 
			
		||||
                        int board_value = minimax(test_board, depth-1, a, b, true);
 | 
			
		||||
 | 
			
		||||
                        if (board_value < best_move_weight)
 | 
			
		||||
                        {
 | 
			
		||||
                            best_move_weight = board_value;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (best_move_weight <= a)
 | 
			
		||||
                        {
 | 
			
		||||
                            return best_move_weight;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (best_move_weight < b)
 | 
			
		||||
                        {
 | 
			
		||||
                            b = best_move_weight;
 | 
			
		||||
                        }
 | 
			
		||||
 | 
			
		||||
                        if (cur_piece.get_type() == PAWN || (piece_moves[i]/BOARD_SIZE) == 0)
 | 
			
		||||
                        {
 | 
			
		||||
                            test_board = Board(current_board.make_FEN());
 | 
			
		||||
                            test_board.do_move(x+y*BOARD_SIZE, piece_moves[i], true);
 | 
			
		||||
 | 
			
		||||
                            board_value = minimax(test_board, depth-1, a, b, true);
 | 
			
		||||
 | 
			
		||||
                            if (board_value < best_move_weight)
 | 
			
		||||
                            {
 | 
			
		||||
                                best_move_weight = board_value;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (best_move_weight <= a)
 | 
			
		||||
                            {
 | 
			
		||||
                                return best_move_weight;
 | 
			
		||||
                            }
 | 
			
		||||
 | 
			
		||||
                            if (best_move_weight < b)
 | 
			
		||||
                            {
 | 
			
		||||
                                b = best_move_weight;
 | 
			
		||||
                            }
 | 
			
		||||
                        }
 | 
			
		||||
                    }
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
 | 
			
		||||
        return best_move_weight;
 | 
			
		||||
    }
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
int Game::board_heuristic(Board current_board)
 | 
			
		||||
{
 | 
			
		||||
    int heuristic = 0;
 | 
			
		||||
    int piece_weights[2][7] = {{-900, -90, -30, -30, -50, -10, 0}, {900, 90, 30, 30, 50, 10, 0}};
 | 
			
		||||
 | 
			
		||||
    int unknown_white_count = 0;
 | 
			
		||||
    int unknown_black_count = 0;
 | 
			
		||||
    for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
    {
 | 
			
		||||
        for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
        {
 | 
			
		||||
            Piece cur_piece = current_board.get_piece(x,y);
 | 
			
		||||
 | 
			
		||||
            if (cur_piece.get_type() == NO_TYPE)
 | 
			
		||||
            {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (cur_piece.get_vis() == HIDDEN)
 | 
			
		||||
            {
 | 
			
		||||
                if (cur_piece.get_team() == WHITE)
 | 
			
		||||
                {
 | 
			
		||||
                    piece_weights[WHITE][UNKNOWN] += piece_weights[WHITE][cur_piece.get_type()];
 | 
			
		||||
                    unknown_white_count++;
 | 
			
		||||
                }
 | 
			
		||||
                else
 | 
			
		||||
                {
 | 
			
		||||
                    piece_weights[BLACK][UNKNOWN] += piece_weights[BLACK][cur_piece.get_type()];
 | 
			
		||||
                    unknown_black_count++;
 | 
			
		||||
                }
 | 
			
		||||
            }
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    if (unknown_white_count != 0)
 | 
			
		||||
    {
 | 
			
		||||
        piece_weights[WHITE][UNKNOWN] /= unknown_white_count;
 | 
			
		||||
    }
 | 
			
		||||
    if (unknown_black_count != 0)
 | 
			
		||||
    {
 | 
			
		||||
        piece_weights[BLACK][UNKNOWN] /= unknown_black_count;
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    for(int x = 0; x < BOARD_SIZE; x++)
 | 
			
		||||
    {
 | 
			
		||||
        for(int y = 0; y < BOARD_SIZE; y++)
 | 
			
		||||
        {
 | 
			
		||||
            Piece cur_piece = current_board.get_piece(x,y);
 | 
			
		||||
 | 
			
		||||
            if (cur_piece.get_type() == NO_TYPE)
 | 
			
		||||
            {
 | 
			
		||||
                continue;
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            if (cur_piece.get_vis() == HIDDEN)
 | 
			
		||||
            {
 | 
			
		||||
                cur_piece = Piece(UNKNOWN, cur_piece.get_team(), SHOWN);
 | 
			
		||||
            }
 | 
			
		||||
 | 
			
		||||
            heuristic += piece_weights[cur_piece.get_team()][cur_piece.get_type()];
 | 
			
		||||
        }
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return heuristic;
 | 
			
		||||
}
 | 
			
		||||
							
								
								
									
										10
									
								
								game.hpp
									
									
									
									
									
								
							
							
						
						
									
										10
									
								
								game.hpp
									
									
									
									
									
								
							@ -1,6 +1,6 @@
 | 
			
		||||
#pragma once
 | 
			
		||||
 | 
			
		||||
#include <SDL2/SDL.h>
 | 
			
		||||
#include "SDL2/SDL.h"
 | 
			
		||||
 | 
			
		||||
#include "board.hpp"
 | 
			
		||||
 | 
			
		||||
@ -15,10 +15,18 @@ private:
 | 
			
		||||
    void tick();
 | 
			
		||||
    void draw();
 | 
			
		||||
 | 
			
		||||
    void process_click(int x, int y);
 | 
			
		||||
 | 
			
		||||
    void do_ai_move();
 | 
			
		||||
    int minimax(Board current_board, int depth, int a, int b, bool maximizing);
 | 
			
		||||
    int board_heuristic(Board current_board);
 | 
			
		||||
 | 
			
		||||
    SDL_Window* window;
 | 
			
		||||
    SDL_Surface* surface;
 | 
			
		||||
 | 
			
		||||
    Board board;
 | 
			
		||||
 | 
			
		||||
    bool running;
 | 
			
		||||
 | 
			
		||||
    bool holding_k;
 | 
			
		||||
};
 | 
			
		||||
							
								
								
									
										6
									
								
								main.cpp
									
									
									
									
									
								
							
							
						
						
									
										6
									
								
								main.cpp
									
									
									
									
									
								
							@ -1,11 +1,13 @@
 | 
			
		||||
#include <SDL2/SDL.h>
 | 
			
		||||
#include "SDL2/SDL.h"
 | 
			
		||||
 | 
			
		||||
#include "app_consts.hpp"
 | 
			
		||||
#include "sprites.hpp"
 | 
			
		||||
#include "game.hpp"
 | 
			
		||||
 | 
			
		||||
int main(int argc, char** argv)
 | 
			
		||||
int main(int argc, char *argv[])
 | 
			
		||||
{
 | 
			
		||||
	(void)argc;
 | 
			
		||||
	(void)argv;
 | 
			
		||||
    //Sourced from lazyfoo's SDL2 tutorials, not really any special code here, just standard init process for the window
 | 
			
		||||
	SDL_Window* window = NULL;
 | 
			
		||||
	
 | 
			
		||||
 | 
			
		||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user