SchrodingersChess/board.cpp

171 lines
4.7 KiB
C++
Executable File

#include "board.hpp"
#include <cstdlib>
#include "sprites.hpp"
Board::Board()
{
load_FEN(std::string("rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/SOCQKCOS w KQkq - 0 1"));
}
Board::Board(std::string board_fen)
{
load_FEN(board_fen);
}
void Board::load_FEN(std::string board_fen)
{
active_color = WHITE;
able_to_castle[0][0] = false;
able_to_castle[0][1] = false;
able_to_castle[1][0] = false;
able_to_castle[1][1] = false;
half_turn_count = 0;
full_turn_count = 0;
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 && y==BOARD_SIZE); i++)
{
if (board_fen[i] == '/')
{
x++;
y=0;
}
else if (std::isdigit(board_fen[i]))
{
y += board_fen[i]-'0';
}
else
{
size_t loc = black_team.find(board_fen[i],0);
if (std::string::npos != loc)
{
Visibility vis = SHOWN;
if (loc >= UNKNOWN)
{
vis = HIDDEN;
loc -= UNKNOWN;
loc += BISHOP;
}
Type type = (Type)loc;
Team team = BLACK;
game_board[x][y] = Piece(type, team, vis);
}
else
{
loc = white_team.find(board_fen[i],0);
if (std::string::npos != loc)
{
Visibility vis = SHOWN;
if (loc >= UNKNOWN)
{
vis = HIDDEN;
loc -= UNKNOWN;
loc += BISHOP;
}
Type type = (Type)loc;
Team team = WHITE;
game_board[x][y] = Piece(type, team, vis);
}
}
y++;
}
}
size_t active_color_loc = board_fen.find(' ', 0);
if (std::string::npos == active_color_loc || active_color_loc+1 >= board_fen.size())
{
return;
}
else
{
active_color_loc = active_color_loc+1;
}
active_color = ('w'==board_fen[active_color_loc])?WHITE:BLACK;
size_t able_to_castle_loc = active_color_loc+2;
while(board_fen[able_to_castle_loc] != ' ')
{
switch(board_fen[able_to_castle_loc])
{
case 'K':
able_to_castle[WHITE][KING] = true;
break;
case 'Q':
able_to_castle[WHITE][QUEEN] = true;
break;
case 'k':
able_to_castle[BLACK][KING] = true;
break;
case 'q':
able_to_castle[BLACK][QUEEN] = true;
break;
}
able_to_castle_loc++;
}
size_t en_passant_loc = able_to_castle_loc+1;
while(board_fen[en_passant_loc] != ' ')
{
if (board_fen[en_passant_loc == '-'])
{
en_passant_loc++;
break;
}
x = board_fen[en_passant_loc]-'a';
y = board_fen[en_passant_loc]-'0';
en_passant.push_back(x+y*BOARD_SIZE);
en_passant_loc+=2;
}
size_t half_turn_count_loc = en_passant_loc+1;
const char* board_fen_cstr = board_fen.c_str();
char* full_turn_count_loc;
half_turn_count = strtol(board_fen_cstr+half_turn_count_loc, &full_turn_count_loc, 10);
full_turn_count = strtol(full_turn_count_loc, nullptr, 10);
}
void Board::draw_board(SDL_Surface* dest_surface)
{
bool light_tile = true;
for (int y = 0; y < BOARD_SIZE; y++)
{
for (int x = 0; x < BOARD_SIZE; x++)
{
SDL_Rect dest_rect({SPRITE_SIZE*y,SPRITE_SIZE*x,SPRITE_SIZE,SPRITE_SIZE});
uint32_t color = 0;
if (light_tile)
{
color = SDL_MapRGB(dest_surface->format, 235, 236, 208);
}
else
{
color = SDL_MapRGB(dest_surface->format, 119, 149, 86);
}
SDL_FillRect(dest_surface, &dest_rect, color);
SDL_Surface* piece_surface = SDL_CreateRGBSurfaceWithFormat(0, SPRITE_SIZE, SPRITE_SIZE, 32, dest_surface->format->format);
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))
{
SDL_BlitSurface(piece_surface, nullptr, dest_surface, &dest_rect);
}
SDL_FreeSurface(piece_surface);
light_tile = !light_tile;
}
light_tile = !light_tile;
}
}