Flipper/Applications/Official/DEV_FW/source/grnch/chess/fast_chess.h
2022-12-28 22:34:27 -08:00

388 lines
13 KiB
C

/*
* fast-chess.h
*
* Created on: 20 de set de 2016
* Author: fvj
*/
#ifndef FAST_CHESS_H_
#define FAST_CHESS_H_
#ifdef _WIN32
#include <windows.h>
#endif
#include <stdint.h>
#define ENGINE_VERSION "v1.8.1"
#define ENGINE_NAME "github.com/fredericojordan/fast-chess " ENGINE_VERSION
#define HUMAN_NAME "Unknown Human Player"
#define NUM_SQUARES (64)
#define ENDGAME_PIECE_COUNT (7)
#define COLOR_MASK (1 << 3)
#define WHITE (0)
#define BLACK (1 << 3)
#define PIECE_MASK (0x7)
#define EMPTY (0)
#define PAWN (1)
#define KNIGHT (2)
#define BISHOP (3)
#define ROOK (4)
#define QUEEN (5)
#define KING (6)
#define ALL_SQUARES (0xFFFFFFFFFFFFFFFF)
#define FILE_A (0x0101010101010101)
#define FILE_B (0x0202020202020202)
#define FILE_C (0x0404040404040404)
#define FILE_D (0x0808080808080808)
#define FILE_E (0x1010101010101010)
#define FILE_F (0x2020202020202020)
#define FILE_G (0x4040404040404040)
#define FILE_H (0x8080808080808080)
#define RANK_1 (0x00000000000000FF)
#define RANK_2 (0x000000000000FF00)
#define RANK_3 (0x0000000000FF0000)
#define RANK_4 (0x00000000FF000000)
#define RANK_5 (0x000000FF00000000)
#define RANK_6 (0x0000FF0000000000)
#define RANK_7 (0x00FF000000000000)
#define RANK_8 (0xFF00000000000000)
#define DIAG_A1H8 (0x8040201008040201)
#define ANTI_DIAG_H1A8 (0x0102040810204080)
#define LIGHT_SQUARES (0x55AA55AA55AA55AA)
#define DARK_SQUARES (0xAA55AA55AA55AA55)
#define CASTLE_KINGSIDE_WHITE (1 << 0)
#define CASTLE_QUEENSIDE_WHITE (1 << 1)
#define CASTLE_KINGSIDE_BLACK (1 << 2)
#define CASTLE_QUEENSIDE_BLACK (1 << 3)
#define BOOL char
#ifndef FALSE
#define TRUE (1)
#define FALSE (0)
#endif
typedef uint_fast64_t Bitboard;
typedef int Move;
#define MAX_BOOK_ENTRY_LEN (300)
#define MAX_PLYS_PER_GAME (1024)
#define MAX_FEN_LEN (100)
// #define MAX_BRANCHING_FACTOR (218) /* R6R/3Q4/1Q4Q1/4Q3/2Q4Q/Q4Q2/pp1Q4/kBNN1KB1 w - - 0 1 3Q4/1Q4Q1/4Q3/2Q4R/Q4Q2/3Q4/1Q4Rp/1K1BBNNk w - - 0 1 */
#define MAX_BRANCHING_FACTOR (100) // okalachev
#define MAX_ATTACKING_PIECES (12)
#define DEFAULT_AI_DEPTH (3)
typedef struct {
Bitboard whiteKing;
Bitboard whiteQueens;
Bitboard whiteRooks;
Bitboard whiteKnights;
Bitboard whiteBishops;
Bitboard whitePawns;
Bitboard blackKing;
Bitboard blackQueens;
Bitboard blackRooks;
Bitboard blackKnights;
Bitboard blackBishops;
Bitboard blackPawns;
} Board;
typedef struct {
Board board;
char toMove;
char epSquare;
char castlingRights;
unsigned int halfmoveClock;
unsigned int fullmoveNumber;
} Position;
typedef struct {
Position position;
unsigned int moveListLen;
Move moveList[MAX_PLYS_PER_GAME];
char positionHistory[MAX_PLYS_PER_GAME][MAX_FEN_LEN];
} Game;
typedef struct {
Move move;
int score;
} Node;
typedef struct {
int depth;
Position pos;
int* alpha;
int* beta;
BOOL verbose;
} ThreadInfo;
extern char FILES[8];
extern char RANKS[8];
extern Bitboard FILES_BB[8];
extern Bitboard RANKS_BB[8];
extern char INITIAL_FEN[];
extern Board INITIAL_BOARD;
extern int PIECE_VALUES[];
#define DOUBLED_PAWN_PENALTY (10)
#define ISOLATED_PAWN_PENALTY (20)
#define BACKWARDS_PAWN_PENALTY (8)
#define PASSED_PAWN_BONUS (20)
#define ROOK_SEMI_OPEN_FILE_BONUS (10)
#define ROOK_OPEN_FILE_BONUS (15)
#define ROOK_ON_SEVENTH_BONUS (20)
extern int PAWN_BONUS[];
extern int KNIGHT_BONUS[];
extern int BISHOP_BONUS[];
extern int KING_BONUS[];
extern int KING_ENDGAME_BONUS[];
extern int FLIP_VERTICAL[];
void getInitialGame(Game* game);
void getFenGame(Game* game, char fen[]);
void insertPiece(Board* board, Bitboard position, char pieceCode);
int loadFen(Position* position, char fen[]);
int toFen(char* fen, Position* position);
int toMinFen(char* fen, Position* position);
void getMovelistGame(Game* game, char moves[]);
// ========= UTILITY =========
BOOL fromInitial(Game* game);
Bitboard index2bb(int index);
int str2index(char* str);
Bitboard str2bb(char* str);
BOOL isSet(Bitboard bb, int index);
Bitboard lsb(Bitboard bb);
Bitboard msb(Bitboard bb);
int bb2index(Bitboard bb);
char* movelist2str(Game* game);
Move getLastMove(Game* game);
BOOL startsWith(const char* str, const char* pre);
int countBookOccurrences(Game* game);
Move getBookMove(Game* game);
char getFile(int position);
char getRank(int position);
Move generateMove(int leavingSquare, int arrivingSquare);
int getFrom(Move move);
int getTo(Move move);
int char2piece(char pieceCode);
int bb2piece(Bitboard position, Board* board);
char bb2char(Bitboard position, Board* board);
char* bb2str(Bitboard position, Board* board);
void printBitboard(Bitboard bitboard);
char getPieceChar(Bitboard position, Board* board);
void printBoard(Board* board);
void printGame(Game* game);
Bitboard not(Bitboard bb);
char opponent(char color);
int countBits(Bitboard bb);
void sortNodes(Node* sortedNodes, Node* nodes, int len, char color);
void printMove(Move move);
void printFullMove(Move move, Board* board);
void printLegalMoves(Position* position);
void printNode(Node node);
void getTimestamp(char* timestamp);
void dumpContent(Game* game);
void dumpPGN(Game* game, char color, BOOL hasAI);
void move2str(char* str, Game* game, int moveNumber);
BOOL isAmbiguous(Position* posBefore, Move move);
unsigned long hashPosition(Position* position);
void writeToHashFile(Position* position, int evaluation, int depth);
// ====== BOARD FILTERS ======
Bitboard getColoredPieces(Board* board, char color);
Bitboard getEmptySquares(Board* board);
Bitboard getOccupiedSquares(Board* board);
Bitboard getTwinPieces(Bitboard position, Board* board);
Bitboard fileFilter(Bitboard positions);
Bitboard rankFilter(Bitboard positions);
// ======= DIRECTIONS ========
Bitboard east(Bitboard bb);
Bitboard west(Bitboard bb);
Bitboard north(Bitboard bb);
Bitboard south(Bitboard bb);
Bitboard NE(Bitboard bb);
Bitboard NW(Bitboard bb);
Bitboard SE(Bitboard bb);
Bitboard SW(Bitboard bb);
Bitboard WNW(Bitboard moving_piece);
Bitboard ENE(Bitboard moving_piece);
Bitboard NNW(Bitboard moving_piece);
Bitboard NNE(Bitboard moving_piece);
Bitboard ESE(Bitboard moving_piece);
Bitboard WSW(Bitboard moving_piece);
Bitboard SSE(Bitboard moving_piece);
Bitboard SSW(Bitboard moving_piece);
// ========== PAWN ===========
Bitboard getPawns(Board* board);
Bitboard pawnSimplePushes(Bitboard moving_piece, Board* board, char color);
Bitboard pawnDoublePushes(Bitboard moving_piece, Board* board, char color);
Bitboard pawnPushes(Bitboard moving_piece, Board* board, char color);
Bitboard pawnEastAttacks(Bitboard moving_piece, Board* board, char color);
Bitboard pawnWestAttacks(Bitboard moving_piece, Board* board, char color);
Bitboard pawnAttacks(Bitboard moving_piece, Board* board, char color);
Bitboard pawnSimpleCaptures(Bitboard moving_piece, Board* board, char color);
Bitboard pawnEpCaptures(Bitboard moving_piece, Position* position, char color);
Bitboard pawnCaptures(Bitboard moving_piece, Position* position, char color);
Bitboard pawnMoves(Bitboard moving_piece, Position* position, char color);
BOOL isDoublePush(int leaving, int arriving);
char getEpSquare(int leaving);
BOOL isDoubledPawn(Bitboard position, Board* board, char color);
BOOL isIsolatedPawn(Bitboard position, Board* board, char color);
BOOL isBackwardsPawn(Bitboard position, Board* board, char color);
BOOL isPassedPawn(Bitboard position, Board* board, char color);
BOOL isOpenFile(Bitboard position, Board* board);
BOOL isSemiOpenFile(Bitboard position, Board* board);
// ========== KNIGHT =========
Bitboard getKnights(Board* board);
Bitboard knightAttacks(Bitboard moving_piece);
Bitboard knightMoves(Bitboard moving_piece, Board* board, char color);
// ========== KING ===========
Bitboard getKing(Board* board, char color);
Bitboard kingAttacks(Bitboard moving_piece);
Bitboard kingMoves(Bitboard moving_piece, Board* board, char color);
BOOL canCastleKingside(Position* position, char color);
BOOL canCastleQueenside(Position* position, char color);
char removeCastlingRights(char original_rights, char removed_rights);
// ========== BISHOP =========
Bitboard getBishops(Board* board);
Bitboard NE_ray(Bitboard bb);
Bitboard SE_ray(Bitboard bb);
Bitboard NW_ray(Bitboard bb);
Bitboard SW_ray(Bitboard bb);
Bitboard NE_attack(Bitboard single_piece, Board* board, char color);
Bitboard NW_attack(Bitboard single_piece, Board* board, char color);
Bitboard SE_attack(Bitboard single_piece, Board* board, char color);
Bitboard SW_attack(Bitboard single_piece, Board* board, char color);
Bitboard diagonalAttacks(Bitboard single_piece, Board* board, char color);
Bitboard antiDiagonalAttacks(Bitboard single_piece, Board* board, char color);
Bitboard bishopAttacks(Bitboard moving_pieces, Board* board, char color);
Bitboard bishopMoves(Bitboard moving_piece, Board* board, char color);
// ========== ROOK ===========
Bitboard getRooks(Board* board);
Bitboard northRay(Bitboard moving_pieces);
Bitboard southRay(Bitboard moving_pieces);
Bitboard eastRay(Bitboard moving_pieces);
Bitboard westRay(Bitboard moving_pieces);
Bitboard northAttack(Bitboard single_piece, Board* board, char color);
Bitboard southAttack(Bitboard single_piece, Board* board, char color);
Bitboard fileAttacks(Bitboard single_piece, Board* board, char color);
Bitboard eastAttack(Bitboard single_piece, Board* board, char color);
Bitboard westAttack(Bitboard single_piece, Board* board, char color);
Bitboard rankAttacks(Bitboard single_piece, Board* board, char color);
Bitboard rookAttacks(Bitboard moving_piece, Board* board, char color);
Bitboard rookMoves(Bitboard moving_piece, Board* board, char color);
// ========== QUEEN ==========
Bitboard getQueens(Board* board);
Bitboard queenAttacks(Bitboard moving_piece, Board* board, char color);
Bitboard queenMoves(Bitboard moving_piece, Board* board, char color);
// ======== MAKE MOVE ========
void clearPositions(Board* board, Bitboard positions);
void movePiece(Board* board, Move move);
void updatePosition(Position* newPosition, Position* position, Move move);
void makeMove(Game* game, Move move);
void unmakeMove(Game* game);
// ======== MOVE GEN =========
Bitboard getMoves(Bitboard movingPiece, Position* position, char color);
int pseudoLegalMoves(Move* moves, Position* position, char color);
Bitboard getAttacks(Bitboard movingPiece, Board* board, char color);
int countAttacks(Bitboard target, Board* board, char color);
BOOL isAttacked(Bitboard target, Board* board, char color);
BOOL isCheck(Board* board, char color);
BOOL isLegalMove(Position* position, Move move);
int legalMoves(Move* legalMoves, Position* position, char color);
int legalMovesCount(Position* position, char color);
int staticOrderLegalMoves(Move* orderedLegalMoves, Position* position, char color);
int legalCaptures(Move* legalCaptures, Position* position, char color);
// ====== GAME CONTROL =======
BOOL isCheckmate(Position* position);
BOOL isStalemate(Position* position);
BOOL hasInsufficientMaterial(Board* board);
BOOL isEndgame(Board* board);
BOOL isOver75MovesRule(Position* position);
BOOL hasGameEnded(Position* position);
void printOutcome(Position* position);
// ========== EVAL ===========
int winScore(char color);
int materialSum(Board* board, char color);
int materialBalance(Board* board);
int positionalBonus(Board* board, char color);
int positionalBalance(Board* board);
int endNodeEvaluation(Position* position);
int staticEvaluation(Position* position);
int getCaptureSequence(Move* captures, Position* position, int targetSquare);
int staticExchangeEvaluation(Position* position, int targetSquare);
int quiescenceEvaluation(Position* position);
// ========= SEARCH ==========
Node staticSearch(Position* position);
Node quiescenceSearch(Position* position);
Node alphaBeta(Position* position, char depth, int alpha, int beta);
int alphaBetaNodes(Node* nodes, Position* position, char depth);
Node iterativeDeepeningAlphaBeta(Position* position, char depth, int alpha, int beta, BOOL verbose);
Node pIDAB(Position* position, char depth, int* p_alpha, int* p_beta);
Node pIDABhashed(Position* position, char depth, int* p_alpha, int* p_beta);
Move getRandomMove(Position* position);
Move getAIMove(Game* game, int depth);
Move parseMove(char* move);
Move getPlayerMove();
Move suggestMove(char fen[], int depth);
// Parallel processing currently only implemented for Windows
#ifdef _WIN32
DWORD WINAPI evaluatePositionThreadFunction(LPVOID lpParam);
DWORD WINAPI evaluatePositionThreadFunctionHashed(LPVOID lpParam);
Node idabThreaded(Position* position, int depth, BOOL verbose);
Node idabThreadedBestFirst(Position* position, int depth, BOOL verbose);
Node idabThreadedBestFirstHashed(Position* position, int depth, BOOL verbose);
#endif
// ===== PLAY LOOP (TEXT) ====
void playTextWhite(int depth);
void playTextBlack(int depth);
void playTextAs(char color, int depth);
void playTextRandomColor(int depth);
// ===========================
#endif /* FAST_CHESS_H_ */