├── Makefile ├── README.md ├── bin └── .gitignore ├── clean.bat ├── license.txt ├── obj └── .gitignore ├── performance.bin ├── vice.sln └── vice ├── attack.c ├── bitboards.c ├── board.c ├── data.c ├── defs.h ├── evaluate.c ├── hashkeys.c ├── init.c ├── io.c ├── makemove.c ├── misc.c ├── movegen.c ├── perft.c ├── polybook.c ├── polykeys.c ├── polykeys.h ├── pvtable.c ├── search.c ├── uci.c ├── validate.c ├── vice.c ├── vice.vcxproj ├── vice.vcxproj.filters └── xboard.c /Makefile: -------------------------------------------------------------------------------- 1 | SRC=vice 2 | BIN=bin 3 | OBJ=obj 4 | INC=vice 5 | 6 | CC=gcc 7 | CFLAGS=-Wall -ggdb -O0 -I$(INC) 8 | 9 | $(BIN)/vice: $(OBJ)/attack.o \ 10 | $(OBJ)/bitboards.o \ 11 | $(OBJ)/board.o \ 12 | $(OBJ)/data.o \ 13 | $(OBJ)/evaluate.o \ 14 | $(OBJ)/hashkeys.o \ 15 | $(OBJ)/init.o \ 16 | $(OBJ)/io.o \ 17 | $(OBJ)/makemove.o \ 18 | $(OBJ)/misc.o \ 19 | $(OBJ)/movegen.o \ 20 | $(OBJ)/perft.o \ 21 | $(OBJ)/polybook.o \ 22 | $(OBJ)/polykeys.o \ 23 | $(OBJ)/pvtable.o \ 24 | $(OBJ)/search.o \ 25 | $(OBJ)/uci.o \ 26 | $(OBJ)/validate.o \ 27 | $(OBJ)/xboard.o \ 28 | $(SRC)/vice.c 29 | $(CC) $(CFLAGS) -o $@ $^ 30 | 31 | $(OBJ)/attack.o: $(SRC)/attack.c 32 | $(CC) $(CFLAGS) -c -o $@ $^ 33 | 34 | $(OBJ)/bitboards.o: $(SRC)/bitboards.c 35 | $(CC) $(CFLAGS) -c -o $@ $^ 36 | 37 | $(OBJ)/board.o: $(SRC)/board.c 38 | $(CC) $(CFLAGS) -c -o $@ $^ 39 | 40 | $(OBJ)/data.o: $(SRC)/data.c 41 | $(CC) $(CFLAGS) -c -o $@ $^ 42 | 43 | $(OBJ)/evaluate.o: $(SRC)/evaluate.c 44 | $(CC) $(CFLAGS) -c -o $@ $^ 45 | 46 | $(OBJ)/hashkeys.o: $(SRC)/hashkeys.c 47 | $(CC) $(CFLAGS) -c -o $@ $^ 48 | 49 | $(OBJ)/init.o: $(SRC)/init.c 50 | $(CC) $(CFLAGS) -c -o $@ $^ 51 | 52 | $(OBJ)/io.o: $(SRC)/io.c 53 | $(CC) $(CFLAGS) -c -o $@ $^ 54 | 55 | $(OBJ)/makemove.o: $(SRC)/makemove.c 56 | $(CC) $(CFLAGS) -c -o $@ $^ 57 | 58 | $(OBJ)/misc.o: $(SRC)/misc.c 59 | $(CC) $(CFLAGS) -c -o $@ $^ 60 | 61 | $(OBJ)/movegen.o: $(SRC)/movegen.c 62 | $(CC) $(CFLAGS) -c -o $@ $^ 63 | 64 | $(OBJ)/polybook.o: $(SRC)/polybook.c 65 | $(CC) $(CFLAGS) -c -o $@ $^ 66 | 67 | $(OBJ)/polykeys.o: $(SRC)/polykeys.c 68 | $(CC) $(CFLAGS) -c -o $@ $^ 69 | 70 | $(OBJ)/perft.o: $(SRC)/perft.c 71 | $(CC) $(CFLAGS) -c -o $@ $^ 72 | 73 | $(OBJ)/pvtable.o: $(SRC)/pvtable.c 74 | $(CC) $(CFLAGS) -c -o $@ $^ 75 | 76 | $(OBJ)/search.o: $(SRC)/search.c 77 | $(CC) $(CFLAGS) -c -o $@ $^ 78 | 79 | $(OBJ)/uci.o: $(SRC)/uci.c 80 | $(CC) $(CFLAGS) -c -o $@ $^ 81 | 82 | $(OBJ)/validate.o: $(SRC)/validate.c 83 | $(CC) $(CFLAGS) -c -o $@ $^ 84 | 85 | $(OBJ)/xboard.o: $(SRC)/xboard.c 86 | $(CC) $(CFLAGS) -c -o $@ $^ 87 | 88 | .PHONY: clean 89 | 90 | clean: 91 | rm -f $(OBJ)/* 92 | rm -f $(BIN)/* 93 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | vice 2 | ==== 3 | 4 | Video Instructions Chess Engine 5 | -------------------------------------------------------------------------------- /bin/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /clean.bat: -------------------------------------------------------------------------------- 1 | @echo off 2 | 3 | CALL :cleanprojdir vice 4 | CALL :cleanprojdir bin 5 | 6 | IF EXIST ipch rd /q /s ipch 7 | IF EXIST vice.sdf del /q vice.sdf 8 | IF EXIST vice.opensdf del /q vice.opensdf 9 | IF EXIST vice.suo ( 10 | ATTRIB -h vice.suo 11 | DEL /q vice.suo 12 | ) 13 | 14 | EXIT /B 0 15 | 16 | :cleanprojdir 17 | SETLOCAL 18 | 19 | ECHO Cleaning %1 20 | 21 | PUSHD %1 22 | CALL :delstarifexist *.user 23 | IF EXIST win32 rd /q /s win32 24 | IF EXIST x64 rd /q /s x64 25 | POPD 26 | 27 | ENDLOCAL 28 | EXIT /B 29 | 30 | :delstarifexist 31 | SETLOCAL 32 | 33 | FOR %%F IN ("%1") DO ( 34 | DEL /q "%%~nxF" 35 | ) 36 | 37 | ENDLOCAL 38 | EXIT /B -------------------------------------------------------------------------------- /license.txt: -------------------------------------------------------------------------------- 1 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 2 | Version 2, December 2004 3 | 4 | Copyright (C) 2004 Sam Hocevar 5 | 6 | Everyone is permitted to copy and distribute verbatim or modified 7 | copies of this license document, and changing it is allowed as long 8 | as the name is changed. 9 | 10 | DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE 11 | TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION 12 | 13 | 0. You just DO WHAT THE FUCK YOU WANT TO. -------------------------------------------------------------------------------- /obj/.gitignore: -------------------------------------------------------------------------------- 1 | * 2 | !.gitignore 3 | -------------------------------------------------------------------------------- /performance.bin: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/peterwankman/vice/b002afce820488824f32066e51cefe56ea299372/performance.bin -------------------------------------------------------------------------------- /vice.sln: -------------------------------------------------------------------------------- 1 |  2 | Microsoft Visual Studio Solution File, Format Version 11.00 3 | # Visual Studio 2010 4 | Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "vice", "vice\vice.vcxproj", "{D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}" 5 | EndProject 6 | Global 7 | GlobalSection(SolutionConfigurationPlatforms) = preSolution 8 | Debug|Win32 = Debug|Win32 9 | Debug|x64 = Debug|x64 10 | Release|Win32 = Release|Win32 11 | Release|x64 = Release|x64 12 | EndGlobalSection 13 | GlobalSection(ProjectConfigurationPlatforms) = postSolution 14 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Debug|Win32.ActiveCfg = Debug|Win32 15 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Debug|Win32.Build.0 = Debug|Win32 16 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Debug|x64.ActiveCfg = Debug|x64 17 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Debug|x64.Build.0 = Debug|x64 18 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Release|Win32.ActiveCfg = Release|Win32 19 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Release|Win32.Build.0 = Release|Win32 20 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Release|x64.ActiveCfg = Release|x64 21 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB}.Release|x64.Build.0 = Release|x64 22 | EndGlobalSection 23 | GlobalSection(SolutionProperties) = preSolution 24 | HideSolutionNode = FALSE 25 | EndGlobalSection 26 | EndGlobal 27 | -------------------------------------------------------------------------------- /vice/attack.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | 14 | const int KnDir[8] = { -8, -19, -21, -12, 8, 19, 21, 12 }; 15 | const int RkDir[4] = { -1, -10, 1, 10 }; 16 | const int BiDir[4] = { -9, -11, 11, 9 }; 17 | const int KiDir[8] = { -1, -10, 1, 10, -9, -11, 11, 9 }; 18 | 19 | int SqAttacked(const int sq, const int side, const S_BOARD *pos) { 20 | int pce, index, t_sq, dir; 21 | 22 | ASSERT(SqOnBoard(sq)); 23 | ASSERT(SideValid(side)); 24 | ASSERT(CheckBoard(pos)); 25 | 26 | if(side == WHITE) { 27 | if(pos->pieces[sq - 11] == wP || pos->pieces[sq - 9] == wP) { 28 | return TRUE; 29 | } 30 | } else { 31 | if(pos->pieces[sq + 11] == bP || pos->pieces[sq + 9] == bP) { 32 | return TRUE; 33 | } 34 | } 35 | 36 | for(index = 0; index < 8; index++) { 37 | pce = pos->pieces[sq + KnDir[index]]; 38 | if(pce != OFFBOARD && IsKn(pce) && PieceCol[pce] == side) 39 | return TRUE; 40 | } 41 | 42 | for(index = 0; index < 4; index++) { 43 | dir = RkDir[index]; 44 | t_sq = sq + dir; 45 | pce = pos->pieces[t_sq]; 46 | while(pce != OFFBOARD) { 47 | if(pce != EMPTY) { 48 | if(IsRQ(pce) && PieceCol[pce] == side) { 49 | return TRUE; 50 | } 51 | break; 52 | } 53 | t_sq += dir; 54 | pce = pos->pieces[t_sq]; 55 | } 56 | } 57 | 58 | for(index = 0; index < 4; index++) { 59 | dir = BiDir[index]; 60 | t_sq = sq + dir; 61 | pce = pos->pieces[t_sq]; 62 | while(pce != OFFBOARD) { 63 | if(pce != EMPTY) { 64 | if(IsBQ(pce) && PieceCol[pce] == side) { 65 | return TRUE; 66 | } 67 | break; 68 | } 69 | t_sq += dir; 70 | pce = pos->pieces[t_sq]; 71 | } 72 | } 73 | 74 | for(index = 0; index < 8; index++) { 75 | pce = pos->pieces[sq + KiDir[index]]; 76 | if(pce != OFFBOARD && IsKi(pce) && PieceCol[pce] == side) { 77 | return TRUE; 78 | } 79 | } 80 | 81 | return FALSE; 82 | } -------------------------------------------------------------------------------- /vice/bitboards.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include "defs.h" 14 | 15 | const int BitTable[64] = { 16 | 63, 30, 3, 32, 25, 41, 22, 33, 15, 50, 42, 13, 11, 53, 19, 34, 61, 29, 2, 17 | 51, 21, 43, 45, 10, 18, 47, 1, 54, 9, 57, 0, 35, 62, 31, 40, 4, 49, 5, 52, 18 | 26, 60, 6, 23, 44, 46, 27, 56, 16, 7, 39, 48, 24, 59, 14, 12, 55, 38, 28, 19 | 58, 20, 37, 17, 36, 8 20 | }; 21 | 22 | int PopBit(U64 *bb) { 23 | U64 b = *bb ^ (*bb - 1); 24 | unsigned int fold = (unsigned) ((b & 0xffffffff) ^ (b >> 32)); 25 | *bb &= (*bb - 1); 26 | return BitTable[((U64)(fold * 0x783a9b23)) >> 26]; 27 | } 28 | 29 | int CountBits(U64 b) { 30 | int r; 31 | for(r = 0; b; r++, b &= b - 1); 32 | return r; 33 | } -------------------------------------------------------------------------------- /vice/board.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | 14 | #include "defs.h" 15 | 16 | int CheckBoard(const S_BOARD *pos) { 17 | int t_pceNum[13] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; 18 | int t_bigPce[2] = { 0, 0 }; 19 | int t_majPce[2] = { 0, 0 }; 20 | int t_minPce[2] = { 0, 0 }; 21 | int t_material[2] = { 0, 0 }; 22 | 23 | int sq64, t_piece, t_pce_num, sq120, colour, pcount; 24 | 25 | U64 t_pawns[3] = { 0ULL, 0ULL, 0ULL }; 26 | 27 | t_pawns[WHITE] = pos->pawns[WHITE]; 28 | t_pawns[BLACK] = pos->pawns[BLACK]; 29 | t_pawns[BOTH] = pos->pawns[BOTH]; 30 | 31 | for(t_piece = wP; t_piece >= bK; ++t_piece) { 32 | for(t_pce_num = 0; t_pce_num < pos->pceNum[t_piece]; ++t_pce_num) { 33 | sq120 = pos->pList[t_piece][t_pce_num]; 34 | ASSERT(pos->pieces[sq120] == t_piece); 35 | } 36 | } 37 | 38 | for(sq64 = 0; sq64 < 64; ++sq64) { 39 | sq120 = SQ120(sq64); 40 | t_piece = pos->pieces[sq120]; 41 | t_pceNum[t_piece]++; 42 | colour = PieceCol[t_piece]; 43 | if(PieceBig[t_piece] == TRUE) t_bigPce[colour]++; 44 | if(PieceMin[t_piece] == TRUE) t_minPce[colour]++; 45 | if(PieceMaj[t_piece] == TRUE) t_majPce[colour]++; 46 | 47 | t_material[colour] += PieceVal[t_piece]; 48 | } 49 | 50 | for(t_piece = wP; t_piece <= bK; ++t_piece) 51 | ASSERT(t_pceNum[t_piece] == pos->pceNum[t_piece]); 52 | 53 | pcount = CNT(t_pawns[WHITE]); 54 | ASSERT(pcount == pos->pceNum[wP]); 55 | pcount = CNT(t_pawns[BLACK]); 56 | ASSERT(pcount == pos->pceNum[bP]); 57 | pcount = CNT(t_pawns[BOTH]); 58 | 59 | ASSERT(pcount == pos->pceNum[wP] + pos->pceNum[bP]); 60 | 61 | while(t_pawns[WHITE]) { 62 | sq64 = POP(&t_pawns[WHITE]); 63 | ASSERT(pos->pieces[SQ120(sq64)] == wP); 64 | } 65 | 66 | while(t_pawns[BLACK]) { 67 | sq64 = POP(&t_pawns[BLACK]); 68 | ASSERT(pos->pieces[SQ120(sq64)] == bP); 69 | } 70 | 71 | while(t_pawns[BOTH]) { 72 | sq64 = POP(&t_pawns[BOTH]); 73 | ASSERT(pos->pieces[SQ120(sq64)] == wP || pos->pieces[SQ120(sq64)] == bP); 74 | } 75 | 76 | ASSERT(t_material[WHITE] == pos->material[WHITE] && t_material[BLACK] == pos->material[BLACK]); 77 | ASSERT(t_minPce[WHITE] == pos->minPce[WHITE] && t_minPce[BLACK] == pos->minPce[BLACK]); 78 | ASSERT(t_majPce[WHITE] == pos->majPce[WHITE] && t_majPce[BLACK] == pos->majPce[BLACK]); 79 | ASSERT(t_bigPce[WHITE] == pos->bigPce[WHITE] && t_bigPce[BLACK] == pos->bigPce[BLACK]); 80 | 81 | ASSERT(pos->side == WHITE || pos->side == BLACK); 82 | ASSERT(GeneratePositionKey(pos) == pos->posKey); 83 | 84 | ASSERT(pos->enPas == NO_SQ || 85 | (RanksBrd[pos->enPas] == RANK_6 && pos->side == WHITE) || 86 | (RanksBrd[pos->enPas] == RANK_3 && pos->side == BLACK)); 87 | 88 | ASSERT(pos->pieces[pos->KingSq[WHITE]] == wK); 89 | ASSERT(pos->pieces[pos->KingSq[BLACK]] == bK); 90 | 91 | return TRUE; 92 | } 93 | 94 | void UpdateListsMaterial(S_BOARD *pos) { 95 | int piece, sq, index, colour; 96 | 97 | for(index = 0; index < BRD_SQ_NUM; ++index) { 98 | sq = index; 99 | piece = pos->pieces[index]; 100 | if(piece != OFFBOARD && piece != EMPTY) { 101 | colour = PieceCol[piece]; 102 | if(PieceBig[piece] == TRUE) pos->bigPce[colour]++; 103 | if(PieceMin[piece] == TRUE) pos->minPce[colour]++; 104 | if(PieceMaj[piece] == TRUE) pos->majPce[colour]++; 105 | 106 | pos->material[colour] += PieceVal[piece]; 107 | 108 | pos->pList[piece][pos->pceNum[piece]] = sq; 109 | pos->pceNum[piece]++; 110 | 111 | if(piece == wK) pos->KingSq[WHITE] = sq; 112 | if(piece == bK) pos->KingSq[BLACK] = sq; 113 | 114 | if(piece == wP) { 115 | SETBIT(pos->pawns[WHITE], SQ64(sq)); 116 | SETBIT(pos->pawns[BOTH], SQ64(sq)); 117 | } else if(piece == bP) { 118 | SETBIT(pos->pawns[BLACK], SQ64(sq)); 119 | SETBIT(pos->pawns[BOTH], SQ64(sq)); 120 | } 121 | } 122 | } 123 | } 124 | 125 | int ParseFen(char *fen, S_BOARD *pos) { 126 | int rank = RANK_8; 127 | int file = FILE_A; 128 | int piece = 0; 129 | int count = 0; 130 | int i = 0; 131 | int sq64 = 0; 132 | int sq120 = 0; 133 | 134 | ASSERT(fen != NULL); 135 | ASSERT(pos != NULL); 136 | 137 | ResetBoard(pos); 138 | 139 | while((rank >= RANK_1) && *fen) { 140 | count = 1; 141 | switch(*fen) { 142 | case 'p': piece = bP; break; 143 | case 'r': piece = bR; break; 144 | case 'n': piece = bN; break; 145 | case 'b': piece = bB; break; 146 | case 'k': piece = bK; break; 147 | case 'q': piece = bQ; break; 148 | case 'P': piece = wP; break; 149 | case 'R': piece = wR; break; 150 | case 'N': piece = wN; break; 151 | case 'B': piece = wB; break; 152 | case 'K': piece = wK; break; 153 | case 'Q': piece = wQ; break; 154 | 155 | case '1': 156 | case '2': 157 | case '3': 158 | case '4': 159 | case '5': 160 | case '6': 161 | case '7': 162 | case '8': 163 | piece = EMPTY; 164 | count = *fen - '0'; 165 | break; 166 | 167 | case '/': 168 | case ' ': 169 | rank--; 170 | file = FILE_A; 171 | fen++; 172 | continue; 173 | 174 | default: 175 | printf("FEN error!\n"); 176 | return -1; 177 | } 178 | 179 | for(i = 0; i < count; i++) { 180 | sq64 = rank * 8 + file; 181 | sq120 = SQ120(sq64); 182 | if(piece != EMPTY) 183 | pos->pieces[sq120] = piece; 184 | file++; 185 | } 186 | fen++; 187 | } 188 | 189 | ASSERT(*fen == 'w' || *fen == 'b'); 190 | 191 | pos->side = (*fen == 'w') ? WHITE : BLACK; 192 | fen += 2; 193 | 194 | for(i = 0; i < 4; i++) { 195 | if(*fen == ' ') 196 | break; 197 | 198 | switch(*fen) { 199 | case 'K': pos->castlePerm |= WKCA; break; 200 | case 'Q': pos->castlePerm |= WQCA; break; 201 | case 'k': pos->castlePerm |= BKCA; break; 202 | case 'q': pos->castlePerm |= BQCA; break; 203 | } 204 | fen++; 205 | } 206 | fen++; 207 | 208 | ASSERT(pos->castlePerm >= 0 && pos->castlePerm <= 15); 209 | 210 | if(*fen != '-') { 211 | file = fen[0] - 'a'; 212 | rank = fen[1] - '1'; 213 | 214 | ASSERT(file >= FILE_A && file <= FILE_H); 215 | ASSERT(rank >= RANK_1 && rank <= RANK_8); 216 | 217 | pos->enPas = FR2SQ(file, rank); 218 | } 219 | 220 | pos->posKey = GeneratePositionKey(pos); 221 | 222 | UpdateListsMaterial(pos); 223 | return 0; 224 | } 225 | 226 | void ResetBoard(S_BOARD *pos) { 227 | int index = 0; 228 | 229 | for(index = 0; index < BRD_SQ_NUM; index++) 230 | pos->pieces[index] = OFFBOARD; 231 | 232 | for(index = 0; index < 64; index++) 233 | pos->pieces[SQ120(index)] = EMPTY; 234 | 235 | for(index = 0; index < 2; index++) { 236 | pos->bigPce[index] = 0; 237 | pos->majPce[index] = 0; 238 | pos->minPce[index] = 0; 239 | pos->material[index] = 0; 240 | } 241 | 242 | for(index = 0; index < 3; index++) { 243 | pos->pawns[index] = 0ULL; 244 | } 245 | 246 | for(index = 0; index < 13; index++) 247 | pos->pceNum[index] = 0; 248 | 249 | pos->KingSq[WHITE] = pos->KingSq[BLACK] = NO_SQ; 250 | 251 | pos->material[WHITE] = pos->material[BLACK] = 0; 252 | 253 | pos->side = BOTH; 254 | pos->enPas = NO_SQ; 255 | pos->fiftyMove = 0; 256 | 257 | pos->ply = 0; 258 | pos->hisPly = 0; 259 | 260 | pos->castlePerm = 0; 261 | 262 | pos->posKey = 0ULL; 263 | } 264 | 265 | void PrintBoard(const S_BOARD *pos) { 266 | int sq, file, rank, piece; 267 | 268 | printf("\nGame Board:\n\n"); 269 | 270 | for(rank = RANK_8; rank >= RANK_1; rank--) { 271 | printf("%d ", rank + 1); 272 | for(file = FILE_A; file <= FILE_H; file++) { 273 | sq = FR2SQ(file, rank); 274 | piece = pos->pieces[sq]; 275 | printf("%3c", PceChar[piece]); 276 | } 277 | printf("\n"); 278 | } 279 | 280 | printf("\n "); 281 | for(file = FILE_A; file <= FILE_H; file++) 282 | printf("%3c", 'a' + file); 283 | 284 | printf("\n"); 285 | printf("side:%c\n", SideChar[pos->side]); 286 | printf("enPas:%d\n", pos->enPas); 287 | printf("castle:%c%c%c%c\n", 288 | pos->castlePerm & WKCA ? 'K' : '-', 289 | pos->castlePerm & WQCA ? 'Q' : '-', 290 | pos->castlePerm & BKCA ? 'k' : '-', 291 | pos->castlePerm & BQCA ? 'q' : '-'); 292 | 293 | printf("PosKey:%0llx\n", pos->posKey); 294 | } 295 | 296 | void MirrorBoard(S_BOARD *pos) { 297 | 298 | int tempPiecesArray[64]; 299 | int tempSide = pos->side^1; 300 | int SwapPiece[13] = { EMPTY, bP, bN, bB, bR, bQ, bK, wP, wN, wB, wR, wQ, wK }; 301 | int tempCastlePerm = 0; 302 | int tempEnPas = NO_SQ; 303 | 304 | int sq; 305 | int tp; 306 | 307 | if (pos->castlePerm & WKCA) tempCastlePerm |= BKCA; 308 | if (pos->castlePerm & WQCA) tempCastlePerm |= BQCA; 309 | 310 | if (pos->castlePerm & BKCA) tempCastlePerm |= WKCA; 311 | if (pos->castlePerm & BQCA) tempCastlePerm |= WQCA; 312 | 313 | if (pos->enPas != NO_SQ) { 314 | tempEnPas = SQ120(Mirror64[SQ64(pos->enPas)]); 315 | } 316 | 317 | for (sq = 0; sq < 64; sq++) { 318 | tempPiecesArray[sq] = pos->pieces[SQ120(Mirror64[sq])]; 319 | } 320 | 321 | ResetBoard(pos); 322 | 323 | for (sq = 0; sq < 64; sq++) { 324 | tp = SwapPiece[tempPiecesArray[sq]]; 325 | pos->pieces[SQ120(sq)] = tp; 326 | } 327 | 328 | pos->side = tempSide; 329 | pos->castlePerm = tempCastlePerm; 330 | pos->enPas = tempEnPas; 331 | 332 | pos->posKey = GeneratePositionKey(pos); 333 | 334 | UpdateListsMaterial(pos); 335 | 336 | ASSERT(CheckBoard(pos)); 337 | } 338 | -------------------------------------------------------------------------------- /vice/data.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | 14 | char PceChar[] = ".PNBRQKpnbrqk"; 15 | char SideChar[] = "wb-"; 16 | char RankChar[] = "12345678"; 17 | char FileChar[] = "abcdefgh"; 18 | 19 | int PieceBig[13] = { FALSE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE, FALSE, TRUE, TRUE, TRUE, TRUE, TRUE }; 20 | int PieceMaj[13] = { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE }; 21 | int PieceMin[13] = { FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE }; 22 | int PieceVal[13] = { 0, 100, 325, 325, 550, 1000, 50000, 100, 325, 325, 550, 1000, 50000 }; 23 | int PieceCol[13] = { BOTH, WHITE, WHITE, WHITE, WHITE, WHITE, WHITE, BLACK, BLACK, BLACK, BLACK, BLACK, BLACK }; 24 | 25 | int PiecePawn[13] = { FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE }; 26 | int PieceKnight[13] = { FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE }; 27 | int PieceKing[13] = { FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE, FALSE, FALSE, FALSE, FALSE, FALSE, TRUE }; 28 | int PieceRookQueen[13] = { FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE, FALSE, FALSE, FALSE, TRUE, TRUE, FALSE }; 29 | int PieceBishopQueen[13] = { FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE, FALSE, FALSE, TRUE, FALSE, TRUE, FALSE }; 30 | int PieceSlides[13] = { FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE, FALSE, FALSE, TRUE, TRUE, TRUE, FALSE }; 31 | 32 | int Mirror64[64] = { 33 | 56, 57, 58, 59, 60, 61, 62, 63, 34 | 48, 49, 50, 51, 52, 53, 54, 55, 35 | 40, 41, 42, 43, 44, 45, 46, 47, 36 | 32, 33, 34, 35, 36, 37, 38, 39, 37 | 24, 25, 26, 27, 28, 29, 30, 31, 38 | 16, 17, 18, 19, 20, 21, 22, 23, 39 | 8, 9, 10, 11, 12, 13, 14, 15, 40 | 0, 1, 2, 3, 4, 5, 6, 7 41 | }; 42 | -------------------------------------------------------------------------------- /vice/defs.h: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #ifndef DEFS_H 13 | #define DEFS_H 14 | #include 15 | #include 16 | 17 | #ifndef DEBUG 18 | #define ASSERT(n) 19 | #else 20 | #define ASSERT(n) \ 21 | do {\ 22 | if(!(n)) { \ 23 | printf("%s ", __DATE__); \ 24 | printf("%s: ", __TIME__); \ 25 | printf("Assertion '%s' failed.\n", #n); \ 26 | printf("File '%s'\n", __FILE__); \ 27 | printf("Line %d\n", __LINE__); \ 28 | getchar(); \ 29 | exit(1); \ 30 | } \ 31 | } while(0); 32 | #endif 33 | 34 | typedef unsigned long long U64; 35 | 36 | #define NAME "Vicemod 1.1" 37 | #define BRD_SQ_NUM 120 38 | 39 | #define MAXGAMEMOVES 2048 40 | #define MAXPOSITIONMOVES 256 41 | #define MAXDEPTH 64 42 | #define MAX_HASH 1024 43 | 44 | #define INF 30000 45 | #define ISMATE (INF - MAXDEPTH) 46 | 47 | #define START_FEN "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1" 48 | 49 | enum { EMPTY, wP, wN, wB, wR, wQ, wK, bP, bN, bB, bR, bQ, bK }; 50 | enum { FILE_A, FILE_B, FILE_C, FILE_D, FILE_E, FILE_F, FILE_G, FILE_H, FILE_NONE }; 51 | enum { RANK_1, RANK_2, RANK_3, RANK_4, RANK_5, RANK_6, RANK_7, RANK_8, RANK_NONE }; 52 | 53 | enum { WHITE, BLACK, BOTH }; 54 | enum { UCIMODE, XBOARDMODE, CONSOLEMODE }; 55 | 56 | enum { 57 | A1 = 21, B1, C1, D1, E1, F1, G1, H1, 58 | A2 = 31, B2, C2, D2, E2, F2, G2, H2, 59 | A3 = 41, B3, C3, D3, E3, F3, G3, H3, 60 | A4 = 51, B4, C4, D4, E4, F4, G4, H4, 61 | A5 = 61, B5, C5, D5, E5, F5, G5, H5, 62 | A6 = 71, B6, C6, D6, E6, F6, G6, H6, 63 | A7 = 81, B7, C7, D7, E7, F7, G7, H7, 64 | A8 = 91, B8, C8, D8, E8, F8, G8, H8, 65 | NO_SQ, OFFBOARD 66 | }; 67 | 68 | enum { FALSE, TRUE }; 69 | 70 | enum { WKCA = 1, WQCA = 2, BKCA = 4, BQCA = 8 }; 71 | 72 | enum { HFNONE, HFALPHA, HFBETA, HFEXACT}; 73 | 74 | typedef struct { 75 | int move; 76 | int score; 77 | } S_MOVE; 78 | 79 | typedef struct { 80 | S_MOVE moves[MAXPOSITIONMOVES]; 81 | int count; 82 | } S_MOVELIST; 83 | 84 | typedef struct { 85 | U64 posKey; 86 | int move, score, depth, flags; 87 | } S_HASHENTRY; 88 | 89 | typedef struct { 90 | S_HASHENTRY *pTable; 91 | int numEntries, newWrite, overWrite, hit, cut; 92 | } S_HASHTABLE; 93 | 94 | typedef struct { 95 | int move, castlePerm, enPas, fiftyMoves; 96 | U64 posKey; 97 | } S_UNDO; 98 | 99 | typedef struct { 100 | int pieces[BRD_SQ_NUM]; 101 | U64 pawns[3]; 102 | 103 | int KingSq[2]; 104 | int side, enPas, fiftyMove; 105 | int ply, hisPly, castlePerm; 106 | 107 | U64 posKey; 108 | 109 | int pceNum[13]; 110 | int bigPce[2]; 111 | int majPce[2]; 112 | int minPce[2]; 113 | int material[2]; 114 | 115 | S_UNDO history[MAXGAMEMOVES]; 116 | int pList[13][10]; 117 | 118 | S_HASHTABLE HashTable[1]; 119 | 120 | int PvArray[MAXDEPTH]; 121 | int searchHistory[13][BRD_SQ_NUM]; 122 | int searchKillers[2][MAXDEPTH]; 123 | } S_BOARD; 124 | 125 | typedef struct { 126 | int starttime, stoptime, depth, timeset, movestogo; 127 | int quit, stopped, nullCut; 128 | int GAME_MODE, POST_THINKING; 129 | 130 | long nodes; 131 | float fh, fhf; 132 | } S_SEARCHINFO; 133 | 134 | typedef struct { 135 | int UseBook; 136 | } S_OPTIONS; 137 | 138 | /* MACROS */ 139 | 140 | #define FR2SQ(f, r) ((21 + (f)) + ((r) * 10)) 141 | #define SQ64(sq120) (Sq120ToSq64[(sq120)]) 142 | #define SQ120(sq64) (Sq64ToSq120[(sq64)]) 143 | #define POP(b) PopBit(b) 144 | #define CNT(b) CountBits(b) 145 | #define CLRBIT(bb, sq) ((bb) &= ClearMask[(sq)]) 146 | #define SETBIT(bb, sq) ((bb) |= SetMask[(sq)]) 147 | 148 | #define IsBQ(p) (PieceBishopQueen[(p)]) 149 | #define IsRQ(p) (PieceRookQueen[(p)]) 150 | #define IsKn(p) (PieceKnight[(p)]) 151 | #define IsKi(p) (PieceKing[(p)]) 152 | 153 | #define MIRROR64(sq) (Mirror64[(sq)]) 154 | 155 | #define FROMSQ(m) ((m) & 0x7f) 156 | #define TOSQ(m) (((m) >> 7) & 0x7f) 157 | #define CAPTURED(m) (((m) >> 14) & 0xf) 158 | #define PROMOTED(m) (((m) >> 20) & 0xf) 159 | 160 | #define MFLAGEP 0x00040000 161 | #define MFLAGPS 0x00080000 162 | #define MFLAGCA 0x01000000 163 | #define MFLAGCAP 0x0007C000 164 | #define MFLAGPROM 0x00f00000 165 | 166 | #define NOMOVE 0 167 | 168 | /* GLOBALS */ 169 | 170 | extern int Sq120ToSq64[BRD_SQ_NUM]; 171 | extern int Sq64ToSq120[64]; 172 | extern U64 SetMask[64]; 173 | extern U64 ClearMask[64]; 174 | extern U64 PieceKeys[13][120]; 175 | extern U64 SideKey; 176 | extern U64 CastleKeys[16]; 177 | extern char PceChar[]; 178 | extern char SideChar[]; 179 | extern char RankChar[]; 180 | extern char FileChar[]; 181 | 182 | extern int PieceBig[13]; 183 | extern int PieceMaj[13]; 184 | extern int PieceMin[13]; 185 | extern int PieceVal[13]; 186 | extern int PieceCol[13]; 187 | 188 | extern int FilesBrd[BRD_SQ_NUM]; 189 | extern int RanksBrd[BRD_SQ_NUM]; 190 | 191 | extern int PiecePawn[13]; 192 | extern int PieceKnight[13]; 193 | extern int PieceKing[13]; 194 | extern int PieceRookQueen[13]; 195 | extern int PieceBishopQueen[13]; 196 | extern int PieceSlides[13]; 197 | 198 | extern int Mirror64[64]; 199 | 200 | extern U64 FileBBMask[8]; 201 | extern U64 RankBBMask[8]; 202 | 203 | extern U64 BlackPassedMask[64]; 204 | extern U64 WhitePassedMask[64]; 205 | extern U64 IsolatedMask[64]; 206 | 207 | S_OPTIONS EngineOptions[1]; 208 | 209 | /* FUNCTIONS */ 210 | 211 | /* init.c */ 212 | extern void AllInit(void); 213 | 214 | /* bitboard.c */ 215 | extern int PopBit(U64 *bb); 216 | extern int CountBits(U64 bb); 217 | extern void PrintBitBoard(U64 bb); 218 | 219 | /* hashkeys.c */ 220 | extern U64 GeneratePositionKey(const S_BOARD *pos); 221 | 222 | /* board.c */ 223 | extern void ResetBoard(S_BOARD *pos); 224 | extern int ParseFen(char *fen, S_BOARD *pos); 225 | extern void PrintBoard(const S_BOARD *pos); 226 | extern void UpdateListsMaterial(S_BOARD *pos); 227 | extern int CheckBoard(const S_BOARD *pos); 228 | extern void MirrorBoard(S_BOARD *pos); 229 | 230 | /* attack.c */ 231 | extern int SqAttacked(const int sq, const int side, const S_BOARD *pos); 232 | 233 | /* io.c */ 234 | extern char *PrMove(const int move); 235 | extern char *PrSq(const int sq); 236 | extern int ParseMove(char *ptrChar, S_BOARD *pos); 237 | extern void PrintMoveList(const S_MOVELIST *list); 238 | 239 | /* validate.c */ 240 | extern int SqOnBoard(const int sq); 241 | extern int SideValid(const int side); 242 | extern int FileRankValid(const int fr); 243 | extern int PieceValidEmpty(const int pce); 244 | extern int PieceValid(const int pce); 245 | extern void MirrorEvalTest(S_BOARD *pos); 246 | 247 | /* movegen.c */ 248 | extern void GenerateAllMoves(const S_BOARD *pos, S_MOVELIST *list); 249 | extern int MoveExists(S_BOARD *pos, const int move); 250 | extern void InitMvvLva(void); 251 | extern void GenerateAllCaps(const S_BOARD *pos, S_MOVELIST *list); 252 | 253 | /* makemove.c */ 254 | extern int MakeMove(S_BOARD *pos, int move); 255 | extern void TakeMove(S_BOARD *pos); 256 | extern void MakeNullMove(S_BOARD *pos); 257 | extern void TakeNullMove(S_BOARD *pos); 258 | 259 | /* perft.c */ 260 | extern void PerftTest(int depth, S_BOARD *pos); 261 | 262 | /* search.c */ 263 | extern void SearchPosition(S_BOARD *pos, S_SEARCHINFO *info); 264 | 265 | /* misc.c */ 266 | extern int GetTimeMs(void); 267 | extern void ReadInput(S_SEARCHINFO *info); 268 | 269 | /* pventry.c */ 270 | extern void InitHashTable(S_HASHTABLE *table, const int MB); 271 | extern void StoreHashEntry(S_BOARD *pos, const int move, int score, const int flags, const int depth); 272 | extern int ProbeHashEntry(S_BOARD *pos, int *move, int *score, int alpha, int beta, int depth); 273 | extern int ProbePvMove(const S_BOARD *pos); 274 | extern int GetPvLine(const int depth, S_BOARD *pos); 275 | extern void ClearHashTable(S_HASHTABLE *table); 276 | 277 | /* evaluate.c */ 278 | extern int EvalPosition(const S_BOARD *pos); 279 | 280 | /* uci.c */ 281 | extern void Uci_Loop(S_BOARD *pos, S_SEARCHINFO *info); 282 | 283 | /* xboard.c */ 284 | extern void XBoard_Loop(S_BOARD *pos, S_SEARCHINFO *info); 285 | extern void Console_Loop(S_BOARD *pos, S_SEARCHINFO *info); 286 | 287 | /* polybook.c */ 288 | extern int GetBookMove(S_BOARD *board); 289 | extern void InitPolyBook(void); 290 | extern void CleanPolyBook(void); 291 | 292 | #endif -------------------------------------------------------------------------------- /vice/evaluate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include "defs.h" 14 | 15 | const int PawnIsolated = -10; 16 | const int PawnPassed[8] = { 0, 5, 10, 20, 35, 60, 100, 200 }; 17 | const int RookOpenFile = 10; 18 | const int RookSemiOpenFile = 5; 19 | const int QueenOpenFile = 5; 20 | const int QueenSemiOpenFile = 3; 21 | const int BishopPair = 30; 22 | 23 | const int PawnTable[64] = { 24 | 0, 0, 0, 0, 0, 0, 0, 0, 25 | 10, 10, 0, -10,-10,0, 10, 10, 26 | 5, 0, 0, 5, 5, 0, 0, 5, 27 | 0, 0, 10, 20, 20, 10, 0, 0, 28 | 5, 5, 5, 10, 10, 5, 5, 5, 29 | 10, 10, 10, 20, 20, 10, 10, 10, 30 | 20, 20, 20, 30, 30, 20, 20, 20, 31 | 0, 0, 0, 0, 0, 0, 0, 0 32 | }; 33 | 34 | const int KnightTable[64] = { 35 | 0, -10,0, 0, 0, 0, -10,0, 36 | 0, 0, 0, 5, 5, 0, 0, 0, 37 | 0, 0, 10, 10, 10, 10, 0, 0, 38 | 0, 0, 10, 20, 20, 10, 5, 0, 39 | 5, 10, 15, 20, 20, 15, 10, 5, 40 | 5, 10, 10, 20, 20, 10, 10, 5, 41 | 0, 0, 5, 10, 10, 5, 0, 0, 42 | 0, 0, 0, 0, 0, 0, 0, 0 43 | }; 44 | 45 | const int BishopTable[64] = { 46 | 0, 0, -10,0, 0, -10,0, 0, 47 | 0, 0, 0, 10, 10, 0, 0, 0, 48 | 0, 0, 10, 15, 15, 10, 0, 0, 49 | 0, 10, 15, 20, 20, 15, 10, 0, 50 | 0, 10, 15, 20, 20, 15, 10, 0, 51 | 0, 0, 10, 15, 15, 10, 0, 0, 52 | 0, 0, 0, 10, 10, 0, 0, 0, 53 | 0, 0, 0, 0, 0, 0, 0, 0 54 | }; 55 | 56 | const int RookTable[64] = { 57 | 0, 0, 5, 10, 10, 5, 0, 0, 58 | 0, 0, 5, 10, 10, 5, 0, 0, 59 | 0, 0, 5, 10, 10, 5, 0, 0, 60 | 0, 0, 5, 10, 10, 5, 0, 0, 61 | 0, 0, 5, 10, 10, 5, 0, 0, 62 | 0, 0, 5, 10, 10, 5, 0, 0, 63 | 25, 25, 25, 25, 25, 25, 25, 25, 64 | 0, 0, 5, 10, 10, 5, 0, 0 65 | }; 66 | 67 | const int KingE[64] = { 68 | -50,-10,0, 0, 0, 0, -10,-50, 69 | -10,0, 10, 10, 10, 10, 0, -10, 70 | 0, 10, 15, 15, 15, 15, 10, 0, 71 | 0, 10, 15, 20, 20, 15, 10, 0, 72 | 0, 10, 15, 20, 20, 15, 10, 0, 73 | 0, 10, 15, 15, 15, 15, 10, 0, 74 | -10,0, 10, 10, 10, 10, 0, -10, 75 | -50,-10,0, 0, 0, 0, -10,-50 76 | }; 77 | 78 | const int KingO[64] = { 79 | 0, 5, 5, -10,-10,0, 10, 5, 80 | -30,-30,-30,-30,-30,-30,-30,-30, 81 | -50,-50,-50,-50,-50,-50,-50,-50, 82 | -70,-70,-70,-70,-70,-70,-70,-70, 83 | -70,-70,-70,-70,-70,-70,-70,-70, 84 | -70,-70,-70,-70,-70,-70,-70,-70, 85 | -70,-70,-70,-70,-70,-70,-70,-70, 86 | -70,-70,-70,-70,-70,-70,-70,-70 87 | }; 88 | 89 | int MaterialDraw(const S_BOARD *pos) { 90 | if(!pos->pceNum[wR] && !pos->pceNum[bR] && !pos->pceNum[wQ] && !pos->pceNum[bQ]) { 91 | if(!pos->pceNum[bB] && !pos->pceNum[wB]) { 92 | if(pos->pceNum[wN] < 3 && pos->pceNum[bN] < 3) 93 | return TRUE; 94 | } else if (!pos->pceNum[wN] && !pos->pceNum[bN]) { 95 | if (abs(pos->pceNum[wB] - pos->pceNum[bB]) < 2) 96 | return TRUE; 97 | } else if ((pos->pceNum[wN] < 3 && !pos->pceNum[wB]) || (pos->pceNum[wB] == 1 && !pos->pceNum[wN])) { 98 | if ((pos->pceNum[bN] < 3 && !pos->pceNum[bB]) || (pos->pceNum[bB] == 1 && !pos->pceNum[bN])) 99 | return TRUE; 100 | } 101 | } else if (!pos->pceNum[wQ] && !pos->pceNum[bQ]) { 102 | if (pos->pceNum[wR] == 1 && pos->pceNum[bR] == 1) { 103 | if ((pos->pceNum[wN] + pos->pceNum[wB]) < 2 && (pos->pceNum[bN] + pos->pceNum[bB]) < 2) 104 | return TRUE; 105 | } else if (pos->pceNum[wR] == 1 && !pos->pceNum[bR]) { 106 | if ((pos->pceNum[wN] + pos->pceNum[wB] == 0) && (((pos->pceNum[bN] + pos->pceNum[bB]) == 1) || ((pos->pceNum[bN] + pos->pceNum[bB]) == 2))) 107 | return TRUE; 108 | } else if (pos->pceNum[bR] == 1 && !pos->pceNum[wR]) { 109 | if ((pos->pceNum[bN] + pos->pceNum[bB] == 0) && (((pos->pceNum[wN] + pos->pceNum[wB]) == 1) || ((pos->pceNum[wN] + pos->pceNum[wB]) == 2))) 110 | return TRUE; 111 | } 112 | } 113 | return FALSE; 114 | } 115 | 116 | #define ENDGAME_MAT (PieceVal[wR] + 2 * PieceVal[wN] + 2 * PieceVal[wP]) 117 | 118 | int EvalPosition(const S_BOARD *pos) { 119 | int pce; 120 | int pceNum; 121 | int sq; 122 | int score = pos->material[WHITE] - pos->material[BLACK]; 123 | 124 | if(!pos->pceNum[wP] && !pos->pceNum[bP] && MaterialDraw(pos) == TRUE) 125 | return 0; 126 | 127 | pce = wP; 128 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 129 | sq = pos->pList[pce][pceNum]; 130 | ASSERT(SqOnBoard(sq)); 131 | score += PawnTable[SQ64(sq)]; 132 | 133 | if((IsolatedMask[SQ64(sq)] & pos->pawns[WHITE]) == 0) 134 | score += PawnIsolated; 135 | 136 | if((WhitePassedMask[SQ64(sq)] & pos->pawns[BLACK]) == 0) 137 | score += PawnPassed[RanksBrd[sq]]; 138 | } 139 | 140 | pce = bP; 141 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 142 | sq = pos->pList[pce][pceNum]; 143 | ASSERT(SqOnBoard(sq)); 144 | score -= PawnTable[MIRROR64(SQ64(sq))]; 145 | 146 | if((IsolatedMask[SQ64(sq)] & pos->pawns[BLACK]) == 0) 147 | score -= PawnIsolated; 148 | 149 | if((BlackPassedMask[SQ64(sq)] & pos->pawns[WHITE]) == 0) 150 | score -= PawnPassed[7 - RanksBrd[sq]]; 151 | } 152 | 153 | pce = wN; 154 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 155 | sq = pos->pList[pce][pceNum]; 156 | ASSERT(SqOnBoard(sq)); 157 | score += KnightTable[SQ64(sq)]; 158 | } 159 | 160 | pce = bN; 161 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 162 | sq = pos->pList[pce][pceNum]; 163 | ASSERT(SqOnBoard(sq)); 164 | score -= KnightTable[MIRROR64(SQ64(sq))]; 165 | } 166 | 167 | pce = wB; 168 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 169 | sq = pos->pList[pce][pceNum]; 170 | ASSERT(SqOnBoard(sq)); 171 | score += BishopTable[SQ64(sq)]; 172 | } 173 | 174 | pce = bB; 175 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 176 | sq = pos->pList[pce][pceNum]; 177 | ASSERT(SqOnBoard(sq)); 178 | score -= BishopTable[MIRROR64(SQ64(sq))]; 179 | } 180 | 181 | pce = wR; 182 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 183 | sq = pos->pList[pce][pceNum]; 184 | ASSERT(SqOnBoard(sq)); 185 | score += RookTable[SQ64(sq)]; 186 | 187 | if(!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) { 188 | score += RookOpenFile; 189 | } else if(!(pos->pawns[WHITE] & FileBBMask[FilesBrd[sq]])) { 190 | score += RookSemiOpenFile; 191 | } 192 | } 193 | 194 | pce = bR; 195 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 196 | sq = pos->pList[pce][pceNum]; 197 | ASSERT(SqOnBoard(sq)); 198 | score -= RookTable[MIRROR64(SQ64(sq))]; 199 | 200 | if(!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) { 201 | score -= RookOpenFile; 202 | } else if(!(pos->pawns[BLACK] & FileBBMask[FilesBrd[sq]])) { 203 | score -= RookSemiOpenFile; 204 | } 205 | } 206 | 207 | pce = wQ; 208 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 209 | sq = pos->pList[pce][pceNum]; 210 | ASSERT(SqOnBoard(sq)); 211 | 212 | if(!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) { 213 | score += QueenOpenFile; 214 | } else if(!(pos->pawns[WHITE] & FileBBMask[FilesBrd[sq]])) { 215 | score += QueenSemiOpenFile; 216 | } 217 | } 218 | 219 | pce = bQ; 220 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 221 | sq = pos->pList[pce][pceNum]; 222 | ASSERT(SqOnBoard(sq)); 223 | 224 | if(!(pos->pawns[BOTH] & FileBBMask[FilesBrd[sq]])) { 225 | score -= QueenOpenFile; 226 | } else if(!(pos->pawns[BLACK] & FileBBMask[FilesBrd[sq]])) { 227 | score -= QueenSemiOpenFile; 228 | } 229 | } 230 | 231 | pce = wK; 232 | sq = pos->pList[pce][0]; 233 | if(pos->material[BLACK] <= ENDGAME_MAT) { 234 | score += KingE[SQ64(sq)]; 235 | } else { 236 | score += KingO[SQ64(sq)]; 237 | } 238 | 239 | pce = bK; 240 | sq = pos->pList[pce][0]; 241 | if(pos->material[WHITE] <= ENDGAME_MAT) { 242 | score -= KingE[MIRROR64(SQ64(sq))]; 243 | } else { 244 | score -= KingO[MIRROR64(SQ64(sq))]; 245 | } 246 | 247 | if(pos->pceNum[wB] >= 2) score += BishopPair; 248 | if(pos->pceNum[bB] >= 2) score -= BishopPair; 249 | 250 | if(pos->side == WHITE) { 251 | return score; 252 | } else { 253 | return -score; 254 | } 255 | } 256 | -------------------------------------------------------------------------------- /vice/hashkeys.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | 14 | U64 GeneratePositionKey(const S_BOARD *pos) { 15 | int sq = 0; 16 | U64 finalKey = 0; 17 | int piece = EMPTY; 18 | 19 | for(sq = 0; sq < BRD_SQ_NUM; ++sq) { 20 | piece = pos->pieces[sq]; 21 | if(piece != OFFBOARD && piece != EMPTY) { 22 | ASSERT(piece >= wP && piece <= bK); 23 | finalKey ^= PieceKeys[piece][sq]; 24 | } 25 | } 26 | 27 | if(pos->side == WHITE) 28 | finalKey ^= SideKey; 29 | 30 | if(pos->enPas != NO_SQ) { 31 | ASSERT(pos->enPas >= 0 && pos->enPas < BRD_SQ_NUM); 32 | finalKey ^= PieceKeys[EMPTY][pos->enPas]; 33 | } 34 | 35 | ASSERT(pos->castlePerm >= 0 && pos->castlePerm <= 15); 36 | finalKey ^= CastleKeys[pos->castlePerm]; 37 | 38 | return finalKey; 39 | } -------------------------------------------------------------------------------- /vice/init.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include "defs.h" 16 | 17 | #define RAND_64 ((U64)rand() | \ 18 | ((U64) rand() << 15) | \ 19 | ((U64) rand() << 30) | \ 20 | ((U64) rand() << 45) | \ 21 | (((U64)rand() & 0xf) << 60)) 22 | 23 | 24 | int Sq120ToSq64[BRD_SQ_NUM]; 25 | int Sq64ToSq120[64]; 26 | 27 | U64 SetMask[64]; 28 | U64 ClearMask[64]; 29 | 30 | U64 PieceKeys[13][120]; 31 | U64 SideKey; 32 | U64 CastleKeys[16]; 33 | 34 | int FilesBrd[BRD_SQ_NUM]; 35 | int RanksBrd[BRD_SQ_NUM]; 36 | 37 | U64 FileBBMask[8]; 38 | U64 RankBBMask[8]; 39 | 40 | U64 BlackPassedMask[64]; 41 | U64 WhitePassedMask[64]; 42 | U64 IsolatedMask[64]; 43 | 44 | void InitEvalMasks(void) { 45 | int sq, tsq, r, f; 46 | 47 | for(sq = 0; sq < 8; ++sq) { 48 | FileBBMask[sq] = 0ULL; 49 | RankBBMask[sq] = 0ULL; 50 | } 51 | 52 | for(r = RANK_8; r >= RANK_1; r--) { 53 | for(f = FILE_A; f <= FILE_H; f++) { 54 | sq = r * 8 + f; 55 | FileBBMask[f] |= (1ULL << sq); 56 | RankBBMask[r] |= (1ULL << sq); 57 | } 58 | } 59 | 60 | for(sq = 0; sq < 64; ++sq) { 61 | IsolatedMask[sq] = 0ULL; 62 | BlackPassedMask[sq] = 0ULL; 63 | WhitePassedMask[sq] = 0ULL; 64 | } 65 | 66 | for(sq = 0; sq < 64; ++sq) { 67 | tsq = sq + 8; 68 | 69 | while(tsq < 64) { 70 | WhitePassedMask[sq] |= (1ULL << tsq); 71 | tsq += 8; 72 | } 73 | 74 | tsq = sq - 8; 75 | while(tsq >= 0) { 76 | BlackPassedMask[sq] |= (1ULL << tsq); 77 | tsq -= 8; 78 | } 79 | 80 | if(FilesBrd[SQ120(sq)] > FILE_A) { 81 | IsolatedMask[sq] |= FileBBMask[FilesBrd[SQ120(sq)] - 1]; 82 | 83 | tsq = sq + 7; 84 | while(tsq < 64) { 85 | WhitePassedMask[sq] |= (1ULL << tsq); 86 | tsq += 8; 87 | } 88 | 89 | tsq = sq - 9; 90 | while(tsq >= 0) { 91 | BlackPassedMask[sq] |= (1ULL << tsq); 92 | tsq -= 8; 93 | } 94 | } 95 | 96 | if(FilesBrd[SQ120(sq)] < FILE_H) { 97 | IsolatedMask[sq] |= FileBBMask[FilesBrd[SQ120(sq)] + 1]; 98 | 99 | tsq = sq + 9; 100 | while(tsq < 64) { 101 | WhitePassedMask[sq] |= (1ULL << tsq); 102 | tsq += 8; 103 | } 104 | 105 | tsq = sq - 7; 106 | while(tsq >= 0) { 107 | BlackPassedMask[sq] |= (1ULL << tsq); 108 | tsq -= 8; 109 | } 110 | } 111 | } 112 | } 113 | 114 | void InitFilesRanksBrd(void) { 115 | int index = 0; 116 | int file = FILE_A; 117 | int rank = RANK_1; 118 | int sq = A1; 119 | 120 | for(index = 0; index < BRD_SQ_NUM; ++index) { 121 | FilesBrd[index] = OFFBOARD; 122 | RanksBrd[index] = OFFBOARD; 123 | } 124 | 125 | for(rank = RANK_1; rank <= RANK_8; ++rank) { 126 | for(file = FILE_A; file <= FILE_H; ++file) { 127 | sq = FR2SQ(file, rank); 128 | FilesBrd[sq] = file; 129 | RanksBrd[sq] = rank; 130 | } 131 | } 132 | } 133 | 134 | void InitHashKeys(void) { 135 | int index = 0; 136 | int index2 = 0; 137 | 138 | for(index = 0; index < 13; index++) 139 | for(index2 = 0; index2 < 120; index2++) 140 | PieceKeys[index][index2] = RAND_64; 141 | 142 | SideKey = RAND_64; 143 | 144 | for(index = 0; index < 16; index++) 145 | CastleKeys[index] = RAND_64; 146 | } 147 | 148 | void InitBitMasks(void) { 149 | int index = 0; 150 | 151 | for(index = 0; index < 64; index++) { 152 | SetMask[index] = 0ULL; 153 | ClearMask[index] = 0ULL; 154 | } 155 | 156 | for(index = 0; index < 64; index++) { 157 | SetMask[index] |= (1ULL << index); 158 | ClearMask[index] = ~SetMask[index]; 159 | } 160 | } 161 | 162 | void InitSq120To64(void) { 163 | int index = 0; 164 | int file = FILE_A; 165 | int rank = RANK_1; 166 | int sq = A1; 167 | int sq64 = 0; 168 | 169 | for(index = 0; index < BRD_SQ_NUM; ++index) 170 | Sq120ToSq64[index] = 65; 171 | 172 | for(index = 0; index < 64; ++index) 173 | Sq64ToSq120[index] = 120; 174 | 175 | for(rank = RANK_1; rank <= RANK_8; ++rank) { 176 | for(file = FILE_A; file <= FILE_H; ++file) { 177 | sq = FR2SQ(file, rank); 178 | Sq64ToSq120[sq64] = sq; 179 | Sq120ToSq64[sq] = sq64; 180 | sq64++; 181 | } 182 | } 183 | } 184 | 185 | void AllInit(void) { 186 | srand(time(NULL)); 187 | InitSq120To64(); 188 | InitBitMasks(); 189 | InitHashKeys(); 190 | InitFilesRanksBrd(); 191 | InitEvalMasks(); 192 | InitMvvLva(); 193 | InitPolyBook(); 194 | } 195 | -------------------------------------------------------------------------------- /vice/io.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | 14 | #include "defs.h" 15 | 16 | char *PrSq(const int sq) { 17 | static char SqStr[3]; 18 | 19 | int file = FilesBrd[sq]; 20 | int rank = RanksBrd[sq]; 21 | 22 | sprintf(SqStr, "%c%c", ('a' + file), ('1' + rank)); 23 | return SqStr; 24 | } 25 | 26 | char *PrMove(const int move) { 27 | static char MvStr[6]; 28 | char pchar; 29 | 30 | int ff = FilesBrd[FROMSQ(move)]; 31 | int rf = RanksBrd[FROMSQ(move)]; 32 | int ft = FilesBrd[TOSQ(move)]; 33 | int rt = RanksBrd[TOSQ(move)]; 34 | 35 | int promoted = PROMOTED(move); 36 | 37 | if(promoted) { 38 | pchar = 'q'; 39 | if(IsKn(promoted)) 40 | pchar = 'n'; 41 | else if(IsRQ(promoted) && !IsBQ(promoted)) 42 | pchar = 'r'; 43 | else if(!IsRQ(promoted) && IsBQ(promoted)) 44 | pchar = 'b'; 45 | 46 | sprintf(MvStr, "%c%c%c%c%c", ('a' + ff), ('1' + rf), ('a' + ft), ('1' + rt), pchar); 47 | } else { 48 | sprintf(MvStr, "%c%c%c%c", ('a' + ff), ('1' + rf), ('a' + ft), ('1' + rt)); 49 | } 50 | 51 | return MvStr; 52 | } 53 | 54 | int ParseMove(char *ptrChar, S_BOARD *pos) { 55 | int from, to; 56 | int MoveNum = 0, Move = 0, PromPce = EMPTY; 57 | S_MOVELIST list[1]; 58 | 59 | if(ptrChar[1] > '8' || ptrChar[1] < '1') return NOMOVE; 60 | if(ptrChar[3] > '8' || ptrChar[3] < '1') return NOMOVE; 61 | if(ptrChar[0] > 'h' || ptrChar[0] < 'a') return NOMOVE; 62 | if(ptrChar[2] > 'h' || ptrChar[2] < 'a') return NOMOVE; 63 | 64 | from = FR2SQ(ptrChar[0] - 'a', ptrChar[1] - '1'); 65 | to = FR2SQ(ptrChar[2] - 'a', ptrChar[3] - '1'); 66 | 67 | ASSERT(SqOnBoard(from) && SqOnBoard(to)); 68 | 69 | GenerateAllMoves(pos, list); 70 | 71 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 72 | Move = list->moves[MoveNum].move; 73 | if(FROMSQ(Move) == from && TOSQ(Move) == to) { 74 | PromPce = PROMOTED(Move); 75 | if(PromPce != EMPTY) { 76 | if(IsRQ(PromPce) && !IsBQ(PromPce) && ptrChar[4] == 'r') { 77 | return Move; 78 | } else if(!IsRQ(PromPce) && IsBQ(PromPce) && ptrChar[4] == 'b') { 79 | return Move; 80 | } else if(IsRQ(PromPce) && IsBQ(PromPce) && ptrChar[4] == 'q') { 81 | return Move; 82 | } else if(IsKn(PromPce) && ptrChar[4] == 'n') { 83 | return Move; 84 | } 85 | continue; 86 | } 87 | return Move; 88 | } 89 | } 90 | 91 | return NOMOVE; 92 | } 93 | 94 | void PrintMoveList(const S_MOVELIST *list) { 95 | int index = 0; 96 | int score = 0; 97 | int move = 0; 98 | printf("MoveList:\n"); 99 | 100 | for(index = 0; index < list->count; ++index) { 101 | move = list->moves[index].move; 102 | score = list->moves[index].score; 103 | 104 | printf("Move:%d > %s (score:%d)\n", index + 1, PrMove(move), score); 105 | } 106 | 107 | printf("MoveList Total %d Moves.\n\n", list->count); 108 | } -------------------------------------------------------------------------------- /vice/makemove.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | 14 | #define HASH_PCE(pce, sq) (pos->posKey ^= (PieceKeys[(pce)][(sq)])) 15 | #define HASH_CA (pos->posKey ^= (CastleKeys[(pos->castlePerm)])) 16 | #define HASH_SIDE (pos->posKey ^= (SideKey)) 17 | #define HASH_EP (pos->posKey ^= (PieceKeys[EMPTY][(pos->enPas)])) 18 | 19 | const int CastlePerm[120] = { 20 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 21 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 22 | 15, 13, 15, 15, 15, 12, 15, 15, 14, 15, 23 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 24 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 25 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 26 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 27 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 28 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 29 | 15, 7, 15, 15, 15, 3, 15, 15, 11, 15, 30 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15, 31 | 15, 15, 15, 15, 15, 15, 15, 15, 15, 15 32 | }; 33 | 34 | static void ClearPiece(const int sq, S_BOARD *pos) { 35 | int pce = pos->pieces[sq]; 36 | int col = PieceCol[pce]; 37 | int index = 0; 38 | int t_pceNum = -1; 39 | 40 | ASSERT(SqOnBoard(sq)); 41 | ASSERT(PieceValid(pce)); 42 | 43 | HASH_PCE(pce, sq); 44 | 45 | pos->pieces[sq] = EMPTY; 46 | pos->material[col] -= PieceVal[pce]; 47 | 48 | if(PieceBig[pce]) { 49 | pos->bigPce[col]--; 50 | 51 | if(PieceMaj[pce]) { 52 | pos->majPce[col]--; 53 | } else { 54 | pos->minPce[col]--; 55 | } 56 | } else { 57 | CLRBIT(pos->pawns[col], SQ64(sq)); 58 | CLRBIT(pos->pawns[BOTH], SQ64(sq)); 59 | } 60 | 61 | for(index = 0; index < pos->pceNum[pce]; ++index) { 62 | if(pos->pList[pce][index] == sq) { 63 | t_pceNum = index; 64 | break; 65 | } 66 | } 67 | 68 | ASSERT(t_pceNum != -1); 69 | 70 | pos->pceNum[pce]--; 71 | pos->pList[pce][t_pceNum] = pos->pList[pce][pos->pceNum[pce]]; 72 | } 73 | 74 | static void AddPiece(const int sq, S_BOARD *pos, const int pce) { 75 | int col = PieceCol[pce]; 76 | 77 | ASSERT(PieceValid(pce)); 78 | ASSERT(SqOnBoard(sq)); 79 | 80 | HASH_PCE(pce, sq); 81 | 82 | pos->pieces[sq] = pce; 83 | 84 | if(PieceBig[pce]) { 85 | pos->bigPce[col]++; 86 | if(PieceMaj[pce]) { 87 | pos->majPce[col]++; 88 | } else { 89 | pos->minPce[col]++; 90 | } 91 | } else { 92 | SETBIT(pos->pawns[col], SQ64(sq)); 93 | SETBIT(pos->pawns[BOTH], SQ64(sq)); 94 | } 95 | 96 | pos->material[col] += PieceVal[pce]; 97 | pos->pList[pce][pos->pceNum[pce]++] = sq; 98 | } 99 | 100 | static void MovePiece(const int from, const int to, S_BOARD *pos) { 101 | int index = 0; 102 | int pce = pos->pieces[from]; 103 | int col = PieceCol[pce]; 104 | #ifdef DEBUG 105 | int t_PieceNum = FALSE; 106 | #endif 107 | 108 | ASSERT(SqOnBoard(from)); 109 | ASSERT(SqOnBoard(to)); 110 | 111 | HASH_PCE(pce, from); 112 | pos->pieces[from] = EMPTY; 113 | 114 | HASH_PCE(pce, to); 115 | pos->pieces[to] = pce; 116 | 117 | if(!PieceBig[pce]) { 118 | CLRBIT(pos->pawns[col], SQ64(from)); 119 | CLRBIT(pos->pawns[BOTH], SQ64(from)); 120 | SETBIT(pos->pawns[col], SQ64(to)); 121 | SETBIT(pos->pawns[BOTH], SQ64(to)); 122 | } 123 | 124 | for(index = 0; index < pos->pceNum[pce]; ++index) { 125 | if(pos->pList[pce][index] == from) { 126 | pos->pList[pce][index] = to; 127 | #ifdef DEBUG 128 | t_PieceNum = TRUE; 129 | #endif 130 | break; 131 | } 132 | } 133 | ASSERT(t_PieceNum); 134 | } 135 | 136 | int MakeMove(S_BOARD *pos, int move) { 137 | int from = FROMSQ(move); 138 | int to = TOSQ(move); 139 | int side = pos->side; 140 | int captured = CAPTURED(move); 141 | int prPce = PROMOTED(move); 142 | 143 | ASSERT(CheckBoard(pos)); 144 | 145 | ASSERT(SqOnBoard(from)); 146 | ASSERT(SqOnBoard(to)); 147 | ASSERT(SideValid(side)); 148 | ASSERT(PieceValid(pos->pieces[from])); 149 | 150 | pos->history[pos->hisPly].posKey = pos->posKey; 151 | 152 | if(move & MFLAGEP) { 153 | if(side == WHITE) { 154 | ClearPiece(to - 10, pos); 155 | } else { 156 | ClearPiece(to + 10, pos); 157 | } 158 | } else if(move & MFLAGCA) { 159 | switch(to) { 160 | case C1: MovePiece(A1, D1, pos); break; 161 | case C8: MovePiece(A8, D8, pos); break; 162 | case G1: MovePiece(H1, F1, pos); break; 163 | case G8: MovePiece(H8, F8, pos); break; 164 | default: ASSERT(FALSE); 165 | } 166 | } 167 | 168 | if(pos->enPas != NO_SQ) HASH_EP; 169 | HASH_CA; 170 | 171 | pos->history[pos->hisPly].move = move; 172 | pos->history[pos->hisPly].fiftyMoves = pos->fiftyMove; 173 | pos->history[pos->hisPly].enPas = pos->enPas; 174 | pos->history[pos->hisPly].castlePerm = pos->castlePerm; 175 | 176 | pos->castlePerm &= CastlePerm[from]; 177 | pos->castlePerm &= CastlePerm[to]; 178 | pos->enPas = NO_SQ; 179 | 180 | HASH_CA; 181 | 182 | pos->fiftyMove++; 183 | 184 | if(captured != EMPTY) { 185 | ASSERT(PieceValid(captured)); 186 | ClearPiece(to, pos); 187 | pos->fiftyMove = 0; 188 | } 189 | 190 | pos->hisPly++; 191 | pos->ply++; 192 | 193 | if(PiecePawn[pos->pieces[from]]) { 194 | pos->fiftyMove = 0; 195 | if(move & MFLAGPS) { 196 | if(side == WHITE) { 197 | pos->enPas = from + 10; 198 | ASSERT(RanksBrd[pos->enPas] == RANK_3); 199 | } else { 200 | pos->enPas = from - 10; 201 | ASSERT(RanksBrd[pos->enPas] == RANK_6); 202 | } 203 | HASH_EP; 204 | } 205 | } 206 | 207 | MovePiece(from, to, pos); 208 | 209 | if(prPce != EMPTY) { 210 | ASSERT(PieceValid(prPce) && !PiecePawn[prPce]); 211 | ClearPiece(to, pos); 212 | AddPiece(to, pos, prPce); 213 | } 214 | 215 | if(PieceKing[pos->pieces[to]]) { 216 | pos->KingSq[pos->side] = to; 217 | } 218 | 219 | pos->side ^= 1; 220 | HASH_SIDE; 221 | 222 | ASSERT(CheckBoard(pos)); 223 | 224 | if(SqAttacked(pos->KingSq[side], pos->side, pos)) { 225 | TakeMove(pos); 226 | return FALSE; 227 | } 228 | 229 | return TRUE; 230 | } 231 | 232 | void TakeMove(S_BOARD *pos) { 233 | int move = pos->history[pos->hisPly - 1].move; 234 | int from = FROMSQ(move); 235 | int to = TOSQ(move); 236 | int captured = CAPTURED(move); 237 | 238 | ASSERT(CheckBoard(pos)); 239 | 240 | pos->hisPly--; 241 | pos->ply--; 242 | 243 | ASSERT(SqOnBoard(from)); 244 | ASSERT(SqOnBoard(to)); 245 | 246 | if(pos->enPas != NO_SQ) HASH_EP; 247 | HASH_CA; 248 | 249 | pos->castlePerm = pos->history[pos->hisPly].castlePerm; 250 | pos->fiftyMove = pos->history[pos->hisPly].fiftyMoves; 251 | pos->enPas = pos->history[pos->hisPly].enPas; 252 | 253 | if(pos->enPas != NO_SQ) HASH_EP; 254 | HASH_CA; 255 | 256 | pos->side ^= 1; 257 | HASH_SIDE; 258 | 259 | if(MFLAGEP & move) { 260 | if(pos->side == WHITE) { 261 | AddPiece(to - 10, pos, bP); 262 | } else { 263 | AddPiece(to + 10, pos, wP); 264 | } 265 | } else if(MFLAGCA & move) { 266 | switch(to) { 267 | case C1: MovePiece(D1, A1, pos); break; 268 | case C8: MovePiece(D8, A8, pos); break; 269 | case G1: MovePiece(F1, H1, pos); break; 270 | case G8: MovePiece(F8, H8, pos); break; 271 | default: ASSERT(FALSE); break; 272 | } 273 | } 274 | 275 | MovePiece(to, from, pos); 276 | 277 | if(PieceKing[pos->pieces[from]]) { 278 | pos->KingSq[pos->side] = from; 279 | } 280 | 281 | if(captured != EMPTY) { 282 | ASSERT(PieceValid(captured)); 283 | AddPiece(to, pos, captured); 284 | } 285 | 286 | if(PROMOTED(move) != EMPTY) { 287 | ASSERT(PieceValid(PROMOTED(move)) && !PiecePawn[PROMOTED(move)]); 288 | ClearPiece(from, pos); 289 | AddPiece(from, pos, (PieceCol[PROMOTED(move)] == WHITE ? wP : bP)); 290 | } 291 | ASSERT(CheckBoard(pos)); 292 | } 293 | 294 | void MakeNullMove(S_BOARD *pos) { 295 | ASSERT(CheckBoard(pos)); 296 | ASSERT(!SqAttacked(pos->KingSq[pos->side], pos->side ^ 1, pos)); 297 | 298 | pos->ply++; 299 | pos->history[pos->hisPly].posKey = pos->posKey; 300 | 301 | if(pos->enPas != NO_SQ) HASH_EP; 302 | 303 | pos->history[pos->hisPly].move = NOMOVE; 304 | pos->history[pos->hisPly].fiftyMoves = pos->fiftyMove; 305 | pos->history[pos->hisPly].enPas = pos->enPas; 306 | pos->history[pos->hisPly].castlePerm = pos->castlePerm; 307 | pos->enPas = NO_SQ; 308 | 309 | pos->side ^= 1; 310 | pos->hisPly++; 311 | HASH_SIDE; 312 | 313 | ASSERT(CheckBoard(pos)); 314 | } 315 | 316 | void TakeNullMove(S_BOARD *pos) { 317 | ASSERT(CheckBoard(pos)); 318 | 319 | pos->hisPly--; 320 | pos->ply--; 321 | 322 | pos->castlePerm = pos->history[pos->hisPly].castlePerm; 323 | pos->fiftyMove = pos->history[pos->hisPly].fiftyMoves; 324 | pos->enPas = pos->history[pos->hisPly].enPas; 325 | 326 | if(pos->enPas != NO_SQ) HASH_EP; 327 | pos->side ^= 1; 328 | HASH_SIDE; 329 | 330 | ASSERT(CheckBoard(pos)); 331 | } -------------------------------------------------------------------------------- /vice/misc.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "defs.h" 17 | 18 | #ifdef WIN32 19 | #include 20 | #include 21 | #else 22 | #include 23 | #include 24 | #endif 25 | 26 | int GetTimeMs(void) { 27 | #ifdef WIN32 28 | return GetTickCount(); 29 | #else 30 | struct timeval t; 31 | gettimeofday(&t, NULL); 32 | return t.tv_sec * 1000 + t.tv_usec / 1000; 33 | #endif 34 | } 35 | 36 | // http://home.arcor.de/dreamlike/chess/ 37 | int InputWaiting() 38 | { 39 | #ifndef WIN32 40 | struct timeval tv; 41 | fd_set readfds; 42 | 43 | FD_ZERO (&readfds); 44 | FD_SET (fileno(stdin), &readfds); 45 | tv.tv_sec=0; tv.tv_usec=0; 46 | select(16, &readfds, 0, 0, &tv); 47 | 48 | return (FD_ISSET(fileno(stdin), &readfds)); 49 | #else 50 | static int init = 0, pipe; 51 | static HANDLE inh; 52 | DWORD dw; 53 | 54 | if (!init) { 55 | init = 1; 56 | inh = GetStdHandle(STD_INPUT_HANDLE); 57 | pipe = !GetConsoleMode(inh, &dw); 58 | if (!pipe) { 59 | SetConsoleMode(inh, dw & ~(ENABLE_MOUSE_INPUT|ENABLE_WINDOW_INPUT)); 60 | FlushConsoleInputBuffer(inh); 61 | } 62 | } 63 | if (pipe) { 64 | if (!PeekNamedPipe(inh, NULL, 0, NULL, &dw, NULL)) 65 | return 1; 66 | return dw; 67 | } else { 68 | GetNumberOfConsoleInputEvents(inh, &dw); 69 | return dw <= 1 ? 0 : dw; 70 | } 71 | #endif 72 | } 73 | 74 | void ReadInput(S_SEARCHINFO *info) { 75 | int bytes; 76 | char input[256] = "", *endc; 77 | 78 | if(InputWaiting()) { 79 | info->stopped = TRUE; 80 | do { 81 | bytes=read(fileno(stdin), input, 256); 82 | } while (bytes<0); 83 | endc = strchr(input, '\n'); 84 | if (endc) 85 | *endc = 0; 86 | 87 | if (strlen(input) > 0) { 88 | if (!strncmp(input, "quit", 4)) { 89 | info->quit = TRUE; 90 | } 91 | } 92 | return; 93 | } 94 | } 95 | -------------------------------------------------------------------------------- /vice/movegen.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include "defs.h" 14 | 15 | #define MOVE(f, t, ca, pro, fl) ((f) | ((t) << 7) | ((ca) << 14) | ((pro) << 20) | (fl)) 16 | #define SQOFFBOARD(sq) (FilesBrd[(sq)] == OFFBOARD) 17 | 18 | const int LoopSlidePce[8] = { wB, wR, wQ, 0, bB, bR, bQ, 0 }; 19 | const int LoopSlideIndex[2] = { 0, 4 }; 20 | const int LoopNonSlidePce[6] = { wN, wK, 0, bN, bK, 0 }; 21 | const int LoopNonSlideIndex[2] = { 0, 3 }; 22 | 23 | const int PceDir[13][8] = { 24 | { 0, 0, 0, 0, 0, 0, 0 }, 25 | { 0, 0, 0, 0, 0, 0, 0 }, 26 | { -8, -19, -21, -12, 8, 19, 21, 12 }, 27 | { -9, -11, 11, 9, 0, 0, 0, 0 }, 28 | { -1, -10, 1, 10, 0, 0, 0, 0 }, 29 | { -1, -10, 1, 10, -9, -11, 11, 9 }, 30 | { -1, -10, 1, 10, -9, -11, 11, 9 }, 31 | { 0, 0, 0, 0, 0, 0, 0 }, 32 | { -8, -19, -21, -12, 8, 19, 21, 12 }, 33 | { -9, -11, 11, 9, 0, 0, 0, 0 }, 34 | { -1, -10, 1, 10, 0, 0, 0, 0 }, 35 | { -1, -10, 1, 10, -9, -11, 11, 9 }, 36 | { -1, -10, 1, 10, -9, -11, 11, 9 } 37 | }; 38 | 39 | const int NumDir[13] = { 0, 0, 8, 4, 4, 8, 8, 0, 8, 4, 4, 8, 8 }; 40 | 41 | const int VictimScore[13] = { 0, 100, 200, 300, 400, 500, 600, 100, 200, 300, 400, 500, 600 }; 42 | static int MvvLvaScores[13][13]; 43 | 44 | void InitMvvLva(void) { 45 | int Attacker; 46 | int Victim; 47 | 48 | for(Attacker = wP; Attacker <= bK; ++Attacker) { 49 | for(Victim = wP; Victim <= bK; ++Victim) { 50 | MvvLvaScores[Victim][Attacker] = VictimScore[Victim] + 6 - (VictimScore[Attacker] / 100); 51 | } 52 | } 53 | } 54 | 55 | int MoveExists(S_BOARD *pos, const int move) { 56 | int MoveNum = 0; 57 | 58 | S_MOVELIST list[1]; 59 | GenerateAllMoves(pos, list); 60 | 61 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 62 | if(!MakeMove(pos, list->moves[MoveNum].move)) { 63 | continue; 64 | } 65 | TakeMove(pos); 66 | if(list->moves[MoveNum].move == move) { 67 | return TRUE; 68 | } 69 | } 70 | return FALSE; 71 | } 72 | 73 | static void AddQuietMove(const S_BOARD *pos, int move, S_MOVELIST *list) { 74 | list->moves[list->count].move = move; 75 | 76 | if(pos->searchKillers[0][pos->ply] == move) { 77 | list->moves[list->count].score = 900000; 78 | } else if(pos->searchKillers[1][pos->ply] == move) { 79 | list->moves[list->count].score = 800000; 80 | } else { 81 | list->moves[list->count].score = pos->searchHistory[pos->pieces[FROMSQ(move)]][TOSQ(move)]; 82 | } 83 | list->count++; 84 | } 85 | 86 | static void AddCaptureMove(const S_BOARD *pos, int move, S_MOVELIST *list) { 87 | list->moves[list->count].move = move; 88 | list->moves[list->count].score = MvvLvaScores[CAPTURED(move)][pos->pieces[FROMSQ(move)]] + 1000000; 89 | list->count++; 90 | } 91 | 92 | static void AddEnPassantMove(const S_BOARD *pos, int move, S_MOVELIST *list) { 93 | list->moves[list->count].move = move; 94 | list->moves[list->count].score = 105 + 1000000; 95 | list->count++; 96 | } 97 | 98 | static void AddWhitePawnCapMove(const S_BOARD *pos, const int from, const int to, const int cap, S_MOVELIST *list) { 99 | ASSERT(PieceValidEmpty(cap)); 100 | ASSERT(SqOnBoard(from)); 101 | ASSERT(SqOnBoard(to)); 102 | 103 | if(RanksBrd[from] == RANK_7) { 104 | AddCaptureMove(pos, MOVE(from, to, cap, wQ, 0), list); 105 | AddCaptureMove(pos, MOVE(from, to, cap, wR, 0), list); 106 | AddCaptureMove(pos, MOVE(from, to, cap, wB, 0), list); 107 | AddCaptureMove(pos, MOVE(from, to, cap, wN, 0), list); 108 | } else { 109 | AddCaptureMove(pos, MOVE(from, to, cap, EMPTY, 0), list); 110 | } 111 | } 112 | 113 | static void AddWhitePawnMove(const S_BOARD *pos, const int from, const int to, S_MOVELIST *list) { 114 | ASSERT(SqOnBoard(from)); 115 | ASSERT(SqOnBoard(to)); 116 | 117 | if(RanksBrd[from] == RANK_7) { 118 | AddQuietMove(pos, MOVE(from, to, EMPTY, wQ, 0), list); 119 | AddQuietMove(pos, MOVE(from, to, EMPTY, wR, 0), list); 120 | AddQuietMove(pos, MOVE(from, to, EMPTY, wB, 0), list); 121 | AddQuietMove(pos, MOVE(from, to, EMPTY, wN, 0), list); 122 | } else { 123 | AddQuietMove(pos, MOVE(from, to, EMPTY, EMPTY, 0), list); 124 | } 125 | } 126 | 127 | static void AddBlackPawnCapMove(const S_BOARD *pos, const int from, const int to, const int cap, S_MOVELIST *list) { 128 | ASSERT(PieceValidEmpty(cap)); 129 | ASSERT(SqOnBoard(from)); 130 | ASSERT(SqOnBoard(to)); 131 | 132 | if(RanksBrd[from] == RANK_2) { 133 | AddCaptureMove(pos, MOVE(from, to, cap, bQ, 0), list); 134 | AddCaptureMove(pos, MOVE(from, to, cap, bR, 0), list); 135 | AddCaptureMove(pos, MOVE(from, to, cap, bB, 0), list); 136 | AddCaptureMove(pos, MOVE(from, to, cap, bN, 0), list); 137 | } else { 138 | AddCaptureMove(pos, MOVE(from, to, cap, EMPTY, 0), list); 139 | } 140 | } 141 | 142 | static void AddBlackPawnMove(const S_BOARD *pos, const int from, const int to, S_MOVELIST *list) { 143 | ASSERT(SqOnBoard(from)); 144 | ASSERT(SqOnBoard(to)); 145 | 146 | if(RanksBrd[from] == RANK_2) { 147 | AddQuietMove(pos, MOVE(from, to, EMPTY, bQ, 0), list); 148 | AddQuietMove(pos, MOVE(from, to, EMPTY, bR, 0), list); 149 | AddQuietMove(pos, MOVE(from, to, EMPTY, bB, 0), list); 150 | AddQuietMove(pos, MOVE(from, to, EMPTY, bN, 0), list); 151 | } else { 152 | AddQuietMove(pos, MOVE(from, to, EMPTY, EMPTY, 0), list); 153 | } 154 | } 155 | 156 | void GenerateAllMoves(const S_BOARD *pos, S_MOVELIST *list) { 157 | int pce = EMPTY; 158 | int side = pos->side; 159 | int sq = 0, t_sq = 0; 160 | int pceNum = 0; 161 | 162 | int dir = 0; 163 | int index = 0; 164 | int pceIndex = 0; 165 | 166 | ASSERT(CheckBoard(pos)); 167 | list->count = 0; 168 | 169 | if(side == WHITE) { 170 | for(pceNum = 0; pceNum < pos->pceNum[wP]; ++pceNum) { 171 | sq = pos->pList[wP][pceNum]; 172 | ASSERT(SqOnBoard(sq)); 173 | 174 | if(pos->pieces[sq + 10] == EMPTY) { 175 | AddWhitePawnMove(pos, sq, sq + 10, list); 176 | if(RanksBrd[sq] == RANK_2 && pos->pieces[sq + 20] == EMPTY) { 177 | AddQuietMove(pos, MOVE(sq, (sq + 20), EMPTY, EMPTY, MFLAGPS), list); 178 | } 179 | } 180 | 181 | if(!SQOFFBOARD(sq + 9) && PieceCol[pos->pieces[sq + 9]] == BLACK) { 182 | AddWhitePawnCapMove(pos, sq, sq + 9, pos->pieces[sq + 9], list); 183 | } 184 | if(!SQOFFBOARD(sq + 11) && PieceCol[pos->pieces[sq + 11]] == BLACK) { 185 | AddWhitePawnCapMove(pos, sq, sq + 11, pos->pieces[sq + 11], list); 186 | } 187 | 188 | if(pos->enPas != NO_SQ) { 189 | if(sq + 9 == pos->enPas) { 190 | AddEnPassantMove(pos, MOVE(sq, sq + 9, EMPTY, EMPTY, MFLAGEP), list); 191 | } 192 | if(sq + 11 == pos->enPas) { 193 | AddEnPassantMove(pos, MOVE(sq, sq + 11, EMPTY, EMPTY, MFLAGEP), list); 194 | } 195 | } 196 | } 197 | 198 | if(pos->castlePerm & WKCA) { 199 | if(pos->pieces[F1] == EMPTY && pos->pieces[G1] == EMPTY) { 200 | if(!SqAttacked(E1, BLACK, pos) && !SqAttacked(F1, BLACK, pos)) { 201 | AddQuietMove(pos, MOVE(E1, G1, EMPTY, EMPTY, MFLAGCA), list); 202 | } 203 | } 204 | } 205 | 206 | if(pos->castlePerm & WQCA) { 207 | if(pos->pieces[D1] == EMPTY && pos->pieces[C1] == EMPTY && pos->pieces[B1] == EMPTY) { 208 | if(!SqAttacked(E1, BLACK, pos) && !SqAttacked(D1, BLACK, pos)) { 209 | AddQuietMove(pos, MOVE(E1, C1, EMPTY, EMPTY, MFLAGCA), list); 210 | } 211 | } 212 | } 213 | } else { 214 | for(pceNum = 0; pceNum < pos->pceNum[bP]; ++pceNum) { 215 | sq = pos->pList[bP][pceNum]; 216 | ASSERT(SqOnBoard(sq)); 217 | 218 | if(pos->pieces[sq - 10] == EMPTY) { 219 | AddBlackPawnMove(pos, sq, sq - 10, list); 220 | if(RanksBrd[sq] == RANK_7 && pos->pieces[sq - 20] == EMPTY) { 221 | AddQuietMove(pos, MOVE(sq, (sq - 20), EMPTY, EMPTY, MFLAGPS), list); 222 | } 223 | } 224 | 225 | if(!SQOFFBOARD(sq - 9) && PieceCol[pos->pieces[sq - 9]] == WHITE) { 226 | AddBlackPawnCapMove(pos, sq, sq - 9, pos->pieces[sq - 9], list); 227 | } 228 | if(!SQOFFBOARD(sq - 11) && PieceCol[pos->pieces[sq - 11]] == WHITE) { 229 | AddBlackPawnCapMove(pos, sq, sq - 11, pos->pieces[sq - 11], list); 230 | } 231 | 232 | if(pos->enPas != NO_SQ) { 233 | if(sq - 9 == pos->enPas) { 234 | AddEnPassantMove(pos, MOVE(sq, sq - 9, EMPTY, EMPTY, MFLAGEP), list); 235 | } 236 | if(sq - 11 == pos->enPas) { 237 | AddEnPassantMove(pos, MOVE(sq, sq - 11, EMPTY, EMPTY, MFLAGEP), list); 238 | } 239 | } 240 | } 241 | 242 | if(pos->castlePerm & BKCA) { 243 | if(pos->pieces[F8] == EMPTY && pos->pieces[G8] == EMPTY) { 244 | if(!SqAttacked(E8, WHITE, pos) && !SqAttacked(F8, WHITE, pos)) { 245 | AddQuietMove(pos, MOVE(E8, G8, EMPTY, EMPTY, MFLAGCA), list); 246 | } 247 | } 248 | } 249 | 250 | if(pos->castlePerm & BQCA) { 251 | if(pos->pieces[D8] == EMPTY && pos->pieces[C8] == EMPTY && pos->pieces[B8] == EMPTY) { 252 | if((!SqAttacked(E8, WHITE, pos)) && (!SqAttacked(D8, WHITE, pos))) { 253 | AddQuietMove(pos, MOVE(E8, C8, EMPTY, EMPTY, MFLAGCA), list); 254 | } 255 | } 256 | } 257 | } 258 | 259 | pceIndex = LoopSlideIndex[side]; 260 | pce = LoopSlidePce[pceIndex++]; 261 | while(pce != 0) { 262 | ASSERT(PieceValid(pce)); 263 | 264 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 265 | sq = pos->pList[pce][pceNum]; 266 | ASSERT(SqOnBoard(sq)); 267 | 268 | for(index = 0; index < NumDir[pce]; ++index) { 269 | dir = PceDir[pce][index]; 270 | t_sq = sq + dir; 271 | 272 | while(!SQOFFBOARD(t_sq)) { 273 | 274 | if(pos->pieces[t_sq] != EMPTY) { 275 | if(PieceCol[pos->pieces[t_sq]] == (side ^ 1)) { 276 | AddCaptureMove(pos, MOVE(sq, t_sq, pos->pieces[t_sq], EMPTY, 0), list); 277 | } 278 | break; 279 | } 280 | AddQuietMove(pos, MOVE(sq, t_sq, EMPTY, EMPTY, 0), list); 281 | t_sq += dir; 282 | } 283 | } 284 | } 285 | pce = LoopSlidePce[pceIndex++]; 286 | } 287 | 288 | pceIndex = LoopNonSlideIndex[side]; 289 | pce = LoopNonSlidePce[pceIndex++]; 290 | while(pce != 0) { 291 | ASSERT(PieceValid(pce)); 292 | 293 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 294 | sq = pos->pList[pce][pceNum]; 295 | ASSERT(SqOnBoard(sq)); 296 | 297 | for(index = 0; index < NumDir[pce]; ++index) { 298 | dir = PceDir[pce][index]; 299 | t_sq = sq + dir; 300 | 301 | if(SQOFFBOARD(t_sq)) 302 | continue; 303 | 304 | if(pos->pieces[t_sq] != EMPTY) { 305 | if(PieceCol[pos->pieces[t_sq]] == (side ^ 1)) { 306 | AddCaptureMove(pos, MOVE(sq, t_sq, pos->pieces[t_sq], EMPTY, 0), list); 307 | } 308 | continue; 309 | } 310 | AddQuietMove(pos, MOVE(sq, t_sq, EMPTY, EMPTY, 0), list); 311 | } 312 | } 313 | pce = LoopNonSlidePce[pceIndex++]; 314 | } 315 | } 316 | 317 | void GenerateAllCaps(const S_BOARD *pos, S_MOVELIST *list) { 318 | int pce = EMPTY; 319 | int side = pos->side; 320 | int sq = 0, t_sq = 0; 321 | int pceNum = 0; 322 | 323 | int dir = 0; 324 | int index = 0; 325 | int pceIndex = 0; 326 | 327 | ASSERT(CheckBoard(pos)); 328 | list->count = 0; 329 | 330 | if(side == WHITE) { 331 | for(pceNum = 0; pceNum < pos->pceNum[wP]; ++pceNum) { 332 | sq = pos->pList[wP][pceNum]; 333 | ASSERT(SqOnBoard(sq)); 334 | 335 | if(!SQOFFBOARD(sq + 9) && PieceCol[pos->pieces[sq + 9]] == BLACK) { 336 | AddWhitePawnCapMove(pos, sq, sq + 9, pos->pieces[sq + 9], list); 337 | } 338 | if(!SQOFFBOARD(sq + 11) && PieceCol[pos->pieces[sq + 11]] == BLACK) { 339 | AddWhitePawnCapMove(pos, sq, sq + 11, pos->pieces[sq + 11], list); 340 | } 341 | 342 | if(pos->enPas != NO_SQ) { 343 | if(sq + 9 == pos->enPas) { 344 | AddEnPassantMove(pos, MOVE(sq, sq + 9, EMPTY, EMPTY, MFLAGEP), list); 345 | } 346 | if(sq + 11 == pos->enPas) { 347 | AddEnPassantMove(pos, MOVE(sq, sq + 11, EMPTY, EMPTY, MFLAGEP), list); 348 | } 349 | } 350 | } 351 | 352 | } else { 353 | for(pceNum = 0; pceNum < pos->pceNum[bP]; ++pceNum) { 354 | sq = pos->pList[bP][pceNum]; 355 | ASSERT(SqOnBoard(sq)); 356 | 357 | if(!SQOFFBOARD(sq - 9) && PieceCol[pos->pieces[sq - 9]] == WHITE) { 358 | AddBlackPawnCapMove(pos, sq, sq - 9, pos->pieces[sq - 9], list); 359 | } 360 | if(!SQOFFBOARD(sq - 11) && PieceCol[pos->pieces[sq - 11]] == WHITE) { 361 | AddBlackPawnCapMove(pos, sq, sq - 11, pos->pieces[sq - 11], list); 362 | } 363 | 364 | if(pos->enPas != NO_SQ) { 365 | if(sq - 9 == pos->enPas) { 366 | AddEnPassantMove(pos, MOVE(sq, sq - 9, EMPTY, EMPTY, MFLAGEP), list); 367 | } 368 | if(sq - 11 == pos->enPas) { 369 | AddEnPassantMove(pos, MOVE(sq, sq - 11, EMPTY, EMPTY, MFLAGEP), list); 370 | } 371 | } 372 | } 373 | 374 | } 375 | 376 | pceIndex = LoopSlideIndex[side]; 377 | pce = LoopSlidePce[pceIndex++]; 378 | while(pce != 0) { 379 | ASSERT(PieceValid(pce)); 380 | 381 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 382 | sq = pos->pList[pce][pceNum]; 383 | ASSERT(SqOnBoard(sq)); 384 | 385 | for(index = 0; index < NumDir[pce]; ++index) { 386 | dir = PceDir[pce][index]; 387 | t_sq = sq + dir; 388 | 389 | while(!SQOFFBOARD(t_sq)) { 390 | 391 | if(pos->pieces[t_sq] != EMPTY) { 392 | if(PieceCol[pos->pieces[t_sq]] == (side ^ 1)) { 393 | AddCaptureMove(pos, MOVE(sq, t_sq, pos->pieces[t_sq], EMPTY, 0), list); 394 | } 395 | break; 396 | } 397 | t_sq += dir; 398 | } 399 | } 400 | } 401 | pce = LoopSlidePce[pceIndex++]; 402 | } 403 | 404 | pceIndex = LoopNonSlideIndex[side]; 405 | pce = LoopNonSlidePce[pceIndex++]; 406 | while(pce != 0) { 407 | ASSERT(PieceValid(pce)); 408 | 409 | for(pceNum = 0; pceNum < pos->pceNum[pce]; ++pceNum) { 410 | sq = pos->pList[pce][pceNum]; 411 | ASSERT(SqOnBoard(sq)); 412 | 413 | for(index = 0; index < NumDir[pce]; ++index) { 414 | dir = PceDir[pce][index]; 415 | t_sq = sq + dir; 416 | 417 | if(SQOFFBOARD(t_sq)) 418 | continue; 419 | 420 | if(pos->pieces[t_sq] != EMPTY) { 421 | if(PieceCol[pos->pieces[t_sq]] == (side ^ 1)) { 422 | AddCaptureMove(pos, MOVE(sq, t_sq, pos->pieces[t_sq], EMPTY, 0), list); 423 | } 424 | continue; 425 | } 426 | } 427 | } 428 | pce = LoopNonSlidePce[pceIndex++]; 429 | } 430 | } -------------------------------------------------------------------------------- /vice/perft.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include "defs.h" 14 | 15 | long leafNodes; 16 | 17 | void Perft(int depth, S_BOARD *pos) { 18 | S_MOVELIST list[1]; 19 | int MoveNum = 0; 20 | 21 | ASSERT(CheckBoard(pos)); 22 | 23 | if(depth == 0) { 24 | leafNodes++; 25 | return; 26 | } 27 | 28 | GenerateAllMoves(pos, list); 29 | 30 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 31 | if(!MakeMove(pos, list->moves[MoveNum].move)) { 32 | continue; 33 | } 34 | 35 | Perft(depth - 1, pos); 36 | TakeMove(pos); 37 | } 38 | 39 | return; 40 | } 41 | 42 | void PerftTest(int depth, S_BOARD *pos) { 43 | S_MOVELIST list[1]; 44 | int move; 45 | int MoveNum = 0; 46 | int start = GetTimeMs(); 47 | long cumnodes, oldnodes; 48 | 49 | ASSERT(CheckBoard(pos)); 50 | 51 | PrintBoard(pos); 52 | printf("\nStarting Test To Depth:%d\n", depth); 53 | leafNodes = 0; 54 | 55 | GenerateAllMoves(pos, list); 56 | 57 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 58 | move = list->moves[MoveNum].move; 59 | if(!MakeMove(pos, move)) 60 | continue; 61 | 62 | cumnodes = leafNodes; 63 | Perft(depth - 1, pos); 64 | TakeMove(pos); 65 | oldnodes = leafNodes - cumnodes; 66 | printf("move %d : %s : %ld\n", MoveNum + 1, PrMove(move), oldnodes); 67 | } 68 | 69 | printf("\nTest Complete : %ld nodes visited in %dms\n", leafNodes, GetTimeMs() - start); 70 | } -------------------------------------------------------------------------------- /vice/polybook.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | #include "polykeys.h" 14 | 15 | typedef struct { 16 | U64 key; 17 | unsigned short move; 18 | unsigned short weight; 19 | unsigned int learn; 20 | } S_POLY_BOOK_ENTRY; 21 | 22 | long NumEntries = 0; 23 | 24 | S_POLY_BOOK_ENTRY *entries = NULL; 25 | 26 | const int PolyKindOfPiece[13] = { 27 | -1, 1, 3, 5, 7, 9, 11, 0, 2, 4, 6, 8, 10 28 | }; 29 | 30 | void InitPolyBook(void) { 31 | FILE *pFile = fopen("performance.bin", "rb"); 32 | long position, returnValue; 33 | 34 | EngineOptions->UseBook = FALSE; 35 | 36 | if(pFile == NULL) { 37 | printf("Book File Not Read\n"); 38 | } else { 39 | fseek(pFile, 0, SEEK_END); 40 | position = ftell(pFile); 41 | 42 | if(position < sizeof(S_POLY_BOOK_ENTRY)) { 43 | printf("No Entries Found\n"); 44 | return; 45 | } 46 | 47 | NumEntries = position / sizeof(S_POLY_BOOK_ENTRY); 48 | printf("%ld Entries Found In File\n", NumEntries); 49 | 50 | entries = malloc(NumEntries * sizeof(S_POLY_BOOK_ENTRY)); /* NULL! */ 51 | 52 | rewind(pFile); 53 | returnValue = fread(entries, sizeof(S_POLY_BOOK_ENTRY), NumEntries, pFile); 54 | printf("fread() %ld Entries Read in from File\n", returnValue); 55 | 56 | if(NumEntries > 0) { 57 | EngineOptions->UseBook = TRUE; 58 | } 59 | } 60 | 61 | fclose(pFile); 62 | } 63 | 64 | void CleanPolyBook(void) { 65 | free(entries); 66 | } 67 | 68 | int HasPawnForCapture(const S_BOARD *board) { 69 | int sqWithPawn = 0; 70 | int targetPce = (board->side == WHITE) ? wP : bP; 71 | if(board->enPas != NO_SQ) { 72 | if(board->side == WHITE) { 73 | sqWithPawn = board->enPas - 10; 74 | } else { 75 | sqWithPawn = board->enPas + 10; 76 | } 77 | 78 | if(board->pieces[sqWithPawn + 1] == targetPce) { 79 | return TRUE; 80 | } else if(board->pieces[sqWithPawn - 1] == targetPce) { 81 | return TRUE; 82 | } 83 | } 84 | return FALSE; 85 | } 86 | 87 | U64 PolyKeyFromBoard(const S_BOARD *board) { 88 | int sq = 0, rank = 0, file = 0; 89 | U64 finalKey = 0; 90 | int piece = EMPTY; 91 | int polyPiece = 0; 92 | int offset = 0; 93 | 94 | for(sq = 0; sq < BRD_SQ_NUM; ++sq) { 95 | piece = board->pieces[sq]; 96 | if(piece != NO_SQ && piece != EMPTY && piece != OFFBOARD) { 97 | ASSERT(piece >= wP && piece <= bK); 98 | polyPiece = PolyKindOfPiece[piece]; 99 | rank = RanksBrd[sq]; 100 | file = FilesBrd[sq]; 101 | 102 | finalKey ^= Random64Poly[(64 * polyPiece) + (8 * rank) + file]; 103 | } 104 | } 105 | 106 | offset = 768; 107 | if(board->castlePerm & WKCA) finalKey ^= Random64Poly[offset + 0]; 108 | if(board->castlePerm & WQCA) finalKey ^= Random64Poly[offset + 1]; 109 | if(board->castlePerm & BKCA) finalKey ^= Random64Poly[offset + 2]; 110 | if(board->castlePerm & BQCA) finalKey ^= Random64Poly[offset + 3]; 111 | 112 | offset = 772; 113 | if(HasPawnForCapture(board) == TRUE) { 114 | file = FilesBrd[board->enPas]; 115 | finalKey ^= Random64Poly[offset + file]; 116 | } 117 | 118 | if(board->side == WHITE) 119 | finalKey ^= Random64Poly[780]; 120 | 121 | return finalKey; 122 | } 123 | 124 | unsigned short endian_swap_u16(unsigned short x) { 125 | x = (x >> 8) | 126 | (x << 8); 127 | return x; 128 | } 129 | 130 | unsigned int endian_swap_u32(unsigned int x) { 131 | x = (x >> 24) | 132 | ((x << 8) & 0x00ff0000) | 133 | ((x >> 8) & 0x0000ff00) | 134 | (x << 24); 135 | return x; 136 | } 137 | 138 | U64 endian_swap_u64(U64 x) { 139 | x = (x >> 56) | 140 | ((x << 40) & 0x00ff000000000000ULL) | 141 | ((x << 24) & 0x0000ff0000000000ULL) | 142 | ((x << 8) & 0x000000ff00000000ULL) | 143 | ((x >> 8) & 0x00000000ff000000ULL) | 144 | ((x >> 24) & 0x0000000000ff0000ULL) | 145 | ((x >> 40) & 0x000000000000ff00ULL) | 146 | (x << 56); 147 | return x; 148 | } 149 | 150 | int ConvertPolyMoveToInternalMove(unsigned short polyMove, S_BOARD *board) { 151 | int ff = (polyMove >> 6) & 7; 152 | int fr = (polyMove >> 9) & 7; 153 | int tf = (polyMove >> 0) & 7; 154 | int tr = (polyMove >> 3) & 7; 155 | int pp = (polyMove >> 12) & 7; 156 | char promChar = 'q'; 157 | 158 | char moveString[6]; 159 | if(pp == 0) { 160 | sprintf(moveString, "%c%c%c%c", 161 | FileChar[ff], 162 | RankChar[fr], 163 | FileChar[tf], 164 | RankChar[tr]); 165 | } else { 166 | switch(pp) { 167 | case 1: promChar = 'n'; 168 | case 2: promChar = 'b'; 169 | case 3: promChar = 'r'; 170 | } 171 | 172 | sprintf(moveString, "%c%c%c%c%c", 173 | FileChar[ff], 174 | RankChar[fr], 175 | FileChar[tf], 176 | RankChar[tr], 177 | promChar); 178 | } 179 | 180 | return ParseMove(moveString, board); 181 | } 182 | 183 | static int PickMove(int *moves, unsigned short *weight, unsigned int cumWeight, int count) { 184 | int i, pick; 185 | 186 | pick = rand() % cumWeight; 187 | 188 | for(i = 0; i < count; i++) { 189 | if(pick < weight[i]) 190 | return moves[i]; 191 | pick -= weight[i]; 192 | cumWeight -= weight[i]; 193 | } 194 | return weight[count - 1]; 195 | } 196 | 197 | int GetBookMove(S_BOARD *board) { 198 | S_POLY_BOOK_ENTRY *entry; 199 | unsigned short move; 200 | const int MAXBOOKMOVES = 32; 201 | int bookMoves[32]; /* !! */ 202 | unsigned short weight[32]; 203 | unsigned int cumWeight = 0; 204 | int tempMove = NOMOVE; 205 | int count = 0; 206 | 207 | U64 polyKey = PolyKeyFromBoard(board); 208 | 209 | for(entry = entries; entry < entries + NumEntries; entry++) { 210 | if(polyKey == endian_swap_u64(entry->key)) { 211 | move = endian_swap_u16(entry->move); 212 | tempMove = ConvertPolyMoveToInternalMove(move, board); 213 | if(tempMove != NOMOVE) { 214 | weight[count] = entry->weight; 215 | cumWeight += weight[count]; 216 | bookMoves[count++] = tempMove; 217 | if(count > MAXBOOKMOVES) 218 | break; 219 | } 220 | } 221 | } 222 | 223 | if(count != 0) { 224 | return PickMove(bookMoves, weight, cumWeight, count); 225 | } else { 226 | return NOMOVE; 227 | } 228 | } 229 | -------------------------------------------------------------------------------- /vice/polykeys.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | #include "polykeys.h" 14 | 15 | const U64 Random64Poly[781] = { 16 | U64_POLY(0x9D39247E33776D41), U64_POLY(0x2AF7398005AAA5C7), U64_POLY(0x44DB015024623547), U64_POLY(0x9C15F73E62A76AE2), 17 | U64_POLY(0x75834465489C0C89), U64_POLY(0x3290AC3A203001BF), U64_POLY(0x0FBBAD1F61042279), U64_POLY(0xE83A908FF2FB60CA), 18 | U64_POLY(0x0D7E765D58755C10), U64_POLY(0x1A083822CEAFE02D), U64_POLY(0x9605D5F0E25EC3B0), U64_POLY(0xD021FF5CD13A2ED5), 19 | U64_POLY(0x40BDF15D4A672E32), U64_POLY(0x011355146FD56395), U64_POLY(0x5DB4832046F3D9E5), U64_POLY(0x239F8B2D7FF719CC), 20 | U64_POLY(0x05D1A1AE85B49AA1), U64_POLY(0x679F848F6E8FC971), U64_POLY(0x7449BBFF801FED0B), U64_POLY(0x7D11CDB1C3B7ADF0), 21 | U64_POLY(0x82C7709E781EB7CC), U64_POLY(0xF3218F1C9510786C), U64_POLY(0x331478F3AF51BBE6), U64_POLY(0x4BB38DE5E7219443), 22 | U64_POLY(0xAA649C6EBCFD50FC), U64_POLY(0x8DBD98A352AFD40B), U64_POLY(0x87D2074B81D79217), U64_POLY(0x19F3C751D3E92AE1), 23 | U64_POLY(0xB4AB30F062B19ABF), U64_POLY(0x7B0500AC42047AC4), U64_POLY(0xC9452CA81A09D85D), U64_POLY(0x24AA6C514DA27500), 24 | U64_POLY(0x4C9F34427501B447), U64_POLY(0x14A68FD73C910841), U64_POLY(0xA71B9B83461CBD93), U64_POLY(0x03488B95B0F1850F), 25 | U64_POLY(0x637B2B34FF93C040), U64_POLY(0x09D1BC9A3DD90A94), U64_POLY(0x3575668334A1DD3B), U64_POLY(0x735E2B97A4C45A23), 26 | U64_POLY(0x18727070F1BD400B), U64_POLY(0x1FCBACD259BF02E7), U64_POLY(0xD310A7C2CE9B6555), U64_POLY(0xBF983FE0FE5D8244), 27 | U64_POLY(0x9F74D14F7454A824), U64_POLY(0x51EBDC4AB9BA3035), U64_POLY(0x5C82C505DB9AB0FA), U64_POLY(0xFCF7FE8A3430B241), 28 | U64_POLY(0x3253A729B9BA3DDE), U64_POLY(0x8C74C368081B3075), U64_POLY(0xB9BC6C87167C33E7), U64_POLY(0x7EF48F2B83024E20), 29 | U64_POLY(0x11D505D4C351BD7F), U64_POLY(0x6568FCA92C76A243), U64_POLY(0x4DE0B0F40F32A7B8), U64_POLY(0x96D693460CC37E5D), 30 | U64_POLY(0x42E240CB63689F2F), U64_POLY(0x6D2BDCDAE2919661), U64_POLY(0x42880B0236E4D951), U64_POLY(0x5F0F4A5898171BB6), 31 | U64_POLY(0x39F890F579F92F88), U64_POLY(0x93C5B5F47356388B), U64_POLY(0x63DC359D8D231B78), U64_POLY(0xEC16CA8AEA98AD76), 32 | U64_POLY(0x5355F900C2A82DC7), U64_POLY(0x07FB9F855A997142), U64_POLY(0x5093417AA8A7ED5E), U64_POLY(0x7BCBC38DA25A7F3C), 33 | U64_POLY(0x19FC8A768CF4B6D4), U64_POLY(0x637A7780DECFC0D9), U64_POLY(0x8249A47AEE0E41F7), U64_POLY(0x79AD695501E7D1E8), 34 | U64_POLY(0x14ACBAF4777D5776), U64_POLY(0xF145B6BECCDEA195), U64_POLY(0xDABF2AC8201752FC), U64_POLY(0x24C3C94DF9C8D3F6), 35 | U64_POLY(0xBB6E2924F03912EA), U64_POLY(0x0CE26C0B95C980D9), U64_POLY(0xA49CD132BFBF7CC4), U64_POLY(0xE99D662AF4243939), 36 | U64_POLY(0x27E6AD7891165C3F), U64_POLY(0x8535F040B9744FF1), U64_POLY(0x54B3F4FA5F40D873), U64_POLY(0x72B12C32127FED2B), 37 | U64_POLY(0xEE954D3C7B411F47), U64_POLY(0x9A85AC909A24EAA1), U64_POLY(0x70AC4CD9F04F21F5), U64_POLY(0xF9B89D3E99A075C2), 38 | U64_POLY(0x87B3E2B2B5C907B1), U64_POLY(0xA366E5B8C54F48B8), U64_POLY(0xAE4A9346CC3F7CF2), U64_POLY(0x1920C04D47267BBD), 39 | U64_POLY(0x87BF02C6B49E2AE9), U64_POLY(0x092237AC237F3859), U64_POLY(0xFF07F64EF8ED14D0), U64_POLY(0x8DE8DCA9F03CC54E), 40 | U64_POLY(0x9C1633264DB49C89), U64_POLY(0xB3F22C3D0B0B38ED), U64_POLY(0x390E5FB44D01144B), U64_POLY(0x5BFEA5B4712768E9), 41 | U64_POLY(0x1E1032911FA78984), U64_POLY(0x9A74ACB964E78CB3), U64_POLY(0x4F80F7A035DAFB04), U64_POLY(0x6304D09A0B3738C4), 42 | U64_POLY(0x2171E64683023A08), U64_POLY(0x5B9B63EB9CEFF80C), U64_POLY(0x506AACF489889342), U64_POLY(0x1881AFC9A3A701D6), 43 | U64_POLY(0x6503080440750644), U64_POLY(0xDFD395339CDBF4A7), U64_POLY(0xEF927DBCF00C20F2), U64_POLY(0x7B32F7D1E03680EC), 44 | U64_POLY(0xB9FD7620E7316243), U64_POLY(0x05A7E8A57DB91B77), U64_POLY(0xB5889C6E15630A75), U64_POLY(0x4A750A09CE9573F7), 45 | U64_POLY(0xCF464CEC899A2F8A), U64_POLY(0xF538639CE705B824), U64_POLY(0x3C79A0FF5580EF7F), U64_POLY(0xEDE6C87F8477609D), 46 | U64_POLY(0x799E81F05BC93F31), U64_POLY(0x86536B8CF3428A8C), U64_POLY(0x97D7374C60087B73), U64_POLY(0xA246637CFF328532), 47 | U64_POLY(0x043FCAE60CC0EBA0), U64_POLY(0x920E449535DD359E), U64_POLY(0x70EB093B15B290CC), U64_POLY(0x73A1921916591CBD), 48 | U64_POLY(0x56436C9FE1A1AA8D), U64_POLY(0xEFAC4B70633B8F81), U64_POLY(0xBB215798D45DF7AF), U64_POLY(0x45F20042F24F1768), 49 | U64_POLY(0x930F80F4E8EB7462), U64_POLY(0xFF6712FFCFD75EA1), U64_POLY(0xAE623FD67468AA70), U64_POLY(0xDD2C5BC84BC8D8FC), 50 | U64_POLY(0x7EED120D54CF2DD9), U64_POLY(0x22FE545401165F1C), U64_POLY(0xC91800E98FB99929), U64_POLY(0x808BD68E6AC10365), 51 | U64_POLY(0xDEC468145B7605F6), U64_POLY(0x1BEDE3A3AEF53302), U64_POLY(0x43539603D6C55602), U64_POLY(0xAA969B5C691CCB7A), 52 | U64_POLY(0xA87832D392EFEE56), U64_POLY(0x65942C7B3C7E11AE), U64_POLY(0xDED2D633CAD004F6), U64_POLY(0x21F08570F420E565), 53 | U64_POLY(0xB415938D7DA94E3C), U64_POLY(0x91B859E59ECB6350), U64_POLY(0x10CFF333E0ED804A), U64_POLY(0x28AED140BE0BB7DD), 54 | U64_POLY(0xC5CC1D89724FA456), U64_POLY(0x5648F680F11A2741), U64_POLY(0x2D255069F0B7DAB3), U64_POLY(0x9BC5A38EF729ABD4), 55 | U64_POLY(0xEF2F054308F6A2BC), U64_POLY(0xAF2042F5CC5C2858), U64_POLY(0x480412BAB7F5BE2A), U64_POLY(0xAEF3AF4A563DFE43), 56 | U64_POLY(0x19AFE59AE451497F), U64_POLY(0x52593803DFF1E840), U64_POLY(0xF4F076E65F2CE6F0), U64_POLY(0x11379625747D5AF3), 57 | U64_POLY(0xBCE5D2248682C115), U64_POLY(0x9DA4243DE836994F), U64_POLY(0x066F70B33FE09017), U64_POLY(0x4DC4DE189B671A1C), 58 | U64_POLY(0x51039AB7712457C3), U64_POLY(0xC07A3F80C31FB4B4), U64_POLY(0xB46EE9C5E64A6E7C), U64_POLY(0xB3819A42ABE61C87), 59 | U64_POLY(0x21A007933A522A20), U64_POLY(0x2DF16F761598AA4F), U64_POLY(0x763C4A1371B368FD), U64_POLY(0xF793C46702E086A0), 60 | U64_POLY(0xD7288E012AEB8D31), U64_POLY(0xDE336A2A4BC1C44B), U64_POLY(0x0BF692B38D079F23), U64_POLY(0x2C604A7A177326B3), 61 | U64_POLY(0x4850E73E03EB6064), U64_POLY(0xCFC447F1E53C8E1B), U64_POLY(0xB05CA3F564268D99), U64_POLY(0x9AE182C8BC9474E8), 62 | U64_POLY(0xA4FC4BD4FC5558CA), U64_POLY(0xE755178D58FC4E76), U64_POLY(0x69B97DB1A4C03DFE), U64_POLY(0xF9B5B7C4ACC67C96), 63 | U64_POLY(0xFC6A82D64B8655FB), U64_POLY(0x9C684CB6C4D24417), U64_POLY(0x8EC97D2917456ED0), U64_POLY(0x6703DF9D2924E97E), 64 | U64_POLY(0xC547F57E42A7444E), U64_POLY(0x78E37644E7CAD29E), U64_POLY(0xFE9A44E9362F05FA), U64_POLY(0x08BD35CC38336615), 65 | U64_POLY(0x9315E5EB3A129ACE), U64_POLY(0x94061B871E04DF75), U64_POLY(0xDF1D9F9D784BA010), U64_POLY(0x3BBA57B68871B59D), 66 | U64_POLY(0xD2B7ADEEDED1F73F), U64_POLY(0xF7A255D83BC373F8), U64_POLY(0xD7F4F2448C0CEB81), U64_POLY(0xD95BE88CD210FFA7), 67 | U64_POLY(0x336F52F8FF4728E7), U64_POLY(0xA74049DAC312AC71), U64_POLY(0xA2F61BB6E437FDB5), U64_POLY(0x4F2A5CB07F6A35B3), 68 | U64_POLY(0x87D380BDA5BF7859), U64_POLY(0x16B9F7E06C453A21), U64_POLY(0x7BA2484C8A0FD54E), U64_POLY(0xF3A678CAD9A2E38C), 69 | U64_POLY(0x39B0BF7DDE437BA2), U64_POLY(0xFCAF55C1BF8A4424), U64_POLY(0x18FCF680573FA594), U64_POLY(0x4C0563B89F495AC3), 70 | U64_POLY(0x40E087931A00930D), U64_POLY(0x8CFFA9412EB642C1), U64_POLY(0x68CA39053261169F), U64_POLY(0x7A1EE967D27579E2), 71 | U64_POLY(0x9D1D60E5076F5B6F), U64_POLY(0x3810E399B6F65BA2), U64_POLY(0x32095B6D4AB5F9B1), U64_POLY(0x35CAB62109DD038A), 72 | U64_POLY(0xA90B24499FCFAFB1), U64_POLY(0x77A225A07CC2C6BD), U64_POLY(0x513E5E634C70E331), U64_POLY(0x4361C0CA3F692F12), 73 | U64_POLY(0xD941ACA44B20A45B), U64_POLY(0x528F7C8602C5807B), U64_POLY(0x52AB92BEB9613989), U64_POLY(0x9D1DFA2EFC557F73), 74 | U64_POLY(0x722FF175F572C348), U64_POLY(0x1D1260A51107FE97), U64_POLY(0x7A249A57EC0C9BA2), U64_POLY(0x04208FE9E8F7F2D6), 75 | U64_POLY(0x5A110C6058B920A0), U64_POLY(0x0CD9A497658A5698), U64_POLY(0x56FD23C8F9715A4C), U64_POLY(0x284C847B9D887AAE), 76 | U64_POLY(0x04FEABFBBDB619CB), U64_POLY(0x742E1E651C60BA83), U64_POLY(0x9A9632E65904AD3C), U64_POLY(0x881B82A13B51B9E2), 77 | U64_POLY(0x506E6744CD974924), U64_POLY(0xB0183DB56FFC6A79), U64_POLY(0x0ED9B915C66ED37E), U64_POLY(0x5E11E86D5873D484), 78 | U64_POLY(0xF678647E3519AC6E), U64_POLY(0x1B85D488D0F20CC5), U64_POLY(0xDAB9FE6525D89021), U64_POLY(0x0D151D86ADB73615), 79 | U64_POLY(0xA865A54EDCC0F019), U64_POLY(0x93C42566AEF98FFB), U64_POLY(0x99E7AFEABE000731), U64_POLY(0x48CBFF086DDF285A), 80 | U64_POLY(0x7F9B6AF1EBF78BAF), U64_POLY(0x58627E1A149BBA21), U64_POLY(0x2CD16E2ABD791E33), U64_POLY(0xD363EFF5F0977996), 81 | U64_POLY(0x0CE2A38C344A6EED), U64_POLY(0x1A804AADB9CFA741), U64_POLY(0x907F30421D78C5DE), U64_POLY(0x501F65EDB3034D07), 82 | U64_POLY(0x37624AE5A48FA6E9), U64_POLY(0x957BAF61700CFF4E), U64_POLY(0x3A6C27934E31188A), U64_POLY(0xD49503536ABCA345), 83 | U64_POLY(0x088E049589C432E0), U64_POLY(0xF943AEE7FEBF21B8), U64_POLY(0x6C3B8E3E336139D3), U64_POLY(0x364F6FFA464EE52E), 84 | U64_POLY(0xD60F6DCEDC314222), U64_POLY(0x56963B0DCA418FC0), U64_POLY(0x16F50EDF91E513AF), U64_POLY(0xEF1955914B609F93), 85 | U64_POLY(0x565601C0364E3228), U64_POLY(0xECB53939887E8175), U64_POLY(0xBAC7A9A18531294B), U64_POLY(0xB344C470397BBA52), 86 | U64_POLY(0x65D34954DAF3CEBD), U64_POLY(0xB4B81B3FA97511E2), U64_POLY(0xB422061193D6F6A7), U64_POLY(0x071582401C38434D), 87 | U64_POLY(0x7A13F18BBEDC4FF5), U64_POLY(0xBC4097B116C524D2), U64_POLY(0x59B97885E2F2EA28), U64_POLY(0x99170A5DC3115544), 88 | U64_POLY(0x6F423357E7C6A9F9), U64_POLY(0x325928EE6E6F8794), U64_POLY(0xD0E4366228B03343), U64_POLY(0x565C31F7DE89EA27), 89 | U64_POLY(0x30F5611484119414), U64_POLY(0xD873DB391292ED4F), U64_POLY(0x7BD94E1D8E17DEBC), U64_POLY(0xC7D9F16864A76E94), 90 | U64_POLY(0x947AE053EE56E63C), U64_POLY(0xC8C93882F9475F5F), U64_POLY(0x3A9BF55BA91F81CA), U64_POLY(0xD9A11FBB3D9808E4), 91 | U64_POLY(0x0FD22063EDC29FCA), U64_POLY(0xB3F256D8ACA0B0B9), U64_POLY(0xB03031A8B4516E84), U64_POLY(0x35DD37D5871448AF), 92 | U64_POLY(0xE9F6082B05542E4E), U64_POLY(0xEBFAFA33D7254B59), U64_POLY(0x9255ABB50D532280), U64_POLY(0xB9AB4CE57F2D34F3), 93 | U64_POLY(0x693501D628297551), U64_POLY(0xC62C58F97DD949BF), U64_POLY(0xCD454F8F19C5126A), U64_POLY(0xBBE83F4ECC2BDECB), 94 | U64_POLY(0xDC842B7E2819E230), U64_POLY(0xBA89142E007503B8), U64_POLY(0xA3BC941D0A5061CB), U64_POLY(0xE9F6760E32CD8021), 95 | U64_POLY(0x09C7E552BC76492F), U64_POLY(0x852F54934DA55CC9), U64_POLY(0x8107FCCF064FCF56), U64_POLY(0x098954D51FFF6580), 96 | U64_POLY(0x23B70EDB1955C4BF), U64_POLY(0xC330DE426430F69D), U64_POLY(0x4715ED43E8A45C0A), U64_POLY(0xA8D7E4DAB780A08D), 97 | U64_POLY(0x0572B974F03CE0BB), U64_POLY(0xB57D2E985E1419C7), U64_POLY(0xE8D9ECBE2CF3D73F), U64_POLY(0x2FE4B17170E59750), 98 | U64_POLY(0x11317BA87905E790), U64_POLY(0x7FBF21EC8A1F45EC), U64_POLY(0x1725CABFCB045B00), U64_POLY(0x964E915CD5E2B207), 99 | U64_POLY(0x3E2B8BCBF016D66D), U64_POLY(0xBE7444E39328A0AC), U64_POLY(0xF85B2B4FBCDE44B7), U64_POLY(0x49353FEA39BA63B1), 100 | U64_POLY(0x1DD01AAFCD53486A), U64_POLY(0x1FCA8A92FD719F85), U64_POLY(0xFC7C95D827357AFA), U64_POLY(0x18A6A990C8B35EBD), 101 | U64_POLY(0xCCCB7005C6B9C28D), U64_POLY(0x3BDBB92C43B17F26), U64_POLY(0xAA70B5B4F89695A2), U64_POLY(0xE94C39A54A98307F), 102 | U64_POLY(0xB7A0B174CFF6F36E), U64_POLY(0xD4DBA84729AF48AD), U64_POLY(0x2E18BC1AD9704A68), U64_POLY(0x2DE0966DAF2F8B1C), 103 | U64_POLY(0xB9C11D5B1E43A07E), U64_POLY(0x64972D68DEE33360), U64_POLY(0x94628D38D0C20584), U64_POLY(0xDBC0D2B6AB90A559), 104 | U64_POLY(0xD2733C4335C6A72F), U64_POLY(0x7E75D99D94A70F4D), U64_POLY(0x6CED1983376FA72B), U64_POLY(0x97FCAACBF030BC24), 105 | U64_POLY(0x7B77497B32503B12), U64_POLY(0x8547EDDFB81CCB94), U64_POLY(0x79999CDFF70902CB), U64_POLY(0xCFFE1939438E9B24), 106 | U64_POLY(0x829626E3892D95D7), U64_POLY(0x92FAE24291F2B3F1), U64_POLY(0x63E22C147B9C3403), U64_POLY(0xC678B6D860284A1C), 107 | U64_POLY(0x5873888850659AE7), U64_POLY(0x0981DCD296A8736D), U64_POLY(0x9F65789A6509A440), U64_POLY(0x9FF38FED72E9052F), 108 | U64_POLY(0xE479EE5B9930578C), U64_POLY(0xE7F28ECD2D49EECD), U64_POLY(0x56C074A581EA17FE), U64_POLY(0x5544F7D774B14AEF), 109 | U64_POLY(0x7B3F0195FC6F290F), U64_POLY(0x12153635B2C0CF57), U64_POLY(0x7F5126DBBA5E0CA7), U64_POLY(0x7A76956C3EAFB413), 110 | U64_POLY(0x3D5774A11D31AB39), U64_POLY(0x8A1B083821F40CB4), U64_POLY(0x7B4A38E32537DF62), U64_POLY(0x950113646D1D6E03), 111 | U64_POLY(0x4DA8979A0041E8A9), U64_POLY(0x3BC36E078F7515D7), U64_POLY(0x5D0A12F27AD310D1), U64_POLY(0x7F9D1A2E1EBE1327), 112 | U64_POLY(0xDA3A361B1C5157B1), U64_POLY(0xDCDD7D20903D0C25), U64_POLY(0x36833336D068F707), U64_POLY(0xCE68341F79893389), 113 | U64_POLY(0xAB9090168DD05F34), U64_POLY(0x43954B3252DC25E5), U64_POLY(0xB438C2B67F98E5E9), U64_POLY(0x10DCD78E3851A492), 114 | U64_POLY(0xDBC27AB5447822BF), U64_POLY(0x9B3CDB65F82CA382), U64_POLY(0xB67B7896167B4C84), U64_POLY(0xBFCED1B0048EAC50), 115 | U64_POLY(0xA9119B60369FFEBD), U64_POLY(0x1FFF7AC80904BF45), U64_POLY(0xAC12FB171817EEE7), U64_POLY(0xAF08DA9177DDA93D), 116 | U64_POLY(0x1B0CAB936E65C744), U64_POLY(0xB559EB1D04E5E932), U64_POLY(0xC37B45B3F8D6F2BA), U64_POLY(0xC3A9DC228CAAC9E9), 117 | U64_POLY(0xF3B8B6675A6507FF), U64_POLY(0x9FC477DE4ED681DA), U64_POLY(0x67378D8ECCEF96CB), U64_POLY(0x6DD856D94D259236), 118 | U64_POLY(0xA319CE15B0B4DB31), U64_POLY(0x073973751F12DD5E), U64_POLY(0x8A8E849EB32781A5), U64_POLY(0xE1925C71285279F5), 119 | U64_POLY(0x74C04BF1790C0EFE), U64_POLY(0x4DDA48153C94938A), U64_POLY(0x9D266D6A1CC0542C), U64_POLY(0x7440FB816508C4FE), 120 | U64_POLY(0x13328503DF48229F), U64_POLY(0xD6BF7BAEE43CAC40), U64_POLY(0x4838D65F6EF6748F), U64_POLY(0x1E152328F3318DEA), 121 | U64_POLY(0x8F8419A348F296BF), U64_POLY(0x72C8834A5957B511), U64_POLY(0xD7A023A73260B45C), U64_POLY(0x94EBC8ABCFB56DAE), 122 | U64_POLY(0x9FC10D0F989993E0), U64_POLY(0xDE68A2355B93CAE6), U64_POLY(0xA44CFE79AE538BBE), U64_POLY(0x9D1D84FCCE371425), 123 | U64_POLY(0x51D2B1AB2DDFB636), U64_POLY(0x2FD7E4B9E72CD38C), U64_POLY(0x65CA5B96B7552210), U64_POLY(0xDD69A0D8AB3B546D), 124 | U64_POLY(0x604D51B25FBF70E2), U64_POLY(0x73AA8A564FB7AC9E), U64_POLY(0x1A8C1E992B941148), U64_POLY(0xAAC40A2703D9BEA0), 125 | U64_POLY(0x764DBEAE7FA4F3A6), U64_POLY(0x1E99B96E70A9BE8B), U64_POLY(0x2C5E9DEB57EF4743), U64_POLY(0x3A938FEE32D29981), 126 | U64_POLY(0x26E6DB8FFDF5ADFE), U64_POLY(0x469356C504EC9F9D), U64_POLY(0xC8763C5B08D1908C), U64_POLY(0x3F6C6AF859D80055), 127 | U64_POLY(0x7F7CC39420A3A545), U64_POLY(0x9BFB227EBDF4C5CE), U64_POLY(0x89039D79D6FC5C5C), U64_POLY(0x8FE88B57305E2AB6), 128 | U64_POLY(0xA09E8C8C35AB96DE), U64_POLY(0xFA7E393983325753), U64_POLY(0xD6B6D0ECC617C699), U64_POLY(0xDFEA21EA9E7557E3), 129 | U64_POLY(0xB67C1FA481680AF8), U64_POLY(0xCA1E3785A9E724E5), U64_POLY(0x1CFC8BED0D681639), U64_POLY(0xD18D8549D140CAEA), 130 | U64_POLY(0x4ED0FE7E9DC91335), U64_POLY(0xE4DBF0634473F5D2), U64_POLY(0x1761F93A44D5AEFE), U64_POLY(0x53898E4C3910DA55), 131 | U64_POLY(0x734DE8181F6EC39A), U64_POLY(0x2680B122BAA28D97), U64_POLY(0x298AF231C85BAFAB), U64_POLY(0x7983EED3740847D5), 132 | U64_POLY(0x66C1A2A1A60CD889), U64_POLY(0x9E17E49642A3E4C1), U64_POLY(0xEDB454E7BADC0805), U64_POLY(0x50B704CAB602C329), 133 | U64_POLY(0x4CC317FB9CDDD023), U64_POLY(0x66B4835D9EAFEA22), U64_POLY(0x219B97E26FFC81BD), U64_POLY(0x261E4E4C0A333A9D), 134 | U64_POLY(0x1FE2CCA76517DB90), U64_POLY(0xD7504DFA8816EDBB), U64_POLY(0xB9571FA04DC089C8), U64_POLY(0x1DDC0325259B27DE), 135 | U64_POLY(0xCF3F4688801EB9AA), U64_POLY(0xF4F5D05C10CAB243), U64_POLY(0x38B6525C21A42B0E), U64_POLY(0x36F60E2BA4FA6800), 136 | U64_POLY(0xEB3593803173E0CE), U64_POLY(0x9C4CD6257C5A3603), U64_POLY(0xAF0C317D32ADAA8A), U64_POLY(0x258E5A80C7204C4B), 137 | U64_POLY(0x8B889D624D44885D), U64_POLY(0xF4D14597E660F855), U64_POLY(0xD4347F66EC8941C3), U64_POLY(0xE699ED85B0DFB40D), 138 | U64_POLY(0x2472F6207C2D0484), U64_POLY(0xC2A1E7B5B459AEB5), U64_POLY(0xAB4F6451CC1D45EC), U64_POLY(0x63767572AE3D6174), 139 | U64_POLY(0xA59E0BD101731A28), U64_POLY(0x116D0016CB948F09), U64_POLY(0x2CF9C8CA052F6E9F), U64_POLY(0x0B090A7560A968E3), 140 | U64_POLY(0xABEEDDB2DDE06FF1), U64_POLY(0x58EFC10B06A2068D), U64_POLY(0xC6E57A78FBD986E0), U64_POLY(0x2EAB8CA63CE802D7), 141 | U64_POLY(0x14A195640116F336), U64_POLY(0x7C0828DD624EC390), U64_POLY(0xD74BBE77E6116AC7), U64_POLY(0x804456AF10F5FB53), 142 | U64_POLY(0xEBE9EA2ADF4321C7), U64_POLY(0x03219A39EE587A30), U64_POLY(0x49787FEF17AF9924), U64_POLY(0xA1E9300CD8520548), 143 | U64_POLY(0x5B45E522E4B1B4EF), U64_POLY(0xB49C3B3995091A36), U64_POLY(0xD4490AD526F14431), U64_POLY(0x12A8F216AF9418C2), 144 | U64_POLY(0x001F837CC7350524), U64_POLY(0x1877B51E57A764D5), U64_POLY(0xA2853B80F17F58EE), U64_POLY(0x993E1DE72D36D310), 145 | U64_POLY(0xB3598080CE64A656), U64_POLY(0x252F59CF0D9F04BB), U64_POLY(0xD23C8E176D113600), U64_POLY(0x1BDA0492E7E4586E), 146 | U64_POLY(0x21E0BD5026C619BF), U64_POLY(0x3B097ADAF088F94E), U64_POLY(0x8D14DEDB30BE846E), U64_POLY(0xF95CFFA23AF5F6F4), 147 | U64_POLY(0x3871700761B3F743), U64_POLY(0xCA672B91E9E4FA16), U64_POLY(0x64C8E531BFF53B55), U64_POLY(0x241260ED4AD1E87D), 148 | U64_POLY(0x106C09B972D2E822), U64_POLY(0x7FBA195410E5CA30), U64_POLY(0x7884D9BC6CB569D8), U64_POLY(0x0647DFEDCD894A29), 149 | U64_POLY(0x63573FF03E224774), U64_POLY(0x4FC8E9560F91B123), U64_POLY(0x1DB956E450275779), U64_POLY(0xB8D91274B9E9D4FB), 150 | U64_POLY(0xA2EBEE47E2FBFCE1), U64_POLY(0xD9F1F30CCD97FB09), U64_POLY(0xEFED53D75FD64E6B), U64_POLY(0x2E6D02C36017F67F), 151 | U64_POLY(0xA9AA4D20DB084E9B), U64_POLY(0xB64BE8D8B25396C1), U64_POLY(0x70CB6AF7C2D5BCF0), U64_POLY(0x98F076A4F7A2322E), 152 | U64_POLY(0xBF84470805E69B5F), U64_POLY(0x94C3251F06F90CF3), U64_POLY(0x3E003E616A6591E9), U64_POLY(0xB925A6CD0421AFF3), 153 | U64_POLY(0x61BDD1307C66E300), U64_POLY(0xBF8D5108E27E0D48), U64_POLY(0x240AB57A8B888B20), U64_POLY(0xFC87614BAF287E07), 154 | U64_POLY(0xEF02CDD06FFDB432), U64_POLY(0xA1082C0466DF6C0A), U64_POLY(0x8215E577001332C8), U64_POLY(0xD39BB9C3A48DB6CF), 155 | U64_POLY(0x2738259634305C14), U64_POLY(0x61CF4F94C97DF93D), U64_POLY(0x1B6BACA2AE4E125B), U64_POLY(0x758F450C88572E0B), 156 | U64_POLY(0x959F587D507A8359), U64_POLY(0xB063E962E045F54D), U64_POLY(0x60E8ED72C0DFF5D1), U64_POLY(0x7B64978555326F9F), 157 | U64_POLY(0xFD080D236DA814BA), U64_POLY(0x8C90FD9B083F4558), U64_POLY(0x106F72FE81E2C590), U64_POLY(0x7976033A39F7D952), 158 | U64_POLY(0xA4EC0132764CA04B), U64_POLY(0x733EA705FAE4FA77), U64_POLY(0xB4D8F77BC3E56167), U64_POLY(0x9E21F4F903B33FD9), 159 | U64_POLY(0x9D765E419FB69F6D), U64_POLY(0xD30C088BA61EA5EF), U64_POLY(0x5D94337FBFAF7F5B), U64_POLY(0x1A4E4822EB4D7A59), 160 | U64_POLY(0x6FFE73E81B637FB3), U64_POLY(0xDDF957BC36D8B9CA), U64_POLY(0x64D0E29EEA8838B3), U64_POLY(0x08DD9BDFD96B9F63), 161 | U64_POLY(0x087E79E5A57D1D13), U64_POLY(0xE328E230E3E2B3FB), U64_POLY(0x1C2559E30F0946BE), U64_POLY(0x720BF5F26F4D2EAA), 162 | U64_POLY(0xB0774D261CC609DB), U64_POLY(0x443F64EC5A371195), U64_POLY(0x4112CF68649A260E), U64_POLY(0xD813F2FAB7F5C5CA), 163 | U64_POLY(0x660D3257380841EE), U64_POLY(0x59AC2C7873F910A3), U64_POLY(0xE846963877671A17), U64_POLY(0x93B633ABFA3469F8), 164 | U64_POLY(0xC0C0F5A60EF4CDCF), U64_POLY(0xCAF21ECD4377B28C), U64_POLY(0x57277707199B8175), U64_POLY(0x506C11B9D90E8B1D), 165 | U64_POLY(0xD83CC2687A19255F), U64_POLY(0x4A29C6465A314CD1), U64_POLY(0xED2DF21216235097), U64_POLY(0xB5635C95FF7296E2), 166 | U64_POLY(0x22AF003AB672E811), U64_POLY(0x52E762596BF68235), U64_POLY(0x9AEBA33AC6ECC6B0), U64_POLY(0x944F6DE09134DFB6), 167 | U64_POLY(0x6C47BEC883A7DE39), U64_POLY(0x6AD047C430A12104), U64_POLY(0xA5B1CFDBA0AB4067), U64_POLY(0x7C45D833AFF07862), 168 | U64_POLY(0x5092EF950A16DA0B), U64_POLY(0x9338E69C052B8E7B), U64_POLY(0x455A4B4CFE30E3F5), U64_POLY(0x6B02E63195AD0CF8), 169 | U64_POLY(0x6B17B224BAD6BF27), U64_POLY(0xD1E0CCD25BB9C169), U64_POLY(0xDE0C89A556B9AE70), U64_POLY(0x50065E535A213CF6), 170 | U64_POLY(0x9C1169FA2777B874), U64_POLY(0x78EDEFD694AF1EED), U64_POLY(0x6DC93D9526A50E68), U64_POLY(0xEE97F453F06791ED), 171 | U64_POLY(0x32AB0EDB696703D3), U64_POLY(0x3A6853C7E70757A7), U64_POLY(0x31865CED6120F37D), U64_POLY(0x67FEF95D92607890), 172 | U64_POLY(0x1F2B1D1F15F6DC9C), U64_POLY(0xB69E38A8965C6B65), U64_POLY(0xAA9119FF184CCCF4), U64_POLY(0xF43C732873F24C13), 173 | U64_POLY(0xFB4A3D794A9A80D2), U64_POLY(0x3550C2321FD6109C), U64_POLY(0x371F77E76BB8417E), U64_POLY(0x6BFA9AAE5EC05779), 174 | U64_POLY(0xCD04F3FF001A4778), U64_POLY(0xE3273522064480CA), U64_POLY(0x9F91508BFFCFC14A), U64_POLY(0x049A7F41061A9E60), 175 | U64_POLY(0xFCB6BE43A9F2FE9B), U64_POLY(0x08DE8A1C7797DA9B), U64_POLY(0x8F9887E6078735A1), U64_POLY(0xB5B4071DBFC73A66), 176 | U64_POLY(0x230E343DFBA08D33), U64_POLY(0x43ED7F5A0FAE657D), U64_POLY(0x3A88A0FBBCB05C63), U64_POLY(0x21874B8B4D2DBC4F), 177 | U64_POLY(0x1BDEA12E35F6A8C9), U64_POLY(0x53C065C6C8E63528), U64_POLY(0xE34A1D250E7A8D6B), U64_POLY(0xD6B04D3B7651DD7E), 178 | U64_POLY(0x5E90277E7CB39E2D), U64_POLY(0x2C046F22062DC67D), U64_POLY(0xB10BB459132D0A26), U64_POLY(0x3FA9DDFB67E2F199), 179 | U64_POLY(0x0E09B88E1914F7AF), U64_POLY(0x10E8B35AF3EEAB37), U64_POLY(0x9EEDECA8E272B933), U64_POLY(0xD4C718BC4AE8AE5F), 180 | U64_POLY(0x81536D601170FC20), U64_POLY(0x91B534F885818A06), U64_POLY(0xEC8177F83F900978), U64_POLY(0x190E714FADA5156E), 181 | U64_POLY(0xB592BF39B0364963), U64_POLY(0x89C350C893AE7DC1), U64_POLY(0xAC042E70F8B383F2), U64_POLY(0xB49B52E587A1EE60), 182 | U64_POLY(0xFB152FE3FF26DA89), U64_POLY(0x3E666E6F69AE2C15), U64_POLY(0x3B544EBE544C19F9), U64_POLY(0xE805A1E290CF2456), 183 | U64_POLY(0x24B33C9D7ED25117), U64_POLY(0xE74733427B72F0C1), U64_POLY(0x0A804D18B7097475), U64_POLY(0x57E3306D881EDB4F), 184 | U64_POLY(0x4AE7D6A36EB5DBCB), U64_POLY(0x2D8D5432157064C8), U64_POLY(0xD1E649DE1E7F268B), U64_POLY(0x8A328A1CEDFE552C), 185 | U64_POLY(0x07A3AEC79624C7DA), U64_POLY(0x84547DDC3E203C94), U64_POLY(0x990A98FD5071D263), U64_POLY(0x1A4FF12616EEFC89), 186 | U64_POLY(0xF6F7FD1431714200), U64_POLY(0x30C05B1BA332F41C), U64_POLY(0x8D2636B81555A786), U64_POLY(0x46C9FEB55D120902), 187 | U64_POLY(0xCCEC0A73B49C9921), U64_POLY(0x4E9D2827355FC492), U64_POLY(0x19EBB029435DCB0F), U64_POLY(0x4659D2B743848A2C), 188 | U64_POLY(0x963EF2C96B33BE31), U64_POLY(0x74F85198B05A2E7D), U64_POLY(0x5A0F544DD2B1FB18), U64_POLY(0x03727073C2E134B1), 189 | U64_POLY(0xC7F6AA2DE59AEA61), U64_POLY(0x352787BAA0D7C22F), U64_POLY(0x9853EAB63B5E0B35), U64_POLY(0xABBDCDD7ED5C0860), 190 | U64_POLY(0xCF05DAF5AC8D77B0), U64_POLY(0x49CAD48CEBF4A71E), U64_POLY(0x7A4C10EC2158C4A6), U64_POLY(0xD9E92AA246BF719E), 191 | U64_POLY(0x13AE978D09FE5557), U64_POLY(0x730499AF921549FF), U64_POLY(0x4E4B705B92903BA4), U64_POLY(0xFF577222C14F0A3A), 192 | U64_POLY(0x55B6344CF97AAFAE), U64_POLY(0xB862225B055B6960), U64_POLY(0xCAC09AFBDDD2CDB4), U64_POLY(0xDAF8E9829FE96B5F), 193 | U64_POLY(0xB5FDFC5D3132C498), U64_POLY(0x310CB380DB6F7503), U64_POLY(0xE87FBB46217A360E), U64_POLY(0x2102AE466EBB1148), 194 | U64_POLY(0xF8549E1A3AA5E00D), U64_POLY(0x07A69AFDCC42261A), U64_POLY(0xC4C118BFE78FEAAE), U64_POLY(0xF9F4892ED96BD438), 195 | U64_POLY(0x1AF3DBE25D8F45DA), U64_POLY(0xF5B4B0B0D2DEEEB4), U64_POLY(0x962ACEEFA82E1C84), U64_POLY(0x046E3ECAAF453CE9), 196 | U64_POLY(0xF05D129681949A4C), U64_POLY(0x964781CE734B3C84), U64_POLY(0x9C2ED44081CE5FBD), U64_POLY(0x522E23F3925E319E), 197 | U64_POLY(0x177E00F9FC32F791), U64_POLY(0x2BC60A63A6F3B3F2), U64_POLY(0x222BBFAE61725606), U64_POLY(0x486289DDCC3D6780), 198 | U64_POLY(0x7DC7785B8EFDFC80), U64_POLY(0x8AF38731C02BA980), U64_POLY(0x1FAB64EA29A2DDF7), U64_POLY(0xE4D9429322CD065A), 199 | U64_POLY(0x9DA058C67844F20C), U64_POLY(0x24C0E332B70019B0), U64_POLY(0x233003B5A6CFE6AD), U64_POLY(0xD586BD01C5C217F6), 200 | U64_POLY(0x5E5637885F29BC2B), U64_POLY(0x7EBA726D8C94094B), U64_POLY(0x0A56A5F0BFE39272), U64_POLY(0xD79476A84EE20D06), 201 | U64_POLY(0x9E4C1269BAA4BF37), U64_POLY(0x17EFEE45B0DEE640), U64_POLY(0x1D95B0A5FCF90BC6), U64_POLY(0x93CBE0B699C2585D), 202 | U64_POLY(0x65FA4F227A2B6D79), U64_POLY(0xD5F9E858292504D5), U64_POLY(0xC2B5A03F71471A6F), U64_POLY(0x59300222B4561E00), 203 | U64_POLY(0xCE2F8642CA0712DC), U64_POLY(0x7CA9723FBB2E8988), U64_POLY(0x2785338347F2BA08), U64_POLY(0xC61BB3A141E50E8C), 204 | U64_POLY(0x150F361DAB9DEC26), U64_POLY(0x9F6A419D382595F4), U64_POLY(0x64A53DC924FE7AC9), U64_POLY(0x142DE49FFF7A7C3D), 205 | U64_POLY(0x0C335248857FA9E7), U64_POLY(0x0A9C32D5EAE45305), U64_POLY(0xE6C42178C4BBB92E), U64_POLY(0x71F1CE2490D20B07), 206 | U64_POLY(0xF1BCC3D275AFE51A), U64_POLY(0xE728E8C83C334074), U64_POLY(0x96FBF83A12884624), U64_POLY(0x81A1549FD6573DA5), 207 | U64_POLY(0x5FA7867CAF35E149), U64_POLY(0x56986E2EF3ED091B), U64_POLY(0x917F1DD5F8886C61), U64_POLY(0xD20D8C88C8FFE65F), 208 | U64_POLY(0x31D71DCE64B2C310), U64_POLY(0xF165B587DF898190), U64_POLY(0xA57E6339DD2CF3A0), U64_POLY(0x1EF6E6DBB1961EC9), 209 | U64_POLY(0x70CC73D90BC26E24), U64_POLY(0xE21A6B35DF0C3AD7), U64_POLY(0x003A93D8B2806962), U64_POLY(0x1C99DED33CB890A1), 210 | U64_POLY(0xCF3145DE0ADD4289), U64_POLY(0xD0E4427A5514FB72), U64_POLY(0x77C621CC9FB3A483), U64_POLY(0x67A34DAC4356550B), 211 | U64_POLY(0xF8D626AAAF278509), 212 | }; -------------------------------------------------------------------------------- /vice/polykeys.h: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #ifndef POLYKEYS_H 13 | #define POLYKEYS_H 14 | 15 | #ifdef _MSC_VER 16 | # define U64_POLY(u) (u##ui64) 17 | #else 18 | # define U64_POLY(u) (u##ULL) 19 | #endif 20 | 21 | extern const U64 Random64Poly[781]; 22 | 23 | #endif -------------------------------------------------------------------------------- /vice/pvtable.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include "defs.h" 14 | 15 | const int PvSize = 0x100000 * 2; 16 | 17 | int GetPvLine(const int depth, S_BOARD *pos) { 18 | int move = ProbePvMove(pos); 19 | int count = 0; 20 | 21 | ASSERT(depth < MAXDEPTH); 22 | 23 | while(move != NOMOVE && count < depth) { 24 | ASSERT(count < MAXDEPTH); 25 | 26 | if(MoveExists(pos, move)) { 27 | MakeMove(pos, move); 28 | pos->PvArray[count++] = move; 29 | } else { 30 | break; 31 | } 32 | move = ProbePvMove(pos); 33 | } 34 | 35 | while(pos->ply > 0) { 36 | TakeMove(pos); 37 | } 38 | 39 | return count; 40 | } 41 | 42 | void ClearHashTable(S_HASHTABLE *table) { 43 | 44 | S_HASHENTRY *tableEntry; 45 | 46 | for (tableEntry = table->pTable; tableEntry < table->pTable + table->numEntries; tableEntry++) { 47 | tableEntry->posKey = 0ULL; 48 | tableEntry->move = NOMOVE; 49 | tableEntry->depth = 0; 50 | tableEntry->score = 0; 51 | tableEntry->flags = 0; 52 | } 53 | table->newWrite=0; 54 | } 55 | 56 | void InitHashTable(S_HASHTABLE *table, const int MB) { 57 | 58 | int HashSize = 0x100000 * MB; 59 | table->numEntries = HashSize / sizeof(S_HASHENTRY); 60 | table->numEntries -= 2; 61 | 62 | if(table->pTable!=NULL) { 63 | free(table->pTable); 64 | } 65 | 66 | table->pTable = (S_HASHENTRY *) malloc(table->numEntries * sizeof(S_HASHENTRY)); 67 | if(table->pTable == NULL) { 68 | printf("Hash Allocation Failed, trying %dMB...\n",MB/2); 69 | InitHashTable(table,MB/2); 70 | } else { 71 | ClearHashTable(table); 72 | printf("HashTable init complete with %d entries\n",table->numEntries); 73 | } 74 | 75 | } 76 | 77 | /* 78 | void StorePvMove(const S_BOARD *pos, const int move) { 79 | int index = pos->posKey % pos->HashTable->numEntries; 80 | 81 | ASSERT(index >= 0 && index <= pos->HashTable->numEntries - 1); 82 | 83 | pos->HashTable->pTable[index].move = move; 84 | pos->HashTable->pTable[index].posKey = pos->posKey; 85 | } 86 | */ 87 | 88 | void StoreHashEntry(S_BOARD *pos, const int move, int score, const int flags, const int depth) { 89 | 90 | int index = pos->posKey % pos->HashTable->numEntries; 91 | 92 | ASSERT(index >= 0 && index <= pos->HashTable->numEntries - 1); 93 | ASSERT(depth>=1&&depth=HFALPHA&&flags<=HFEXACT); 95 | ASSERT(score>=-INF&&score<=INF); 96 | ASSERT(pos->ply>=0&&pos->plyHashTable->pTable[index].posKey == 0) { 99 | pos->HashTable->newWrite++; 100 | } else { 101 | pos->HashTable->overWrite++; 102 | } 103 | 104 | if(score > ISMATE) score += pos->ply; 105 | else if(score < -ISMATE) score -= pos->ply; 106 | 107 | pos->HashTable->pTable[index].move = move; 108 | pos->HashTable->pTable[index].posKey = pos->posKey; 109 | pos->HashTable->pTable[index].flags = flags; 110 | pos->HashTable->pTable[index].score = score; 111 | pos->HashTable->pTable[index].depth = depth; 112 | } 113 | 114 | 115 | int ProbeHashEntry(S_BOARD *pos, int *move, int *score, int alpha, int beta, int depth) { 116 | 117 | int index = pos->posKey % pos->HashTable->numEntries; 118 | 119 | ASSERT(index >= 0 && index <= pos->HashTable->numEntries - 1); 120 | ASSERT(depth>=1&&depth=-INF&&alpha<=INF); 123 | ASSERT(beta>=-INF&&beta<=INF); 124 | ASSERT(pos->ply>=0&&pos->plyHashTable->pTable[index].posKey == pos->posKey ) { 127 | *move = pos->HashTable->pTable[index].move; 128 | if(pos->HashTable->pTable[index].depth >= depth){ 129 | pos->HashTable->hit++; 130 | 131 | ASSERT(pos->HashTable->pTable[index].depth>=1&&pos->HashTable->pTable[index].depthHashTable->pTable[index].flags>=HFALPHA&&pos->HashTable->pTable[index].flags<=HFEXACT); 133 | 134 | *score = pos->HashTable->pTable[index].score; 135 | if(*score > ISMATE) *score -= pos->ply; 136 | else if(*score < -ISMATE) *score += pos->ply; 137 | 138 | switch(pos->HashTable->pTable[index].flags) { 139 | 140 | ASSERT(*score>=-INF&&*score<=INF); 141 | 142 | case HFALPHA: if(*score<=alpha) { 143 | *score=alpha; 144 | return TRUE; 145 | } 146 | break; 147 | case HFBETA: if(*score>=beta) { 148 | *score=beta; 149 | return TRUE; 150 | } 151 | break; 152 | case HFEXACT: 153 | return TRUE; 154 | break; 155 | default: ASSERT(FALSE); break; 156 | } 157 | } 158 | } 159 | 160 | return FALSE; 161 | } 162 | 163 | int ProbePvMove(const S_BOARD *pos) { 164 | 165 | int index = pos->posKey % pos->HashTable->numEntries; 166 | ASSERT(index >= 0 && index <= pos->HashTable->numEntries - 1); 167 | 168 | if( pos->HashTable->pTable[index].posKey == pos->posKey ) { 169 | return pos->HashTable->pTable[index].move; 170 | } 171 | 172 | return NOMOVE; 173 | } 174 | -------------------------------------------------------------------------------- /vice/search.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include "defs.h" 13 | 14 | #define INF 30000 15 | #define MATE 29000 16 | 17 | static void CheckUp(S_SEARCHINFO *info) { 18 | if(info->timeset == TRUE && GetTimeMs() > info->stoptime) 19 | info->stopped = TRUE; 20 | 21 | ReadInput(info); 22 | } 23 | 24 | static void PickNextMove(int moveNum, S_MOVELIST *list) { 25 | S_MOVE temp; 26 | int index = 0; 27 | int bestScore = 0; 28 | int bestNum = moveNum; 29 | 30 | for(index = moveNum; index < list->count; ++index) { 31 | if(list->moves[index].score > bestScore) { 32 | bestScore = list->moves[index].score; 33 | bestNum = index; 34 | } 35 | } 36 | 37 | temp = list->moves[moveNum]; 38 | list->moves[moveNum] = list->moves[bestNum]; 39 | list->moves[bestNum] = temp; 40 | } 41 | 42 | static int IsRepetition(const S_BOARD *pos) { 43 | int index = 0; 44 | 45 | for(index = pos->hisPly - pos->fiftyMove; index < pos->hisPly; ++index) { 46 | ASSERT(index >= 0 && index < MAXGAMEMOVES); 47 | if(pos->posKey == pos->history[index].posKey) 48 | return TRUE; 49 | } 50 | 51 | return FALSE; 52 | } 53 | 54 | static void ClearForSearch(S_BOARD *pos, S_SEARCHINFO *info) { 55 | int index = 0; 56 | int index2 = 0; 57 | 58 | for(index = 0; index < 13; ++index) 59 | for(index2 = 0; index2 < BRD_SQ_NUM; ++index2) 60 | pos->searchHistory[index][index2] = 0; 61 | 62 | for(index = 0; index < 2; ++index) 63 | for(index2 = 0; index2 < MAXDEPTH; ++index2) 64 | pos->searchKillers[index][index2] = 0; 65 | 66 | ClearHashTable(pos->HashTable); 67 | pos->ply = 0; 68 | 69 | info->stopped = 0; 70 | info->nodes = 0; 71 | info->fh = 0; 72 | info->fhf = 0; 73 | } 74 | 75 | static int Quiescence(int alpha, int beta, S_BOARD *pos, S_SEARCHINFO *info) { 76 | int MoveNum = 0; 77 | int Legal = 0; 78 | int Score; 79 | S_MOVELIST list[1]; 80 | 81 | ASSERT(CheckBoard(pos)); 82 | ASSERT(beta > alpha); 83 | 84 | if((info->nodes & 2047) == 0) 85 | CheckUp(info); 86 | 87 | info->nodes++; 88 | 89 | if(IsRepetition(pos) || pos->fiftyMove >= 100) 90 | return 0; 91 | 92 | if(pos->ply > MAXDEPTH - 1) 93 | return EvalPosition(pos); 94 | 95 | Score = EvalPosition(pos); 96 | 97 | ASSERT(Score > -INF && Score < INF); 98 | 99 | if(Score >= beta) 100 | return beta; 101 | 102 | if(Score > alpha) 103 | alpha = Score; 104 | 105 | GenerateAllCaps(pos, list); 106 | 107 | Score = -INF; 108 | 109 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 110 | PickNextMove(MoveNum, list); 111 | 112 | if (!MakeMove(pos, list->moves[MoveNum].move)) 113 | continue; 114 | 115 | Legal++; 116 | Score = -Quiescence(-beta, -alpha, pos, info); 117 | TakeMove(pos); 118 | 119 | if(info->stopped == TRUE) 120 | return 0; 121 | 122 | if(Score > alpha) { 123 | if(Score >= beta) { 124 | if(Legal == 1) 125 | info->fhf++; 126 | info->fh++; 127 | return beta; 128 | } 129 | alpha = Score; 130 | } 131 | } 132 | 133 | return alpha; 134 | } 135 | 136 | static int AlphaBeta(int alpha, int beta, int depth, S_BOARD *pos, S_SEARCHINFO *info, int DoNull) { 137 | S_MOVELIST list[1]; 138 | int InCheck; 139 | int Score = -INF; 140 | int PvMove = NOMOVE; 141 | int MoveNum = 0; 142 | int Legal = 0; 143 | int OldAlpha = alpha; 144 | int BestMove = NOMOVE; 145 | int BestScore = -INF; 146 | 147 | ASSERT(CheckBoard(pos)); 148 | ASSERT(beta > alpha); 149 | ASSERT(depth >= 0); 150 | 151 | if(depth <= 0) 152 | return Quiescence(alpha, beta, pos, info); 153 | 154 | if((info->nodes & 2047) == 0) 155 | CheckUp(info); 156 | 157 | info->nodes++; 158 | 159 | if((IsRepetition(pos) || pos->fiftyMove >= 100) && pos->ply) 160 | return 0; 161 | 162 | if(pos->ply > MAXDEPTH - 1) 163 | return EvalPosition(pos); 164 | 165 | InCheck = SqAttacked(pos->KingSq[pos->side], pos->side ^ 1, pos); 166 | 167 | if(InCheck == TRUE) 168 | depth++; 169 | 170 | if(ProbeHashEntry(pos, &PvMove, &Score, alpha, beta, depth) == TRUE) { 171 | pos->HashTable->cut++; 172 | return Score; 173 | } 174 | 175 | if(DoNull && !InCheck && pos->ply && (pos->bigPce[pos->side] > 0) && depth >= 4) { 176 | MakeNullMove(pos); 177 | Score = -AlphaBeta(-beta, -beta + 1, depth - 4, pos, info, FALSE); 178 | TakeNullMove(pos); 179 | if(info->stopped == TRUE) 180 | return 0; 181 | 182 | if (Score >= beta && abs(Score) < ISMATE) { 183 | info->nullCut++; 184 | return beta; 185 | } 186 | } 187 | 188 | GenerateAllMoves(pos, list); 189 | 190 | Score = -INF; 191 | 192 | if(PvMove != NOMOVE) { 193 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 194 | if( list->moves[MoveNum].move == PvMove) { 195 | list->moves[MoveNum].score = 2000000; 196 | break; 197 | } 198 | } 199 | } 200 | 201 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 202 | PickNextMove(MoveNum, list); 203 | 204 | if(!MakeMove(pos,list->moves[MoveNum].move)) 205 | continue; 206 | 207 | Legal++; 208 | Score = -AlphaBeta(-beta, -alpha, depth - 1, pos, info, TRUE); 209 | TakeMove(pos); 210 | 211 | if(info->stopped == TRUE) 212 | return 0; 213 | 214 | if(Score > BestScore) { 215 | BestScore = Score; 216 | BestMove = list->moves[MoveNum].move; 217 | if(Score > alpha) { 218 | if(Score >= beta) { 219 | if(Legal == 1) 220 | info->fhf++; 221 | info->fh++; 222 | 223 | if(!(list->moves[MoveNum].move & MFLAGCAP)) { 224 | pos->searchKillers[1][pos->ply] = pos->searchKillers[0][pos->ply]; 225 | pos->searchKillers[0][pos->ply] = list->moves[MoveNum].move; 226 | } 227 | 228 | StoreHashEntry(pos, BestMove, beta, HFBETA, depth); 229 | return beta; 230 | } 231 | alpha = Score; 232 | 233 | if(!(list->moves[MoveNum].move & MFLAGCAP)) 234 | pos->searchHistory[pos->pieces[FROMSQ(BestMove)]][TOSQ(BestMove)] += depth; 235 | } 236 | } 237 | } 238 | 239 | if(Legal == 0) { 240 | if(InCheck) { 241 | return -INF + pos->ply; 242 | } else { 243 | return 0; 244 | } 245 | } 246 | 247 | ASSERT(alpha >= OldAlpha); 248 | 249 | if(alpha != OldAlpha) { 250 | StoreHashEntry(pos, BestMove, BestScore, HFEXACT, depth); 251 | } else { 252 | StoreHashEntry(pos, BestMove, alpha, HFALPHA, depth); 253 | } 254 | 255 | return alpha; 256 | } 257 | 258 | void SearchPosition(S_BOARD *pos, S_SEARCHINFO *info) { 259 | int bestMove = NOMOVE; 260 | int bestScore = -INF; 261 | int currentDepth = 0; 262 | int pvMoves = 0; 263 | int pvNum = 0; 264 | 265 | ClearForSearch(pos, info); 266 | 267 | if(EngineOptions->UseBook == TRUE) 268 | bestMove = GetBookMove(pos); 269 | 270 | if(bestMove == NOMOVE) { 271 | for(currentDepth = 1; currentDepth <= info->depth; ++currentDepth) { 272 | bestScore = AlphaBeta(-INF, INF, currentDepth, pos, info, TRUE); 273 | 274 | if(info->stopped == TRUE) 275 | break; 276 | 277 | pvMoves = GetPvLine(currentDepth, pos); 278 | bestMove = pos->PvArray[0]; 279 | 280 | if(info->GAME_MODE == UCIMODE) { 281 | printf("info score cp %d depth %d nodes %ld time %d ", 282 | bestScore, currentDepth, info->nodes, GetTimeMs() - info->starttime); 283 | } else if(info->GAME_MODE == XBOARDMODE && info->POST_THINKING == TRUE) { 284 | printf("%d %d %d %ld ", 285 | currentDepth, bestScore, (GetTimeMs() - info->starttime) / 10, info->nodes); 286 | } else if(info->POST_THINKING == TRUE) { 287 | printf("score:%d depth:%d nodes:%ld time:%d(ms) ", 288 | bestScore, currentDepth, info->nodes, GetTimeMs() - info->starttime); 289 | } 290 | 291 | if(info->GAME_MODE == UCIMODE || info->POST_THINKING == TRUE) { 292 | pvMoves = GetPvLine(currentDepth, pos); 293 | printf("pv"); 294 | for(pvNum = 0; pvNum < pvMoves; ++pvNum) 295 | printf(" %s", PrMove(pos->PvArray[pvNum])); 296 | printf("\n"); 297 | } 298 | } 299 | } 300 | 301 | if(info->GAME_MODE == UCIMODE) { 302 | printf("bestmove %s\n", PrMove(bestMove)); 303 | } else if(info->GAME_MODE == XBOARDMODE) { 304 | printf("move %s\n", PrMove(bestMove)); 305 | MakeMove(pos, bestMove); 306 | } else { 307 | printf("\n\n***!! Vice makes move %s !!***\n\n", PrMove(bestMove)); 308 | MakeMove(pos, bestMove); 309 | PrintBoard(pos); 310 | } 311 | } 312 | -------------------------------------------------------------------------------- /vice/uci.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include 14 | #include "defs.h" 15 | 16 | #define INPUTBUFFER 400 * 6 17 | 18 | void ParseGo(char* line, S_SEARCHINFO *info, S_BOARD *pos) { 19 | 20 | int depth = -1, movestogo = 30,movetime = -1; 21 | int time = -1, inc = 0; 22 | char *ptr = NULL; 23 | info->timeset = FALSE; 24 | 25 | if((ptr = strstr(line,"INF"))); 26 | 27 | if((ptr = strstr(line,"binc")) && pos->side == BLACK) 28 | inc = atoi(ptr + 5); 29 | if((ptr = strstr(line,"winc")) && pos->side == WHITE) 30 | inc = atoi(ptr + 5); 31 | if((ptr = strstr(line,"wtime")) && pos->side == WHITE) 32 | time = atoi(ptr + 6); 33 | if((ptr = strstr(line,"btime")) && pos->side == BLACK) 34 | time = atoi(ptr + 6); 35 | if((ptr = strstr(line,"movestogo"))) 36 | movestogo = atoi(ptr + 10); 37 | if((ptr = strstr(line,"movetime"))) 38 | movetime = atoi(ptr + 9); 39 | 40 | if((ptr = strstr(line,"depth"))) 41 | depth = atoi(ptr + 6); 42 | 43 | if(movetime != -1) { 44 | time = movetime; 45 | movestogo = 1; 46 | } 47 | 48 | info->starttime = GetTimeMs(); 49 | info->depth = depth; 50 | 51 | if(time != -1) { 52 | info->timeset = TRUE; 53 | time /= movestogo; 54 | time -= 50; 55 | info->stoptime = info->starttime + time + inc; 56 | } 57 | 58 | if(depth == -1) 59 | info->depth = MAXDEPTH; 60 | 61 | printf("time:%d start:%d stop:%d depth:%d timeset:%d\n", 62 | time, info->starttime, info->stoptime, info->depth, info->timeset); 63 | SearchPosition(pos, info); 64 | } 65 | 66 | void ParsePosition(char *lineIn, S_BOARD *pos) { 67 | char *ptrChar = lineIn + 9; 68 | int move; 69 | 70 | lineIn = ptrChar; 71 | 72 | if(strncmp(lineIn, "startpos", 8) == 0) { 73 | ParseFen(START_FEN, pos); 74 | } else { 75 | ptrChar = strstr(lineIn, "fen"); 76 | if(ptrChar == NULL) { 77 | ParseFen(START_FEN, pos); 78 | } else { 79 | ptrChar += 4; 80 | ParseFen(ptrChar, pos); 81 | } 82 | } 83 | 84 | ptrChar = strstr(lineIn, "moves"); 85 | 86 | if(ptrChar != NULL) { 87 | ptrChar += 6; 88 | while(*ptrChar) { 89 | move = ParseMove(ptrChar, pos); 90 | if(move == NOMOVE) 91 | break; 92 | MakeMove(pos, move); 93 | pos->ply = 0; 94 | while(*ptrChar && *ptrChar != ' ') 95 | ptrChar++; 96 | ptrChar++; 97 | } 98 | } 99 | PrintBoard(pos); 100 | } 101 | 102 | void Uci_Loop(S_BOARD *pos, S_SEARCHINFO *info) { 103 | char line[INPUTBUFFER], *ptrTrue = NULL; 104 | int MB = 64; 105 | 106 | info->GAME_MODE = UCIMODE; 107 | info->quit = 0; 108 | 109 | setbuf(stdin, NULL); 110 | setbuf(stdout, NULL); 111 | printf("id name %s\n",NAME); 112 | printf("id author Bluefever\n"); 113 | printf("option name Hash type spin default 64 min 4 max %d\n", MAX_HASH); 114 | printf("option name Book type check default true\n"); 115 | printf("uciok\n"); 116 | 117 | 118 | while (TRUE) { 119 | memset(&line[0], 0, sizeof(line)); 120 | fflush(stdout); 121 | if (!fgets(line, INPUTBUFFER, stdin)) 122 | continue; 123 | 124 | if (line[0] == '\n') 125 | continue; 126 | 127 | if (!strncmp(line, "isready", 7)) { 128 | printf("readyok\n"); 129 | continue; 130 | } else if (!strncmp(line, "position", 8)) { 131 | ParsePosition(line, pos); 132 | } else if (!strncmp(line, "ucinewgame", 10)) { 133 | ParsePosition("position startpos\n", pos); 134 | } else if (!strncmp(line, "go", 2)) { 135 | ParseGo(line, info, pos); 136 | } else if (!strncmp(line, "quit", 4)) { 137 | info->quit = TRUE; 138 | break; 139 | } else if (!strncmp(line, "uci", 3)) { 140 | printf("id name %s\n", NAME); 141 | printf("id author Bluefever\n"); 142 | printf("uciok\n"); 143 | } else if(!strncmp(line, "setoption name Hash value ", 26)) { 144 | sscanf(line, "%*s %*s %*s %*s %d", &MB); 145 | if(MB < 4) MB = 4; 146 | if(MB > MAX_HASH) MB = MAX_HASH; 147 | printf("Set Hash to %d MB\n", MB); 148 | InitHashTable(pos->HashTable, MB); 149 | } else if(!strncmp(line, "setoption name Book value ", 26)) { 150 | ptrTrue = strstr(line, "true"); 151 | if(ptrTrue != NULL) { 152 | EngineOptions->UseBook = TRUE; 153 | } else { 154 | EngineOptions->UseBook = FALSE; 155 | } 156 | } 157 | if(info->quit) break; 158 | } 159 | } 160 | -------------------------------------------------------------------------------- /vice/validate.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include "defs.h" 14 | 15 | int SqOnBoard(const int sq) { 16 | return (FilesBrd[sq] == OFFBOARD) ? 0 : 1; 17 | } 18 | 19 | int SideValid(const int side) { 20 | return ((side == WHITE) || (side == BLACK)) ? 1 : 0; 21 | } 22 | 23 | int FileRankValid(const int fr) { 24 | return (fr >= 0 && fr <= 7) ? 1 : 0; 25 | } 26 | 27 | int PieceValidEmpty(const int pce) { 28 | return (pce >= EMPTY && pce <= bK) ? 1 : 0; 29 | } 30 | 31 | int PieceValid(const int pce) { 32 | return (pce >= wP && pce <= bK) ? 1 : 0; 33 | } 34 | 35 | void MirrorEvalTest(S_BOARD *pos) { 36 | FILE *file; 37 | char lineIn [1024]; 38 | int ev1 = 0; int ev2 = 0; 39 | int positions = 0; 40 | 41 | file = fopen("mirror.epd","r"); 42 | 43 | if(file == NULL) { 44 | printf("File Not Found\n"); 45 | return; 46 | } else { 47 | while(fgets (lineIn, 1024, file) != NULL) { 48 | ParseFen(lineIn, pos); 49 | positions++; 50 | ev1 = EvalPosition(pos); 51 | MirrorBoard(pos); 52 | ev2 = EvalPosition(pos); 53 | 54 | if(ev1 != ev2) { 55 | printf("\n\n\n"); 56 | ParseFen(lineIn, pos); 57 | PrintBoard(pos); 58 | MirrorBoard(pos); 59 | PrintBoard(pos); 60 | printf("\n\nMirror Fail:\n%s\n", lineIn); 61 | getchar(); 62 | return; 63 | } 64 | 65 | if((positions % 1000) == 0) { 66 | printf("position %d\n", positions); 67 | } 68 | 69 | memset(&lineIn[0], 0, sizeof(lineIn)); 70 | } 71 | } 72 | } 73 | -------------------------------------------------------------------------------- /vice/vice.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include 14 | #include 15 | 16 | #include "defs.h" 17 | 18 | int main(int argc, char **argv) { 19 | S_BOARD pos[1]; 20 | S_SEARCHINFO info[1]; 21 | char line[256]; 22 | int ArgNum = 0; 23 | 24 | pos->HashTable->pTable = NULL; 25 | 26 | AllInit(); 27 | InitHashTable(pos->HashTable, 64); 28 | memset(pos->searchKillers, 0, 2 * MAXDEPTH * sizeof(int)); 29 | 30 | setbuf(stdin, NULL); 31 | setbuf(stdout, NULL); 32 | 33 | for(ArgNum = 0; ArgNum < argc; ++ArgNum) { 34 | if(strncmp(argv[ArgNum], "NoBook", 6) == 0) { 35 | EngineOptions->UseBook = FALSE; 36 | } 37 | } 38 | 39 | printf("Welcome to Vice! Type 'vice' for console mode...\n"); 40 | 41 | while (TRUE) { 42 | memset(&line[0], 0, sizeof(line)); 43 | 44 | fflush(stdout); 45 | if (!fgets(line, 256, stdin)) 46 | continue; 47 | if (line[0] == '\n') 48 | continue; 49 | if (!strncmp(line, "uci",3)) { 50 | Uci_Loop(pos, info); 51 | if(info->quit == TRUE) break; 52 | continue; 53 | } else if (!strncmp(line, "xboard",6)) { 54 | XBoard_Loop(pos, info); 55 | if(info->quit == TRUE) break; 56 | continue; 57 | } else if (!strncmp(line, "vice",4)) { 58 | Console_Loop(pos, info); 59 | if(info->quit == TRUE) break; 60 | continue; 61 | } else if(!strncmp(line, "quit",4)) { 62 | break; 63 | } 64 | } 65 | 66 | free(pos->HashTable->pTable); 67 | CleanPolyBook(); 68 | return 0; 69 | } 70 | -------------------------------------------------------------------------------- /vice/vice.vcxproj: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | Debug 6 | Win32 7 | 8 | 9 | Debug 10 | x64 11 | 12 | 13 | Release 14 | Win32 15 | 16 | 17 | Release 18 | x64 19 | 20 | 21 | 22 | {D0A65C84-4087-4F8D-88DB-79EBB9B5EFCB} 23 | Win32Proj 24 | vice 25 | 26 | 27 | 28 | Application 29 | true 30 | Unicode 31 | 32 | 33 | Application 34 | true 35 | Unicode 36 | 37 | 38 | Application 39 | false 40 | true 41 | Unicode 42 | 43 | 44 | Application 45 | false 46 | true 47 | Unicode 48 | 49 | 50 | 51 | 52 | 53 | 54 | 55 | 56 | 57 | 58 | 59 | 60 | 61 | 62 | 63 | 64 | 65 | 66 | true 67 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 68 | $(Platform)\$(Configuration)\ 69 | 70 | 71 | true 72 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 73 | $(Platform)\$(Configuration)\ 74 | 75 | 76 | false 77 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 78 | $(Platform)\$(Configuration)\ 79 | 80 | 81 | false 82 | $(SolutionDir)bin\$(Platform)\$(Configuration)\ 83 | $(Platform)\$(Configuration)\ 84 | 85 | 86 | 87 | NotUsing 88 | Level3 89 | Disabled 90 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;DEBUG;%(PreprocessorDefinitions) 91 | MultiThreadedDebug 92 | 4996 93 | 94 | 95 | Console 96 | true 97 | 98 | 99 | 100 | 101 | NotUsing 102 | Level3 103 | Disabled 104 | _CRT_SECURE_NO_WARNINGS;WIN32;_DEBUG;_CONSOLE;DEBUG;%(PreprocessorDefinitions) 105 | MultiThreadedDebug 106 | 4996 107 | 108 | 109 | Console 110 | true 111 | 112 | 113 | 114 | 115 | Level3 116 | NotUsing 117 | MaxSpeed 118 | true 119 | true 120 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 121 | MultiThreaded 122 | 4996 123 | 124 | 125 | Console 126 | true 127 | true 128 | true 129 | 130 | 131 | 132 | 133 | Level3 134 | NotUsing 135 | MaxSpeed 136 | true 137 | true 138 | _CRT_SECURE_NO_WARNINGS;WIN32;NDEBUG;_CONSOLE;%(PreprocessorDefinitions) 139 | MultiThreaded 140 | 4996 141 | 142 | 143 | Console 144 | true 145 | true 146 | true 147 | 148 | 149 | 150 | 151 | CompileAsC 152 | CompileAsC 153 | CompileAsC 154 | CompileAsC 155 | 156 | 157 | CompileAsC 158 | CompileAsC 159 | CompileAsC 160 | CompileAsC 161 | 162 | 163 | CompileAsC 164 | CompileAsC 165 | CompileAsC 166 | CompileAsC 167 | 168 | 169 | CompileAsC 170 | CompileAsC 171 | CompileAsC 172 | CompileAsC 173 | 174 | 175 | CompileAsC 176 | CompileAsC 177 | CompileAsC 178 | CompileAsC 179 | 180 | 181 | CompileAsC 182 | CompileAsC 183 | CompileAsC 184 | CompileAsC 185 | 186 | 187 | CompileAsC 188 | CompileAsC 189 | CompileAsC 190 | CompileAsC 191 | 192 | 193 | CompileAsC 194 | CompileAsC 195 | CompileAsC 196 | CompileAsC 197 | 198 | 199 | CompileAsC 200 | CompileAsC 201 | CompileAsC 202 | CompileAsC 203 | 204 | 205 | CompileAsC 206 | CompileAsC 207 | CompileAsC 208 | CompileAsC 209 | 210 | 211 | CompileAsC 212 | CompileAsC 213 | CompileAsC 214 | CompileAsC 215 | 216 | 217 | CompileAsC 218 | CompileAsC 219 | CompileAsC 220 | CompileAsC 221 | 222 | 223 | 224 | 225 | CompileAsC 226 | CompileAsC 227 | CompileAsC 228 | CompileAsC 229 | 230 | 231 | CompileAsC 232 | CompileAsC 233 | CompileAsC 234 | CompileAsC 235 | 236 | 237 | CompileAsC 238 | CompileAsC 239 | CompileAsC 240 | CompileAsC 241 | 242 | 243 | CompileAsC 244 | CompileAsC 245 | CompileAsC 246 | CompileAsC 247 | 248 | 249 | CompileAsC 250 | CompileAsC 251 | CompileAsC 252 | CompileAsC 253 | 254 | 255 | CompileAsC 256 | CompileAsC 257 | CompileAsC 258 | CompileAsC 259 | 260 | 261 | 262 | 263 | 264 | 265 | 266 | 267 | 268 | -------------------------------------------------------------------------------- /vice/vice.vcxproj.filters: -------------------------------------------------------------------------------- 1 |  2 | 3 | 4 | 5 | {4FC737F1-C7A5-4376-A066-2A32D752A2FF} 6 | cpp;c;cc;cxx;def;odl;idl;hpj;bat;asm;asmx 7 | 8 | 9 | {93995380-89BD-4b04-88EB-625FBE52EBFB} 10 | h;hpp;hxx;hm;inl;inc;xsd 11 | 12 | 13 | {67DA6AB6-F800-4c08-8B7A-83BB121AAD01} 14 | rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms 15 | 16 | 17 | 18 | 19 | Source Files 20 | 21 | 22 | Source Files 23 | 24 | 25 | Source Files 26 | 27 | 28 | Source Files 29 | 30 | 31 | Source Files 32 | 33 | 34 | Source Files 35 | 36 | 37 | Source Files 38 | 39 | 40 | Source Files 41 | 42 | 43 | Source Files 44 | 45 | 46 | Source Files 47 | 48 | 49 | Source Files 50 | 51 | 52 | Source Files 53 | 54 | 55 | Source Files 56 | 57 | 58 | Source Files 59 | 60 | 61 | Source Files 62 | 63 | 64 | Source Files 65 | 66 | 67 | Source Files 68 | 69 | 70 | Source Files 71 | 72 | 73 | Source Files 74 | 75 | 76 | Source Files 77 | 78 | 79 | 80 | 81 | Header Files 82 | 83 | 84 | Header Files 85 | 86 | 87 | -------------------------------------------------------------------------------- /vice/xboard.c: -------------------------------------------------------------------------------- 1 | /* 2 | * VICE -- Video Instructions Chess Engine 3 | * (C) 2013 Bluefever Software 4 | * 5 | * This program is free software. It comes without any warranty, to 6 | * the extent permitted by applicable law. You can redistribute it 7 | * and/or modify it under the terms of the Do What The Fuck You Want 8 | * To Public License, Version 2, as published by Sam Hocevar. See 9 | * http://sam.zoy.org/wtfpl/COPYING for more details. 10 | */ 11 | 12 | #include 13 | #include 14 | 15 | #include "defs.h" 16 | 17 | int ThreeFoldRep(const S_BOARD *pos) { 18 | int i = 0, r = 0; 19 | for(i = 0; i < pos->hisPly; ++i) { 20 | if(pos->history[i].posKey == pos->posKey) { 21 | r++; 22 | } 23 | } 24 | 25 | return r; 26 | } 27 | 28 | int DrawMaterial(const S_BOARD *pos) { 29 | if(pos->pceNum[wP] || pos->pceNum[bP]) return FALSE; 30 | if(pos->pceNum[wQ] || pos->pceNum[bQ] || pos->pceNum[wR] || pos->pceNum[bR]) return FALSE; 31 | if(pos->pceNum[wB] > 1 || pos->pceNum[bB] > 1) return FALSE; 32 | if(pos->pceNum[wN] > 1 || pos->pceNum[bN] > 1) return FALSE; 33 | if(pos->pceNum[wN] && pos->pceNum[wB]) return FALSE; 34 | if(pos->pceNum[bN] && pos->pceNum[bB]) return FALSE; 35 | 36 | return TRUE; 37 | } 38 | 39 | int checkresult(S_BOARD *pos) { 40 | S_MOVELIST list[1]; 41 | int MoveNum = 0; 42 | int found = 0; 43 | int InCheck; 44 | 45 | if(pos->fiftyMove > 100) { 46 | printf("1/2-1/2 (fifty move rule (claimed by Vice))\n"); return TRUE; 47 | } 48 | 49 | if(ThreeFoldRep(pos)) { 50 | printf("1/2-1/2 (3-fold repetition (claimed by Vice))\n"); return TRUE; 51 | } 52 | 53 | if(DrawMaterial(pos) == TRUE) { 54 | printf("1/2-1/2 (insufficient material (claimed by Vice))\n"); return TRUE; 55 | } 56 | 57 | GenerateAllMoves(pos, list); 58 | for(MoveNum = 0; MoveNum < list->count; ++MoveNum) { 59 | if(!MakeMove(pos, list->moves[MoveNum].move)) { 60 | continue; 61 | } 62 | found++; 63 | TakeMove(pos); 64 | break; 65 | } 66 | 67 | if(found != 0) return FALSE; 68 | 69 | InCheck = SqAttacked(pos->KingSq[pos->side], pos->side ^ 1, pos); 70 | 71 | if(InCheck == TRUE) { 72 | if(pos->side == WHITE) { 73 | printf("0-1 (black mates (claimed by Vice))\n"); return TRUE; 74 | } else { 75 | printf("0-1 (white mates (claimed by Vice))\n"); return TRUE; 76 | } 77 | } else { 78 | printf("1/2-1/2 (stalemate (claimed by Vice))\n"); return TRUE; 79 | } 80 | 81 | return FALSE; 82 | } 83 | 84 | void PrintOptions() { 85 | printf("feature ping=1 setboard=1 colors=0 usermove=1 memory=1\n"); 86 | printf("feature done=1\n"); 87 | } 88 | 89 | void XBoard_Loop(S_BOARD *pos, S_SEARCHINFO *info) { 90 | int depth = -1, movestogo[2] = {30,30 }, movetime = -1; 91 | int time = -1, inc = 0; 92 | int engineSide = BOTH; 93 | int timeLeft; 94 | int sec; 95 | int mps; 96 | int move = NOMOVE; 97 | char inBuf[80], command[80]; 98 | int MB; 99 | 100 | info->GAME_MODE = XBOARDMODE; 101 | info->POST_THINKING = TRUE; 102 | setbuf(stdin, NULL); 103 | setbuf(stdout, NULL); 104 | PrintOptions(); // HACK 105 | 106 | engineSide = BLACK; 107 | ParseFen(START_FEN, pos); 108 | depth = -1; 109 | time = -1; 110 | 111 | while(TRUE) { 112 | 113 | fflush(stdout); 114 | 115 | if(pos->side == engineSide && checkresult(pos) == FALSE) { 116 | info->starttime = GetTimeMs(); 117 | info->depth = depth; 118 | 119 | if(time != -1) { 120 | info->timeset = TRUE; 121 | time /= movestogo[pos->side]; 122 | time -= 50; 123 | info->stoptime = info->starttime + time + inc; 124 | } 125 | 126 | if(depth == -1 || depth > MAXDEPTH) { 127 | info->depth = MAXDEPTH; 128 | } 129 | 130 | printf("time:%d start:%d stop:%d depth:%d timeset:%d movestogo:%d mps:%d\n", 131 | time, info->starttime, info->stoptime, info->depth, info->timeset, movestogo[pos->side], mps); 132 | SearchPosition(pos, info); 133 | 134 | if(mps != 0) { 135 | movestogo[pos->side ^ 1]--; 136 | if(movestogo[pos->side ^ 1] < 1) { 137 | movestogo[pos->side ^ 1] = mps; 138 | } 139 | } 140 | } 141 | 142 | fflush(stdout); 143 | 144 | memset(&inBuf[0], 0, sizeof(inBuf)); 145 | fflush(stdout); 146 | if (!fgets(inBuf, 80, stdin)) 147 | continue; 148 | 149 | sscanf(inBuf, "%s", command); 150 | 151 | printf("command seen:%s\n",inBuf); 152 | 153 | if(!strcmp(command, "quit")) { 154 | info->quit = TRUE; 155 | break; 156 | } 157 | 158 | if(!strcmp(command, "force")) { 159 | engineSide = BOTH; 160 | continue; 161 | } 162 | 163 | if(!strcmp(command, "protover")){ 164 | PrintOptions(); 165 | continue; 166 | } 167 | 168 | if(!strcmp(command, "sd")) { 169 | sscanf(inBuf, "sd %d", &depth); 170 | printf("DEBUG depth:%d\n",depth); 171 | continue; 172 | } 173 | 174 | if(!strcmp(command, "st")) { 175 | sscanf(inBuf, "st %d", &movetime); 176 | printf("DEBUG movetime:%d\n",movetime); 177 | continue; 178 | } 179 | 180 | if(!strcmp(command, "time")) { 181 | sscanf(inBuf, "time %d", &time); 182 | time *= 10; 183 | printf("DEBUG time:%d\n",time); 184 | continue; 185 | } 186 | 187 | if(!strcmp(command, "polykey")) { 188 | PrintBoard(pos); 189 | GetBookMove(pos); 190 | continue; 191 | } 192 | 193 | if(!strcmp(command, "memory")) { 194 | sscanf(inBuf, "memory %d", &MB); 195 | if(MB < 4) MB = 4; 196 | if(MB > MAX_HASH) MB = MAX_HASH; 197 | printf("Set Hash to %d MB\n",MB); 198 | InitHashTable(pos->HashTable, MB); 199 | continue; 200 | } 201 | 202 | if(!strcmp(command, "level")) { 203 | sec = 0; 204 | movetime = -1; 205 | if( sscanf(inBuf, "level %d %d %d", &mps, &timeLeft, &inc) != 3) { 206 | sscanf(inBuf, "level %d %d:%d %d", &mps, &timeLeft, &sec, &inc); 207 | printf("DEBUG level with :\n"); 208 | } else { 209 | printf("DEBUG level without :\n"); 210 | } 211 | timeLeft *= 60000; 212 | timeLeft += sec * 1000; 213 | movestogo[0] = movestogo[1] = 30; 214 | if(mps != 0) { 215 | movestogo[0] = movestogo[1] = mps; 216 | } 217 | time = -1; 218 | printf("DEBUG level timeLeft:%d movesToGo:%d inc:%d mps%d\n",timeLeft,movestogo[0],inc,mps); 219 | continue; 220 | } 221 | 222 | if(!strcmp(command, "ping")) { 223 | printf("pong%s\n", inBuf+4); 224 | continue; 225 | } 226 | 227 | if(!strcmp(command, "new")) { 228 | ClearHashTable(pos->HashTable); 229 | engineSide = BLACK; 230 | ParseFen(START_FEN, pos); 231 | depth = -1; 232 | time = -1; 233 | continue; 234 | } 235 | 236 | if(!strcmp(command, "setboard")){ 237 | engineSide = BOTH; 238 | ParseFen(inBuf+9, pos); 239 | continue; 240 | } 241 | 242 | if(!strcmp(command, "go")) { 243 | engineSide = pos->side; 244 | continue; 245 | } 246 | 247 | if(!strcmp(command, "usermove")){ 248 | movestogo[pos->side]--; 249 | move = ParseMove(inBuf+9, pos); 250 | if(move == NOMOVE) continue; 251 | MakeMove(pos, move); 252 | pos->ply=0; 253 | } 254 | } 255 | } 256 | 257 | void Console_Loop(S_BOARD *pos, S_SEARCHINFO *info) { 258 | int depth = MAXDEPTH, movetime = 3000; 259 | int engineSide = BOTH; 260 | int move = NOMOVE; 261 | char inBuf[80], command[80]; 262 | 263 | printf("Welcome to Vice In Console Mode!\n"); 264 | printf("Type help for commands\n\n"); 265 | 266 | info->GAME_MODE = CONSOLEMODE; 267 | info->POST_THINKING = TRUE; 268 | engineSide = BLACK; 269 | ParseFen(START_FEN, pos); 270 | 271 | setbuf(stdin, NULL); 272 | setbuf(stdout, NULL); 273 | 274 | while(TRUE) { 275 | 276 | fflush(stdout); 277 | 278 | if(pos->side == engineSide && checkresult(pos) == FALSE) { 279 | info->starttime = GetTimeMs(); 280 | info->depth = depth; 281 | 282 | if(movetime != 0) { 283 | info->timeset = TRUE; 284 | info->stoptime = info->starttime + movetime; 285 | } 286 | 287 | SearchPosition(pos, info); 288 | } 289 | 290 | printf("\nVice > "); 291 | 292 | fflush(stdout); 293 | 294 | memset(&inBuf[0], 0, sizeof(inBuf)); 295 | fflush(stdout); 296 | if (!fgets(inBuf, 80, stdin)) 297 | continue; 298 | 299 | sscanf(inBuf, "%s", command); 300 | 301 | if(!strcmp(command, "help")) { 302 | printf("Commands:\n"); 303 | printf("quit - quit game\n"); 304 | printf("force - computer will not think\n"); 305 | printf("print - show board\n"); 306 | printf("post - show thinking\n"); 307 | printf("nopost - do not show thinking\n"); 308 | printf("new - start new game\n"); 309 | printf("go - set computer thinking\n"); 310 | printf("depth x - set depth to x\n"); 311 | printf("time x - set thinking time to x seconds (depth still applies if set)\n"); 312 | printf("view - show current depth and movetime settings\n"); 313 | printf("setboard x - set position to fen x\n"); 314 | printf("** note ** - to reset time and depth, set to 0\n"); 315 | printf("enter moves using b7b8q notation\n\n\n"); 316 | continue; 317 | } 318 | 319 | if(!strcmp(command, "mirror")) { 320 | engineSide = BOTH; 321 | MirrorEvalTest(pos); 322 | continue; 323 | } 324 | 325 | if(!strcmp(command, "eval")) { 326 | PrintBoard(pos); 327 | printf("Eval:%d",EvalPosition(pos)); 328 | MirrorBoard(pos); 329 | PrintBoard(pos); 330 | printf("Eval:%d",EvalPosition(pos)); 331 | continue; 332 | } 333 | 334 | if(!strcmp(command, "setboard")){ 335 | engineSide = BOTH; 336 | ParseFen(inBuf+9, pos); 337 | continue; 338 | } 339 | 340 | if(!strcmp(command, "quit")) { 341 | info->quit = TRUE; 342 | break; 343 | } 344 | 345 | if(!strcmp(command, "post")) { 346 | info->POST_THINKING = TRUE; 347 | continue; 348 | } 349 | 350 | if(!strcmp(command, "print")) { 351 | PrintBoard(pos); 352 | continue; 353 | } 354 | 355 | if(!strcmp(command, "nopost")) { 356 | info->POST_THINKING = FALSE; 357 | continue; 358 | } 359 | 360 | if(!strcmp(command, "force")) { 361 | engineSide = BOTH; 362 | continue; 363 | } 364 | 365 | if(!strcmp(command, "view")) { 366 | if(depth == MAXDEPTH) printf("depth not set "); 367 | else printf("depth %d",depth); 368 | 369 | if(movetime != 0) printf(" movetime %ds\n",movetime/1000); 370 | else printf(" movetime not set\n"); 371 | 372 | continue; 373 | } 374 | 375 | if(!strcmp(command, "depth")) { 376 | sscanf(inBuf, "depth %d", &depth); 377 | if(depth==0) depth = MAXDEPTH; 378 | continue; 379 | } 380 | 381 | if(!strcmp(command, "time")) { 382 | sscanf(inBuf, "time %d", &movetime); 383 | movetime *= 1000; 384 | continue; 385 | } 386 | 387 | if(!strcmp(command, "new")) { 388 | ClearHashTable(pos->HashTable); 389 | engineSide = BLACK; 390 | ParseFen(START_FEN, pos); 391 | continue; 392 | } 393 | 394 | if(!strcmp(command, "go")) { 395 | engineSide = pos->side; 396 | continue; 397 | } 398 | 399 | move = ParseMove(inBuf, pos); 400 | if(move == NOMOVE) { 401 | printf("Command unknown:%s\n",inBuf); 402 | continue; 403 | } 404 | MakeMove(pos, move); 405 | pos->ply=0; 406 | } 407 | } 408 | --------------------------------------------------------------------------------