You are on page 1of 42

/////////////////////////////////

// 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

whitePawnMoves(unsigned __int64* piece);


whiteKnightMoves(unsigned __int64* piece);
whiteBishopMoves(unsigned __int64* piece);
whiteRookMoves(unsigned __int64* piece);
whiteQueenMoves(unsigned __int64* piece);
whiteKingMoves(unsigned __int64* piece);

unsigned
unsigned
unsigned
unsigned
unsigned
unsigned

__int64
__int64
__int64
__int64
__int64
__int64

blackPawnMoves(unsigned __int64* piece);


blackKnightMoves(unsigned __int64* piece);
blackBishopMoves(unsigned __int64* piece);
blackRookMoves(unsigned __int64* piece);
blackQueenMoves(unsigned __int64* piece);
blackKingMoves(unsigned __int64* piece);

unsigned __int64* getWhitePiece(unsigned __int64* bit);


unsigned __int64* getBlackPiece(unsigned __int64* bit);
void makeWhitePawnMove(unsigned __int64* from, unsigned __int64*
to);
void makeWhiteKnightMove(unsigned __int64* from, unsigned __int6
4* to);
void makeWhiteBishopMove(unsigned __int64* from, unsigned __int6
4* to);
void makeWhiteRookMove(unsigned __int64* from, unsigned __int64*
to);
void makeWhiteQueenMove(unsigned __int64* from, unsigned __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;

char fill1 = 176;


char fill2 = 177;
char fill3 = 178;
char
char
char
char
char
char

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};

static const unsigned __int64 knightMovement[64] = {132096ULL, 329728ULL, 659712


ULL, 1319424ULL, 2638848ULL, 5277696ULL, 10489856ULL, 4202496ULL, 33816580ULL,84
410376ULL, 168886289ULL, 337772578ULL, 675545156ULL, 1351090312ULL, 2685403152UL
L, 1075839008ULL, 8657044482ULL, 21609056261ULL, 43234889994ULL, 86469779988ULL,
172939559976ULL, 345879119952ULL, 687463207072ULL, 275414786112ULL, 22162033873
92ULL, 5531918402816ULL, 11068131838464ULL, 22136263676928ULL, 44272527353856ULL
, 88545054707712ULL, 175990581010432ULL, 70506185244672ULL, 567348067172352ULL,
1416171111120896ULL, 2833441750646784ULL, 5666883501293568ULL, 11333767002587136
ULL, 22667534005174272ULL, 45053588738670592ULL, 18049583422636032ULL, 145241105
196122112ULL, 362539804446949376ULL, 725361088165576704ULL, 1450722176331153408U
LL, 2901444352662306816ULL, 5802888705324613632ULL, 11533718717099671552ULL, 462
0693356194824192ULL, 288234782788157440ULL, 576469569871282176ULL, 1224997833292
120064ULL, 2449995666584240128ULL, 4899991333168480256ULL, 9799982666336960512UL
L, 1152939783987658752ULL, 2305878468463689728ULL, 1128098930098176ULL, 22572973
71824128ULL, 4796069720358912ULL, 9592139440717824ULL, 19184278881435648ULL, 383
68557762871296ULL, 4679521487814656ULL, 9077567998918656ULL};
static const unsigned __int64 bishopMovement[64] = {9241421688590303744ULL, 3609
9303471056128ULL, 141012904249856ULL, 550848566272ULL, 6480472064ULL, 1108177604
608ULL, 283691315142656ULL, 72624976668147712ULL, 4620710844295151618ULL, 924142
1688590368773ULL, 36099303487963146ULL, 141017232965652ULL, 1659000848424ULL, 28
3693466779728ULL, 72624976676520096ULL, 145249953336262720ULL, 23103554221475107
88ULL, 4620710844311799048ULL, 9241421692918565393ULL, 36100411639206946ULL, 424
704217196612ULL, 72625527495610504ULL, 145249955479592976ULL, 290499906664153120
ULL, 1155177711057110024ULL, 2310355426409252880ULL, 4620711952330133792ULL, 924
1705379636978241ULL, 108724279602332802ULL, 145390965166737412ULL, 2905004553566
98632ULL, 580999811184992272ULL, 577588851267340304ULL, 1155178802063085600ULL,
2310639079102947392ULL, 4693335752243822976ULL, 9386671504487645697ULL, 32659893
5265674242ULL, 581140276476643332ULL, 1161999073681608712ULL, 288793334762704928
ULL, 577868148797087808ULL, 1227793891648880768ULL, 2455587783297826816ULL, 4911
175566595588352ULL, 9822351133174399489ULL, 1197958188344280066ULL, 232385768313
9004420ULL, 144117404414255168ULL, 360293502378066048ULL, 720587009051099136ULL,
1441174018118909952ULL, 2882348036221108224ULL, 5764696068147249408ULL, 1152939
1036782871041ULL, 4611756524879479810ULL, 567382630219904ULL, 1416240237150208UL
L, 2833579985862656ULL, 5667164249915392ULL, 11334324221640704ULL, 2266754893171
9168ULL, 45053622886727936ULL, 18049651735527937ULL};
static const unsigned __int64 rookMovement[64] = {72340172838076926ULL, 14468034
5676153597ULL, 289360691352306939ULL, 578721382704613623ULL, 1157442765409226991
ULL, 2314885530818453727ULL, 4629771061636907199ULL, 9259542123273814143ULL, 723
40172838141441ULL, 144680345676217602ULL, 289360691352369924ULL, 578721382704674
568ULL, 1157442765409283856ULL, 2314885530818502432ULL, 4629771061636939584ULL,
9259542123273813888ULL, 72340172854657281ULL, 144680345692602882ULL, 28936069136
8494084ULL, 578721382720276488ULL, 1157442765423841296ULL, 2314885530830970912UL
L, 4629771061645230144ULL, 9259542123273748608ULL, 72340177082712321ULL, 1446803
49887234562ULL, 289360695496279044ULL, 578721386714368008ULL, 115744276915054593
6ULL, 2314885534022901792ULL, 4629771063767613504ULL, 9259542123257036928ULL, 72
341259464802561ULL, 144681423712944642ULL, 289361752209228804ULL, 57872240920179
7128ULL, 1157443723186933776ULL, 2314886351157207072ULL, 4629771607097753664ULL,
9259542118978846848ULL, 72618349279904001ULL, 144956323094725122ULL, 2896322707
24367364ULL, 578984165983651848ULL, 1157687956502220816ULL, 2315095537539358752U
LL, 4629910699613634624ULL, 9259541023762186368ULL, 143553341945872641ULL, 21533
0564830528002ULL, 358885010599838724ULL, 645993902138460168ULL, 1220211685215703
056ULL, 2368647251370188832ULL, 4665518383679160384ULL, 9259260648297103488ULL,
18302911464433844481ULL, 18231136449196065282ULL, 18087586418720506884ULL, 17800
486357769390088ULL, 17226286235867156496ULL, 16077885992062689312ULL, 1378108550
4453754944ULL, 9187484529235886208ULL};
static const unsigned __int64 queenMovement[64] = {9313761861428380670ULL, 18077
9649147209725ULL, 289501704256556795ULL, 578721933553179895ULL, 1157442771889699
055ULL, 2314886638996058335ULL, 4630054752952049855ULL, 9332167099941961855ULL,
4693051017133293059ULL, 9386102034266586375ULL, 325459994840333070ULL, 578862399
937640220ULL, 1157444424410132280ULL, 2315169224285282160ULL, 470239603831345968

0ULL, 9404792076610076608ULL, 2382695595002168069ULL, 4765391190004401930ULL, 95


30782384287059477ULL, 614821794359483434ULL, 1157867469641037908ULL, 23875110583
26581416ULL, 4775021017124823120ULL, 9550042029937901728ULL, 1227517888139822345
ULL, 2455035776296487442ULL, 4910072647826412836ULL, 9820426766351346249ULL, 126
6167048752878738ULL, 2460276499189639204ULL, 4920271519124312136ULL, 98405419344
42029200ULL, 649930110732142865ULL, 1299860225776030242ULL, 2600000831312176196U
LL, 5272058161445620104ULL, 10544115227674579473ULL, 2641485286422881314ULL, 521
0911883574396996ULL, 10421541192660455560ULL, 361411684042608929ULL, 72282447189
1812930ULL, 1517426162373248132ULL, 3034571949281478664ULL, 6068863523097809168U
LL, 12137446670713758241ULL,5827868887957914690ULL, 11583398706901190788ULL, 287
670746360127809ULL, 575624067208594050ULL, 1079472019650937860ULL, 2087167920257
370120ULL, 4102559721436811280ULL, 8133343319517438240ULL, 16194909420462031425U
LL, 13871017173176583298ULL, 18303478847064064385ULL, 18232552689433215490ULL, 1
8090419998706369540ULL, 17806153522019305480ULL, 17237620560088797200ULL, 161005
53540994408480ULL, 13826139127340482880ULL, 9205534180971414145ULL};
static const unsigned __int64 kingMovement[64] = {770ULL, 1797ULL, 3594ULL, 7188
ULL, 14376ULL, 28752ULL, 57504ULL, 49216ULL, 197123ULL, 460039ULL, 920078ULL, 18
40156ULL, 3680312ULL, 7360624ULL, 14721248ULL, 12599488ULL, 50463488ULL, 1177699
84ULL, 235539968ULL, 471079936ULL, 942159872ULL, 1884319744ULL, 3768639488ULL, 3
225468928ULL, 12918652928ULL, 30149115904ULL, 60298231808ULL, 120596463616ULL, 2
41192927232ULL, 482385854464ULL, 964771708928ULL, 825720045568ULL, 3307175149568
ULL, 7718173671424ULL, 15436347342848ULL, 30872694685696ULL, 61745389371392ULL,
123490778742784ULL, 246981557485568ULL, 211384331665408ULL, 846636838289408ULL,
1975852459884544ULL, 3951704919769088ULL, 7903409839538176ULL, 15806819679076352
ULL, 31613639358152704ULL, 63227278716305408ULL, 54114388906344448ULL, 216739030
602088448ULL, 505818229730443264ULL, 1011636459460886528ULL, 2023272918921773056
ULL, 4046545837843546112ULL, 8093091675687092224ULL, 16186183351374184448ULL, 13
853283560024178688ULL, 144959613005987840ULL, 362258295026614272ULL, 72451659005
3228544ULL, 1449033180106457088ULL, 2898066360212914176ULL, 5796132720425828352U
LL, 11592265440851656704ULL, 4665729213955833856ULL};
static const unsigned __int64 rightRay[64] = {0ULL, 1ULL, 3ULL, 7ULL, 15ULL, 31U
LL, 63ULL, 127ULL, 0ULL, 256ULL, 768ULL, 1792ULL, 3840ULL, 7936ULL, 16128ULL, 32
512ULL, 0ULL, 65536ULL, 196608ULL, 458752ULL, 983040ULL, 2031616ULL, 4128768ULL,
8323072ULL, 0ULL, 16777216ULL, 50331648ULL, 117440512ULL, 251658240ULL, 5200936
96ULL, 1056964608ULL, 2130706432ULL, 0ULL, 4294967296ULL, 12884901888ULL, 300647
71072ULL, 64424509440ULL, 133143986176ULL, 270582939648ULL, 545460846592ULL, 0UL
L, 1099511627776ULL, 3298534883328ULL, 7696581394432ULL, 16492674416640ULL, 3408
4860461056ULL, 69269232549888ULL, 139637976727552ULL, 0ULL, 281474976710656ULL,
844424930131968ULL, 1970324836974592ULL, 4222124650659840ULL, 8725724278030336UL
L, 17732923532771328ULL, 35747322042253312ULL, 0ULL, 72057594037927936ULL, 21617
2782113783808ULL, 504403158265495552ULL, 1080863910568919040ULL, 223378541517576
6016ULL, 4539628424389459968ULL, 9151314442816847872ULL};
static const unsigned __int64 leftRay[64] = {254ULL, 252ULL, 248ULL, 240ULL, 224
ULL, 192ULL, 128ULL, 0ULL, 65024ULL, 64512ULL, 63488ULL, 61440ULL, 57344ULL, 491
52ULL, 32768ULL, 0ULL, 16646144ULL, 16515072ULL, 16252928ULL, 15728640ULL, 14680
064ULL, 12582912ULL, 8388608ULL, 0ULL, 4261412864ULL, 4227858432ULL, 4160749568U
LL, 4026531840ULL, 3758096384ULL, 3221225472ULL, 2147483648ULL, 0ULL, 1090921693
184ULL, 1082331758592ULL, 1065151889408ULL, 1030792151040ULL, 962072674304ULL, 8
24633720832ULL, 549755813888ULL, 0ULL, 279275953455104ULL, 277076930199552ULL, 2
72678883688448ULL, 263882790666240ULL, 246290604621824ULL, 211106232532992ULL, 1
40737488355328ULL, 0ULL, 71494644084506624ULL, 70931694131085312ULL, 69805794224
242688ULL, 67553994410557440ULL, 63050394783186944ULL, 54043195528445952ULL, 360
28797018963968ULL, 0ULL, 18302628885633695744ULL, 18158513697557839872ULL, 17870
283321406128128ULL, 17293822569102704640ULL, 16140901064495857664ULL, 1383505805
5282163712ULL, 9223372036854775808ULL, 0ULL};
static const unsigned __int64 upRay[64] = {72340172838076672ULL, 144680345676153
344ULL, 289360691352306688ULL, 578721382704613376ULL, 1157442765409226752ULL, 23
14885530818453504ULL, 4629771061636907008ULL, 9259542123273814016ULL, 7234017283
8076416ULL, 144680345676152832ULL, 289360691352305664ULL, 578721382704611328ULL,

1157442765409222656ULL, 2314885530818445312ULL, 4629771061636890624ULL, 9259542


123273781248ULL, 72340172838010880ULL, 144680345676021760ULL, 289360691352043520
ULL, 578721382704087040ULL, 1157442765408174080ULL, 2314885530816348160ULL, 4629
771061632696320ULL, 9259542123265392640ULL, 72340172821233664ULL, 14468034564246
7328ULL, 289360691284934656ULL, 578721382569869312ULL, 1157442765139738624ULL, 2
314885530279477248ULL, 4629771060558954496ULL, 9259542121117908992ULL, 723401685
26266368ULL, 144680337052532736ULL, 289360674105065472ULL, 578721348210130944ULL
, 1157442696420261888ULL, 2314885392840523776ULL, 4629770785681047552ULL, 925954
1571362095104ULL, 72339069014638592ULL, 144678138029277184ULL, 28935627605855436
8ULL, 578712552117108736ULL, 1157425104234217472ULL, 2314850208468434944ULL, 462
9700416936869888ULL, 9259400833873739776ULL, 72057594037927936ULL, 1441151880758
55872ULL, 288230376151711744ULL, 576460752303423488ULL, 1152921504606846976ULL,
2305843009213693952ULL, 4611686018427387904ULL, 9223372036854775808ULL, 0ULL, 0U
LL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
static const unsigned __int64 downRay[64] = {0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL,
0ULL, 0ULL, 1ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32ULL, 64ULL, 128ULL, 257ULL, 514ULL
, 1028ULL, 2056ULL, 4112ULL, 8224ULL, 16448ULL, 32896ULL, 65793ULL, 131586ULL, 2
63172ULL, 526344ULL, 1052688ULL, 2105376ULL, 4210752ULL, 8421504ULL, 16843009ULL
, 33686018ULL, 67372036ULL, 134744072ULL, 269488144ULL, 538976288ULL, 1077952576
ULL, 2155905152ULL, 4311810305ULL, 8623620610ULL, 17247241220ULL, 34494482440ULL
, 68988964880ULL, 137977929760ULL, 275955859520ULL, 551911719040ULL, 11038234380
81ULL, 2207646876162ULL, 4415293752324ULL, 8830587504648ULL, 17661175009296ULL,
35322350018592ULL, 70644700037184ULL, 141289400074368ULL, 282578800148737ULL, 56
5157600297474ULL, 1130315200594948ULL, 2260630401189896ULL, 4521260802379792ULL,
9042521604759584ULL, 18085043209519168ULL, 36170086419038336ULL};
static const unsigned __int64 rightUpRay[64] = {0ULL, 256ULL, 66048ULL, 16909312
ULL, 4328785920ULL, 1108169199616ULL, 283691315109888ULL, 72624976668147712ULL,
0ULL, 65536ULL, 16908288ULL, 4328783872ULL, 1108169195520ULL, 283691315101696ULL
, 72624976668131328ULL, 145249953336262656ULL, 0ULL, 16777216ULL, 4328521728ULL,
1108168671232ULL, 283691314053120ULL, 72624976666034176ULL, 145249953332068352U
LL, 290499906664136704ULL, 0ULL, 4294967296ULL, 1108101562368ULL, 28369117983539
2ULL, 72624976397598720ULL, 145249952795197440ULL, 290499905590394880ULL, 580999
811180789760ULL, 0ULL, 1099511627776ULL, 283673999966208ULL, 72624942037860352UL
L, 145249884075720704ULL, 290499768151441408ULL, 580999536302882816ULL, 11619990
72605765632ULL, 0ULL, 281474976710656ULL, 72620543991349248ULL, 1452410879826984
96ULL, 290482175965396992ULL, 580964351930793984ULL, 1161928703861587968ULL, 232
3857407723175936ULL, 0ULL, 72057594037927936ULL, 144115188075855872ULL, 28823037
6151711744ULL, 576460752303423488ULL, 1152921504606846976ULL, 230584300921369395
2ULL, 4611686018427387904ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
static const unsigned __int64 leftUpRay[64] = {9241421688590303744ULL, 360993034
71055872ULL, 141012904183808ULL, 550831656960ULL, 2151686144ULL, 8404992ULL, 327
68ULL, 0ULL, 4620710844295151616ULL, 9241421688590303232ULL, 36099303471054848UL
L, 141012904181760ULL, 550831652864ULL, 2151677952ULL, 8388608ULL, 0ULL, 2310355
422147510272ULL, 4620710844295020544ULL, 9241421688590041088ULL, 360993034705305
60ULL, 141012903133184ULL, 550829555712ULL, 2147483648ULL, 0ULL, 115517771105697
7920ULL, 2310355422113955840ULL, 4620710844227911680ULL, 9241421688455823360ULL,
36099303202095104ULL, 141012366262272ULL, 549755813888ULL, 0ULL, 57758885123352
1664ULL, 1155177702467043328ULL, 2310355404934086656ULL, 4620710809868173312ULL,
9241421619736346624ULL, 36099165763141632ULL, 140737488355328ULL, 0ULL, 2887933
26105133056ULL, 577586652210266112ULL, 1155173304420532224ULL, 23103466088410644
48ULL, 4620693217682128896ULL, 9241386435364257792ULL, 36028797018963968ULL, 0UL
L, 144115188075855872ULL, 288230376151711744ULL, 576460752303423488ULL, 11529215
04606846976ULL, 2305843009213693952ULL, 4611686018427387904ULL, 9223372036854775
808ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0ULL};
static const unsigned __int64 rightDownRay[64] = {0ULL, 0ULL, 0ULL, 0ULL, 0ULL,
0ULL, 0ULL, 0ULL, 0ULL, 1ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32ULL, 64ULL, 0ULL, 256UL
L, 513ULL, 1026ULL, 2052ULL, 4104ULL, 8208ULL, 16416ULL, 0ULL, 65536ULL, 131328U
LL, 262657ULL, 525314ULL, 1050628ULL, 2101256ULL, 4202512ULL, 0ULL, 16777216ULL,
33619968ULL, 67240192ULL, 134480385ULL, 268960770ULL, 537921540ULL, 1075843080U

LL, 0ULL, 4294967296ULL, 8606711808ULL, 17213489152ULL, 34426978560ULL, 68853957


121ULL, 137707914242ULL, 275415828484ULL, 0ULL, 1099511627776ULL, 2203318222848U
LL, 4406653222912ULL, 8813306511360ULL, 17626613022976ULL, 35253226045953ULL, 70
506452091906ULL, 0ULL, 281474976710656ULL, 564049465049088ULL, 1128103225065472U
LL, 2256206466908160ULL, 4512412933881856ULL, 9024825867763968ULL, 1804965173552
7937ULL};
static const unsigned __int64 leftDownRay[64] = {0ULL, 0ULL, 0ULL, 0ULL, 0ULL, 0
ULL, 0ULL, 0ULL, 2ULL, 4ULL, 8ULL, 16ULL, 32ULL, 64ULL, 128ULL, 0ULL, 516ULL, 10
32ULL, 2064ULL, 4128ULL, 8256ULL, 16512ULL, 32768ULL, 0ULL, 132104ULL, 264208ULL
, 528416ULL, 1056832ULL, 2113664ULL, 4227072ULL, 8388608ULL, 0ULL, 33818640ULL,
67637280ULL, 135274560ULL, 270549120ULL, 541097984ULL, 1082130432ULL, 2147483648
ULL, 0ULL, 8657571872ULL, 17315143744ULL, 34630287488ULL, 69260574720ULL, 138521
083904ULL, 277025390592ULL, 549755813888ULL, 0ULL, 2216338399296ULL, 44326767985
92ULL, 8865353596928ULL, 17730707128320ULL, 35461397479424ULL, 70918499991552ULL
, 140737488355328ULL, 0ULL, 567382630219904ULL, 1134765260439552ULL, 22695305208
13568ULL, 4539061024849920ULL, 9078117754732544ULL, 18155135997837312ULL, 360287
97018963968ULL, 0ULL};
#define
#define
#define
#define
static
static
static
static

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);

unsigned __int64 indexToBit(int index);


unsigned __int64* LS1B(unsigned __int64 p);
unsigned __int64* MS1B(unsigned __int64 p);
void showPromotionMenu();
void showMenu();
void turnBoard();
int intAbs(int x);
float floatMax(float a, float b);
float floatMin(float a, float b);
int numSetBits(unsigned __int64 i);
void animate(bool showAnimation, unsigned __int64* toSelect);
void saveBitboard(bitboard* bb);
void makeMove(int i);
void checkGameState();
void checkmate(bool turn);
void stalemate();
void check();
void updateBoard(bitboard* bb);
void drawLine(bitboard* bb, int y);
void drawSquare(bitboard* bb, int x);
/////////////////////////////////
// BITBOARD FUNCTIONS
/////////////////////////////////
void bitboard::setToNewGame() {
turn = true;
whiteCastlingOO = true;
whiteCastlingOOO = true;
blackCastlingOO = true;
blackCastlingOOO = true;
whitePawn = 65280ULL;
whiteKnight = 66ULL;
whiteBishop = 36ULL;
whiteRook = 129ULL;
whiteQueen = 16ULL;
whiteKing = 8ULL;
blackPawn = 71776119061217280ULL;
blackKnight = 4755801206503243776ULL;
blackBishop = 2594073385365405696ULL;
blackRook = 9295429630892703744ULL;
blackQueen = 1152921504606846976ULL;
blackKing = 576460752303423488ULL;
enPassiant = 0ULL;
buildBitboard();
getMoves();
gameLength = historyIndex = 0;
gameHistory[0] = game;
}
/*aiThinking = true; // complex situation for checking evaluation
turn = 0;

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);
}

unsigned __int64 bitboard::whiteKingMoves(unsigned __int64* piece) {


int index = bitToIndex(piece);
selection = kingMovement[index];
return selection&~(white);
}
unsigned __int64 bitboard::blackPawnMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
if (all&(*piece>>8)) selection = 0;
else selection = blackPawnMovement[index]&~all;
selection |= blackPawnCapture[index]&(white|enPassiant);
return selection&~(black);
}
unsigned __int64 bitboard::blackKnightMoves(unsigned __int64* piece) {
int index = bitToIndex(piece);
selection = knightMovement[index];
return selection&~(black);
}
unsigned __int64 bitboard::blackBishopMoves(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&~(black);
}
unsigned __int64 bitboard::blackRookMoves(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&~(black);
}
unsigned __int64 bitboard::blackQueenMoves(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&~(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);

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&(whiteRook|whiteQueen)) return true; // ROOK | QUEEN
else if (kingMovement[kingIndex] & whiteKing) return true; // KING
return false;
}
void bitboard::getMoves() { // Get Moves
int numCaptures = 0;
bool promote = false;
numMoves = 0;
if (turn) { // White
tempBit = whitePawn; // Pawns
while(tempBit) {
fromBit = tempBit^tempBit&(tempBit-1);
tempBit ^= fromBit;
// ---------------------------selection = whitePawnMoves(&fromBit); // Moves
while(selection) {
toBit = selection^selection&(selection-1);
selection ^= toBit;
// ---------------------------promote = false;
if (toBit&black) {
copyTo(&tempCaptures[numCaptures]);
tempCaptures[numCaptures].makeWhitePawnM
ove(&fromBit, &toBit);
if (!tempCaptures[numCaptures].whiteInCh
eck()) {
if (toBit&72057594037927935) {
numCaptures++;
} else {
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();
}
}
} 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) {

for (int i=63; i>=0; i--) {


if (*b & intPow(2, i)) {
cout << 1;
} else {
cout << 0;
}
if (i%8 == 0) {
cout << endl;
}
}
cout << endl;
}
void cinBitboard() {
unsigned __int64 bitboard = 0;
char line[9];
for (int i=0; i<8; i++) {
cin >> line;
for (int j=0; j<8; j++) {
if (line[j] == '1') bitboard += intPow(2, 63-(8*i)-j);
}
}
cout << bitboard;
}
unsigned __int64 intPow(int a, int b) {
unsigned __int64 c = a;
if (!b) return 1;
while (--b) c = c*a;
return c;
}
int coordinateToIndex(char a, char b) {
if (a>48 && a<57) {
if (b<97) b += 32;
if (b<97 || b>104) return -1;
return (a-48)*8-b+96;
} else if (b>48 && b<57) {
if (a<97) a += 32;
if (a<97 || a>104) return -1;
return (b-48)*8-a+96;
}
return -1;
}
map<unsigned __int64, unsigned __int64> _bitToIndex, _indexToBit;
//_bitToIndex[1] = 0;
int bitToIndex(unsigned __int64* bit) {
/*unsigned long index;
BitScanForward64(&index, *bit);
return (int)index;*/
switch (*bit) {
case 1ULL: return 0;
case 2ULL: return 1;
case 4ULL: return 2;
case 8ULL: return 3;
case 16ULL: return 4;
case 32ULL: return 5;
case 64ULL: return 6;
case 128ULL: return 7;
case 256ULL: return 8;
case 512ULL: return 9;

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

1024ULL: return 10;


2048ULL: return 11;
4096ULL: return 12;
8192ULL: return 13;
16384ULL: return 14;
32768ULL: return 15;
65536ULL: return 16;
131072ULL: return 17;
262144ULL: return 18;
524288ULL: return 19;
1048576ULL: return 20;
2097152ULL: return 21;
4194304ULL: return 22;
8388608ULL: return 23;
16777216ULL: return 24;
33554432ULL: return 25;
67108864ULL: return 26;
134217728ULL: return 27;
268435456ULL: return 28;
536870912ULL: return 29;
1073741824ULL: return 30;
2147483648ULL: return 31;
4294967296ULL: return 32;
8589934592ULL: return 33;
17179869184ULL: return 34;
34359738368ULL: return 35;
68719476736ULL: return 36;
137438953472ULL: return 37;
274877906944ULL: return 38;
549755813888ULL: return 39;
1099511627776ULL: return 40;
2199023255552ULL: return 41;
4398046511104ULL: return 42;
8796093022208ULL: return 43;
17592186044416ULL: return 44;
35184372088832ULL: return 45;
70368744177664ULL: return 46;
140737488355328ULL: return 47;
281474976710656ULL: return 48;
562949953421312ULL: return 49;
1125899906842624ULL: return 50;
2251799813685248ULL: return 51;
4503599627370496ULL: return 52;
9007199254740992ULL: return 53;
18014398509481984ULL: return 54;
36028797018963968ULL: return 55;
72057594037927936ULL: return 56;
144115188075855872ULL: return 57;
288230376151711744ULL: return 58;
576460752303423488ULL: return 59;
1152921504606846976ULL: return 60;
2305843009213693952ULL: return 61;
4611686018427387904ULL: return 62;
9223372036854775808ULL: return 63;

}
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
}

<< c2 << " MENU " << c3 << endl;


Continue" << endl;
New Game" << endl;
Turn board" << endl;
Help" << endl;
= !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

)&~files[7]) indexBit >>= 1;


else indexBit <<
= 7;
} else {
if ((indexBit<<1
)&~files[0]) indexBit <<= 1;
else indexBit >>
= 7;
}
}
break;
case 13: // ENTER
//if (!(game.whiteCastlingOO &&
game.whiteCastlingOOO && game.blackCastlingOO && game.blackCastlingOOO)) cout <<
'\a';
if (promoting) { // Promote
if (promoteTo == 0) make
Move(promoteIndex+2);
else if (promoteTo == 1)
makeMove(promoteIndex+3);
else if (promoteTo == 2)
makeMove(promoteIndex+1);
else if (promoteTo == 3)
makeMove(promoteIndex);
selection = 0;
updateBoard(&game);
checkGameState();
promoting = false;
promoteTo = 3;
break;
} else if ((game.turn && indexBi
t&game.white) || (!game.turn && indexBit&game.black)) { // Select
if (fromBit == indexBit
&& selection) {
selection = 0;
} else {
fromBit = indexB
it;
selection = 0;
if (game.turn) {
for (int
i=0; i<game.numMoves; i++) {
if (!(game.moves[i].white&fromBit)) {
selection |= game.white^game.moves[i].white;
}
}
selectio
n &= ~game.white;
} else {
for (int
i=0; i<game.numMoves; i++) {
if (!(game.moves[i].black&fromBit)) {
selection |= game.black^game.moves[i].black;

}
}
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;