Professional Documents
Culture Documents
// INCLUDE
/////////////////////////////////
#include <iostream>
#include <conio.h>
#include <fstream>
#include <intrin.h>
#include <map>
#include <string>
#include <stdlib.h>
#include <time.h>
#include <vector>
#include <windows.h>
#include <wincon.h>
//#include "headers.h"
#pragma intrinsic(_BitScanForward64)
#pragma intrinsic(__rdtsc)
/////////////////////////////////
// NAMESPACE
/////////////////////////////////
using namespace std;
/////////////////////////////////
// SETTINGS
/////////////////////////////////
bool aiVsAi = false;
bool aiIsWhite = aiVsAi || false;
bool aiThinking = aiIsWhite;
bool boardTurned = aiIsWhite && !aiVsAi;
float infinity = 9999999.0f;
bool promoting = false;
short promoteTo = 3;
int searchDepth = 5;
/////////////////////////////////
// CLASSES
/////////////////////////////////
class bitboard {
public:
/////////////////////////////////
// MEMBERS
/////////////////////////////////
bool turn, whiteCastlingOO, whiteCastlingOOO, blackCastlingOO, b
lackCastlingOOO;
unsigned __int64 whitePawn, whiteKnight, whiteBishop, whiteRook,
whiteQueen, whiteKing, blackPawn, blackKnight, blackBishop, blackRook, blackQue
en, blackKing, enPassiant, white, black, all;
int numMoves;
bitboard* moves;
/////////////////////////////////
// CONSTRUCTOR & DESTRUCTOR
/////////////////////////////////
~bitboard() {
delete &turn;
delete &whiteCastlingOO;
delete &whiteCastlingOOO;
delete &blackCastlingOO;
delete &blackCastlingOOO;
delete &whitePawn;
delete &whiteKnight;
delete &whiteBishop;
delete &whiteRook;
delete &whiteQueen;
delete &whiteKing;
delete &blackPawn;
delete &blackKnight;
delete &blackBishop;
delete &blackRook;
delete &blackQueen;
delete &blackKing;
delete &enPassiant;
delete &white;
delete &black;
delete &all;
delete &numMoves;
delete[] moves;
}
/////////////////////////////////
// METHODS
/////////////////////////////////
void setToNewGame();
void buildBitboard();
void destroy();
void copyTo(bitboard* copy);
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
__int64
__int64
__int64
__int64
__int64
__int64
unsigned
unsigned
unsigned
unsigned
unsigned
unsigned
__int64
__int64
__int64
__int64
__int64
__int64
* to);
void makeWhiteKingMove(unsigned __int64* from, unsigned __int64*
to);
void makeBlackPawnMove(unsigned __int64* from, unsigned __int64*
to);
void makeBlackKnightMove(unsigned __int64* from, unsigned __int6
4* to);
void makeBlackBishopMove(unsigned __int64* from, unsigned __int6
4* to);
void makeBlackRookMove(unsigned __int64* from, unsigned __int64*
to);
void makeBlackQueenMove(unsigned __int64* from, unsigned __int64
* to);
void makeBlackKingMove(unsigned __int64* from, unsigned __int64*
to);
bool whiteInCheck();
bool blackInCheck();
void getMoves();
float evaluate();
float gameOver();
float alphaBeta(int depth, float a, float b);
} game;
class Interface {
public:
bool boardTurned;
void init() {
}
void updateBoard() {
}
} gameInterface;
/////////////////////////////////
// VARIABLES
/////////////////////////////////
int gameLength = 0;
bitboard gameHistory[999] = {};
int i, j, k, x, y, squareColor, index, kingIndex, growIndex, fromIndex, toIndex,
historyIndex, promoteIndex;
unsigned __int64 bit, selection, tempBit, indexBit, blocking, legalMoves, ev, ch
angeWhite, changeBlack;
unsigned __int64* indexBitPtr = &indexBit;
unsigned __int64 fromBit, toBit;
char fromCoordinate[2], toCoordinate[2], piece;
bitboard* tempMoves = new bitboard[218];
bitboard* tempCaptures = new bitboard[218];
float best, e;
HANDLE handle = GetStdHandle(STD_OUTPUT_HANDLE);
/////////////////////////////////
// INTERFACE
/////////////////////////////////
char
char
char
char
char
char
pawnChar = 127;
knightChar = 156;
bishopChar = '&';
rookChar = 35;
queenChar = 12;
kingChar = 11;
f1a
f1b
f1c
f1d
f1e
f1f
=
=
=
=
=
=
205;
186;
187;
201;
188;
200;
char c1 = 26;
char c2 = 174;
char c3 = 175;
char cursor = 30;
#define
#define
#define
#define
#define
#define
selectionColor 144
selectedPieceColor 288
lightSquareColor 208
darkSquareColor 192
whitePieceColor 15
blackPieceColor 0
#define
#define
#define
#define
frameColor 12
cornerColor 4
writeColor 15
textColor 8
/////////////////////////////////
// SQUARES
/////////////////////////////////
static const unsigned __int64 squares[64] = {1ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32UL
L, 64ULL, 128ULL, 256ULL, 512ULL, 1024ULL, 2048ULL, 4096ULL, 8192ULL, 16384ULL,
32768ULL, 65536ULL, 131072ULL, 262144ULL, 524288ULL, 1048576ULL, 2097152ULL, 419
4304ULL, 8388608ULL, 16777216ULL, 33554432ULL, 67108864ULL, 134217728ULL, 268435
456ULL, 536870912ULL, 1073741824ULL, 2147483648ULL, 4294967296ULL, 8589934592ULL
, 17179869184ULL, 34359738368ULL, 68719476736ULL, 137438953472ULL, 274877906944U
LL, 549755813888ULL, 1099511627776ULL, 2199023255552ULL, 4398046511104ULL, 87960
93022208ULL, 17592186044416ULL, 35184372088832ULL, 70368744177664ULL, 1407374883
55328ULL, 281474976710656ULL, 562949953421312ULL, 1125899906842624ULL, 225179981
3685248ULL, 4503599627370496ULL, 9007199254740992ULL, 18014398509481984ULL, 3602
8797018963968ULL, 72057594037927936ULL, 144115188075855872ULL, 28823037615171174
4ULL, 576460752303423488ULL, 1152921504606846976ULL, 2305843009213693952ULL, 461
1686018427387904ULL, 9223372036854775808ULL};
static const unsigned __int64 files[8] = {72340172838076673ULL, 1446803456761533
46ULL, 289360691352306692ULL, 578721382704613384ULL, 1157442765409226768ULL, 231
4885530818453536ULL, 4629771061636907072ULL, 9259542123273814144ULL};
static const unsigned __int64 ranks[8] = {255ULL, 65280ULL, 16711680ULL, 4278190
080ULL, 1095216660480ULL, 280375465082880ULL, 71776119061217280ULL, 183746864796
71623680ULL};
static const unsigned __int64 positiveDiagonals[15] = {1ULL, 258ULL, 66052ULL, 1
6909320ULL, 4328785936ULL, 1108169199648ULL, 283691315109952ULL, 726249766681478
40ULL, 145249953336295424ULL, 290499906672525312ULL, 580999813328273408ULL, 1161
999622361579520ULL, 2323998145211531264ULL, 4647714815446351872ULL, 922337203685
4775808ULL};
static const unsigned __int64 negativeDiagonals[15] = {128ULL, 32832ULL, 8405024
ULL, 2151686160ULL, 550831656968ULL, 141012904183812ULL, 36099303471055874ULL, 9
241421688590303745ULL, 4620710844295151872ULL, 2310355422147575808ULL, 115517771
1073755136ULL, 577588855528488960ULL, 288794425616760832ULL, 144396663052566528U
LL, 72057594037927936ULL};
static const unsigned __int64 whitePawnMovement[64] = {0ULL, 0ULL, 0ULL, 0ULL, 0
ULL, 0ULL, 0ULL, 0ULL, 16842752ULL, 33685504ULL, 67371008ULL, 134742016ULL, 2694
84032ULL, 538968064ULL, 1077936128ULL, 2155872256ULL, 16777216ULL, 33554432ULL,
67108864ULL, 134217728ULL, 268435456ULL, 536870912ULL, 1073741824ULL, 2147483648
ULL, 4294967296ULL, 8589934592ULL, 17179869184ULL, 34359738368ULL, 68719476736UL
L, 137438953472ULL, 274877906944ULL, 549755813888ULL, 1099511627776ULL, 21990232
55552ULL, 4398046511104ULL, 8796093022208ULL, 17592186044416ULL, 35184372088832U
LL, 70368744177664ULL, 140737488355328ULL, 281474976710656ULL, 562949953421312UL
L, 1125899906842624ULL,2251799813685248ULL, 4503599627370496ULL, 900719925474099
2ULL, 18014398509481984ULL, 36028797018963968ULL, 72057594037927936ULL, 14411518
8075855872ULL, 288230376151711744ULL, 576460752303423488ULL, 1152921504606846976
ULL, 2305843009213693952ULL, 4611686018427387904ULL, 9223372036854775808ULL, 0UL
L, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
static const unsigned __int64 whitePawnCapture[64] = {512ULL, 1280ULL, 2560ULL,
5120ULL, 10240ULL, 20480ULL, 40960ULL, 16384ULL, 131072ULL, 327680ULL, 655360ULL
, 1310720ULL, 2621440ULL, 5242880ULL, 10485760ULL, 4194304ULL, 33554432ULL, 8388
6080ULL, 167772160ULL, 335544320ULL, 671088640ULL, 1342177280ULL, 2684354560ULL,
1073741824ULL, 8589934592ULL, 21474836480ULL, 42949672960ULL, 85899345920ULL, 1
71798691840ULL, 343597383680ULL, 687194767360ULL, 274877906944ULL, 2199023255552
ULL, 5497558138880ULL, 10995116277760ULL, 21990232555520ULL, 43980465111040ULL,
87960930222080ULL, 175921860444160ULL, 70368744177664ULL, 562949953421312ULL, 14
07374883553280ULL, 2814749767106560ULL, 5629499534213120ULL, 11258999068426240UL
L, 22517998136852480ULL, 45035996273704960ULL, 18014398509481984ULL, 14411518807
5855872ULL, 360287970189639680ULL, 720575940379279360ULL, 1441151880758558720ULL
, 2882303761517117440ULL, 5764607523034234880ULL, 11529215046068469760ULL, 46116
86018427387904ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
static const unsigned __int64 blackPawnMovement[64] = {0ULL, 0ULL, 0ULL, 0ULL, 0
ULL, 0ULL, 0ULL, 0ULL, 1ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32ULL, 64ULL, 128ULL, 256U
LL, 512ULL, 1024ULL, 2048ULL, 4096ULL, 8192ULL, 16384ULL, 32768ULL, 65536ULL, 13
1072ULL, 262144ULL, 524288ULL, 1048576ULL, 2097152ULL, 4194304ULL, 8388608ULL, 1
6777216ULL, 33554432ULL, 67108864ULL, 134217728ULL, 268435456ULL, 536870912ULL,
1073741824ULL, 2147483648ULL, 4294967296ULL, 8589934592ULL, 17179869184ULL, 3435
9738368ULL, 68719476736ULL, 137438953472ULL, 274877906944ULL, 549755813888ULL, 1
103806595072ULL, 2207613190144ULL, 4415226380288ULL, 8830452760576ULL, 176609055
21152ULL, 35321811042304ULL, 70643622084608ULL, 141287244169216ULL, 0ULL, 0ULL,
0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
static const unsigned __int64 blackPawnCapture[64] = {0ULL, 0ULL, 0ULL, 0ULL, 0U
LL, 0ULL, 0ULL, 0ULL, 2ULL, 5ULL, 10ULL, 20ULL, 40ULL, 80ULL, 160ULL, 64ULL, 512
ULL, 1280ULL, 2560ULL, 5120ULL, 10240ULL, 20480ULL, 40960ULL, 16384ULL, 131072UL
L, 327680ULL, 655360ULL, 1310720ULL, 2621440ULL, 5242880ULL, 10485760ULL, 419430
4ULL, 33554432ULL, 83886080ULL, 167772160ULL, 335544320ULL, 671088640ULL, 134217
7280ULL, 2684354560ULL, 1073741824ULL, 8589934592ULL, 21474836480ULL, 4294967296
0ULL, 85899345920ULL, 171798691840ULL, 343597383680ULL, 687194767360ULL, 2748779
06944ULL, 2199023255552ULL, 5497558138880ULL, 10995116277760ULL, 21990232555520U
LL, 43980465111040ULL, 87960930222080ULL, 175921860444160ULL, 70368744177664ULL,
562949953421312ULL, 1407374883553280ULL, 2814749767106560ULL, 5629499534213120U
LL, 11258999068426240ULL, 22517998136852480ULL, 45035996273704960ULL, 1801439850
9481984ULL};
whiteRookCastlingOO 5ULL
whiteRookCastlingOOO 144ULL
blackRookCastlingOO 360287970189639680ULL
blackRookCastlingOOO 10376293541461622784ULL
unsigned
unsigned
unsigned
unsigned
__int64
__int64
__int64
__int64
whiteKingCastlingOO = 2ULL;
whiteKingCastlingOOO = 32ULL;
blackKingCastlingOO = 144115188075855872ULL;
blackKingCastlingOOO = 2305843009213693952ULL;
#define
#define
#define
#define
whiteCastlingOOEmpty 4ULL
whiteCastlingOOOEmpty 112ULL
blackCastlingOOEmpty 432345564227567616ULL
blackCastlingOOOEmpty 8070450532247928832ULL
#define
#define
#define
#define
rightDownCorner 1ULL
leftDownCorner 128ULL
rightUpCorner 72057594037927936ULL
leftUpCorner 9223372036854775808ULL
/////////////////////////////////
// Evaluation parameters
/////////////////////////////////
float
float
float
float
float
float
pawnValue = 1.0f;
knightValue = 3.0f;
bishopValue = 3.33f;
rookValue = 5.0f;
queenValue = 9.0f;
kingValue = 40.0f;
/////////////////////////////////
// HEADERS
/////////////////////////////////
void coutBitboard(unsigned __int64* b);
void cinBitboard();
unsigned __int64 intPow(int a, int b);
int coordinateToIndex(char c[]);
int bitToIndex(unsigned __int64* bit);
whiteCastlingOO = false;
whiteCastlingOOO = false;
blackCastlingOO = true;
blackCastlingOOO = true;
whitePawn = 4431561216ULL;
whiteKnight = 2ULL;
whiteBishop = 4ULL;
whiteRook = 129ULL;
whiteQueen = 16ULL;
whiteKing = 2048ULL;
blackPawn = 37440948443021312ULL;
blackKnight = 268435456ULL>>6;
blackBishop = 0ULL;
blackRook = 9295429630892703744ULL;
blackQueen = 70368744177664ULL;
blackKing = 576460752303423488ULL;
enPassiant = 0ULL;*/
void bitboard::destroy() {
delete this;
}
void bitboard::buildBitboard() {
white = whitePawn | whiteKnight | whiteBishop | whiteRook | whiteQueen |
whiteKing;
black = blackPawn | blackKnight | blackBishop | blackRook | blackQueen |
blackKing;
all = white | black;
}
void bitboard::copyTo(bitboard* copy) {
copy->turn = turn;
copy->whiteCastlingOO = whiteCastlingOO;
copy->whiteCastlingOOO = whiteCastlingOOO;
copy->blackCastlingOO = blackCastlingOO;
copy->blackCastlingOOO = blackCastlingOOO;
copy->whitePawn = whitePawn;
copy->whiteKnight = whiteKnight;
copy->whiteBishop = whiteBishop;
copy->whiteRook = whiteRook;
copy->whiteQueen = whiteQueen;
copy->whiteKing = whiteKing;
copy->blackPawn = blackPawn;
copy->blackKnight = blackKnight;
copy->blackBishop = blackBishop;
copy->blackRook = blackRook;
copy->blackQueen = blackQueen;
copy->blackKing = blackKing;
copy->enPassiant = enPassiant;
copy->white = white;
copy->black = black;
copy->all = all;
}
unsigned __int64 bitboard::whitePawnMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
if (all&(*piece<<8)) selection = 0;
else selection = whitePawnMovement[index]&~all;
selection |= whitePawnCapture[index]&(black|enPassiant);
return selection&~(white);
}
unsigned __int64 bitboard::whiteKnightMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
selection = knightMovement[index];
return selection&~(white);
}
unsigned __int64 bitboard::whiteBishopMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
selection = bishopMovement[index];
blocking = *LS1B(rightUpRay[index]&all);
if (blocking) selection ^= rightUpRay[bitToIndex(&blocking)];
blocking = *LS1B(leftUpRay[index]&all);
if (blocking) selection ^= leftUpRay[bitToIndex(&blocking)];
blocking = *MS1B(rightDownRay[index]&all);
if (blocking) selection ^= rightDownRay[bitToIndex(&blocking)];
blocking = *MS1B(leftDownRay[index]&all);
if (blocking) selection ^= leftDownRay[bitToIndex(&blocking)];
return selection&~(white);
}
unsigned __int64 bitboard::whiteRookMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
selection = rookMovement[index];
blocking = *MS1B(rightRay[index]&all);
if (blocking) selection ^= rightRay[bitToIndex(&blocking)];
blocking = *LS1B(leftRay[index]&all);
if (blocking) selection ^= leftRay[bitToIndex(&blocking)];
blocking = *LS1B(upRay[index]&all);
if (blocking) selection ^= upRay[bitToIndex(&blocking)];
blocking = *MS1B(downRay[index]&all);
if (blocking) selection ^= downRay[bitToIndex(&blocking)];
return selection&~(white);
}
unsigned __int64 bitboard::whiteQueenMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
selection = queenMovement[index];
blocking = *LS1B(rightUpRay[index]&all);
if (blocking) selection ^= rightUpRay[bitToIndex(&blocking)];
blocking = *LS1B(leftUpRay[index]&all);
if (blocking) selection ^= leftUpRay[bitToIndex(&blocking)];
blocking = *MS1B(rightDownRay[index]&all);
if (blocking) selection ^= rightDownRay[bitToIndex(&blocking)];
blocking = *MS1B(leftDownRay[index]&all);
if (blocking) selection ^= leftDownRay[bitToIndex(&blocking)];
blocking = *MS1B(rightRay[index]&all);
if (blocking) selection ^= rightRay[bitToIndex(&blocking)];
blocking = *LS1B(leftRay[index]&all);
if (blocking) selection ^= leftRay[bitToIndex(&blocking)];
blocking = *LS1B(upRay[index]&all);
if (blocking) selection ^= upRay[bitToIndex(&blocking)];
blocking = *MS1B(downRay[index]&all);
if (blocking) selection ^= downRay[bitToIndex(&blocking)];
return selection&~(white);
}
blocking = *MS1B(rightRay[index]&all);
if (blocking) selection ^= rightRay[bitToIndex(&blocking)];
blocking = *LS1B(leftRay[index]&all);
if (blocking) selection ^= leftRay[bitToIndex(&blocking)];
blocking = *LS1B(upRay[index]&all);
if (blocking) selection ^= upRay[bitToIndex(&blocking)];
blocking = *MS1B(downRay[index]&all);
if (blocking) selection ^= downRay[bitToIndex(&blocking)];
return selection&~(black);
}
unsigned __int64 bitboard::blackKingMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
selection = kingMovement[index];
return selection&~(black);
}
unsigned __int64* bitboard::getWhitePiece(unsigned __int64* bit) {
if ((*bit)&whitePawn) {
return &whitePawn;
} else if ((*bit)&whiteKnight) {
return &whiteKnight;
} else if ((*bit)&whiteBishop) {
return &whiteBishop;
} else if ((*bit)&whiteRook) {
return &whiteRook;
} else if ((*bit)&whiteQueen) {
return &whiteQueen;
} else if ((*bit)&whiteKing) {
return &whiteKing;
} else {
/*/updateBoard();
coutBitboard(bit);
coutBitboard(&(all));
coutBitboard(&(white));
coutBitboard(&(whitePawn));
coutBitboard(&(whiteKnight));
coutBitboard(&(whiteBishop));
coutBitboard(&(whiteRook));
coutBitboard(&(whiteQueen));
coutBitboard(&(whiteKing));
0;//*/
}
return 0;
}
unsigned __int64* bitboard::getBlackPiece(unsigned __int64* bit) {
if ((*bit)&blackPawn) {
return &blackPawn;
} else if ((*bit)&blackKnight) {
return &blackKnight;
} else if ((*bit)&blackBishop) {
return &blackBishop;
} else if ((*bit)&blackRook) {
return &blackRook;
} else if ((*bit)&blackQueen) {
return &blackQueen;
} else if ((*bit)&blackKing) {
return &blackKing;
} else {
//
//updateBoard();
getch();
coutBitboard(bit);
getch();
coutBitboard(&(all));
getch();
coutBitboard(&(black));
getch();
coutBitboard(&(blackPawn));
getch();
coutBitboard(&(blackKnight));
getch();
coutBitboard(&(blackBishop));
getch();
coutBitboard(&(blackRook));
getch();
coutBitboard(&(blackQueen));
getch();
coutBitboard(&(blackKing));
getch();
0;//*/
}
return 0;
}
void bitboard::makeWhitePawnMove(unsigned __int64* from, unsigned __int64* to) {
whitePawn ^= *from|(*to);
if (*to == enPassiant) blackPawn ^= enPassiant>>8;
enPassiant = 0;
if ((*to)&72057594037927935) {
whitePawn |= *to;
if (*from<=32768 && *to>8388608) enPassiant = *from<<8;
}
if ((*to)&black) { // Capture black
*getBlackPiece(to) ^= *to;
}
buildBitboard();
turn = false;
}
void bitboard::makeWhiteKnightMove(unsigned __int64* from, unsigned __int64* to)
{
whiteKnight ^= *from|(*to);
if ((*to)&black) { // Capture black
*getBlackPiece(to) ^= *to;
}
buildBitboard();
enPassiant = 0;
turn = false;
}
void bitboard::makeWhiteBishopMove(unsigned __int64* from, unsigned __int64* to)
{
whiteBishop ^= *from|(*to);
if ((*to)&black) { // Capture black
*getBlackPiece(to) ^= *to;
}
buildBitboard();
enPassiant = 0;
turn = false;
}
void bitboard::makeWhiteRookMove(unsigned __int64* from, unsigned __int64* to) {
whiteRook ^= *from|(*to);
if (*from == 128) whiteCastlingOOO = false;
else if (*from == 8) whiteCastlingOO = whiteCastlingOOO = false;
if ((*to)&black) { // Capture black
*getBlackPiece(to) ^= *to;
}
if (*from|(*to) == rightDownCorner) whiteCastlingOO = false;
else if (*from|(*to) == leftDownCorner) whiteCastlingOOO = false;
buildBitboard();
enPassiant = 0;
turn = false;
}
void bitboard::makeWhiteQueenMove(unsigned __int64* from, unsigned __int64* to)
{
whiteQueen ^= *from|(*to);
if ((*to)&black) { // Capture black
*getBlackPiece(to) ^= *to;
}
buildBitboard();
enPassiant = 0;
turn = false;
}
void bitboard::makeWhiteKingMove(unsigned __int64* from, unsigned __int64* to) {
whiteKing ^= *from|(*to);
if ((*to)&black) { // Capture black
*getBlackPiece(to) ^= *to;
}
whiteCastlingOO = whiteCastlingOOO = false;
buildBitboard();
enPassiant = 0;
turn = false;
}
void bitboard::makeBlackPawnMove(unsigned __int64* from, unsigned __int64* to) {
blackPawn ^= *from|(*to);
if (*to == enPassiant) whitePawn ^= enPassiant<<8;
enPassiant = 0;
if ((*to)&18446744073709551360) {
blackPawn |= *to;
if (*from>140737488355328 && *to<=549755813888) enPassiant = *fr
om>>8;
}
if ((*to)&white) { // Capture white
*getWhitePiece(to) ^= *to;
}
buildBitboard();
turn = true;
}
void bitboard::makeBlackKnightMove(unsigned __int64* from, unsigned __int64* to)
{
blackKnight ^= *from|(*to);
if ((*to)&white) { // Capture white
*getWhitePiece(to) ^= *to;
}
buildBitboard();
enPassiant = 0;
turn = true;
}
void bitboard::makeBlackBishopMove(unsigned __int64* from, unsigned __int64* to)
{
blackBishop ^= *from|(*to);
if ((*to)&white) { // Capture white
*getWhitePiece(to) ^= *to;
}
buildBitboard();
enPassiant = 0;
turn = true;
}
void bitboard::makeBlackRookMove(unsigned __int64* from, unsigned __int64* to) {
blackRook ^= *from|(*to);
if ((*to)&white) { // Capture white
*getWhitePiece(to) ^= *to;
}
if (*from|(*to) == rightUpCorner) blackCastlingOO = false;
else if (*from|(*to) == leftUpCorner) blackCastlingOOO = false;
buildBitboard();
enPassiant = 0;
turn = true;
}
void bitboard::makeBlackQueenMove(unsigned __int64* from, unsigned __int64* to)
{
blackQueen ^= *from|(*to);
if ((*to)&white) { // Capture white
*getWhitePiece(to) ^= *to;
}
buildBitboard();
enPassiant = 0;
turn = true;
}
void bitboard::makeBlackKingMove(unsigned __int64* from, unsigned __int64* to) {
blackKing ^= *from|(*to);
if ((*to)&white) { // Capture white
*getWhitePiece(to) ^= *to;
}
blackCastlingOO = blackCastlingOOO = false;
buildBitboard();
enPassiant = 0;
turn = true;
}
bool bitboard::whiteInCheck() {
int kingIndex = bitToIndex(&(whiteKing));
if (whitePawnCapture[kingIndex] & blackPawn) return true; // PAWN
else if (knightMovement[kingIndex] & blackKnight) return true; // KNIGHT
legalMoves = bishopMovement[kingIndex];
blocking = *LS1B(rightUpRay[kingIndex]&all);
if (blocking) legalMoves ^= rightUpRay[bitToIndex(&blocking)];
blocking = *LS1B(leftUpRay[kingIndex]&all);
if (blocking) legalMoves ^= leftUpRay[bitToIndex(&blocking)];
blocking = *MS1B(rightDownRay[kingIndex]&all);
if (blocking) legalMoves ^= rightDownRay[bitToIndex(&blocking)];
blocking = *MS1B(leftDownRay[kingIndex]&all);
if (blocking) legalMoves ^= leftDownRay[bitToIndex(&blocking)];
if (legalMoves&(blackBishop|blackQueen)) return true; // BISHOP | QUEEN
legalMoves = rookMovement[kingIndex];
blocking = *MS1B(rightRay[kingIndex]&all);
if (blocking) legalMoves ^= rightRay[bitToIndex(&blocking)];
blocking = *LS1B(leftRay[kingIndex]&all);
if (blocking) legalMoves ^= leftRay[bitToIndex(&blocking)];
blocking = *LS1B(upRay[kingIndex]&all);
if (blocking) legalMoves ^= upRay[bitToIndex(&blocking)];
blocking = *MS1B(downRay[kingIndex]&all);
if (blocking) legalMoves ^= downRay[bitToIndex(&blocking)];
if (legalMoves&(blackRook|blackQueen)) return true; // ROOK | QUEEN
if (kingMovement[kingIndex] & blackKing) return true; // KING
return false;
}
bool bitboard::blackInCheck() {
int kingIndex = bitToIndex(&(blackKing));
if (blackPawnCapture[kingIndex] & whitePawn) return true; // PAWN
else if (knightMovement[kingIndex] & whiteKnight) return true; // KNIGHT
legalMoves = bishopMovement[kingIndex];
blocking = *LS1B(rightUpRay[kingIndex]&all);
if (blocking) legalMoves ^= rightUpRay[bitToIndex(&blocking)];
blocking = *LS1B(leftUpRay[kingIndex]&all);
if (blocking) legalMoves ^= leftUpRay[bitToIndex(&blocking)];
blocking = *MS1B(rightDownRay[kingIndex]&all);
if (blocking) legalMoves ^= rightDownRay[bitToIndex(&blocking)];
blocking = *MS1B(leftDownRay[kingIndex]&all);
if (blocking) legalMoves ^= leftDownRay[bitToIndex(&blocking)];
if (legalMoves&(whiteBishop|whiteQueen)) return true; // BISHOP | QUEEN
legalMoves = rookMovement[kingIndex];
blocking = *MS1B(rightRay[kingIndex]&all);
if (blocking) legalMoves ^= rightRay[bitToIndex(&blocking)];
blocking = *LS1B(leftRay[kingIndex]&all);
].whiteKnight |= toBit;
tempCaptures[numCaptures
].whitePawn ^= toBit;
tempCaptures[numCaptures
++].buildBitboard();
tempCaptures[numCaptures
].whiteBishop |= toBit;
tempCaptures[numCaptures
].whitePawn ^= toBit;
tempCaptures[numCaptures
++].buildBitboard();
}
}
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhitePawnMove(&f
romBit, &toBit);
if (!tempMoves[numMoves].whiteInCheck())
{
if (toBit&72057594037927935) {
numMoves++;
} else {
tempMoves[numMoves].copy
To(&tempCaptures[numCaptures]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+1]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+2]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+3]);
tempCaptures[numCaptures
].whiteQueen |= toBit;
tempCaptures[numCaptures
].whitePawn ^= toBit;
tempCaptures[numCaptures
++].buildBitboard();
tempCaptures[numCaptures
].whiteRook |= toBit;
tempCaptures[numCaptures
].whitePawn ^= toBit;
tempCaptures[numCaptures
++].buildBitboard();
tempCaptures[numCaptures
].whiteKnight |= toBit;
tempCaptures[numCaptures
].whitePawn ^= toBit;
tempCaptures[numCaptures
++].buildBitboard();
tempCaptures[numCaptures
].whiteBishop |= toBit;
tempCaptures[numCaptures
].whitePawn ^= toBit;
tempCaptures[numCaptures
++].buildBitboard();
}
}
}
}
}
tempBit = whiteKnight; // Knights
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = whiteKnightMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&black) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeWhiteKnigh
tMove(&fromBit, &toBit);
if (tempCaptures[numCaptures].whiteInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteKnightMove(
&fromBit, &toBit);
if (tempMoves[numMoves].whiteInCheck())
continue;
numMoves++;
}
}
}
tempBit = whiteBishop; // Bishops
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = whiteBishopMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&black) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeWhiteBisho
pMove(&fromBit, &toBit);
if (tempCaptures[numCaptures].whiteInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteBishopMove(
&fromBit, &toBit);
if (tempMoves[numMoves].whiteInCheck())
continue;
numMoves++;
}
}
}
tempBit = whiteRook; // Rooks
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = whiteRookMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&black) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeWhiteRookM
ove(&fromBit, &toBit);
if (tempCaptures[numCaptures].whiteInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteRookMove(&f
romBit, &toBit);
if (tempMoves[numMoves].whiteInCheck())
continue;
numMoves++;
}
}
}
tempBit = whiteQueen; // Queens
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = whiteQueenMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&black) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeWhiteQueen
Move(&fromBit, &toBit);
if (tempCaptures[numCaptures].whiteInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteQueenMove(&
fromBit, &toBit);
if (tempMoves[numMoves].whiteInCheck())
continue;
numMoves++;
}
}
}
tempBit = whiteKing; // Kings
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = whiteKingMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeWhiteKingM
ove(&fromBit, &toBit);
if (tempCaptures[numCaptures].whiteInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteKingMove(&f
romBit, &toBit);
if (tempMoves[numMoves].whiteInCheck())
continue;
numMoves++;
}
if (whiteCastlingOO && (toBit == 4) && !(white&w
hiteCastlingOOEmpty) && whiteRook&rightDownCorner) {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteKingMove(&f
romBit, &whiteKingCastlingOO);
if (!tempMoves[numMoves].whiteInCheck())
{
tempMoves[numMoves].whiteRook ^=
whiteRookCastlingOO;
tempMoves[numMoves].whiteCastlin
gOO = tempMoves[numMoves].whiteCastlingOOO = false;
tempMoves[numMoves++].buildBitbo
ard();
}
}
if (whiteCastlingOOO && (toBit == 16) && !(white
&whiteCastlingOOOEmpty) && whiteRook&leftDownCorner) {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeWhiteKingMove(&f
romBit, &whiteKingCastlingOOO);
if (!tempMoves[numMoves].whiteInCheck())
{
tempMoves[numMoves].whiteRook ^=
whiteRookCastlingOOO;
tempMoves[numMoves].whiteCastlin
gOO = tempMoves[numMoves].whiteCastlingOOO = false;
tempMoves[numMoves++].buildBitbo
ard();
}
}
}
}
} else { // Black
tempBit = blackPawn; // Pawns
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = blackPawnMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------promote = false;
if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeBlackPawnM
ove(&fromBit, &toBit);
if (!tempCaptures[numCaptures].blackInCh
eck()) {
if (toBit&18446744073709551360)
{
numCaptures++;
} else {
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+1]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+2]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+3]);
tempCaptures[numCaptures
].blackQueen |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
tempCaptures[numCaptures
].blackRook |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
tempCaptures[numCaptures
].blackKnight |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
tempCaptures[numCaptures
].blackBishop |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
}
}
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackPawnMove(&f
romBit, &toBit);
if (!tempMoves[numMoves].blackInCheck())
{
if (toBit&18446744073709551360)
{
numMoves++;
} else {
tempMoves[numMoves].copy
To(&tempCaptures[numCaptures]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+1]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+2]);
tempCaptures[numCaptures
].copyTo(&tempCaptures[numCaptures+3]);
tempCaptures[numCaptures
].blackQueen |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
tempCaptures[numCaptures
].blackRook |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
tempCaptures[numCaptures
].blackKnight |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
tempCaptures[numCaptures
].blackBishop |= toBit;
tempCaptures[numCaptures
].blackPawn ^= toBit;
}
}
}
}
}
tempBit = blackKnight; // Knights
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = blackKnightMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeBlackKnigh
tMove(&fromBit, &toBit);
if (tempCaptures[numCaptures].blackInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackKnightMove(
&fromBit, &toBit);
if (tempMoves[numMoves].blackInCheck())
continue;
numMoves++;
}
}
}
tempBit = blackBishop; // Bishops
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = blackBishopMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeBlackBisho
pMove(&fromBit, &toBit);
if (tempCaptures[numCaptures].blackInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackBishopMove(
&fromBit, &toBit);
if (tempMoves[numMoves].blackInCheck())
continue;
numMoves++;
}
}
}
tempBit = blackRook; // Rooks
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = blackRookMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeBlackRookM
ove(&fromBit, &toBit);
if (tempCaptures[numCaptures].blackInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackRookMove(&f
romBit, &toBit);
if (tempMoves[numMoves].blackInCheck())
continue;
numMoves++;
}
}
}
tempBit = blackQueen; // Queens
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = blackQueenMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeBlackQueen
Move(&fromBit, &toBit);
if (tempCaptures[numCaptures].blackInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackQueenMove(&
fromBit, &toBit);
if (tempMoves[numMoves].blackInCheck())
continue;
numMoves++;
}
}
}
tempBit = blackKing; // Kings
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = blackKingMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------if (toBit&white) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeBlackKingM
ove(&fromBit, &toBit);
if (tempCaptures[numCaptures].blackInChe
ck()) continue;
numCaptures++;
} else {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackKingMove(&f
romBit, &toBit);
if (tempMoves[numMoves].blackInCheck())
continue;
numMoves++;
}
if (blackCastlingOO && (toBit == 288230376151711
744ULL) && !(black&blackCastlingOOEmpty) && blackRook&rightUpCorner) {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackKingMove(&f
romBit, &blackKingCastlingOO);
if (!tempMoves[numMoves].blackInCheck())
{
tempMoves[numMoves].blackRook ^=
blackRookCastlingOO;
tempMoves[numMoves].blackCastlin
gOO = tempMoves[numMoves].blackCastlingOOO = false;
tempMoves[numMoves++].buildBitbo
ard();
}
}
if (blackCastlingOOO && (toBit == 11529215046068
46976ULL) && !(black&blackCastlingOOOEmpty) && blackRook&leftUpCorner) {
copyTo(&tempMoves[numMoves]);
tempMoves[numMoves].makeBlackKingMove(&f
romBit, &blackKingCastlingOOO);
if (!tempMoves[numMoves].blackInCheck())
{
tempMoves[numMoves].blackRook ^=
blackRookCastlingOOO;
tempMoves[numMoves].blackCastlin
gOO = tempMoves[numMoves].blackCastlingOOO = false;
tempMoves[numMoves++].buildBitbo
ard();
}
}
}
}
}
moves = new bitboard[numCaptures+numMoves];
for (i=0; i<numCaptures; i++) {
moves[i] = tempCaptures[i];
}
for (i=0; i<numMoves; i++) {
moves[numCaptures+i] = tempMoves[i];
}
numMoves += numCaptures;
}
float bitboard::evaluate() {
float evaluation = 0;
tempBit = 1;
for (int i=0; i<64; i++) {
if (tempBit&whitePawn) {
//evaluation += (int)(i/8)*8*0.0000001f;
//evaluation += numSetBits(whitePawnMoves(&tempBit))*0.0
01f;
evaluation += pawnValue;
} else if (tempBit&blackPawn) {
//evaluation -= 8-(int)(i/8)*8*0.00001f;
//evaluation -= (float)numSetBits(blackPawnMoves(&tempBi
t))*0.001f;
evaluation -= pawnValue;
} else if (tempBit&whiteKnight) {
//evaluation += (float)numSetBits(whiteKnightMoves(&temp
Bit))*0.001f;
evaluation += knightValue;
} else if (tempBit&blackKnight) {
//evaluation -= (float)numSetBits(blackKnightMoves(&temp
Bit))*0.001f;
evaluation -= knightValue;
} else if (tempBit&whiteBishop) {
//evaluation += (float)numSetBits(whiteBishopMoves(&temp
Bit))*0.001f;
evaluation += bishopValue;
} else if (tempBit&blackBishop) {
//evaluation -= (float)numSetBits(blackBishopMoves(&temp
Bit))*0.001f;
evaluation -= bishopValue;
} else if (tempBit&whiteRook) {
//evaluation += (float)numSetBits(whiteRookMoves(&tempBi
t))*0.001f;
evaluation += rookValue;
} else if (tempBit&blackRook) {
//evaluation -= (float)numSetBits(blackRookMoves(&tempBi
t))*0.001f;
evaluation -= rookValue;
} else if (tempBit&whiteQueen) {
//evaluation += (float)numSetBits(whiteQueenMoves(&tempB
it))*0.001f;
evaluation += queenValue;
} else if (tempBit&blackQueen) {
//evaluation -= (float)numSetBits(blackQueenMoves(&tempB
it))*0.001f;
evaluation -= queenValue;
}
tempBit <<= 1;
}
return evaluation;
}
float bitboard::gameOver() {
if (turn) {
if (whiteInCheck()) return -9999999.0f;
} else {
if (blackInCheck()) return 9999999.0f;
}
return 0;
}
float bitboard::alphaBeta(int depth, float a, float b) {
/*/ ===(Animate thinking)===
updateBoard(this);
cout << "Depth: " << depth << "\nChilds: " << numMoves << "\nValue: " <<
evaluate();
//*/
// RETURN
if (!depth) return evaluate(); // evaluate mste innehlla en koll efter gam
eOver, tnk om den nr djup noll och har en checkmate?
getMoves();
if (!numMoves) return gameOver();
// RECALL
if (turn) {
for (int i=0; i<numMoves; i++) {
a = floatMax(a, moves[i].alphaBeta(depth-1, a, b));
if (b<=a) break;
}
return a;
} else {
for (int i=0; i<numMoves; i++) {
b = floatMin(b, moves[i].alphaBeta(depth-1, a, b));
if (b<=a) break;
}
return b;
}
}
/////////////////////////////////
// FUNCTIONS
/////////////////////////////////
void coutBitboard(unsigned __int64* b) {
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
case
}
return -1;
}
unsigned __int64 indexToBit(int index) {
/*unsigned __int64 bit = 1ULL<<(long)index;
//bit <<= (long)index;
return bit;*/
switch (index) {
case 0: return 1ULL;
case 1: return 2ULL;
case 2: return 4ULL;
case 3: return 8ULL;
case 4: return 16ULL;
case 5: return 32ULL;
case 6: return 64ULL;
case 7: return 128ULL;
case 8: return 256ULL;
case 9: return 512ULL;
case 10: return 1024ULL;
case 11: return 2048ULL;
case 12: return 4096ULL;
case 13: return 8192ULL;
case 14: return 16384ULL;
case 15: return 32768ULL;
case 16: return 65536ULL;
case 17: return 131072ULL;
case 18: return 262144ULL;
case 19: return 524288ULL;
case 20: return 1048576ULL;
case 21: return 2097152ULL;
case 22: return 4194304ULL;
case 23: return 8388608ULL;
case 24: return 16777216ULL;
case 25: return 33554432ULL;
case 26: return 67108864ULL;
case 27: return 134217728ULL;
case 28: return 268435456ULL;
case 29: return 536870912ULL;
case 30: return 1073741824ULL;
case 31: return 2147483648ULL;
case 32: return 4294967296ULL;
case 33: return 8589934592ULL;
case 34: return 17179869184ULL;
case 35: return 34359738368ULL;
case 36: return 68719476736ULL;
case 37: return 137438953472ULL;
case 38: return 274877906944ULL;
case 39: return 549755813888ULL;
case 40: return 1099511627776ULL;
case 41: return 2199023255552ULL;
case 42: return 4398046511104ULL;
case 43: return 8796093022208ULL;
case 44: return 17592186044416ULL;
case 45: return 35184372088832ULL;
case 46: return 70368744177664ULL;
case 47: return 140737488355328ULL;
case 48: return 281474976710656ULL;
case 49: return 562949953421312ULL;
case 50: return 1125899906842624ULL;
case 51: return 2251799813685248ULL;
case 52: return 4503599627370496ULL;
case 53: return 9007199254740992ULL;
case 54: return 18014398509481984ULL;
case 55: return 36028797018963968ULL;
case 56: return 72057594037927936ULL;
case 57: return 144115188075855872ULL;
case
case
case
case
case
case
58:
59:
60:
61:
62:
63:
return
return
return
return
return
return
288230376151711744ULL;
576460752303423488ULL;
1152921504606846976ULL;
2305843009213693952ULL;
4611686018427387904ULL;
9223372036854775808ULL;
}
return 1337;
}
unsigned __int64* LS1B(unsigned __int64 p) {
unsigned __int64 x = p^p&(p-1);
return &x;
}
unsigned __int64* MS1B(unsigned __int64 p) {
unsigned __int64 x = p;
x |= x >> 32; x |= x >> 16;
x |= x >> 8; x |= x >> 4;
x |= x >> 2; x |= x >> 1;
x = ((x>>1)+1)&p;
return &x;
}
void updateBoard(bitboard* bb) {
system("cls");
SetConsoleTextAttribute(handle, frameColor);
if (boardTurned) { cout << endl << " HGFEDCBA " << endl;
} else { cout << endl << " ABCDEFGH " << endl; }
SetConsoleTextAttribute(handle, cornerColor); cout << " " << f1d;
SetConsoleTextAttribute(handle, frameColor); cout << fill1 << fill1 << f
ill1 << fill1 << fill1 << fill1 << fill1 << fill1;
SetConsoleTextAttribute(handle, cornerColor); cout << f1c << endl;
if (boardTurned) {
for (y=7; y>-1; y--) {
drawLine(bb, y);
}
} else {
for (y=0; y<8; y++) {
drawLine(bb, y);
}
}
SetConsoleTextAttribute(handle, cornerColor); cout << " " << f1f;
SetConsoleTextAttribute(handle, frameColor); cout << fill1 << fill1 << f
ill1 << fill1 << fill1 << fill1 << fill1 << fill1;
SetConsoleTextAttribute(handle, cornerColor); cout << f1e << endl;
SetConsoleTextAttribute(handle, frameColor);
if (boardTurned) { cout << " HGFEDCBA " << endl << endl;
} else { cout << " ABCDEFGH " << endl << endl; }
}
void drawLine(bitboard* bb, int y) {
SetConsoleTextAttribute(handle, frameColor);
cout << " " << 8-y << fill1;
if (boardTurned) {
for (x=7; x>-1; x--) {
drawSquare(bb, x);
}
} else {
for (x=0; x<8; x++) {
drawSquare(bb, x);
}
}
SetConsoleTextAttribute(handle, frameColor);
cout << fill1 << 8-y << endl;
}
void drawSquare(bitboard* bb, int x) {
bit = indexToBit(63-x-y*8);
if (!aiThinking && (bit&indexBit || (bit&fromBit && selection))) {
squareColor = selectedPieceColor;
} else if (!aiThinking && (bit&selection)) {
squareColor = selectionColor;
} else if ((x+y)%2) {
squareColor = darkSquareColor;
} else {
squareColor = lightSquareColor;
}
SetConsoleTextAttribute(handle, squareColor);
if (bit&bb->all) {
if (bit&bb->white) {
SetConsoleTextAttribute(handle, squareColor+whitePieceCo
lor);
} else {
SetConsoleTextAttribute(handle, squareColor+blackPieceCo
lor);
}
if (bit&(bb->whitePawn|bb->blackPawn)) {
cout << pawnChar;
} else if (bit&(bb->whiteKnight|bb->blackKnight)) {
cout << knightChar;
} else if (bit&(bb->whiteBishop|bb->blackBishop)) {
cout << bishopChar;
} else if (bit&(bb->whiteRook|bb->blackRook)) {
cout << rookChar;
} else if (bit&(bb->whiteQueen|bb->blackQueen)) {
cout << queenChar;
} else if (bit&(bb->whiteKing|bb->blackKing)) {
cout << kingChar;
}
} else {
cout << " ";
}
}
void showPromotionMenu() {
cout << "
";
int pieceColor;
if (game.turn) {
pieceColor = whitePieceColor;
} else {
pieceColor = blackPieceColor;
}
SetConsoleTextAttribute(handle, darkSquareColor+pieceColor);
cout << knightChar;
SetConsoleTextAttribute(handle, lightSquareColor+pieceColor);
cout << bishopChar;
SetConsoleTextAttribute(handle, darkSquareColor+pieceColor);
cout << rookChar;
SetConsoleTextAttribute(handle, lightSquareColor+pieceColor);
cout << queenChar << endl;
SetConsoleTextAttribute(handle, writeColor);
cout << "
";
for (short i=0; i<promoteTo; i++) {
cout << ' ';
}
cout << cursor << endl;
}
void showMenu() {
cout << " "
cout << "1.
cout << "2.
cout << "3.
cout << "4.
}
void turnBoard() {
boardTurned
}
int intAbs(int x) {
return (x^(x>>31))-(x>>31);
}
float floatMax(float a, float b) {
if (a>b) return a;
return b;
}
float floatMin(float a, float b) {
if (a<b) return a;
return b;
}
int numSetBits(unsigned __int64 i) {
i = i - ((i >> 1) & 0x5555555555555555ULL);
i = (i & 0x3333333333333333ULL) + ((i >> 2) & 0x3333333333333333ULL);
return (int)((((i+(i>>4)) & 0xF0F0F0F0F0F0F0FULL) * 0x101010101010101ULL
) >> 56);
}
void animate(bool showAnimation, unsigned __int64* toSelect) {
ofstream save;
if (!showAnimation) save.open("patterns.txt");
for (int o=0; o<64; o++) {
if (showAnimation) system("cls");
if (toSelect) {
selection = toSelect[o];
} else {
selection = 0;
int ox = o%8;
int oy = (o-ox)/8;
unsigned __int64 indx;
for (int y=0; y<8; y++) {
for (int x=0; x<8; x++) {
indx = indexToBit(x+y*8);
if (x<ox && y>oy && intAbs(x-ox) == abs(
y-oy)) { // && intAbs(x-ox) == abs(y-oy)
selection |= indx;
}
}
}
}
indexBit = indexToBit(o);
if (showAnimation) {
updateBoard(&game);
} else {
cout << selection << endl;
if (!showAnimation) { save << selection; if (o<63) save
<< ", "; }
}
}
if (!showAnimation) { save << endl; save.close(); }
}
void saveBitboard(bitboard* bb) {
ofstream save;
save.open("bitboard.txt");
save << "turn = " << bb->turn << ";\n"; save << "whiteCastlingOO = " <<
(bb->whiteCastlingOO ? "true" : "false") << ";\n"; save << "whiteCastlingOOO = "
<< (bb->whiteCastlingOOO ? "true" : "false") << ";\n";
save << "blackCastlingOO = " << (bb->blackCastlingOO ? "true" : "false")
<< ";\n"; save << "blackCastlingOOO = " << (bb->blackCastlingOOO ? "true" : "fa
lse") << ";\n"; save << "whitePawn = " << bb->whitePawn << "ULL;\n";
save << "whiteKnight = " << bb->whiteKnight << "ULL;\n"; save << "whiteB
ishop = " << bb->whiteBishop << "ULL;\n"; save << "whiteRook = " << bb->whiteRoo
k << "ULL;\n";
save << "whiteQueen = " << bb->whiteQueen << "ULL;\n"; save << "whiteKin
g = " << bb->whiteKing << "ULL;\n"; save << "blackPawn = " << bb->blackPawn << "
ULL;\n";
save << "blackKnight = " << bb->blackKnight << "ULL;\n"; save << "black
Bishop = " << bb->blackBishop << "ULL;\n"; save << "blackRook = " << bb->blackRo
ok << "ULL;\n";
save << "blackQueen = " << bb->blackQueen << "ULL;\n"; save << "blackKin
g = " << bb->blackKing << "ULL;\n"; save << "enPassiant = " << bb->enPassiant <<
"ULL;\n";
save.close();
}
void makeMove(int i) {
changeWhite = game.white;
changeBlack = game.black;
game = game.moves[i];
game.getMoves();
if (!aiVsAi) aiThinking = !aiThinking;
selection = (changeWhite^game.white)|(changeBlack^game.black);
}
void checkGameState() {
if (!game.numMoves) {
if (game.turn && game.whiteInCheck()) checkmate(game.turn);
else if (!game.turn && game.blackInCheck()) checkmate(game.turn)
;
else stalemate();
} else if (game.turn && game.whiteInCheck()) { check(); }
}
void checkmate(bool turn) {
SetConsoleTextAttribute(handle, writeColor);
cout << " CHECK MATE" << endl;
while(true) {} // <--return;
}
void stalemate() {
SetConsoleTextAttribute(handle, writeColor);
cout << " STALE MATE" << endl;
while(true) {} // <--return;
}
void check() {
SetConsoleTextAttribute(handle, writeColor);
cout << "
CHECK!" << endl;
}
/////////////////////////////////
// MAIN
/////////////////////////////////
int main() {
/////////////////////////////////
// SETUP
/////////////////////////////////
SetConsoleTitle("CHESS");
if (aiIsWhite) indexBit = indexToBit(51);
else indexBit = indexToBit(11);
game.setToNewGame();
updateBoard(&game);
/////////////////////////////////
// Main loop
/////////////////////////////////
int keyboardInput = 0;
while (keyboardInput != 27) { // ESC out of program
if (!aiThinking) {
/////////////////////////////////
// HUMAN INPUT (KEYBOARD)
warning: capslock disa
bles wasd
/////////////////////////////////
if (_kbhit()) {
keyboardInput = _getch();
game.buildBitboard();
switch (keyboardInput) {
case 44: // ,
if (historyIndex<gameLength) {
selection = fromBit = 0;
historyIndex++;
game = gameHistory[gameL
ength-historyIndex];
updateBoard(&game);
}
break;
case 46: // .
if (historyIndex>0) {
selection = fromBit = 0;
historyIndex--;
game = gameHistory[gameL
ength-historyIndex];
updateBoard(&game);
}
break;
case 245: //
saveBitboard(&game);
break;
case 119: // W
if (!promoting) {
if (boardTurned) {
if (indexBit>>8)
indexBit >>= 8;
else indexBit <<
= 56;
} else {
if (indexBit<<8)
indexBit <<= 8;
else indexBit >>
= 56;
}
}
break;
case 97: // A
if (promoting) {
if (promoteTo>0) promote
To--;
} else {
if (!boardTurned) {
if ((indexBit<<1
)&~files[0]) indexBit <<= 1;
else indexBit >>
= 7;
} else {
if ((indexBit>>1
)&~files[7]) indexBit >>= 1;
else indexBit <<
= 7;
}
}
break;
case 115: // S
if (!promoting) {
if (boardTurned) {
if (indexBit<<8)
indexBit <<= 8;
else indexBit >>
= 56;
} else {
if (indexBit>>8)
indexBit >>= 8;
else indexBit <<
= 56;
}
}
break;
case 100: // D
if (promoting) {
if (promoteTo<3) promote
To++;
} else {
if (!boardTurned) {
if ((indexBit>>1
}
}
selectio
n &= ~game.black;
}
}
} else if (indexBit&selection) {
// Make move
toBit = indexBit;
for (int i=0; i<game.num
Moves; i++) {
if ((fromBit&(ga
me.whiteKing|game.blackKing) && intAbs(bitToIndex(&fromBit)-bitToIndex(&toBit))
== 2)) { // Castling
if ((gam
e.moves[i].whiteKing|game.moves[i].blackKing)&toBit) {
makeMove(i);
break;
}
} else if (fromB
it&game.whitePawn && toBit&ranks[7] || fromBit&game.blackPawn && toBit&ranks[0])
{ // Promotion
if (toBi
t&(game.moves[i].whiteQueen|game.moves[i].blackQueen)) {
promoteIndex = i;
promoting = true;
break;
}
} else if (((gam
e.turn && (fromBit|toBit) == (game.white^game.moves[i].white)) || (!game.turn &&
(fromBit|toBit) == (game.black^game.moves[i].black))) ) { // Ordinary move
makeMove
(i);
break;
}
}
selection = 0;
updateBoard(&game);
checkGameState();
} else {
selection = 0;
}
break;
}
if (keyboardInput == 119 || keyboardInput == 97
|| keyboardInput == 115 || keyboardInput == 100 || keyboardInput == 13) {
updateBoard(&game);
if (promoting) showPromotionMenu();
}
}
} else {
/////////////////////////////////
// AI
/////////////////////////////////
j = -1;
SetConsoleTextAttribute(handle, writeColor);
cout << endl << " THINKING" << endl;
gameLength += 1-historyIndex;
historyIndex = 0;
int startTime = clock();
/////////////////////////////////
// MATE IN 1?
/////////////////////////////////
for (int i=0; i<game.numMoves; i++) {
game.moves[i].getMoves();
if (!game.moves[i].numMoves && (game.turn && gam
e.moves[i].blackInCheck() || !game.turn && game.moves[i].whiteInCheck())) {
j = i;
break;
}
}
if (j<0) {
/////////////////////////////////
// Alpha Beta
/////////////////////////////////
best = -999999.0f;
if (!game.turn) best *= -1.0f;
for (int i=0; i<game.numMoves; i++) {
e = game.moves[i].alphaBeta(searchDepth1, -infinity, infinity);
if ((game.turn && e>best) || (!game.turn
&& e<best)) {
best = e;
j = i;
}
//cout << '.';
}
}
/////////////////////////////////
// Make move
/////////////////////////////////
system("cls");
makeMove(j);
updateBoard(&game);
checkGameState();
gameHistory[gameLength] = game;
SetConsoleTextAttribute(handle, writeColor);
cout << "
" << clock()-startTime << " ms";
cout << "\a";
}
}
/////////////////////////////////
// END
/////////////////////////////////
return 0;