Initial version, load default FEN, displays for 5 seconds and closes

This commit is contained in:
Marcus Penate 2022-04-14 16:03:32 -04:00
commit 8c7fe707a1
12 changed files with 465 additions and 0 deletions

1
.gitignore vendored Normal file
View File

@ -0,0 +1 @@
chess

34
.vscode/launch.json vendored Executable file
View File

@ -0,0 +1,34 @@
{
// Use IntelliSense to learn about possible attributes.
// Hover to view descriptions of existing attributes.
// For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387
"version": "0.2.0",
"configurations": [
{
"name": "g++ - Build and debug active project",
"type": "cppdbg",
"request": "launch",
"program": "${fileDirname}/chess",
"args": [],
"stopAtEntry": false,
"cwd": "${fileDirname}",
"environment": [],
"externalConsole": false,
"MIMode": "gdb",
"setupCommands": [
{
"description": "Enable pretty-printing for gdb",
"text": "-enable-pretty-printing",
"ignoreFailures": true
},
{
"description": "Set Disassembly Flavor to Intel",
"text": "-gdb-set disassembly-flavor intel",
"ignoreFailures": true
}
],
"preLaunchTask": "C/C++: g++ build project",
"miDebuggerPath": "/usr/bin/gdb"
}
]
}

30
.vscode/tasks.json vendored Executable file
View File

@ -0,0 +1,30 @@
{
"tasks": [
{
"type": "cppbuild",
"label": "C/C++: g++ build project",
"command": "/usr/bin/g++",
"args": [
"*.cpp",
"-std=c++1z",
"-fdiagnostics-color=always",
"-g",
"-lSDL2",
"-o",
"./chess"
],
"options": {
"cwd": "${fileDirname}"
},
"problemMatcher": [
"$gcc"
],
"group": {
"kind": "build",
"isDefault": true
},
"detail": "Task generated by Debugger."
}
],
"version": "2.0.0"
}

BIN
Chess_Pieces_Sprite.bmp Executable file

Binary file not shown.

After

Width:  |  Height:  |  Size: 28 KiB

35
app_consts.hpp Executable file
View File

@ -0,0 +1,35 @@
#pragma once
#include <cstdint>
inline constexpr int SPRITE_SIZE{45};
inline constexpr int SCREEN_WIDTH{SPRITE_SIZE*8};
inline constexpr int SCREEN_HEIGHT{SPRITE_SIZE*8};
inline constexpr int BOARD_SIZE{8};
enum Type
{
NO_TYPE=-1,
KING=0,
QUEEN=1,
BISHOP=2,
KNIGHT=3,
ROOK=4,
PAWN=5,
UNKNOWN=6,
};
enum Team
{
NO_TEAM=-1,
WHITE=0,
BLACK=1,
};
enum Visibility
{
VIS_NONE=-1,
SHOWN=0,
HIDDEN=1,
};

171
board.cpp Executable file
View File

@ -0,0 +1,171 @@
#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;
}
}

26
board.hpp Executable file
View File

@ -0,0 +1,26 @@
#pragma once
#include <SDL2/SDL.h>
#include <string>
#include <vector>
#include "app_consts.hpp"
#include "piece.hpp"
class Board
{
public:
Board();
Board(std::string board_fen);
void load_FEN(std::string board_fen);
void draw_board(SDL_Surface* dest_surface);
private:
Piece game_board[BOARD_SIZE][BOARD_SIZE];
Team active_color;
bool able_to_castle[2][2];
std::vector<int> en_passant;
int half_turn_count, full_turn_count;
};

58
main.cpp Executable file
View File

@ -0,0 +1,58 @@
#include <SDL2/SDL.h>
#include "app_consts.hpp"
#include "board.hpp"
#include "sprites.hpp"
int main(int argc, char** argv)
{
//Sourced from lazyfoo's SDL2 tutorials, not really any special code here, just standard init process for the window
//The window we'll be rendering to
SDL_Window* window = NULL;
//The surface contained by the window
SDL_Surface* screenSurface = NULL;
//Initialize SDL
if(SDL_Init(SDL_INIT_VIDEO) < 0)
{
printf("SDL could not initialize! SDL_Error: %s\n", SDL_GetError());
}
else
{
//Create window
window = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
if(window == NULL)
{
printf("Window could not be created! SDL_Error: %s\n", SDL_GetError());
}
else
{
//Get window surface
screenSurface = SDL_GetWindowSurface(window);
//Fill the surface white
SDL_FillRect(screenSurface, NULL, SDL_MapRGB(screenSurface->format, 0x00, 0x00, 0x00));
Board board;
board.draw_board(screenSurface);
//Update the surface
SDL_UpdateWindowSurface(window);
//Wait two seconds
SDL_Delay(5000);
}
}
Sprite::close();
//Destroy window
SDL_DestroyWindow(window);
//Quit SDL subsystems
SDL_Quit();
return 0;
}

30
piece.cpp Normal file
View File

@ -0,0 +1,30 @@
#include "piece.hpp"
Piece::Piece()
{
type = NO_TYPE;
team = NO_TEAM;
vis = VIS_NONE;
}
Piece::Piece(Type type, Team team, Visibility vis)
{
this->type = type;
this->team = team;
this->vis = vis;
}
Team Piece::get_team()
{
return team;
}
Type Piece::get_type()
{
return type;
}
Visibility Piece::get_vis()
{
return vis;
}

20
piece.hpp Normal file
View File

@ -0,0 +1,20 @@
#pragma once
#include <SDL2/SDL.h>
#include "app_consts.hpp"
class Piece
{
public:
Piece();
Piece(Type type, Team team, Visibility vis);
Team get_team();
Type get_type();
Visibility get_vis();
private:
Type type;
Team team;
Visibility vis;
};

43
sprites.cpp Normal file
View File

@ -0,0 +1,43 @@
#include "sprites.hpp"
SDL_Surface* Sprite::sheet = nullptr;
int Sprite::get(Piece piece, SDL_Surface* dest_surface)
{
return get(piece.get_team(), piece.get_type(), piece.get_vis(), dest_surface);
}
int Sprite::get(Team team, Type type, Visibility vis, SDL_Surface* dest_surface)
{
if (nullptr == sheet)
{
load();
}
if (NO_TYPE == type || NO_TEAM == team || VIS_NONE == vis)
{
return -1;
}
SDL_Rect dest_rect{0,0,45,45};
SDL_Rect src_rect{type*45,team*45+vis*90,45,45};
SDL_BlitSurface(sheet, &src_rect, dest_surface, &dest_rect);
return 0;
}
void Sprite::close()
{
if (nullptr != sheet)
{
SDL_FreeSurface(sheet);
sheet = nullptr;
}
}
void Sprite::load()
{
close();
sheet = SDL_LoadBMP("Chess_Pieces_Sprite.bmp");
SDL_SetColorKey(sheet, SDL_TRUE, SDL_MapRGB(sheet->format, 0xFF, 0, 0xFF));
}

17
sprites.hpp Normal file
View File

@ -0,0 +1,17 @@
#pragma once
#include "piece.hpp"
class Sprite
{
public:
static int get(Piece piece, SDL_Surface* dest_surface);
static int get(Team team, Type type, Visibility vis, SDL_Surface* dest_surface);
static void close();
private:
static void load();
static SDL_Surface* sheet;
};