Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Comparing changes

Choose two branches to see what’s changed or to start a new pull request. If you need to, you can also compare across forks.

Open a pull request

Create a new pull request by comparing changes across two branches. If you need to, you can also compare across forks.
base fork: lorenzo-stoakes/weak
base: d9fb574612
...
head fork: lorenzo-stoakes/weak
compare: a31fa55e4e
  • 12 commits
  • 9 files changed
  • 0 commit comments
  • 1 contributor
View
4 eval.c
@@ -25,7 +25,7 @@ static double weights[] = { 0, 1, 3.5, 3.5, 5, 9 };
// Value of game position for white.
double
-Eval(Game *game, Side side)
+Eval(Game *game)
{
double ret = 0;
Piece piece;
@@ -41,5 +41,5 @@ Eval(Game *game, Side side)
}
}
- return ret * (1 - 2*side);
+ return ret * (1 - 2*game->WhosTurn);
}
View
15 game.c
@@ -280,7 +280,7 @@ DoMove(Game *game, Move move)
if((msg = checkConsistency(game)) != NULL) {
printf("Inconsistency in %s's DoMove of %s at doMoveCount %llu:-\n\n",
StringSide(side),
- StringMove(move, piece, capturePiece != MissingPiece),
+ StringMoveFull(move, piece, capturePiece != MissingPiece),
doMoveCount);
puts(StringChessSet(chessSet));
puts(msg);
@@ -322,10 +322,11 @@ GivesCheck(Game *game, Move move)
switch(piece) {
case Pawn:
case King:
- // If the piece blocking the discovered check is a rook, knight or bishop, then for it not to
- // be a direct check (considered above), it must be blocking an attack in the direction
- // it cannot move. Therefore any movement will 'discover' the check. Since a queen can
- // attack in all directions, it can't be involved.
+ // If the piece blocking the discovered check is a rook, knight or bishop, then for it
+ // not to be a direct check (considered above), it must be blocking an attack in the
+ // direction it cannot move. Therefore any movement will 'discover' the check. Since a
+ // queen can attack in all directions, it can't be involved.
+
// A pawn or king, however, can move in the same direction as the attack the 'discoverer'
// threatens, meaning our check is not revealed. So make sure from, to and the king do
// not sit along the same line!
@@ -536,8 +537,6 @@ NewGame(bool debug, Side humanSide)
ret.HumanSide = humanSide;
ret.WhosTurn = White;
-
-
return ret;
}
@@ -773,7 +772,7 @@ Unmove(Game *game)
if((msg = checkConsistency(game)) != NULL) {
printf("Inconsistency in %s's Unmove of %s at unmoveCount %llu:-\n\n",
StringSide(side),
- StringMove(move, piece, capturePiece != MissingPiece),
+ StringMoveFull(move, piece, capturePiece != MissingPiece),
unmoveCount);
puts(StringChessSet(chessSet));
puts(msg);
View
7 interface.c
@@ -66,7 +66,7 @@ RunInterface(Game *game)
count = 0;
ticks = clock();
- reply = Search(game, &count);
+ reply = IterSearch(game, &count, MAX_THINK);
ticks = clock() - ticks;
elapsed = 1000*((double)ticks)/CLOCKS_PER_SEC;
printf("%fms elapsed, considered %llu moves.\n", elapsed, count);
@@ -74,7 +74,7 @@ RunInterface(Game *game)
fromPiece = PieceAt(&game->ChessSet, FROM(reply));
capture = PieceAt(&game->ChessSet, TO(reply)) != MissingPiece;
DoMove(game, reply);
- puts(StringMove(reply, fromPiece, capture));
+ puts(StringMoveFull(reply, fromPiece, capture));
break;
case CmdMoves:
@@ -82,13 +82,12 @@ RunInterface(Game *game)
printf("%ld moves:-\n\n", end-moves);
for(curr = moves; curr != end; curr++) {
- puts(StringMove(*curr, PieceAt(&game->ChessSet, FROM(*curr)),
+ puts(StringMoveFull(*curr, PieceAt(&game->ChessSet, FROM(*curr)),
PieceAt(&game->ChessSet, TO(*curr)) != MissingPiece));
}
printf("\n");
break;
-
case CmdPerft:
ticks = clock();
count = QuickPerft(game, command.PerftDepth);
View
17 movegen.c
@@ -19,11 +19,12 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
+#include <stdio.h>
+
#include "weak.h"
#include "magic.h"
static FORCE_INLINE Move* bishopMoves(Position*, Move*, BitBoard, BitBoard);
-static Move* evasions(Move*, Game*);
static Move* evasionsCaptures(Move*, Game*);
static FORCE_INLINE Move* kingMoves(Position, Move*, BitBoard);
static FORCE_INLINE Move* knightMoves(Position*, Move*, BitBoard);
@@ -40,6 +41,7 @@ Move*
AllCaptures(Move *start, Game *game)
{
Move *curr = start, *end = start;
+ Move move;
end = game->CheckStats.CheckSources ?
evasionsCaptures(start, game) :
@@ -47,7 +49,8 @@ AllCaptures(Move *start, Game *game)
// Filter out illegal moves.
while(curr != end) {
- if(!PseudoLegal(game, *curr, game->CheckStats.Pinned)) {
+ move = *curr;
+ if(!PseudoLegal(game, move, game->CheckStats.Pinned)) {
// Switch last move with the one we are rejecting.
end--;
*curr = *end;
@@ -64,7 +67,7 @@ AllMoves(Move *start, Game *game)
{
Move *curr = start, *end = start;
- end = game->CheckStats.CheckSources ? evasions(start, game) : nonEvasions(start, game);
+ end = game->CheckStats.CheckSources ? Evasions(start, game) : nonEvasions(start, game);
// Filter out illegal moves.
while(curr != end) {
@@ -208,14 +211,14 @@ CastleMoves(Game *game, Move *end)
return end;
}
-static Move*
-evasions(Move *end, Game *game)
+Move*
+Evasions(Move *end, Game *game)
{
BitBoard attacks, moves, targets;
BitBoard checks = game->CheckStats.CheckSources;
BitBoard slideAttacks = EmptyBoard;
ChessSet *chessSet = &game->ChessSet;
- BitBoard occupancy = chessSet->Occupancy;
+ BitBoard occupancy = chessSet->Occupancy;
int checkCount = 0;
Piece piece;
Position check;
@@ -296,7 +299,7 @@ evasionsCaptures(Move *end, Game *game)
BitBoard checks = game->CheckStats.CheckSources;
BitBoard slideAttacks = EmptyBoard;
ChessSet *chessSet = &game->ChessSet;
- BitBoard occupancy = chessSet->Occupancy;
+ BitBoard occupancy = chessSet->Occupancy;
int checkCount = 0;
Piece piece;
Position check;
View
2  parser.c
@@ -69,7 +69,7 @@ ParseFen(char *fen)
// TODO: fix.
int file, rank;
Game ret = NewEmptyGame(false, White);
- Piece piece;
+ Piece piece = MissingPiece;
Position king, pos;
Side side;
View
162 search.c
@@ -19,17 +19,62 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include "weak.h"
+#define PRINT_PV
+
+#if defined(PRINT_PV)
+#include <stdio.h>
+#endif
-#define DEPTH 6
+#include <time.h>
+#include "weak.h"
-static double quiesce(Game*, double, double, uint64_t*, Side);
-static double miniMax(Game*, double, double, int, uint64_t*);
+static double quiesce(Game*, double, double, uint64_t*);
static double negaMax(Game*, double, double, int, uint64_t*);
-// Perform hacky mini-max. Note the scoring is from white's perspective.
+#if defined(PRINT_PV)
+static Move pv[218][30];
+static int pvBestVar;
+static int pvCurrVar;
+static int pvIndex;
+static int pvLength;
+#endif
+
Move
-Search(Game *game, uint64_t *count)
+IterSearch(Game *game, uint64_t *count, uint32_t maxSecs)
+{
+ clock_t ticks;
+ uint32_t elapsed = 0;
+ int depth;
+ Move best = INVALID_MOVE;
+ uint64_t currCount = 0;
+
+ ticks = clock();
+ // We run through this loop at least once.
+ for(depth = 1; 30*elapsed < maxSecs; depth++) {
+#if defined(PRINT_PV)
+ pvCurrVar = 0;
+ pvBestVar = -1;
+ pvLength = depth;
+#endif
+ best = Search(game, &currCount, depth);
+ *count += currCount;
+
+ elapsed = (clock() - ticks)/CLOCKS_PER_SEC;
+ }
+
+#if defined(PRINT_PV)
+ // Output PV.
+ for(depth = 0; depth < pvLength; depth++) {
+ printf("%s ", StringMove(pv[pvBestVar][depth]));
+ }
+ printf("\n");
+#endif
+
+ return best;
+}
+
+Move
+Search(Game *game, uint64_t *count, int depth)
{
double max, val;
Move moves[INIT_MOVE_LEN];
@@ -51,13 +96,25 @@ Search(Game *game, uint64_t *count)
for(curr = start; curr != end; curr++) {
DoMove(game, *curr);
- val = negaMax(game, SMALL, BIG, 1, count);
+#if defined(PRINT_PV)
+ pvIndex = 1;
+ pv[pvCurrVar][0] = *curr;
+#endif
+
+ val = negaMax(game, SMALL, BIG, depth-1, count);
if((side == White && val > max) || (side == Black && val < max)) {
max = val;
best = *curr;
+#if defined(PRINT_PV)
+ pvBestVar = pvCurrVar;
+#endif
}
+#if defined(PRINT_PV)
+ pvCurrVar++;
+#endif
+
Unmove(game);
}
@@ -69,61 +126,6 @@ Search(Game *game, uint64_t *count)
}
static double
-miniMax(Game *game, double alpha, double beta, int depth, uint64_t *count)
-{
- double max, val;
- Move moves[INIT_MOVE_LEN];
- Move *start = moves;
- Move *curr, *end;
- Side side = game->WhosTurn;
-
- if(depth == DEPTH) {
- return quiesce(game, alpha, beta, count, White);
- }
-
- end = AllMoves(moves, game);
-
- *count += end-start;
-
- // Iterate through all moves looking for the best, whose definition
- // varies based on who's turn it is.
-
- max = side == White ? SMALL : BIG;
-
- for(curr = start; curr != end; curr++) {
- DoMove(game, *curr);
- val = miniMax(game, alpha, beta, depth+1, count);
- Unmove(game);
-
- if(side == White) {
- if(val >= beta) {
- return beta;
- }
-
- if(val > max) {
- max = val;
- if(val > alpha) {
- alpha = val;
- }
- }
- } else {
- if(val <= alpha) {
- return alpha;
- }
-
- if(val < max) {
- max = val;
- if(val < beta) {
- beta = val;
- }
- }
- }
- }
-
- return max;
-}
-
-static double
negaMax(Game *game, double alpha, double beta, int depth, uint64_t *count)
{
double val;
@@ -131,27 +133,38 @@ negaMax(Game *game, double alpha, double beta, int depth, uint64_t *count)
Move *start = moves;
Move *curr, *end;
- if(depth == DEPTH) {
- return quiesce(game, alpha, beta, count, game->WhosTurn);
+ if(depth == 0) {
+ return quiesce(game, alpha, beta, count);
}
end = AllMoves(moves, game);
- *count += end-start;
+ *count += end - start;
// Iterate through all moves looking for the best, whose definition
// varies based on who's turn it is.
for(curr = start; curr != end; curr++) {
DoMove(game, *curr);
- val = -negaMax(game, -beta, -alpha, depth+1, count);
+#if defined(PRINT_PV)
+ pvIndex++;
+#endif
+ val = -negaMax(game, -beta, -alpha, depth-1, count);
+#if defined(PRINT_PV)
+ pvIndex--;
+#endif
Unmove(game);
+ // Fail high.
if(val >= beta) {
return val;
}
if(val >= alpha) {
+#if defined(PRINT_PV)
+ pv[pvCurrVar][pvIndex] = *curr;
+#endif
+
alpha = val;
}
}
@@ -161,24 +174,29 @@ negaMax(Game *game, double alpha, double beta, int depth, uint64_t *count)
// Quiescent search. See http://chessprogramming.wikispaces.com/Quiescence+Search
static double
-quiesce(Game *game, double alpha, double beta, uint64_t *count, Side evalSide)
+quiesce(Game *game, double alpha, double beta, uint64_t *count)
{
double val;
- double standPat = Eval(game, evalSide);
+ double standPat = Eval(game);
Move buffer[INIT_MOVE_LEN];
Move move;
Move *end;
Move *curr = buffer;
+ // Fail high.
if(standPat >= beta) {
return beta;
}
-
+
if(alpha < standPat) {
alpha = standPat;
}
- end = AllCaptures(curr, game);
+ if(Checked(game)) {
+ return alpha;
+ } else {
+ end = AllCaptures(curr, game);
+ }
*count += end-curr;
@@ -186,12 +204,14 @@ quiesce(Game *game, double alpha, double beta, uint64_t *count, Side evalSide)
move = *curr;
DoMove(game, move);
- val = -quiesce(game, -beta, -alpha, count, evalSide);
+ val = -quiesce(game, -beta, -alpha, count);
Unmove(game);
+ // Fail high.
if(val >= beta) {
return beta;
}
+
if(val > alpha) {
val = alpha;
}
View
5 set.c
@@ -61,8 +61,7 @@ NewChessSet()
// Clear down piece locations.
for(side = White; side <= Black; side++) {
- // We ignore king here. King locations stored in CheckStats.
- for(piece = Pawn; piece < King; piece++) {
+ for(piece = Pawn; piece <= King; piece++) {
for(i = 0; i < MAX_PIECE_LOCATION; i++) {
ret.PiecePositions[side][piece][i] = EmptyPosition;
}
@@ -155,7 +154,7 @@ NewChessSet()
ret.PiecePositionIndexes[E1] = 0;
ret.Squares[E8] = King;
- ret.PiecePositions[White][King][0] = E8;
+ ret.PiecePositions[Black][King][0] = E8;
ret.PiecePositionIndexes[E8] = 0;
UpdateOccupancies(&ret);
View
587 stringer.c
@@ -19,298 +19,307 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
- #include <stdio.h>
- #include <strings.h>
- #include <ctype.h>
- #include "weak.h"
-
- char
- CharPiece(Piece piece)
- {
- switch(piece) {
- case Pawn:
- return 'P';
- case Rook:
- return 'R';
- case Knight:
- return 'N';
- case Bishop:
- return 'B';
- case Queen:
- return 'Q';
- case King:
- return 'K';
- default:
- return '?';
- }
- }
-
- char*
- StringBitBoard(BitBoard bitBoard)
- {
- const int LINE_LENGTH = 36;
- const int LINE_COUNT = 18;
-
- // TODO: Reduce duplication from StringChessSet.
-
- // Include space for newlines.
- char ret[LINE_LENGTH * LINE_COUNT + 1 + 1000];
- int file, offset, rank;
- Position pos;
- Side lineSide = Black;
-
- char *topLine = " A B C D E F G H \n";
- char *dottedLine = " ---------------------------------\n";
- char *blackLine = " | |...| |...| |...| |...|\n";
- char *whiteLine = " |...| |...| |...| |...| |\n";
-
- // Add top lines.
- strncpy(ret, topLine, LINE_LENGTH);
- strncpy(ret+LINE_LENGTH, dottedLine, LINE_LENGTH);
-
- for(rank = Rank8; rank >= Rank1; rank--) {
- offset = 2*LINE_LENGTH + 2*LINE_LENGTH*(Rank8-rank);
-
- // Add line.
- strncpy(ret + offset, lineSide == White ? whiteLine : blackLine, LINE_LENGTH);
-
- // Add number.
- ret[offset] = '1'+rank;
-
- // Add pieces.
-
- // For the sake of debugging, avoid PieceAt() in case it is buggy.
-
- offset += 4;
- for(file = FileA; file <= FileH; file++) {
- pos = POSITION(rank, file);
-
- if((bitBoard&POSBOARD(pos)) == POSBOARD(pos)) {
- ret[offset] = 'X';
- }
+#include <stdio.h>
+#include <strings.h>
+#include <ctype.h>
+#include "weak.h"
- offset += 4;
- }
-
- // Add dotted line.
- strncpy(ret + offset, dottedLine, LINE_LENGTH);
-
- lineSide = OPPOSITE(lineSide);
- }
-
- ret[LINE_LENGTH * LINE_COUNT] = '\0';
-
- return strdup(ret);
- }
-
- // ASCII-art representation of chessboard.
- char*
- StringChessSet(ChessSet *chessSet)
- {
- const int LINE_LENGTH = 36;
- const int LINE_COUNT = 18;
-
- // Include space for newlines.
- char ret[LINE_LENGTH * LINE_COUNT + 1 + 1000];
- char pieceChr;
- int file, offset, rank;
- Piece piece;
- Position pos;
- Side side;
- Side lineSide = Black;
-
- char *topLine = " A B C D E F G H \n";
- char *dottedLine = " ---------------------------------\n";
- char *blackLine = " | |...| |...| |...| |...|\n";
- char *whiteLine = " |...| |...| |...| |...| |\n";
-
- // Add top lines.
- strncpy(ret, topLine, LINE_LENGTH);
- strncpy(ret+LINE_LENGTH, dottedLine, LINE_LENGTH);
-
- // Outputs chess set as ascii-art.
- // pieces are upper-case if white, lower-case if black.
- // P=pawn, R=rook, N=knight, B=bishop, Q=queen, K=king, .=empty square.
-
- // e.g., the initial position is output as follows:-
-
- // A B C D E F G H
- // ---------------------------------
- // 8 | r |.n.| b |.q.| k |.b.| n |.r.|
- // ---------------------------------
- // 7 |.p.| p |.p.| p |.p.| p |.p.| p |
- // ---------------------------------
- // 6 | |...| |...| |...| |...|
- // ---------------------------------
- // 5 |...| |...| |...| |...| |
- // ---------------------------------
- // 4 | |...| |...| |...| |...|
- // ---------------------------------
- // 3 |...| |...| |...| |...| |
- // ---------------------------------
- // 2 | P |.P.| P |.P.| P |.P.| P |.P.|
- // ---------------------------------
- // 1 |.R.| N |.B.| Q |.K.| B |.N.| R |
- // ---------------------------------
-
- for(rank = Rank8; rank >= Rank1; rank--) {
- offset = 2*LINE_LENGTH + 2*LINE_LENGTH*(Rank8-rank);
-
- // Add line.
- strncpy(ret + offset, lineSide == White ? whiteLine : blackLine, LINE_LENGTH);
-
- // Add number.
- ret[offset] = '1'+rank;
-
- // Add pieces.
-
- // For the sake of debugging, avoid PieceAt() in case it is buggy.
-
- offset += 4;
- for(file = FileA; file <= FileH; file++) {
- pos = POSITION(rank, file);
-
- pieceChr = '\0';
-
- for(side = White; side <= Black; side++) {
- for(piece = Pawn; piece <= King; piece++) {
- if((chessSet->Sets[side].Boards[piece]&POSBOARD(pos)) == POSBOARD(pos)) {
- switch(piece) {
- case Pawn:
- pieceChr = 'P';
- break;
- case Rook:
- pieceChr = 'R';
- break;
- case Knight:
- pieceChr = 'N';
- break;
- case Bishop:
- pieceChr = 'B';
- break;
- case Queen:
- pieceChr = 'Q';
- break;
- case King:
- pieceChr = 'K';
- break;
- default:
- panic("Impossible.");
- }
- goto loop;
- }
- }
- }
- loop:
- if(pieceChr != '\0') {
- if(side == Black) {
- pieceChr += 32;
- }
- ret[offset] = pieceChr;
- }
+char
+CharPiece(Piece piece)
+{
+ switch(piece) {
+ case Pawn:
+ return 'P';
+ case Rook:
+ return 'R';
+ case Knight:
+ return 'N';
+ case Bishop:
+ return 'B';
+ case Queen:
+ return 'Q';
+ case King:
+ return 'K';
+ default:
+ return '?';
+ }
+}
+
+char*
+StringBitBoard(BitBoard bitBoard)
+{
+ const int LINE_LENGTH = 36;
+ const int LINE_COUNT = 18;
+
+ // TODO: Reduce duplication from StringChessSet.
+
+ // Include space for newlines.
+ char ret[LINE_LENGTH * LINE_COUNT + 1 + 1000];
+ int file, offset, rank;
+ Position pos;
+ Side lineSide = Black;
+
+ char *topLine = " A B C D E F G H \n";
+ char *dottedLine = " ---------------------------------\n";
+ char *blackLine = " | |...| |...| |...| |...|\n";
+ char *whiteLine = " |...| |...| |...| |...| |\n";
+
+ // Add top lines.
+ strncpy(ret, topLine, LINE_LENGTH);
+ strncpy(ret+LINE_LENGTH, dottedLine, LINE_LENGTH);
+
+ for(rank = Rank8; rank >= Rank1; rank--) {
+ offset = 2*LINE_LENGTH + 2*LINE_LENGTH*(Rank8-rank);
+
+ // Add line.
+ strncpy(ret + offset, lineSide == White ? whiteLine : blackLine, LINE_LENGTH);
+
+ // Add number.
+ ret[offset] = '1'+rank;
+
+ // Add pieces.
+
+ // For the sake of debugging, avoid PieceAt() in case it is buggy.
+
+ offset += 4;
+ for(file = FileA; file <= FileH; file++) {
+ pos = POSITION(rank, file);
+
+ if((bitBoard&POSBOARD(pos)) == POSBOARD(pos)) {
+ ret[offset] = 'X';
+ }
+
+ offset += 4;
+ }
+
+ // Add dotted line.
+ strncpy(ret + offset, dottedLine, LINE_LENGTH);
+
+ lineSide = OPPOSITE(lineSide);
+ }
+
+ ret[LINE_LENGTH * LINE_COUNT] = '\0';
+
+ return strdup(ret);
+}
+
+// ASCII-art representation of chessboard.
+char*
+StringChessSet(ChessSet *chessSet)
+{
+ const int LINE_LENGTH = 36;
+ const int LINE_COUNT = 18;
+
+ // Include space for newlines.
+ char ret[LINE_LENGTH * LINE_COUNT + 1 + 1000];
+ char pieceChr;
+ int file, offset, rank;
+ Piece piece;
+ Position pos;
+ Side side;
+ Side lineSide = Black;
+
+ char *topLine = " A B C D E F G H \n";
+ char *dottedLine = " ---------------------------------\n";
+ char *blackLine = " | |...| |...| |...| |...|\n";
+ char *whiteLine = " |...| |...| |...| |...| |\n";
+
+ // Add top lines.
+ strncpy(ret, topLine, LINE_LENGTH);
+ strncpy(ret+LINE_LENGTH, dottedLine, LINE_LENGTH);
+
+ // Outputs chess set as ascii-art.
+ // pieces are upper-case if white, lower-case if black.
+ // P=pawn, R=rook, N=knight, B=bishop, Q=queen, K=king, .=empty square.
+
+ // e.g., the initial position is output as follows:-
+
+ // A B C D E F G H
+ // ---------------------------------
+ // 8 | r |.n.| b |.q.| k |.b.| n |.r.|
+ // ---------------------------------
+ // 7 |.p.| p |.p.| p |.p.| p |.p.| p |
+ // ---------------------------------
+ // 6 | |...| |...| |...| |...|
+ // ---------------------------------
+ // 5 |...| |...| |...| |...| |
+ // ---------------------------------
+ // 4 | |...| |...| |...| |...|
+ // ---------------------------------
+ // 3 |...| |...| |...| |...| |
+ // ---------------------------------
+ // 2 | P |.P.| P |.P.| P |.P.| P |.P.|
+ // ---------------------------------
+ // 1 |.R.| N |.B.| Q |.K.| B |.N.| R |
+ // ---------------------------------
+
+ for(rank = Rank8; rank >= Rank1; rank--) {
+ offset = 2*LINE_LENGTH + 2*LINE_LENGTH*(Rank8-rank);
+
+ // Add line.
+ strncpy(ret + offset, lineSide == White ? whiteLine : blackLine, LINE_LENGTH);
+
+ // Add number.
+ ret[offset] = '1'+rank;
+
+ // Add pieces.
+
+ // For the sake of debugging, avoid PieceAt() in case it is buggy.
+
+ offset += 4;
+ for(file = FileA; file <= FileH; file++) {
+ pos = POSITION(rank, file);
+
+ pieceChr = '\0';
+
+ for(side = White; side <= Black; side++) {
+ for(piece = Pawn; piece <= King; piece++) {
+ if((chessSet->Sets[side].Boards[piece]&POSBOARD(pos)) == POSBOARD(pos)) {
+ switch(piece) {
+ case Pawn:
+ pieceChr = 'P';
+ break;
+ case Rook:
+ pieceChr = 'R';
+ break;
+ case Knight:
+ pieceChr = 'N';
+ break;
+ case Bishop:
+ pieceChr = 'B';
+ break;
+ case Queen:
+ pieceChr = 'Q';
+ break;
+ case King:
+ pieceChr = 'K';
+ break;
+ default:
+ panic("Impossible.");
+ }
+ goto loop;
+ }
+ }
+ }
+ loop:
+ if(pieceChr != '\0') {
+ if(side == Black) {
+ pieceChr += 32;
+ }
+ ret[offset] = pieceChr;
+ }
offset += 4;
- }
-
- // Add dotted line.
- strncpy(ret + offset, dottedLine, LINE_LENGTH);
-
- lineSide = OPPOSITE(lineSide);
- }
-
- ret[LINE_LENGTH * LINE_COUNT] = '\0';
-
- return strdup(ret);
- }
-
- // String move in long algebraic form.
- char*
- StringMove(Move move, Piece piece, bool capture)
- {
- char actionChr, pieceChr;
- char *suffix, *from, *to;
- char ret[1+2+1+2+2+1];
-
- from = StringPosition(FROM(move));
- to = StringPosition(TO(move));
-
- switch(TYPE(move)) {
- default:
- suffix = "??";
- break;
- case CastleQueenSide:
- return strdup("O-O-O");
- case CastleKingSide:
- return strdup("O-O");
- case EnPassant:
- suffix = "ep";
- break;
- case PromoteKnight:
- suffix = "=N";
- break;
- case PromoteBishop:
- suffix = "=B";
- break;
- case PromoteRook:
- suffix = "=R";
- break;
- case PromoteQueen:
- suffix = "=Q";
- break;
- case Normal:
- suffix = "";
- break;
- }
-
- if(capture) {
- actionChr = 'x';
- } else {
- actionChr = '-';
- }
-
- pieceChr = CharPiece(piece);
-
- if(pieceChr == 'P' || pieceChr == 'p') {
- sprintf(ret, "%s%c%s%s", from, actionChr, to, suffix);
- } else {
- sprintf(ret, "%c%s%c%s%s", pieceChr, from, actionChr, to, suffix);
- }
-
- return strdup(ret);
- }
-
- char*
- StringMoveHistory(MemorySlice *history)
- {
- Move move;
- Memory *curr;
- Side side = White;
- StringBuilder builder = NewStringBuilder();
- int fullMoveCount = 1;
-
- // TODO: Determine positions + capture condition for moves.
-
- for(curr = history->Vals; curr != history->Curr; curr++) {
- move = curr->Move;
-
- switch(side) {
- case White:
- AppendString(&builder, "%d. ?%s",
- fullMoveCount, StringMove(move, Pawn, false));
- break;
- case Black:
- AppendString(&builder, " ?%s\n",
- StringMove(move, Pawn, false));
-
- fullMoveCount++;
-
- break;
- }
-
- side = OPPOSITE(side);
- }
-
- return builder.Length == 0 ? NULL : BuildString(&builder, true);
+ }
+
+ // Add dotted line.
+ strncpy(ret + offset, dottedLine, LINE_LENGTH);
+
+ lineSide = OPPOSITE(lineSide);
+ }
+
+ ret[LINE_LENGTH * LINE_COUNT] = '\0';
+
+ return strdup(ret);
+}
+
+char*
+StringMove(Move move)
+{
+ char ret[5];
+
+ sprintf(ret, "%s%s", StringPosition(FROM(move)),
+ StringPosition(TO(move)));
+
+ return strdup(ret);
+}
+
+// String move in long algebraic form.
+char*
+StringMoveFull(Move move, Piece piece, bool capture)
+{
+ char actionChr, pieceChr;
+ char *suffix, *from, *to;
+ char ret[1+2+1+2+2+1];
+
+ from = StringPosition(FROM(move));
+ to = StringPosition(TO(move));
+
+ switch(TYPE(move)) {
+ default:
+ suffix = "??";
+ break;
+ case CastleQueenSide:
+ return strdup("O-O-O");
+ case CastleKingSide:
+ return strdup("O-O");
+ case EnPassant:
+ suffix = "ep";
+ break;
+ case PromoteKnight:
+ suffix = "=N";
+ break;
+ case PromoteBishop:
+ suffix = "=B";
+ break;
+ case PromoteRook:
+ suffix = "=R";
+ break;
+ case PromoteQueen:
+ suffix = "=Q";
+ break;
+ case Normal:
+ suffix = "";
+ break;
+ }
+
+ if(capture) {
+ actionChr = 'x';
+ } else {
+ actionChr = '-';
+ }
+
+ pieceChr = CharPiece(piece);
+
+ if(pieceChr == 'P' || pieceChr == 'p') {
+ sprintf(ret, "%s%c%s%s", from, actionChr, to, suffix);
+ } else {
+ sprintf(ret, "%c%s%c%s%s", pieceChr, from, actionChr, to, suffix);
+ }
+
+ return strdup(ret);
+}
+
+char*
+StringMoveHistory(MemorySlice *history)
+{
+ Move move;
+ Memory *curr;
+ Side side = White;
+ StringBuilder builder = NewStringBuilder();
+ int fullMoveCount = 1;
+
+ for(curr = history->Vals; curr != history->Curr; curr++) {
+ move = curr->Move;
+
+ switch(side) {
+ case White:
+ AppendString(&builder, "%d. %s",
+ fullMoveCount, StringMove(move));
+ break;
+ case Black:
+ AppendString(&builder, " %s\n",
+ StringMove(move));
+
+ fullMoveCount++;
+
+ break;
+ }
+
+ side = OPPOSITE(side);
+ }
+
+ return builder.Length == 0 ? NULL : BuildString(&builder, true);
}
char*
View
14 weak.h
@@ -49,6 +49,8 @@
#define BIG 1E10
#define SMALL -1E10
+#define MAX_THINK 30
+
/*
From 1 size = 6
@@ -529,7 +531,7 @@ BitBoard Rotate90AntiClockwise(BitBoard);
BitBoard Rotate90Clockwise(BitBoard);
// eval.c
-double Eval(Game*, Side);
+double Eval(Game*);
// game.c
CheckStats CalculateCheckStats(Game*);
@@ -557,6 +559,7 @@ Move* AllCaptures(Move*, Game*);
Move* AllMoves(Move*, Game*);
bool AnyMoves(Game*);
Move* CastleMoves(Game*, Move*);
+Move* Evasions(Move*, Game*);
// parser.c
Command ParseCommand(char*);
@@ -580,7 +583,8 @@ BitBoard PawnAttacksFrom(Position, Side);
BitBoard CalcRookSquareThreats(Position, BitBoard);
// search.c
-Move Search(Game*, uint64_t*);
+Move IterSearch(Game*, uint64_t*, uint32_t);
+Move Search(Game*, uint64_t*, int);
// set.c
Set NewBlackSet(void);
@@ -592,7 +596,6 @@ BitBoard PinnedPieces(ChessSet*, Side, Position, bool);
void UpdateOccupancies(ChessSet*);
// slices.c
-
MemorySlice NewMemorySlice(void);
MoveSlice NewMoveSlice(Move*);
@@ -600,7 +603,8 @@ MoveSlice NewMoveSlice(Move*);
char CharPiece(Piece);
char* StringBitBoard(BitBoard);
char* StringChessSet(ChessSet*);
-char* StringMove(Move, Piece, bool);
+char* StringMove(Move);
+char* StringMoveFull(Move, Piece, bool);
char* StringMoveHistory(MemorySlice*);
char* StringPerft(PerftStats*);
char* StringPiece(Piece);
@@ -632,6 +636,6 @@ int Distance[64][64];
// Array containing attacks for a specified piece and position on an empty BitBoard.
// We only calculate this for sliding pieces.
-BitBoard EmptyAttacks[5][64];
+BitBoard EmptyAttacks[6][64];
#endif

No commit comments for this range

Something went wrong with that request. Please try again.