From: Scott Gasch Date: Thu, 2 Jun 2016 01:58:58 +0000 (-0700) Subject: Initial checkin for typhoon chess engine. X-Git-Url: https://wannabe.guru.org/gitweb/?a=commitdiff_plain;h=3fd43cd5fcb22bb65bf2a92a25d95d801b11c9e0;p=typhoon.git Initial checkin for typhoon chess engine. --- 3fd43cd5fcb22bb65bf2a92a25d95d801b11c9e0 diff --git a/pgn/cegtges.pgn.bz2 b/pgn/cegtges.pgn.bz2 new file mode 100644 index 0000000..252ee5f Binary files /dev/null and b/pgn/cegtges.pgn.bz2 differ diff --git a/pgn/twic.pgn.bz2 b/pgn/twic.pgn.bz2 new file mode 100644 index 0000000..c00a328 Binary files /dev/null and b/pgn/twic.pgn.bz2 differ diff --git a/pgn/twic.pl b/pgn/twic.pl new file mode 100755 index 0000000..1fccae2 --- /dev/null +++ b/pgn/twic.pl @@ -0,0 +1,6 @@ +#!/usr/bin/perl + +for ($x = 608; $x > 0; $x--) +{ + system "fetch http://www.chesscenter.com/twic/zips/twic" . $x . "g.zip"; +} diff --git a/src/._GNUmakefile b/src/._GNUmakefile new file mode 100644 index 0000000..5bfc819 Binary files /dev/null and b/src/._GNUmakefile differ diff --git a/src/.gdb_history b/src/.gdb_history new file mode 100644 index 0000000..881db24 --- /dev/null +++ b/src/.gdb_history @@ -0,0 +1,36 @@ +run +bt +frame 1 +quit +run +bt +frame 1 +print mvRef +quit +run +quit +run +frame 1 +print x +print ctx->sMoveStack.uEnd[ctx->uPly] +print mv +print uLegalMoves +print ctx->sMoveStack.mvf[x].bvFlags +print ctx->sMoveStack.mvf[x] +print mvHash +print ctx->uPly +bt +frame 1 +print x +print ctx->sMoveStack.uEnd[7] +print ctx->sMoveStack.uBegin[7] +bt +frame 3 +print ctx->uPly +frame 2 +frame 1 +quit +run +quit +run +quit diff --git a/src/GNUmakefile b/src/GNUmakefile new file mode 100644 index 0000000..1ef7fc9 --- /dev/null +++ b/src/GNUmakefile @@ -0,0 +1,176 @@ +# Makefile (for typhoon/GNU-style make). Recognized gmake variables: +# +# DEBUG=1: make debug version (includes asserts and sanity checks) +# TEST=1: include self-test code in the binary produced +# ASM=1: create assembly code, does not link final binary +# EVAL_DUMP=1: make a version that can dump eval breakdowns +# EVAL_HASH=1: hash eval scores +# EVAL_TIME=1: make a version that counts cycles spent in eval +# PERF_COUNTERS=1: make version with perf counters enabled +# BOUNDS_CHECKING=1: make version with bounds checking enabled +# MP=1: make version for multi-processor machine +# DUMP_TREE=1: internal tree dumping version +# SEE_HEAPS=1: use minheaps in the SEE code +# OSX=1: build for an Intel-based Apple Mac (omit this for FreeBSD/Linux) +# USE_READLINE=1: link against the GNU readline library +# SIXTYFOUR=1: make an X64 binary +# CROUTINES=1: use the C versions of the asm routines [slower] +# EVERYTHING=1: everything everything everything everything +# +# $Id$ +# +CC = gcc +CXX = g++ +NASM = yasm +ifdef OSX + LIBRARIES = -pthread -lc + ifdef SIXTYFOUR + $(warning you will need to use yasm for now to get x64 on OSX) + NASMFLAGS = -f macho64 -dOSX -d_X64_ + else + NASMFLAGS = -f macho -dOSX + endif +else + LIBRARIES = -pthread -lc -lstdc++ + ifdef SIXTYFOUR + NASMFLAGS = -f elf64 -d__GNUC__ + else + NASMFLAGS = -f elf -d__GNUC__ + endif +endif +RM = /bin/rm + +# +# Setup commandline based on make defines +# +ifdef ASM + ifdef SIXTYFOUR + PROFILE = -S -fverbose-asm -std=gnu99 -D_X64_ + else + PROFILE = -S -fverbose-asm -std=gnu99 -D_X86_ + endif +else + ifdef SIXTYFOUR + PROFILE = -std=gnu99 -D_X64_ + else + PROFILE = -std=gnu99 -D_X86_ + endif +endif + +ifdef OSX + PROFILE += -DOSX +endif + +ifdef GENETIC + PROFILE += -DGENETIC +endif + +ifdef DEBUG + PROFILE += -g -O2 -DDEBUG + BINARY = _typhoon +else + PROFILE += -g -O3 -fexpensive-optimizations -ffast-math -finline-functions + BINARY = typhoon +endif + +ifdef USE_READLINE + LIBRARIES += -lreadline + PROFILE += -DUSE_READLINE +endif + +ifdef SIXTYFOUR + PROFILE += -m64 + NASMFLAGS += -d_X64_ +else + PROFILE += -m32 + NASMFLAGS += -d_X86_ +endif + +ifdef CROUTINES + PROFILE += -DCROUTINES +endif + +ifdef EVERYTHING +PROFILE += -DEVAL_DUMP -DEVAL_HASH -DEVAL_TIME -DPERF_COUNTERS -DMP -DSMP -DTEST_NULL -DDUMP_TREE -fbounds-checking +else +ifdef EVAL_DUMP +PROFILE += -DEVAL_DUMP +endif +ifdef EVAL_HASH +PROFILE += -DEVAL_HASH +endif +ifdef EVAL_TIME +PROFILE += -DEVAL_TIME +endif +ifdef PERF_COUNTERS +PROFILE += -DPERF_COUNTERS +endif +ifdef BOUNDS_CHECKING +PROFILE += -fbounds-checking +endif +ifdef MP +PROFILE += -DMP -DSMP +endif +ifdef TEST_NULL +PROFILE += -DTEST_NULL +endif +ifdef DUMP_TREE +PROFILE += -DDUMP_TREE +endif +endif # EVERYTHING + +CFLAGS = -DPROFILE="\"$(PROFILE)\"" $(PROFILE) -Wall +HEADERS = chess.h compiler.h + +# +# ---> .o, not .c! <--- +# +OBJS = main.o root.o search.o searchsup.o draw.o dynamic.o \ + hash.o eval.o evalhash.o x86.o pawnhash.o bitboard.o \ + generate.o see.o move.o movesup.o command.o script.o \ + input.o vars.o util.o unix.o gamelist.o mersenne.o \ + sig.o piece.o ics.o san.o fen.o book.o bench.o board.o \ + data.o probe.o egtb.o recogn.o poshash.o list.o x64.o + +ifdef TEST +# ---> .o, not .c! <--- +# +OBJS += testdraw.o testmove.o testfen.o testgenerate.o \ + testsan.o testics.o testeval.o testbitboard.o \ + testhash.o testsee.o testsearch.o testsup.o +PROFILE += -DTEST +else +ifdef EVAL_DUMP +OBJS += testeval.o testsup.o +endif +endif +ifdef DUMP_TREE +OBJS += dumptree.o +endif +ifdef MP +OBJS += split.o +endif + +.SUFFIXES: .c .o +.SUFFIXES: .cpp .o +.SUFFIXES: .asm .o + +.PHONY: all +all: $(BINARY) + +$(BINARY): $(OBJS) + $(CXX) $(PROFILE) -o $(BINARY) -Wall $(LIBRARIES) \ + $(OBJS) + +%.o: %.c $(HEADERS) + $(CC) $(CFLAGS) -c $< -o $@ + +%.o: %.cpp $(HEADERS) + $(CXX) $(CFLAGS) -c -w $< -o $@ + +%.o: %.asm $(HEADERS) + $(NASM) $(NASMFLAGS) -o $@ $< + +.PHONY: clean +clean: + $(RM) -f *.o *.core *~ *.gmon \#*\# typhoon _typhoon diff --git a/src/README b/src/README new file mode 100644 index 0000000..6478608 --- /dev/null +++ b/src/README @@ -0,0 +1,35 @@ + + Most of the code in this directory is code that I wrote and has + the comment "Copyright (C) Scott Gasch" at the start of the file. + You can do whatever you want with this code except: + + 1. Redistribute it; I'd like to be the "official" source for + code related to this engine. + 2. Sell it; as the copyright holder I expressly forbid you + from selling the code or any binary it produces. + 3. Claim it is your own; any work based on or inspired by the + code in question must also contain the copyright notice and + my name. + + Some of the code under this directory (specifically, the genetic + programming framework implemented in Java) was written by me but + is released under the Apache 2.0 license (which is more liberal + than the restrictions above). + + Some of the code in this directory was written by other people. + For example, mersenne.c, egtb.cpp and tbdecode.h. I am using this + code by permission and do not own the copyright for it. Please + contact the code's original author (see comments) for details + about what can and cannot be done with it. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR `AS IS'' AND ANY EXPRESS + OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED + WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE + ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY + DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE + GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS + INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, + WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS + SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/src/TODO b/src/TODO new file mode 100644 index 0000000..1ac53b2 --- /dev/null +++ b/src/TODO @@ -0,0 +1,10 @@ +Better understanding of stuff like KRKRB == drawish, Q's come off = !drawish +Think about the path to a killer instead of the depth of a killer +Pawnhash size tunable from cmdline again +Evalhash size tunable? +EGTB cache size tunable? +Poshash size tunable? +Think about when to avoid nullmove pruning based on checks in the line +Think about futility pruning when a >= +NMATE +Stick eval / king score in ply info and use it to trigger extensions + diff --git a/src/autoplay/._child_process.cc b/src/autoplay/._child_process.cc new file mode 100644 index 0000000..dc5fc97 Binary files /dev/null and b/src/autoplay/._child_process.cc differ diff --git a/src/autoplay/a.out b/src/autoplay/a.out new file mode 100755 index 0000000..d157d18 Binary files /dev/null and b/src/autoplay/a.out differ diff --git a/src/autoplay/child_process.cc b/src/autoplay/child_process.cc new file mode 100644 index 0000000..6486a0e --- /dev/null +++ b/src/autoplay/child_process.cc @@ -0,0 +1,188 @@ +#include "child_process.h" + +#include +#include +#include +#include +#include +#include +#include + +namespace util { + +void ChildProcess::ParseCommandline(vector *args) { + char *p = commandline_; + bool in_quote; + do { + // Find the start of a chunk. + while(*p && isspace(*p)) p++; + if (!*p) break; + args->push_back(p); + in_quote = false; + + // Find the end of the chunk. + while (*p) { + if (*p == '"') { + in_quote = !in_quote; + } else if (isspace(*p) && !in_quote) { + break; + } + p++; + } + if (!*p) break; + *p = '\0'; + p++; + } while(1); + args->push_back(NULL); +} + +static volatile bool _child_ready = false; +static void SignalHandler(int signo) { + printf("SIGNAL!\n"); + _child_ready = true; +} + +void ChildProcess::Start() { + Stop(); + vector args; + ParseCommandline(&args); + + if (args.size() > 1) { + if (pipe(read_pipe_) != 0) { + perror("pipe"); + exit(-1); + } + if (pipe(write_pipe_) != 0) { + perror("pipe"); + exit(-1); + } + + // Prepare a signal handler to tell us when the child process is + // ready. + _child_ready = false; + if (signal(SIGUSR1, SignalHandler) == SIG_ERR) { + perror("signal"); + exit(-1); + } + sigset_t zeromask, mask, orig; + sigemptyset(&zeromask); + sigemptyset(&mask); + sigaddset(&mask, SIGUSR1); + if (sigprocmask(SIG_BLOCK, &mask, &orig) < 0) { + perror("sigprocmask"); + exit(-1); + } + + // Fork. + pid_ = fork(); + if (pid_ < 0) { + perror("fork"); + exit(-1); + } + if (pid_ == 0) { + printf("In the child process...\n"); + + // In the child process we do not need the pipes for parent + // reads and writes. + close(write_pipe_[1]); + close(read_pipe_[0]); + if (dup2(write_pipe_[0], fileno(stdin)) < 0) { + perror("dup2"); + exit(-1); + } + close(write_pipe_[0]); + if (dup2(read_pipe_[1], fileno(stdout)) < 0) { + perror("dup2"); + exit(-1); + } + if (dup2(fileno(stdout), fileno(stderr)) < 0) { + perror("dup2"); + exit(-1); + } + close(read_pipe_[1]); + + // Tell the parent that the pipes are set up then exec the child + // image. + kill(getppid(), SIGUSR1); + execvp(args[0], &(args[0])); + perror("exec"); + exit(-1); + } else { + printf("In the parent process waiting...\n"); + while(!_child_ready) { + sigsuspend(&zeromask); + } + printf("PARENT WAKEUP!\n"); + _child_ready = false; + if (sigprocmask(SIG_SETMASK, &orig, NULL) < 0) { + perror("sigprocmask"); + exit(-1); + } + close(write_pipe_[0]); + close(read_pipe_[1]); + from_ = fdopen(read_pipe_[0], "r"); + to_ = fdopen(write_pipe_[1], "w"); + setbuf(from_, NULL); + setbuf(to_, NULL); + running_ = true; + name_ = args[0]; + } + } +} + +void ChildProcess::Stop() { + if (!running_) { + return; + } + fclose(to_); + fclose(from_); + close(write_pipe_[1]); + close(read_pipe_[0]); + kill(pid_, SIGTERM); + int x; + waitpid(pid_, &x, 0); +} + +void ChildProcess::Send(char *line) { + if (!running_) { + return; + } + fprintf(to_, "%s", line); + printf("%s sent: %s", name_, line); +} + +void ChildProcess::Receive(char *line, int size) { + if (!size) return; + *line = '\0'; + if (!running_) { + return; + } + if (!Poll()) { + return; + } + fgets(line, size, from_); + printf("%s recv: %s\n", name_, line); +} + +bool ChildProcess::Poll() { + fd_set myset; + FD_ZERO(&myset); + FD_SET(read_pipe_[0], &myset); + timeval mytime; + mytime.tv_sec = 0; + mytime.tv_usec = 0; + return select(read_pipe_[0] + 1, &myset, NULL, NULL, &mytime) > 0; +} + +void ChildProcess::Flush() { + static char line[1000]; + while (Poll()) { + Receive(line, 1000); + printf("flush: %s", line); + if (!line[0]) { + break; + } + } +} + +} // namespace diff --git a/src/autoplay/child_process.h b/src/autoplay/child_process.h new file mode 100644 index 0000000..6c03ecd --- /dev/null +++ b/src/autoplay/child_process.h @@ -0,0 +1,53 @@ +// child_process.h -- description + +#ifndef _CHILD_PROCESS_H_ +#define _CHILD_PROCESS_H_ + +#include +#include +#include +#include +#include +using namespace std; + +namespace util { + +class ChildProcess { + public: + explicit ChildProcess(const char *commandline) + : commandline_(strdup(commandline)), + name_(NULL), + running_(false), + pid_(-1), + to_(NULL), + from_(NULL), + child_ready_(false) {} + virtual ~ChildProcess() { + Stop(); + free(commandline_); + commandline_ = NULL; + } + + virtual void Start(); + virtual void Stop(); + void Send(char *line); + void Receive(char *line, int size); + bool Poll(); + void Flush(); + + private: + void ParseCommandline(vector *args); + char *commandline_; + char *name_; + bool running_; + pid_t pid_; + int write_pipe_[2]; + int read_pipe_[2]; + FILE *to_; + FILE *from_; + volatile bool child_ready_; +}; + +} // namespace + +#endif /* _CHILD_PROCESS_H_ */ diff --git a/src/autoplay/child_process_test.cc b/src/autoplay/child_process_test.cc new file mode 100644 index 0000000..d723701 --- /dev/null +++ b/src/autoplay/child_process_test.cc @@ -0,0 +1,13 @@ +#include "child_process.h" +#include "gtest/gtest.h" + +TEST(ChildProcessTest, BasicUsage) { + util::ChildProcess ps("/usr/bin/bc"); + ps.Start(); + ps.Flush(); + ps.Send("1 + 1\n"); + char buf[128]; + ps.Receive(buf, 128); + EXPECT_STREQ("2\n", buf); + ps.Stop(); +} diff --git a/src/autoplay/foo b/src/autoplay/foo new file mode 100755 index 0000000..3b87b38 Binary files /dev/null and b/src/autoplay/foo differ diff --git a/src/autoplayer/._main.cpp b/src/autoplayer/._main.cpp new file mode 100644 index 0000000..94ca2d3 Binary files /dev/null and b/src/autoplayer/._main.cpp differ diff --git a/src/autoplayer/._settings.txt b/src/autoplayer/._settings.txt new file mode 100644 index 0000000..2cbebf0 Binary files /dev/null and b/src/autoplayer/._settings.txt differ diff --git a/src/autoplayer/._settings2.txt b/src/autoplayer/._settings2.txt new file mode 100644 index 0000000..462a614 Binary files /dev/null and b/src/autoplayer/._settings2.txt differ diff --git a/src/autoplayer/._settings3.txt b/src/autoplayer/._settings3.txt new file mode 100644 index 0000000..b7684b6 Binary files /dev/null and b/src/autoplayer/._settings3.txt differ diff --git a/src/autoplayer/._settings4.txt b/src/autoplayer/._settings4.txt new file mode 100644 index 0000000..4f6001a Binary files /dev/null and b/src/autoplayer/._settings4.txt differ diff --git a/src/autoplayer/RESULTS b/src/autoplayer/RESULTS new file mode 100644 index 0000000..744a8e2 --- /dev/null +++ b/src/autoplayer/RESULTS @@ -0,0 +1,16 @@ +sn 100k +Typhoon r356 vs. Crafty: +341 -495 =164, 42.30%, ELO: -53 + +sn 100k +Typhoon r357 vs. Fruit: +213 -635 =152, 28.90%, ELO: -156 + Typhoon vs. Fruit: +211 -622 =167, 29.45%, ELO: -151 + +sn 10k +Typhoon r356 vs. (tiny) Fruit: +163 -732 =105, 21.55%, ELO: -224 + Typhoon vs. Fruit: +173 -719 =108, 22.70%, ELO: -212 + Typhoon vs. Fruit: +180 -701 =119, 23.95%, ELO: -200 +Typhoon r357 vs. (tiny) Fruit: +180 -701 =119, 23.95%, ELO: -200 + +st 1 1k games +Typhoon vs. Crafty : +251 -600 =149, 32.55%, ELO: -126 + diff --git a/src/autoplayer/a.out b/src/autoplayer/a.out new file mode 100755 index 0000000..be8afda Binary files /dev/null and b/src/autoplayer/a.out differ diff --git a/src/autoplayer/a.out.dSYM/Contents/Info.plist b/src/autoplayer/a.out.dSYM/Contents/Info.plist new file mode 100644 index 0000000..a9a4ac4 --- /dev/null +++ b/src/autoplayer/a.out.dSYM/Contents/Info.plist @@ -0,0 +1,25 @@ + + + + + CFBundleDevelopmentRegion + English + CFBundleIdentifier + com.apple.xcode.dsym.a.out + CFBundleInfoDictionaryVersion + 6.0 + CFBundlePackageType + dSYM + CFBundleShortVersionString + 1.0 + CFBundleSignature + ???? + CFBundleVersion + 1.0 + dSYM_UUID + + i386 + 75 db 1e 21 ae cf df 5c d5 88 08 7c 9c 70 e0 0e + + + diff --git a/src/autoplayer/a.out.dSYM/Contents/Resources/DWARF/a.out b/src/autoplayer/a.out.dSYM/Contents/Resources/DWARF/a.out new file mode 100644 index 0000000..0d7ed7a Binary files /dev/null and b/src/autoplayer/a.out.dSYM/Contents/Resources/DWARF/a.out differ diff --git a/src/autoplayer/book.lrn b/src/autoplayer/book.lrn new file mode 100644 index 0000000..5477dde --- /dev/null +++ b/src/autoplayer/book.lrn @@ -0,0 +1,21597 @@ +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 Bg5 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {10 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {100 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Bxf6 gxf6 Nd5 f5 Bd3 Be6 O-O {111 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O b5 Nxc6 + Qxc6 {-20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bb4 + {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-38 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Bb4 {36 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 {5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 {-103 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + a6 Bg5 Nbd7 {-15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {54 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {77 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.06.30"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.06.30"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {100 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + a6 Bg5 Nbd7 {-15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 d4 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 d4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Qc8 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {54 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {77 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 c5 Bf5 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 c5 Bf5 {19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {7 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Nxc4 Nd5 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O e4 Bg6 e5 Nd5 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {-33 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {-46 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 exf6 Bh6 {-45 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 Bb4 O-O + {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 exf6 Bh6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {-5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {76 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 {-42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 {79 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + Be7 {-15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 O-O + b4 {135 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 O-O + b4 {30 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 Nb6 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Qb6 Be4 {-6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {-55 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 e6 Nc3 Bd6 {20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {-41 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Ne5 Bb4 {-12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 e6 Nc3 Bd6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 e6 Nh4 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 Nbd7 {42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 dxc4 Bxc4 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 Nbd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 Ne5 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 cxd5 exd5 Be2 {-43 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 a6 Ne5 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 c4 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 O-O Be7 Be3 + {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Be3 {41 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 d4 cxd4 Nxd4 e5 {6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 {5 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {-39 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {20 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 Qxd1+ Kxd1 Nc6 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 Nc6 d3 {-20 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 e6 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Bg5 f6 Bd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Be2 {-4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 Nc6 d3 {300 3 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 cxd5 exd5 Be2 c4 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Qc2 Qe7 {-14 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Be2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + Qxd5 {49 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 d4 cxd4 Nxd4 Bg7 e4 O-O {-43 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 Nc6 Be2 d6 d4 cxd4 Nxd4 Qb6 {-2 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 d5 + {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 d5 + {-18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Nc3 g6 d4 {-25 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 d5 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 e6 O-O Be7 d4 Nxc3 + bxc3 {36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 {8 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 e5 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O {-300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 Qe2 Na6 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O Nc6 {-6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 c5 dxc5 {-24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O Nc6 {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 dxc4 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 c5 {47 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 c5 {-15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 c5 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 c5 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {76 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {16 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 a3 + {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 a3 + {49 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 c5 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {71 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Qb3 + Nxc3 bxc3 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 cxd5 + Nxd5 Bxe7 Qxe7 Bd3 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 cxd5 + Nxd5 Bxe7 Qxe7 Bd3 {50 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O Re8 Bd3 {-35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 cxd5 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 Rc1 dxc4 {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 a3 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 Rc1 dxc4 {-99 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 Rc1 dxc4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 h6 {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 h6 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 h6 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Nf6 Be3 {48 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Bxd2+ Qxd2 O-O Bc4 Nd7 O-O Nb6 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Qa5 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {82 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 {0 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 Be7 e3 d5 Qc2 {49 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 O-O a3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 h6 {30 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 h6 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 h6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 {-35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 c5 {13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 e3 d5 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 e3 d5 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 h6 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 h6 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 dxc4 {19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Bd6 + {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 Qxc3 f6 + {14 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + c5 Bb5+ {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {111 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 f5 {72 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 f5 {-172 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 c5 Bf4 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qb3 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qb3 {-28 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-19 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {-21 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {-185 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {216 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qb3 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bd6 {-12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bb7 Bg2 {107 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O e4 d5 cxd5 + Bxf1 Rxf1 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bd6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {13 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 cxd5 {-4 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 Nxd7 Nd2 Bd6 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {-25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 cxd5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Qb3 {146 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Qb3 {43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Nh5 + {22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 Qxc3 {-28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 {-27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-64 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 cxd5 {7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 Nc3 dxc4 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 {-46 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + c5 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + c5 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bd2 {-28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bd2 {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {2 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {21 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Re8 f3 Ne5 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Ne5 {56 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {42 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 h3 {52 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 h3 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 h3 {-4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {23 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Re8 Nd5 Nxd5 cxd5 {21 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 h3 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Qc2 {116 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Bg5 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Qc2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {-6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {-3 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Qb3 {16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nd3 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 {158 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nd3 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {83 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 Nc5 Qc2 {66 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {322 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 h6 + {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {228 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 {58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + O-O-O Nc6 h3 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Nc6 + {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Nc6 + {33 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Rb1 O-O + Be2 Nc6 Be3 {-18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 e4 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Bc4 Nb6 Bb3 Nc6 + {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d6 Qb3 {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d5 cxd5 Nxd5 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Bf4 {-41 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + Re1 exd4 Nxd4 Ng4 Nce2 Nge5 b3 {33 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 Qb3 {5 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 Re8 Bg5 + {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 Re8 Bg5 + {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Qxd4 + {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 e5 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 Bd7 {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 Qb3 + {-25 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 e4 Bd7 + {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 Qb3 + {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {8 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {35 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {1 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {60 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 d5 Ne7 Qb3 + {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 c5 d5 b5 {40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 c5 d5 b5 {35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 c5 d5 b5 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {-9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {187 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 h3 Bf5 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bd6 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bc5 {10 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nc3 b5 Bd3 {15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + a3 O-O b4 Ba7 {4 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nc3 b5 Bd3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {-15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 e3 Nc6 {49 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-10 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 Qb6 b3 Ne4 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 cxd4 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 h6 Bf4 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 h6 Bh4 g5 Bg3 Ne4 Nbd2 Nxg3 hxg3 Nc6 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 Nc3 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Nc6 {53 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 O-O d5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O c5 Na3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O Na6 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 d5 Nc3 {-50 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 O-O Bd3 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 d5 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 d5 {40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {112 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 h6 {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e4 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e3 d5 Bd3 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c3 bxc3 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 Nc6 Nxc4 {-60 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {-3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {32 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {-12 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 Nc6 Nxc4 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d3 Nbd7 Nbd2 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d3 Nbd7 Nbd2 e5 h3 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d3 Nbd7 Nbd2 e5 h3 {-44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 Na3 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 Nf6 Nc3 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 Nf6 Nc3 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 {26 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Nc3 e6 d4 cxd4 Nxd4 Qc7 Ndb5 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Nc3 Nf6 Bc4 {-7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 d4 {25 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 Nc3 O-O d4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 Nc3 O-O d4 {-19 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-19 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 Nc3 O-O d4 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 d4 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nb5 Qe5 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 Qd6 {44 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Bd7 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {44 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {28 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {66 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 e5 {-18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 Nf3 h6 {-16 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 e5 {-42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 e5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 Bxf6 gxf6 Kb1 b4 {51 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {-28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Qb6 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Qb6 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bg7 {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bd7 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {-6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bg7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Nxd4 + {-28 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Bd7 + O-O-O O-O Rhg1 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Be6 {31 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Bg5 Be2 {13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bb4 + {111 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bb4 + {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bb4 + {-20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-38 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Bb4 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {56 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {-65 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bg5 Nf6 N1c3 a6 Na3 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bg5 Nf6 N1c3 a6 Na3 {10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + {17 0 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 d6 O-O + Bd7 Nb3 a5 a4 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 b6 O-O + Bb7 f3 Nxd4 {4 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Be2 Bg7 + O-O O-O Qd3 Be6 Bd2 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Bd2 {30 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Bd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Qd3 Be6 Bd2 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 a6 Nc3 d6 d4 cxd4 Nxd4 g6 {9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 a6 d4 cxd4 Nxd4 Nf6 Nc3 e5 Nf3 Nc6 {5 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Be7 O-O O-O f4 + Nbd7 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Be7 O-O O-O f4 + Nbd7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Bd7 {-36 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Bd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Be7 Na4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Nc6 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {-76 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 e5 {-43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 f5 h6 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {480 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {95 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 Nc6 Be3 Bd7 {-83 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {63 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Qb6 Be3 Qb7 Qg3 b4 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Bb7 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 e5 Nf3 Qc7 Bg5 Nbd7 a5 + {-11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Nxc6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Be2 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Bd3 Nc6 Nxc6 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 Nbd7 Be3 {-53 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 e5 {17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 e5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Be7 a5 + {-33 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Qa5 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 e5 Nb3 Be7 Bg5 {-18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 Nc6 {-108 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Nxc6 + {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Nxc6 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Kh1 + Qb6 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Be7 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Be7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Nc6 Qd2 + Bd7 {33 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {-37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {28 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O O-O-O + d5 Nxc6 bxc6 exd5 cxd5 Nxd5 Nxd5 Qxd5 Qc7 Qxa8 {37 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O O-O-O + Nxd4 Bxd4 Be6 g4 Qa5 a3 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Bg5 Bd7 + {40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Bg5 Bd7 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Bg5 Qb6 + {57 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 Nf6 Qa4 {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 Nf6 Qa4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 e6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 e6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Nc3 {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Qe2 e6 b3 Be7 Bb2 O-O + c4 Ng4 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O {-12 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O Nf6 e5 dxe5 Nxe5 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 {5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 {97 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-61 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Bd7 Qb4 {116 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Bd7 Qb4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Nc6 Bb5 Bd7 Bxc6 Bxc6 Nc3 e6 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 Bg5 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 Bg5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 f4 {-19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 a6 g3 Be7 {-29 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 a6 Be3 {-7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 a6 Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 Nf6 Be2 {13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 Nf6 Be2 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 d4 Nf6 Be3 {52 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 d4 Nf6 Be2 Nc6 Bg5 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-39 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-251 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb6 Nc3 {-2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb6 Nc3 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb4+ {42 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb4+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Nf6 O-O d6 Nc3 Be7 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Nf6 Nc3 Qc7 f4 {-26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Bb4+ {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 g6 d4 Bg7 dxc5 Qa5+ {34 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 g6 d4 Nf6 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 g3 Nc6 Bg2 e5 Nc3 {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 g3 Nc6 Bg2 e5 O-O d5 c4 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d6 d4 Bg4 c4 Nd7 Nc3 e5 {119 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d6 d4 Bg4 c4 Nd7 {26 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d6 d4 Bg4 e4 d5 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d6 d4 Bg4 e4 Nc6 {26 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d6 d4 g6 Nc3 Bg7 e4 Nf6 e5 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d6 d4 g6 g3 Nf6 Bg2 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 b3 Bf5 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 b3 Bf5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 b3 Nc6 {-11 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 b3 Nc6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 c6 d4 e6 cxd5 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 c4 c6 d4 e6 e3 Nf6 Nc3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 Bg4 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 Bg4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {77 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 d4 Qa4+ {92 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 d4 Qa4+ {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 c4 d4 e3 Nc6 exd4 Nxd4 Nxd4 Qxd4 Nc3 {39 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 Qb3 Na5 Qa4 {-64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 Qa4 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 {-16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 d4 Ne4 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 d4 Ne4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 d4 c5 c4 dxc4 Qa4+ {122 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 d4 c5 c4 dxc4 Qa4+ {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 d4 c5 c4 e6 cxd5 exd5 Nc3 Nf6 g3 Nc6 Bg2 Be6 O-O {46 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 g3 Bg4 Bg2 e6 {-51 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 g3 Bg4 Bg2 Nc6 {63 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 g3 c6 Bg2 Bg4 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 g3 c6 Bg2 Bg4 O-O Nf6 d3 Nbd7 Nbd2 e5 h3 Bh5 e4 {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 d5 g3 c5 Bg2 Nc6 d4 e6 Nc3 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 d5 g3 c5 Bg2 Nc6 d4 cxd4 {26 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 e6 d4 Nf6 Nc3 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 e6 d4 Nf6 Bg5 Nc6 {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 f5 g3 Nc6 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 f5 g3 Nc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 f5 g3 Nf6 Bg2 Na6 {18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 e5 {-35 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 Nf6 e4 O-O Be2 c5 O-O cxd4 Nxd4 Bd7 Be3 + Nc6 f4 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O Bg4 Be3 Nc6 Qd2 e5 d5 + Ne7 Bh6 {40 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O Bg4 Be3 Nc6 Qd2 e5 d5 + Ne7 Rad1 Bd7 Ne1 h5 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 e5 {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 e5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 Re1 Nbd7 Bf4 Nb6 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 h3 O-O Be3 d5 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 h3 O-O Be3 d5 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + b3 e5 Bb2 Nc6 e3 Bd6 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + b3 e5 Bb2 Nc6 e3 Bd6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + b3 e5 Bb2 Nc6 e3 Nf6 {1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + b3 e5 Bb2 Nc6 e3 Nf6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 c5 g3 e5 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 c5 g3 d5 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 d4 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 d4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 {35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 O-O {-18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 O-O {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 Nc6 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 exd5 {-32 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 g5 {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Nf3 Bxc5 Bf4 Nc6 a3 b6 e3 + {-6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Nf3 Bxc5 Bg5 Nc6 Rd1 {29 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 {-63 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Be3 + {-40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Be3 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Bh4 + g5 {63 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 Nxd4 Bxc3+ {84 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 Nxd4 Ne4 {3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 Nxd4 Ne4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Qc2 {-3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Bb2 Bd7 {-154 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Bb2 Bd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 Nb6 {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 Nb6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 cxd4 exd4 Nb6 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 {11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 e3 Qa5 {7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {-4 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Bxc3+ Nxc3 d5 Qf3 {-21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Bxc3+ Nxc3 d5 Qf3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Be7 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Be7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 O-O O-O + Rb1 {360 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 O-O O-O + Rb1 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 O-O e5 Nd2 + cxd4 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 {-23 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 exd4 d5 {15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 exd4 d5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 O-O a3 Ba5 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 O-O a3 Ba5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 Ne4 Bd2 {38 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Qc2 {-33 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Qc2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Nf4 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Qc2 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Bd2 {96 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 Bxc3+ bxc3 {-61 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 Bxc3+ bxc3 {14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 c5 Qc2 {27 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 Nc6 Bd3 d5 O-O Bd7 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 Nc6 Bd3 d5 O-O Bd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 exd5 f3 {-3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 Nxd5 Qc2 {21 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 Qa5 + Bb2 Nc6 e4 Nb6 d5 {-23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 Qa5 + Bb2 Nc6 e4 Nb6 d5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 f5 + {-120 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 f5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 h6 {-17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 h6 {300 3 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 Bb4 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Nf3 Nbd7 c5 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Rc1 Ne4 Bxe7 Qxe7 cxd5 + Nxc3 Rxc3 exd5 Bd3 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 Nbd7 Nf3 h6 {-6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 Nbd7 Nf3 h6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 Ne4 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 Bg4 {-24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 h6 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Be7 Nf3 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Bf5 Qf3 {31 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 Nf3 {-32 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 d4 cxd4 Qxd4 Nc6 Qe4 d6 Nf3 {-1 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 d4 cxd4 Qxd4 Nc6 Qe4 d6 Nf3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 e4 d5 e5 Nfd7 d4 {44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e6 e4 d5 e5 d4 exf6 {16 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {3 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 Bxc3 dxc3 {-15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 Bxc3 dxc3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 d5 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 e4 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 Ba5 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O Re8 a3 {-6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 O-O + b4 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 O-O + b4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 Be6 + b4 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O Nf3 d6 {-29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O Nf3 d6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O Nf3 Nc6 O-O d6 {6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Nf3 h6 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Qc1 c5 d5 {18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Qc1 c5 d5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 c5 d5 h6 Bd2 {-6 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 c5 d5 h6 Be3 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 Nc6 {242 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 Nc6 {-300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 e5 {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 {-5 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 Nge2 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 a6 {-4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 a6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 O-O g3 Bg4 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 O-O g3 Bg4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 g4 {-17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 g4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 h4 Bd7 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 Bxc5 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 Bxc5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 Qxd8 Rxd8 + Bxc5 Nc6 Ba3 {13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 Qxd8 Rxd8 + Bxc5 Nc6 Ba3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Bd7 {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Bd7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Nc6 {40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 {78 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 Nh5 Qd2 Na6 {19 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 Nh5 Qd2 Na6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Nge2 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Bd3 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 Nc6 Nge2 a6 d5 {-23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 Nc6 Nge2 a6 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 h6 Be3 e5 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c5 Be2 cxd4 Nxd4 Nc6 Nxc6 + {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c6 {18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c6 {-300 5 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 e5 Bg5 {-31 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 c5 Be2 cxd4 Nxd4 {7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 c5 Be2 cxd4 Nxd4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 O-O e5 Ne8 f4 d6 {-26 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 O-O Nf3 d6 Be2 c5 O-O cxd4 Nxd4 Bd7 Be3 + Nc6 f4 {35 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 O-O Nf3 d5 cxd5 Nxd5 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 d5 cxd5 Nxd5 Bg2 {25 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bxa6 Qxg2 Qf3 Qxf3 Nxf3 bxa6 O-O Bb7 Nd2 {18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bxa6 Qxg2 Qf3 Qxf3 Nxf3 bxa6 O-O Bb7 Nd2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bg3 {54 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bg3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 f3 {54 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 f3 {17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 f3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {23 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 O-O Ne2 Qd7 + O-O b5 {4 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 O-O Ne2 Qd7 + O-O b5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 Nc6 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 Nc6 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 c6 Nf3 d6 O-O Na6 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Be6 {102 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Bf5 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Bd3 O-O O-O a6 Qb3 {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 Nf3 bxc4 e3 {52 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 Nf3 bxc4 e3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 Nf3 Qa5+ {25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 Nf3 Qa5+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e5 {205 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e6 {19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 d6 e4 Bxf1 Rxf1 + {102 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 d6 e4 Bxf1 Kxf1 + Bg7 h3 O-O Kg1 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 e6 Nc3 {46 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 e6 Nc3 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 d6 Nc3 Bd7 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Bg4 {-6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Bg4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Na6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Re8 Qc2 Qe7 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Re8 Qc2 Qe7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Qb6 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {-6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {7 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 exd4 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Nc6 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Nc6 {64 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Nc3 Bxc3+ {78 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Nc3 Bxc3+ {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Bd2 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {-36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Nc6 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Nc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Bc6 Nf3 Bd5 Qd3 Nc6 + {-45 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Bc6 Nf3 Bd5 Qd3 Nc6 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e5 dxe5 Ng4 Nf3 Bc5 e3 Nc6 {80 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 e5 dxe5 Ng4 Nf3 Bc5 e3 Nc6 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 e5 {-138 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 Nxc3 bxc3 O-O Qb3 {-61 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 g6 g3 c6 Nf3 Bg7 Nc3 {-12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 d4 g6 g3 c6 Nf3 Bg7 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 g6 g3 c6 Nf3 {21 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 d4 g6 g3 c6 Nf3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 Nf6 g3 c6 Nc3 {-1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 g3 c6 Bg2 d5 b3 {9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 Nf6 g3 c6 Bg2 d5 b3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 b6 Nf3 Nf6 Nc3 Bb7 d4 e6 Bg5 Bb4 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + d6 Bd3 Bxc3+ bxc3 Nxg3 fxg3 Nd7 h3 {-24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 b6 Nf3 Nf6 Nc3 Bb7 d4 e6 Bg5 Bb4 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + d6 Bd3 Bxc3+ bxc3 Nxg3 fxg3 Nd7 h3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 b6 Nf3 Nf6 g3 Nc6 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 d4 d5 e3 Nf6 Nc3 e6 Nf3 Bd6 c5 {-9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 d4 d5 e3 Nf6 Nc3 e6 Nf3 Bd6 c5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 d4 d5 e3 Nf6 Nc3 Bf5 cxd5 cxd5 Qb3 {37 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 Bb5+ {175 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 Bb5+ {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 Nf3 Nc6 d4 Bf5 {22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 Nf3 Nc6 d4 Bf5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 {-27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 Ne5 Qd4 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 Bf6 Ne5 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 {-2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Bd2 O-O + {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Qc2 Nc6 + Bd3 Nxc3 {13 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Qc2 Nc6 + Bd3 Nxc3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 c5 {18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 cxd5 {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 Nc6 Nf3 e5 e3 Nf6 Qb3 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c5 Nc3 Nc6 g3 Nf6 Bg2 {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 Nf6 d4 cxd4 Nxd4 O-O O-O Qa5 + {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 Nf6 d4 cxd4 Nxd4 O-O O-O Qa5 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 d6 O-O Nf6 {-6 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 d3 {-6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 d3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 Rb1 {9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 Nf6 {-16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 Nf6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 d6 {-129 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 d6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 Bf5 g4 Bg6 h4 Qb6 {-135 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 Bf5 g4 Bg6 h4 Qb6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e6 d4 Bb4+ Bd2 Qe7 Nf3 Nf6 a3 {-5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e6 d4 Bb4+ Bd2 Qe7 Nf3 Nf6 a3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 O-O Nc3 d6 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 Nc6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 Nf3 f5 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 Nf3 f5 d4 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 f5 Nh3 {-35 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 f5 Nh3 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 Nf6 Nf3 d6 O-O O-O d3 Bg4 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 Nf6 Nf3 d6 O-O O-O d3 Bg4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Nf3 f5 Be3 {-17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Nf3 f5 Be3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Rb1 Nf6 Nf3 O-O O-O Bd7 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 h5 d4 h4 d5 Nce7 e4 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 Bg4 {65 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 Bb4 Nd5 {-64 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Bb4 Nf3 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 Bb4 Nf3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 Nc3 d6 g3 g6 Nf3 {-14 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 Nc3 d6 g3 Nc6 Bg2 Nf6 d3 {3 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 g3 Nf6 Bg2 Bc5 {-2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 e5 g3 Nf6 Bg2 Bc5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 g3 Nf6 Bg2 d5 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 e5 g3 Nf6 Bg2 d5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 f5 Nf3 {43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 f5 Nf3 Nf6 Nc3 {14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 Nf3 {3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 Nf3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 dxe5 Bxe5 {17 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 dxe5 Bxe5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 g3 d6 Nf3 Nf6 d4 O-O Bg2 Nbd7 Qb3 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 g3 Nf6 Bg2 Nc6 Nf3 O-O O-O d5 cxd5 Nxd5 Nxd5 Qxd5 + d3 {9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 g6 Nc3 Bg7 g3 Nf6 Bg2 Nc6 Nf3 O-O O-O d5 cxd5 Nxd5 Nxd5 Qxd5 + d3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + c4 g6 g3 Bg7 Bg2 Nf6 Nc3 O-O d4 Nc6 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 g6 g3 Bg7 Bg2 Nc6 {-141 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + c4 g6 g3 Bg7 Bg2 Nc6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 Nf6 Nc3 d5 Bg5 e6 Nf3 Bb4 a3 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 Nf6 Nc3 d5 Bg5 Bf5 Bxf6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 Nf6 Bg5 Ne4 Bf4 d5 f3 Nf6 Nc3 {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 Nf6 Bg5 Ne4 Bf4 g5 {22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 Nf6 Bg5 Ne4 Bf4 g5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 c5 d5 Nf6 Nc3 d6 e4 g6 Nf3 Bg7 e5 {-1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 c5 d5 Nf6 Nc3 d6 e4 g6 Nf3 Bg7 e5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 c5 d5 Nf6 Nc3 {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 c4 e5 Nf3 exd4 Nxd4 Nf6 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 c4 e5 Nf3 exd4 Nxd4 Nf6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 c4 e5 Nf3 exd4 Nxd4 Bd7 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 e6 {-10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 Bg4 h3 Bh5 {-31 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 Be3 Bg7 h3 O-O Nf3 d5 {16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 Be3 Nc6 {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Nbd7 {82 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Nbd7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Nc6 {-41 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 c5 dxc5 {123 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 c5 dxc5 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 e5 Nd7 {81 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 e5 dxe5 {-46 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 e5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 e5 dxe5 fxe5 Nd5 Nxd5 + Qxd5 c3 {15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 d5 {140 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 h3 {-115 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 Nf6 f3 e6 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d6 e4 g6 Nc3 Bg7 Be3 Nf6 h3 O-O Nf3 d5 {47 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d6 e4 g6 Nc3 Bg7 Be3 Nf6 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 Bg5 c6 Nf3 Qb6 b3 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 Bg5 h6 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 Bg5 h6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 Nf3 a6 e3 Be6 {144 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 Nf3 a6 e3 Be6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 a4 Bb7 b3 cxb3 {5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 a4 Bb7 b3 cxb3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 e6 Nc3 c5 Nf3 cxd4 Nxd4 {76 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 e6 Nc3 c5 Nf3 cxd4 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 Nbd7 Nf3 Nb6 Be2 Bf5 Nc3 e6 Nh4 {9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 Nbd7 Nf3 Nb6 Be2 Bf5 Nc3 e6 Nh4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nb6 Bb5+ {-4 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nc6 Ne2 Nb6 Bd3 Be6 Nbc3 Qd7 + Ne4 {73 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Bc5 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Bc5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Bb4+ Bd2 Bxd2+ Nbxd2 Nc6 O-O + Nf6 e5 Ng4 h3 Ngxe5 {65 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 Nf3 f5 Nc3 {-4 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 Nf3 f5 g3 Nf6 Bg2 Na6 {4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 Nf3 f5 g3 Nf6 Bg2 Na6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 Ne2 dxe4 a3 Be7 Nxe4 Nf6 N2g3 O-O {101 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 Ne2 dxe4 a3 Bxc3+ Nxc3 {7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 exd5 exd5 Nf3 Ne7 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 exd5 exd5 Nf3 Nf6 {-6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 Qc7 Qxg7 Rg8 + Qxh7 cxd4 Ne2 Nbc6 f4 dxc3 {-44 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 Qc7 Qxg7 Rg8 + Qxh7 cxd4 Ne2 Nbc6 f4 dxc3 Qd3 Nf5 {3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {0 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O Bd3 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Bd7 Bg5 {-31 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Nbc6 Be2 {-5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 O-O {12 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 O-O {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 Bd7 {-18 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {19 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 a3 Bxc3+ bxc3 Ne7 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 Nf3 {600 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 Nf3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 b4 cxb4 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Bf4 {22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Bf4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Qg4 {99 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Qh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Nb5 {2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Bb4 e5 h6 exf6 hxg5 fxg7 Rg8 Qh5 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Bb4 e5 h6 exf6 hxg5 fxg7 Rg8 Qh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Bb4 e5 h6 exf6 hxg5 fxg7 Rg8 h4 gxh4 + Qh5 Qf6 Nf3 {120 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Bd3 {51 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Nxf6+ Nxf6 Nf3 h6 Bd2 + {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 {22 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 O-O Qd2 {33 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bb4 {-17 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bc5 {12 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Bd3 Nxe4 {-1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Bd3 Nxe4 Bxe4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Bd3 Nxe4 Bxe4 Nf6 Bg5 + {21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Bd3 Nxe4 Bxe4 Nf6 Bg5 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {-60 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {-22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Nb4 {-62 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Nb4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Bb4+ {24 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Bb4+ {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Ba7 Bg5 f6 + {0 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Ba7 Bg5 f6 + {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {373 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {-104 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O cxd4 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O cxd4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O Qb6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Nxd5 {-5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Qxd5 Bc4 {36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 Be3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 Bb3 {3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + Nxc5 Ndf3 {68 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + Nxc5 Ndf3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + Nxc5 Nb3 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + Nxc5 Nb3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 exd5 exd5 Nf3 Bf5 {25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 exd5 exd5 Nf3 Nc6 Bb5 Nf6 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 Nge7 dxc5 {-43 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 f6 O-O Qb6 dxc5 Bxc5 b4 + Be7 Bf4 {61 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4 Nbd2 Na5 Rb1 {-11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4 g3 {-24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 f5 Nf3 Nf6 g3 e6 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 f5 Nf3 Nf6 g3 Nc6 {-7 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 f5 g3 Nf6 Bg2 g6 Nc3 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 f5 g3 Nf6 Bg2 g6 Nh3 c6 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + d4 g6 e4 Bg7 Nc3 c6 Nf3 d5 exd5 cxd5 Ne5 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + d4 g6 e4 Bg7 Nc3 c6 Bc4 b5 Bb3 {-49 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nc6 Nf3 e5 Nc3 Nf6 a3 Bc5 {-17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nc6 Nf3 e5 Nc3 Nf6 a3 Bc5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 Nc6 Nf3 Nf6 e5 Nd5 Bc4 Nb6 Bb3 d6 exd6 {16 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nf6 Nc3 d5 exd5 Nxd5 Ne4 {-42 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 Nf6 Nc3 d5 exd5 Nxd5 g3 Nxc3 bxc3 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 h3 Bf5 {-2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 h3 Bf5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 h3 Bh5 Nc3 + {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Ng5 e6 f4 dxe5 fxe5 + c5 Qf3 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 O-O Nc6 exd6 Qxd6 + Nc3 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 dxe5 fxe5 Nc6 Nf3 Bg4 Be3 e6 {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 Bf5 {-24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {321 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 f5 {97 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 f5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Bc4 {23 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d3 d5 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d3 d5 Nd2 e5 Ngf3 Bd6 {21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {103 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {-2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 c3 {39 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 c3 {30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 c3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Be3 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 O-O {-36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 O-O {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Bc4 {1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 c3 Bg4 h3 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 Nf3 Nd7 Nh4 {9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 Nf3 Nd7 h4 Ngf6 {-44 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 Ngf6 O-O-O e6 Kb1 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 e6 O-O-O Ngf6 Ne4 O-O-O g3 Nxe4 Qxe4 Nf6 Qe2 + {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 Bd2 Qc7 O-O-O e6 Kb1 {-2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 Bd2 Qc7 O-O-O e6 Kb1 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 Bd2 e6 O-O-O Qb6 {10 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qc7 O-O-O {-9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qc7 O-O-O {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qb6 {-15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 {-11 5 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 c3 {-42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Nf3 Bg4 {56 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Bc4 {18 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Nd7 {23 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Nd7 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Bb4 {-64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Bb4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Na6 {79 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Na6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Na6 {76 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 Nge2 e5 Ng3 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 Nge2 e5 Ng3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 Nge2 e5 Nd5 Nf6 {73 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d6 Bb5 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d5 Bb5 {11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d5 Bb5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Be3 e6 Nf3 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Be3 Nf6 {14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O Be3 + Qb6 {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nd4 {-18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nf6 d4 cxd4 Nxd4 Qb6 {17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nf6 d4 cxd4 Nxd4 Qb6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 d6 g3 Nc6 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Nc3 d6 g3 Nc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Nc3 d6 g3 Nc6 Nf3 Nf6 Bg2 {9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 Ne2 Nf6 Nbc3 d5 e5 {-38 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Ne2 Nf6 Nbc3 e5 {34 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 Ne2 Nf6 Nbc3 e5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 Bc4 Nb6 Bb3 d5 cxd4 Bg4 Nc3 + {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 cxd4 d6 Nc3 Nxc3 bxc3 Qa5 + {-99 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 c3 d5 exd5 Qxd5 d4 Nf6 Nf3 Bg4 Be2 cxd4 cxd4 Nc6 Nc3 Qa5 + O-O e6 h3 Bh5 Be3 Bd6 {46 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 c3 d5 exd5 Qxd5 d4 Nf6 Nf3 Bg4 Be2 cxd4 cxd4 Nc6 Nc3 Qa5 + O-O e6 h3 Bh5 Be3 Bd6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Be3 cxd4 cxd4 Bb4+ Nc3 O-O + {217 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Be3 cxd4 cxd4 Bb4+ Nc3 O-O + {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Be3 cxd4 cxd4 Bb4+ {16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Be3 cxd4 cxd4 Bb4+ {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 c3 e6 d4 d5 exd5 Qxd5 Nf3 Nf6 Be3 cxd4 cxd4 Bb4+ Nc3 Qa5 + {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 c3 e6 d4 d5 exd5 Qxd5 Nf3 Nf6 Na3 cxd4 Nb5 Na6 Nbxd4 {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 d4 cxd4 Qxd4 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 d4 cxd4 Qxd4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 d4 cxd4 Nf3 e5 Bc4 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 d4 cxd4 Nf3 e5 Bc4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 c5 f4 d5 exd5 Qxd5 Nc3 Qd8 Bb5+ {152 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 c5 f4 d5 exd5 Qxd5 Nc3 Qe6+ {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bf5 Bc4 Ne4 {29 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bg4 {-1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 d5 exd5 Nf6 d4 Nxd5 c4 Nf6 {-9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 d5 exd5 Nf6 d4 Nxd5 c4 Nf6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 d5 exd5 Nf6 d4 Nxd5 c4 Nf6 {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e6 d3 d5 Nd2 Nc6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Nxe4 {-16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Nxe4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Qf3 Bc5 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Bc4 Nf6 d3 c6 Bb3 {14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Bd3 {-89 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Ba4 c6 d3 Bb4 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 Qe7 + Qe2 {-6 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 Be6 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 cxd5 Qxe7+ {97 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Bxe2 {18 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Bxe2 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 Bxb4 c3 Ba5 Qb3 {-34 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 {-75 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Bc5 c3 Nf6 d3 d6 {64 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Bc5 c3 Nf6 d3 d6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 Ng5 d5 exd5 Nxd5 Qf3 {-89 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 Ng5 d5 exd5 Nxd5 Qf3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 Ng5 d5 exd5 Nxd5 Nxf7 Kxf7 Qf3+ Ke6 Nc3 + Nb4 Qe4 c6 a3 {52 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Nc3 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Bb3 d5 exd5 Nxd5 h3 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 Nxd4 {30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 O-O Nxe4 Re1 d5 Bxd5 Qxd5 Nc3 Qc4 + {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {-1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {-24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Bc5 c3 a6 {-6 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Bc5 O-O Nge7 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Be7 d5 {67 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Be7 dxe5 {105 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Bg5+ {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Bg5+ {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Nc3 Be7 {-6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Nc3 Be7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {55 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 c5 Nf5 {-16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 c5 Nf5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 Ne7 Be3 Qd6 + {43 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 b5 Bb3 Bc5 a4 Rb8 axb5 axb5 + Nc3 O-O {-26 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 Bc5 {-25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 Nc3 Be7 O-O {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 c3 b5 {35 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 b5 Bb3 {46 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 b5 Bb3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 b5 e5 {80 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 O-O + Nc4 f6 Be3 {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 O-O + Nc4 f6 Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 bxa4 {-15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 Na5 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 Na5 {-13 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 exd4 cxd4 Na5 Bc2 c5 dxc5 dxc5 Nbd2 Be6 {23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 exd4 cxd4 Na5 Bc2 c5 dxc5 dxc5 Nbd2 Be6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 Rc8 {63 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 c5 {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {-6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 d5 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 Nbd2 cxd4 cxd4 Bb7 Nf1 {-35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {-85 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Na3 {-12 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Na3 {300 5 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Nbd2 Bb7 Nf1 Kh8 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {38 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Be7 {11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Na5 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 cxd4 Nb4 Bb1 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 cxd4 Nb4 Bb1 {-40 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 Bxb3 axb3 exd4 Nxd4 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 Bxb3 axb3 exd4 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 {11 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 bxa4 {-22 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 bxa4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 Bb7 Na3 exd4 cxd4 Kh8 {22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {-23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Nc6 {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Qc7 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Qc7 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d3 + {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d3 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Bf3 + Qf1 Qh5 Nd2 Bg4 {480 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Bf3 + Qf1 Qh5 Nd2 Bg4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Nxe3 + Rxe3 Rae8 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 d4 {45 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 Bxc6+ bxc6 d4 exd4 + Nxd4 Bd7 Nc3 {40 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Nbd2 + Nc5 c3 g5 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + Be7 c4 {93 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + {19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Nxe4 {96 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Nxe4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Re1 Nc5 Nf1 Nxb3 axb3 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 Bf5 Nxe4 {-15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 Bxf2+ Rxf2 Nxf2 Kxf2 f6 exf6 Qxf6 Kg1 Bf5 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 Bxf2+ Rxf2 Nxf2 Kxf2 f6 exf6 Qxf6 Kg1 Bf5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Ng5 {112 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Ng5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Re1 Na5 {5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Re1 Na5 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 d4 b5 dxe5 dxe5 Qxd8+ Nxd8 + Bb3 Bd6 {-11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 Bxc6+ bxc6 d4 Nxe4 Re1 {22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 Bxc6+ bxc6 d4 Nxe4 Re1 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 exd4 Qxd4 {-3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 exd4 Qxd4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 Nf6 {24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 Nf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 Nf6 d5 {-34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 Nf6 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 {16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 Nc3 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 c3 Nf6 d4 exd4 {61 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 Bd7 d5 Nb4 {60 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 exd4 Qxd4 {97 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 Bc4 {-6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 Bc4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 O-O {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 O-O {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {-17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {-130 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Bc4 Bc5 Ng5 Nh6 Nxf7 Nxf7 Bxf7+ Kxf7 Qh5+ + g6 {-44 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Bc4 Qe7 {-66 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 f3 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 Bc4 Ne5 Be2 d5 + {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 Nc3 Bb4 Qd4 {-35 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 Nc3 Bb4 Qd4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 Bd3 d5 e5 Ng4 Bf4 Qe7 + {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 Bg4 Nd4 Bxe2 Ncxe2 Nc6 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 O-O O-O-O {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Be7 O-O Nc6 Re1 Bg4 + Bxe4 dxe4 Rxe4 Bxf3 Qxf3 Nxd4 {-11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Be7 O-O Nc6 Re1 Bf5 + Nbd2 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 Be6 cxd5 + Bxd5 {-32 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 Re8 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Bb4+ {3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Nc6 Nxc6 bxc6 Qe2 {125 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 Nf3 d6 d4 Nd7 Nc3 {-6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 d6 d4 exd4 Bc4 {-52 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 Nf3 d6 d4 exd4 Bc4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 d4 exd4 Qxd4 Nc6 Qc4 {386 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 d4 exd4 Qxd4 Nc6 Qc4 {-300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 d4 exd4 c3 dxc3 Bc4 cxb2 Bxb2 {-140 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 d4 exd4 c3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 f4 d5 exd5 exf4 Qe2+ {-18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 f4 d5 exd5 exf4 Qe2+ {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 f4 d5 exd5 Qxd5 {-196 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 f4 d5 exd5 Qxd5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 f4 exf4 Bc4 Qh4+ Kf1 d6 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 f4 exf4 Bc4 Qh4+ Kf1 Nc6 {53 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 f4 exf4 Nf3 g5 h4 {94 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + e4 e5 f4 exf4 Nf3 g5 h4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + e4 e5 f4 exf4 Nf3 g5 h4 g4 Ne5 h5 Bc4 Nh6 d4 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + f4 Nf6 Nf3 g6 Nc3 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + f4 Nc6 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + g3 c5 Nf3 b6 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + g3 c5 Bg2 Nc6 c4 Nf6 Nc3 {-15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + g3 d5 Bg2 e5 d4 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + g3 d5 Bg2 e5 d4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + g3 d5 Bg2 Nf6 Nf3 Nc6 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + g3 e5 d4 {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + g3 e5 Bg2 d5 c4 {7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + g3 g6 Bg2 Bg7 d4 Nf6 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + g3 g6 Bg2 Bg7 c4 Nc6 {-141 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + g3 g6 Bg2 Bg7 c4 Nc6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 {100 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + a6 Bg5 Nbd7 {-15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Qc8 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {54 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {77 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-103 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-244 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + a6 Bg5 Nbd7 {-15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 a6 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 a6 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Qc8 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {54 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {77 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {7 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 {-33 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 {-46 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 {3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {-46 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 Qc2 dxc4 Bxf6 + Nxf6 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 exf6 Bh6 {-45 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 Bb4 O-O + {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 exf6 Bh6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 dxc4 Bxc4 + Nb6 {76 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {-5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {-42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {79 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + Be7 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {135 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {-6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {-55 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 e6 Nc3 Bd6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {-41 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Ne5 Bb4 {-12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 e6 Nc3 Bd6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 e6 Nh4 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 cxd5 cxd5 Qb3 Qc8 Bd2 Nc6 {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 dxc4 Bxc4 {-7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 Ne5 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 {-43 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 c4 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 e4 {6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 e4 {-12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {-39 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {20 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 Qxd1+ Kxd1 Nc6 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 g6 d4 {-30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 e4 Nc6 d4 cxd4 Nxd4 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 e6 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Bg5 f6 Bd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Be7 {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Bd3 cxd4 exd4 dxc4 Bxc4 Bd6 + O-O O-O Re1 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Qc2 Qe7 {-14 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 {49 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 {-2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 {-43 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 d5 + {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 e6 O-O Be7 d4 O-O {-25 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 e6 O-O Be7 d4 O-O {36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 e6 O-O Be7 d4 O-O {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Na6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Na6 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 {8 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 e5 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 Qe2 Na6 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O Ne4 Qc2 Nxc3 Qxc3 + d6 Qc2 f5 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O Qc2 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 dxc4 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 dxc4 {-24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 Qc2 Re8 cxd5 + exd5 Bd3 h6 {47 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 c5 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 Qc2 Re8 cxd5 + exd5 Bd3 h6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {-15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {76 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {16 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 c5 {49 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 c5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {71 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 c5 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Bd3 + Nxc3 bxc3 Nc6 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Bd3 + Nxc3 bxc3 Nc6 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 cxd5 + Nxd5 Bxe7 Qxe7 Bd3 {50 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O Re8 Bd3 {-35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 cxd5 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 Rc1 dxc4 {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 Qa4+ Nc6 {-96 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Bxc3+ {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Qxf6 Qb3 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Qb6 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Nf6 Be3 {48 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Bxd2+ Qxd2 O-O Bc4 Nd7 O-O Nb6 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Qa5 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Qb6 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {82 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-69 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 Be7 e3 d5 Qc2 {49 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 O-O a3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 {26 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 {30 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 {-35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 {20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 c5 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 Be7 e3 Ne4 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 Be7 e3 Ne4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 h6 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 dxc4 {19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Bd6 + {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 Qxc3 f6 + {14 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + c5 Bb5+ {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {111 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 {72 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 {-72 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 c5 Bf4 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 Na6 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {-28 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-19 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 {-58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 {-21 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {-185 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 Bd6 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {216 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qb3 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bd6 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bb7 Bg2 {107 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O e4 d5 cxd5 + Bxf1 Rxf1 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bd6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {13 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 {-4 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {-25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Qb3 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Qb3 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Qb3 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Nh5 + {22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 Qxc3 {-28 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 bxc3 b5 Nb2 a5 {36 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 a6 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 a6 {-9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-64 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 cxd5 {7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 Nc3 dxc4 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 {-46 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + c5 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + Bc6 Nxc6 Nxc6 e3 Na5 Nd2 c6 {17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {-28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {2 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {4 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {21 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Re8 f3 Ne5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Ne5 {56 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {42 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 h3 {52 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 dxe5 {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 dxe5 {-4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {23 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 dxe5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Re8 Nd5 Nxd5 cxd5 {21 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Qc2 {116 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Bg5 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Qc2 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {-6 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 {-3 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Qb3 {16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nb5 b6 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 {158 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 Rb1 f5 b4 Kh8 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 c5 Bd7 {34 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 Nc5 Qc2 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 Nc5 Qc2 {83 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 Nc5 Qc2 {66 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 Bg7 Bf4 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 Qxd1+ Kxd1 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {322 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {4 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 Qxd1+ Kxd1 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 h6 + {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {228 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Be2 c5 d5 + {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + Qb3 {58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + O-O-O Nc6 h3 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Nc6 + {33 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Nc6 + {-18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Nc6 + {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 e4 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Bc4 Nb6 Bb3 Nc6 + {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d6 Qb3 {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d5 cxd5 Nxd5 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Bf4 {-41 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + d5 Nc5 Be3 {-55 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 Qb3 {5 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 b3 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 Re8 Bg5 + {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Qxd4 + {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 e5 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 Bd7 {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 Qb3 + {-25 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {8 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 Qb3 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {35 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {1 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {60 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 d5 Ne7 Qb3 + {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 c5 d5 b5 {40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 c5 d5 b5 {35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 c5 d5 b5 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {-9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {187 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 a4 + c4 Bc2 Bd6 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 a4 + c4 Bc2 Bd6 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bd6 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bc5 {10 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 a4 + c4 Bc2 Bd6 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nc3 b5 Bd3 {15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + a3 O-O b4 Ba7 {4 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {-20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nc3 b5 Bd3 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 d5 e3 Nc6 {49 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bf4 d5 Nc3 {-10 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 Qb6 b3 Ne4 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 h6 Bh4 d5 Bg3 {-5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 h6 Bh4 d5 Bg3 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 Bg5 h6 Bh4 d5 Bg3 {-32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 Nc3 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Nc6 {53 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O c5 Na3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 d5 {40 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {112 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 h6 {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e4 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O c3 d5 e3 Nc6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O c3 d5 e3 Nc6 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bg5 d5 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c3 bxc3 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {-3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {32 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {-12 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d3 Nbd7 Nbd2 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d4 Nbd7 Nc3 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d3 Nbd7 Nbd2 e5 h3 {-44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 Na3 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 O-O {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 Nf6 Nc3 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d3 Nbd7 Nbd2 e5 h3 {300 4 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Nc3 e6 d4 cxd4 Nxd4 a6 Be3 Nge7 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Nc3 Nf6 Bc4 {-7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 d4 {25 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 d4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 Nc3 O-O d4 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 Qd6 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 Qd6 {44 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Bd7 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {44 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {28 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {66 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 e5 {-18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 Nf3 h6 {-16 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 e5 {-42 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 Bxf6 gxf6 Kb1 b4 {51 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 e5 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Be7 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bg7 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bg7 {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 Nb3 Be6 Nd4 Bc8 + Bg5 Bd7 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {-6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bg7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 O-O Be7 + Be3 Qd8 {13 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Nxd4 + {-28 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Qe2 {31 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Qe2 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Bg5 Be2 {13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O b5 Nxc6 + Qxc6 {111 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O b5 Nxc6 + Qxc6 {-20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bb4 + {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-38 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 Bg5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 Bg5 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 g3 {56 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 g3 {-65 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bg5 Nf6 N1c3 a6 Na3 {10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bd3 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bd3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 Ng4 + Qxg4 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Qb6 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 d6 O-O + Bd7 Nb3 a5 a4 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 b6 O-O + Bb7 f3 Nxd4 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Bg5 {-50 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Be2 Bg7 + O-O O-O Qd3 Be6 Bd2 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Bd2 {30 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Bd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Qd3 Be6 Bd2 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 a6 Nc3 d6 d4 cxd4 Nxd4 g6 {9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 a6 d4 cxd4 Nxd4 Nf6 Nc3 e5 Nf3 Nc6 {5 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Be7 O-O O-O f4 + Nbd7 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Be7 O-O O-O f4 + Nbd7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Bd7 {-36 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Bd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Be7 Na4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Nc6 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {-76 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 e5 {-43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 Be2 Nbd7 {56 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {480 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {95 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 Nc6 Be3 Bd7 {-83 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {63 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Qb6 Be3 Qb7 Qg3 b4 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Bb7 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Bg5 {128 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Bg5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Nxc6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Be2 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Bd3 Nc6 Nxc6 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {56 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {-65 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 f4 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 Qb3 Nd7 {7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 Qb3 Nd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bg5 Nf6 N1c3 a6 Na3 {10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bd3 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bd3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 Ng4 + Qxg4 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 Bg5 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 Bg5 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-48 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Bb4 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-48 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Bb4 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-48 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Bb4 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 Ne4 Nxe4 Bxe4 + Bf4 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d5 Ne5 Nbd7 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + a6 Bg5 Nbd7 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + a6 Bg5 Nbd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Qc8 {39 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 e4 + b4 Na4 Qa5 {25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 e4 + b4 Na4 Qa5 {-300 3 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {57 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {-32 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + Ne4 g4 {-21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {-26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 Qc2 dxc4 Bxf6 + Nxf6 {-45 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Rg8 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 Bb4 O-O + {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 dxc4 Bxc4 + Nb6 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {79 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + Be7 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {135 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 Nb6 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Qb6 Be4 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {-58 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 e6 Nc3 Bd6 {20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Ne5 Bb4 {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Ne5 Bb4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {-11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 e6 Nh4 {151 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 e6 Nh4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 Nbd7 {42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 dxc4 Bxc4 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 Na6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 Na6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 Ne5 {-14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 Ne5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 cxd5 exd5 Be2 {-43 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 cxd5 exd5 Be2 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 a6 Ne5 {-22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 c4 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Be3 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Be3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {-30 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 d4 cxd4 Nxd4 e5 {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 d4 cxd4 Nxd4 e5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 b6 e4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 cxd4 e6 e4 Nc6 + a3 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {43 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 Qxd1+ Kxd1 Nc6 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 g6 d4 {-30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 e6 Bg2 Nc6 O-O Be7 d4 Qa5 {41 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Be2 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 cxd5 exd5 Bb5 a6 Bxc6+ bxc6 + O-O Bd6 Qa4 Qc7 e4 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Qc2 Qe7 {-21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Qc2 Qe7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + Qxd5 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 d4 cxd4 Nxd4 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 Nc6 Be2 d6 d4 cxd4 Nxd4 Bd7 {38 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 d5 + {-30 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 d5 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 {24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Nc3 g6 d4 {-31 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 e6 O-O Be7 d4 Nxc3 + bxc3 {36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 d6 Nc3 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O d4 d5 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 {8 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 e5 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 Qe2 Na6 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O Ne4 Nxe4 Bxe4 + Bf4 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O Ne4 Nxe4 Bxe4 + Bf4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O d5 Ne5 Nbd7 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 c5 dxc5 {-25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 dxc4 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 Qc2 Re8 cxd5 + exd5 Bd3 h6 {47 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 c5 {8 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {-15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {86 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {-168 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {-10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Qxd4 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 c5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {71 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Qb3 + Nxc3 bxc3 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Bd3 + Nxc3 bxc3 Nc6 {21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 cxd5 + Nxd5 Bxe7 Qxe7 Bd3 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O Re8 Qd3 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 cxd5 {-19 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 Rc1 dxc4 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {36 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Bxc3+ {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Qxf6 Qb3 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Qb6 {-31 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Qb6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Nf6 Be3 {31 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Bxd2+ Qxd2 O-O Bc4 Nd7 O-O Nb6 {54 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Qa5 {33 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {82 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 {-5 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O {67 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 Be7 e3 d5 Bd3 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 O-O a3 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 O-O Nc3 d5 e3 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 h6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 Bxd2+ {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 Bxd2+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 e3 d6 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 Be7 e3 Ne4 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 h6 {31 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {64 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 dxc4 {19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Bd6 + {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Nd7 + {5 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + c5 Bb5+ {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 Nxg3 hxg3 g4 {72 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 Nxg3 hxg3 g4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 f5 {-172 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 c5 Bf4 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 Ba5 {43 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {-28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-58 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O dxc4 Bxc4 a6 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {-185 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 Bd6 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qb3 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bd6 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bb7 Bg2 {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O e4 d5 cxd5 + Bxf1 Rxf1 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O e4 d5 cxd5 + Bxf1 Rxf1 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.01"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {13 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 cxd5 {-24 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 Nxd7 Nd2 O-O O-O {19 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {-22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Bg5 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Bd2 Nc6 e3 O-O {44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Nh5 + {23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Nh5 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 Qxc3 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bg5 + {4 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bg5 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 Qe7 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 a6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 cxd5 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 cxd5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 Nc3 dxc4 {4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 Nc3 dxc4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 {-31 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + c5 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + c5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + Bc6 Nxc6 Nxc6 e3 Na5 Nd2 c6 {3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + Bc6 Nxc6 Nxc6 e3 Na5 Nd2 c6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ {-1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {2 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Re8 f3 Ne5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Ne5 {21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {29 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 h3 {55 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 h3 {50 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + c6 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {180 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Re8 Nd5 Nxd5 cxd5 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Qc2 {100 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Bg5 {18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 Bg5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 {-3 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Qb3 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Qb3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nb5 b6 {7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nb5 b6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 Qb3 {128 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 Qb3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 c5 Bd7 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 c5 Bd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {2 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 Nc5 Bxc5 + {-6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 Nc5 Bxc5 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {49 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 Bg7 Bf4 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {-13 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O e3 c6 h3 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 h6 + {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {96 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + Qb3 Nb6 {58 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + O-O-O Nc6 h3 {21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 cxd4 + {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Rb1 O-O + Be2 Nc6 Be3 {-18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 e4 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Bc4 Nb6 Bb3 Nc6 + {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d6 Qb3 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d5 cxd5 Nxd5 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Bf4 {-46 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + Re1 exd4 Nxd4 Ng4 Nce2 Nge5 b3 {17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + Re1 exd4 Nxd4 Ng4 Nce2 Nge5 b3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 Qb3 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 b3 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 Re8 Bg5 + {-9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 Re8 Bg5 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Qxd4 + {37 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Qxd4 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 e5 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 Bd7 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 Bd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 Qb3 + {-25 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 Qb3 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 e4 Bd7 + {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 e4 Bd7 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {46 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + Be3 {-12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {60 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 {67 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 d5 Na5 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 c5 d5 b5 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 c5 d5 b5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 c5 d5 b5 {15 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {187 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {99 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 a4 + c4 Bc2 Bd6 {20 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 a4 + c4 Bc2 Bd6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bd6 {-17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bc5 {8 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nc3 b5 Bd3 {15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + a3 b5 Bd3 {-263 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + a3 b5 Bd3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {-1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 Nc6 {36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bf4 d5 Nc3 {-10 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-58 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 Qb6 b3 Ne4 {-79 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 cxd4 {7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 h6 Bf4 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 h6 Bxf6 Qxf6 e3 Nc6 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 Nc3 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Nc6 {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O c5 Na3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O Na6 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 O-O Bd3 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 d5 {56 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {112 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 h6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e4 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e3 d5 Bd3 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c3 bxc3 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 Nc6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {-3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d3 Nbd7 Nbd2 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d4 Nbd7 Nc3 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d3 Nbd7 Nbd2 e5 h3 {-44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 Na3 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 O-O {6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 O-O {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 Nf6 Nc3 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 {35 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Nc3 e6 d4 cxd4 Nxd4 a6 Be3 Nf6 Nxc6 {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Nc3 e6 d4 cxd4 Nxd4 a6 Be3 Nf6 Nxc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Nc3 Nf6 Bc4 {-7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 d4 {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 Nc3 a6 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 Nc3 a6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 Nc3 O-O d4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nb5 Qe5 {91 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 Qd6 {44 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 Qd6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Bd7 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Bd7 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {27 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {44 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {33 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {58 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {-43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 e5 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 Nf3 h6 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 e5 {-38 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 Bxf6 gxf6 Kb1 b4 {39 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {-20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Be7 {-18 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Qb6 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bg7 {-4 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bd7 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {60 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Nxd4 + {-28 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Bd7 + O-O-O O-O Rhg1 {2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Bd7 + O-O-O O-O Rhg1 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Be6 {-2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Be6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Bg5 Be2 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Bxf6 gxf6 Nd5 f5 Bd3 Be6 O-O Bg7 c4 {-111 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Bxf6 gxf6 Nd5 f5 Bd3 Be6 O-O {98 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O b5 Nxc6 + Qxc6 {-10 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bb4 + {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {-3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Qd2 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Bb4 {36 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 Bg5 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {-39 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 O-O Nxd4 Qxd4 Nc6 + Qd3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {-65 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 {-23 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 {7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bg5 Nf6 N1c3 a6 Na3 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bd3 {-32 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bd3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 Ng4 + Qxg4 {-12 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {-11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Qb6 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 d6 O-O + Bd7 Nb3 a5 a4 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 b6 O-O + Bb7 f3 Nxd4 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Bg5 {105 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Bg5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Bg5 Bg7 + Be2 O-O Qd2 Bd7 {25 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Bg5 Bg7 + Be2 O-O Qd2 Bd7 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Bg5 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Qd3 Be6 Bd2 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 a6 Nc3 d6 d4 cxd4 Nxd4 g6 Bc4 Bg7 Be3 Nf6 f3 b5 Bb3 + Bb7 a4 {-12 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 a6 Nc3 d6 d4 cxd4 Nxd4 g6 Bc4 Bg7 Be3 Nf6 f3 b5 Bb3 + Bb7 a4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 a6 d4 cxd4 Nxd4 Nf6 Nc3 e5 Nf3 Nc6 {5 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Be7 O-O O-O f4 + Nbd7 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Qd2 {48 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Be7 Na4 {25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Nc6 {21 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {-27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 e5 dxe5 fxe5 Nfd7 {-43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 f5 h6 {26 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {-96 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 Nc6 Be3 Bd7 {-21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {72 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Qb6 Be3 Qb7 Qg3 b4 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Bb7 {19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 e5 Nf3 Qc7 Bg5 Nbd7 a5 + {-11 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 e5 Nf3 Qc7 Bg5 Nbd7 a5 + {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Nxc6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Nxc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Be2 {-2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Be2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Be2 {3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 Nbd7 Be3 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 e5 {22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 e5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Be7 a5 + {-29 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Qa5 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 e5 Nb3 Be7 Bg5 {-21 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 e5 Nb3 Be7 Bg5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 Nc6 {-400 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Nxc6 + {16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Kh1 + Qb6 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Nc6 Nxc6 + {71 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Nc6 Qd2 + Bd7 {33 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 g5 {10 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {-32 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O O-O-O + Nxd4 Bxd4 Be6 Nd5 {-38 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O O-O-O + Nxd4 Bxd4 Be6 g4 Qa5 a3 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Bg5 Nc6 + Nxc6 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Bg5 Qb6 + {62 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Bg5 Qb6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 Nf6 Qa4 {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 Nf6 Qa4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 e6 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Nc3 {37 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Qe2 e6 b3 Be7 Bb2 O-O + c4 Ng4 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O {-12 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O Nf6 e5 dxe5 Nxe5 {50 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 {22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-61 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Nc6 Bb5 Bd7 Qe3 {162 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Nc6 Bb5 Nf6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 Bg5 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 Bg5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 f4 {15 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 {173 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 a6 Be3 {-6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 a6 Be3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 Nf6 Bc4 Nc6 Bb3 Nxd4 {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 d4 Nf6 Bf4 {26 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 d4 Nf6 Be2 Nc6 Bg5 {-25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 d4 Nf6 Be2 Nc6 Bg5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-33 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb6 Na3 {-8 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb6 Na3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bb4+ {3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Nf6 O-O d6 Nc3 Be7 {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Nf6 Nc3 Qc7 Bg5 {0 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Nf6 Nc3 Qc7 Bg5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Nf6 Nc3 Bb4 Bd2 Bxc3 {14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Nf6 Nc3 Bb4 Bd2 Bxc3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 g6 d4 Bg7 dxc5 Qa5+ {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 g6 d4 Nf6 {13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 g6 d4 Nf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 g3 Nc6 Bg2 e5 Nc3 {-35 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 g3 Nc6 Bg2 e5 O-O {13 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d6 d4 Bg4 c4 Nd7 Nc3 e5 {120 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d6 d4 Bg4 c4 Nd7 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d6 d4 Bg4 c4 Nd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d6 d4 Bg4 e4 d5 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d6 d4 Bg4 e4 Nc6 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d6 d4 Bg4 e4 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d6 d4 g6 Nc3 Bg7 e4 Nf6 e5 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d6 d4 g6 g3 Nf6 Bg2 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 b3 Bf5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 b3 Bf5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 b3 Nc6 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 c6 d4 e6 cxd5 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 c6 d4 e6 Qc2 dxc4 Qxc4 Nf6 g3 Na6 {41 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 Bg4 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 Bg4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 e6 d4 Nbd7 Qc2 Bb4 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 d4 Qa4+ {102 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 d4 e3 Nc6 exd4 Nxd4 Nxd4 Qxd4 Nc3 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 d4 e3 Nc6 exd4 Nxd4 Nxd4 Qxd4 Nc3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 Qb3 Na5 Qa4 {-56 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 Qc2 {24 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 d4 Ne4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 d4 Ne4 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 d4 Ne4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 d4 c5 c4 dxc4 Qa4+ {142 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 d4 c5 c4 dxc4 Qa4+ {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 d4 c5 c4 e6 cxd5 exd5 Nc3 Nf6 g3 Nc6 Bg2 Be6 O-O {33 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 g3 Bg4 Bg2 e6 {-51 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 g3 Bg4 Bg2 Nc6 {63 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 g3 c6 Bg2 Bg4 d4 {42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 g3 c6 Bg2 Bg4 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 g3 c6 Bg2 Bg4 O-O Nf6 d3 Nbd7 Nbd2 e5 h3 Bh5 e4 {-41 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 g3 c6 Bg2 Bg4 O-O Nf6 d3 Nbd7 Nbd2 e5 h3 Bh5 e4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 g3 c5 Bg2 Nc6 d4 e6 Nc3 {64 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 d5 g3 c5 Bg2 Nc6 d4 e6 Nc3 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 d5 g3 c5 Bg2 Nc6 d4 cxd4 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 e6 d4 Nf6 Nc3 {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 e6 d4 Nf6 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 e6 d4 Nf6 Bg5 Nc6 {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 f5 g3 Nf6 Nc3 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 f5 g3 Nf6 Bg2 Na6 {18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 e5 {-35 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 Nf6 e4 O-O Be2 c5 O-O cxd4 Nxd4 Bd7 Be3 + Nc6 Rc1 Nxd4 Bxd4 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O Bg4 Be3 Nc6 Qd2 e5 d5 + Ne7 Bh6 {40 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O Bg4 Be3 Nc6 Qd2 e5 d5 + Ne7 Rad1 Bd7 Ne1 Kh8 Nf3 Kg8 Ng5 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 e5 {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 e5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 Re1 Nbd7 Bf4 Nb6 {-78 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 h3 O-O Be3 d5 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 h3 O-O Be3 d5 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + b3 e5 Bb2 Nc6 e3 Bd6 {-4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + b3 e5 Bb2 Nc6 e3 Bd6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + b3 e5 Bb2 Nc6 e3 d5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 c5 g3 e5 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 c5 g3 d5 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 d4 {-15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 d5 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 d5 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 d5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 exd5 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 d6 {-420 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 d6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Nf3 Bxc5 Bf4 Nc6 e3 d5 a3 + {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Nf3 Qa5 {58 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 Bf4 {-29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 Bf4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 Bxf6 {9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 Bxf6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {39 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Be3 + {-43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Bh4 + g5 {63 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {17 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 Nxd4 Bxc3+ {68 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 Nxd4 Bxc3+ {-300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 {2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Qc2 {-3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Bd3 e5 Qc2 g6 {-16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 cxd4 exd4 Nb6 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 cxd4 exd4 Nb6 {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 Nf3 {13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 e3 Qa5 Bd2 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 e3 Qa5 Bd2 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Be7 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Be7 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 a3 Be7 Nf4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 O-O O-O + Rb1 {-18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 O-O e5 Ng5 + {36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 O-O e5 Ng5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 {-23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 exd4 d5 {15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 exd4 d5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 O-O a3 Ba5 {39 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 Ne4 Bd2 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Qc2 {-39 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Nf4 {63 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Qc2 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Bd2 {110 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 Bxc3+ bxc3 {-6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 {7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 dxc4 Bxh7+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 c5 Bd3 d5 Qc2 {23 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 Nc6 Bd3 d5 O-O Bd7 {3 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 exd5 f3 {-3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 exd5 f3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 Nxd5 Qc2 {21 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 cxd4 + {-27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 cxd4 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 f5 + {-236 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 f5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 h6 {-21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 h6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 Bb4 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Nf3 Nbd7 c5 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Nf3 {22 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 Nc6 {37 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 Ne4 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 Bg4 {-24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 h6 {15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 h6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Be7 Nf3 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Be7 Nf3 Bf5 Bd3 Bxd3 + Qxd3 Nbd7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Bf5 Qf3 {14 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 e4 c5 e5 {-45 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 Nf3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 Nf3 d6 exd6 {22 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 Nf3 d6 exd6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 e4 d5 e5 Nfd7 d4 {-6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e6 e4 d5 e5 d4 exf6 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 O-O Bd3 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 d5 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 e4 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 e4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 Ba5 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O Re8 a3 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O Re8 a3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 O-O + b4 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 O-O + b4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 Be6 + b4 {-23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O Nf3 d6 {44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O Nf3 Nc6 O-O d6 {1 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Nf3 h6 {-1 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Nf3 h6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Nf3 h6 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 c5 d5 h6 Bd2 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 c5 d5 h6 Be3 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 Nc6 {242 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 Nc6 {-300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 e5 d5 {3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 O-O f3 c5 Be3 Nc6 dxc5 {-5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 O-O {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 g4 {-22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 h4 Bd7 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 {-28 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Bd7 {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Bd7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Nc6 {40 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 {-2 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 Nh5 Qd2 Na6 {19 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 Nh5 Qd2 Na6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Nge2 {30 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Qd2 {16 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 h6 Be3 e5 {12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 Nc6 Nge2 h6 {60 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c5 Be2 cxd4 Nxd4 Nc6 Nxc6 + {-6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c6 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 c5 d5 e5 {11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Be3 c5 {-73 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 O-O Be3 d6 f3 e5 d5 c5 g4 h6 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 O-O Be3 d6 f3 e5 d5 c5 g4 h6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 O-O Nf3 d5 cxd5 Nxd5 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 d5 cxd5 Nxd5 Bg2 {25 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 d5 cxd5 Nxd5 Bg2 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bg3 {44 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bg3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bg3 {52 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 Nxd5 Nxd5 Qxd5 Bxc7 Na6 + Bg3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 f3 {18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {40 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 O-O Ne2 Qd7 + {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 O-O Ne2 Qd7 + O-O b5 {4 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 Nc6 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 Nc6 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 c6 Nf3 d6 O-O Na6 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Be6 {102 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Be6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Bf5 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Bd3 O-O O-O a6 Qb3 {-5 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Bd3 O-O O-O Qc7 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 Nf3 bxc4 e3 {53 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 Nf3 Qa5+ {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 Nf3 Qa5+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e5 {56 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e6 {19 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 d6 e4 Bxf1 Rxf1 + {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 d6 e4 Bxf1 Rxf1 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 d6 e4 Bxf1 Kxf1 + Bg7 h3 Qa5 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 e6 Nc3 {39 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 d6 Nc3 Bd7 {53 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Bg4 {23 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O h3 Na6 Nf3 Nb4 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Re8 Qc2 Qe7 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Qb6 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 exd4 {55 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 exd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 exd4 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Nc6 {-11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Nc6 {80 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Nc3 Bxc3+ {82 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Bd2 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 {-36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Bc6 Nf3 Bd5 Qa4+ Bc6 + Qc4 Bd5 Qa4+ {1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Bc6 Nf3 Bd5 Qd3 Na6 + {-45 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e5 {40 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 e5 dxe5 Ng4 Nf3 Bc5 e3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 e5 dxe5 Ng4 Nf3 Bc5 e3 Nc6 {26 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 e5 dxe5 Ng4 Nf3 Bc5 e3 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 Nxc3 bxc3 O-O Qb3 {-23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 g6 g3 c6 Nf3 Bg7 Nc3 {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 d4 g6 g3 c6 Nf3 Bg7 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 d4 g6 g3 c6 Nf3 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 Nf6 g3 c6 Nc3 {41 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 Nf6 g3 c6 Nf3 Na6 {120 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 b6 Nf3 Nf6 Nc3 Bb7 d4 e6 Bf4 Bb4 Qb3 {17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 b6 Nf3 Nf6 g3 Nc6 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 d4 d5 e3 Nf6 Nc3 e6 Nf3 Bd6 c5 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 d4 d5 e3 Nf6 Nc3 Bf5 cxd5 cxd5 Qb3 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 d4 d5 e3 Nf6 Nc3 Bf5 cxd5 cxd5 Qb3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 {175 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 {-68 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 Nxd5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 {-22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 Ne5 Qd4 {14 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 Ne5 Qd4 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 Bf6 Ne5 {-9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 Bf6 Ne5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Bd2 O-O + {13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Bd2 Nc6 + Bd3 Nf6 O-O Nxd4 {46 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 c5 {-33 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 c5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 cxd5 {36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c5 Nc3 Nc6 Nf3 g6 d4 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c5 Nc3 Nc6 g3 Nf6 Bg2 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 Nh6 {113 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 Nh6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 d6 O-O Nf6 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 d3 {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 d3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 Rb1 {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 Rb1 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 Nf6 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 d6 {-129 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 d6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 {67 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 Bf5 Nge2 Bg6 {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e6 d4 Bb4+ Bd2 Qe7 Nf3 Nf6 Nc3 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 {-30 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 O-O Nc3 d6 {-17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 O-O Nc3 d6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 Nc6 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 Nf3 f5 d4 {30 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 Nf3 f5 d4 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 Nf6 Nf3 O-O O-O d6 d3 Bf5 {-3 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 Nf6 Nf3 O-O O-O d6 d3 Bf5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 Nf6 Nf3 d6 O-O O-O d3 Bd7 {12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Nf3 Nge7 {-3 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Nf3 Nge7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Rb1 Nf6 Nf3 O-O O-O Bd7 {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 h5 d4 h4 d5 Nce7 e4 {-14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 h5 d4 h4 d5 Nce7 e4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 Bg4 {65 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Bb4 {100 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 Bb4 Nd5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 Bb4 Nd5 {-39 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 Bb4 Nd5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 Nc3 d6 g3 g6 Nf3 {-14 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 Nc3 d6 g3 Nc6 Bg2 Nf6 d3 {3 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 g3 Nf6 Bg2 Bc5 {-2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 e5 g3 Nf6 Bg2 Bc5 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 g3 Nf6 Bg2 d5 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 e5 g3 Nf6 Bg2 d5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 f5 Nf3 {-4 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 f5 d4 Nf6 g3 d5 {15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 f5 d4 Nf6 g3 d5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 dxe5 Bxe5 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 g6 Nc3 Bg7 g3 Nf6 d4 O-O Nf3 d5 cxd5 Nxd5 {-36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 g6 Nc3 Bg7 g3 Nf6 Bg2 Nc6 Nf3 d6 O-O O-O d3 Bd7 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + c4 g6 g3 Bg7 Bg2 Nf6 Nc3 O-O d4 Nc6 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 g6 g3 Bg7 Bg2 Nc6 {-141 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + c4 g6 g3 Bg7 Bg2 Nc6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 Nf6 Nc3 d5 Bg5 c6 Nf3 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 Nf6 Nc3 d5 Bg5 Bf5 Bxf6 {11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 Nf6 Nc3 d5 Bg5 Bf5 Bxf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 Nf6 Bg5 Ne4 Bf4 d5 f3 Nf6 Nc3 {-31 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 Nf6 Bg5 Ne4 Bf4 g5 {22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 c5 d5 Nf6 Nc3 d6 e4 g6 Nf3 Bg7 e5 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 c5 d5 Nf6 Nc3 {-320 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 c5 d5 Nf6 Nc3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 c4 e5 Nf3 Nd7 Nc3 g6 dxe5 {-2 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 c4 e5 Nf3 exd4 Nxd4 Bd7 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 Bg4 h3 Bh5 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 Bg4 h3 Bh5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 Bg4 h3 Bh5 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 Be3 Bg7 h3 c6 {-15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 Be3 Nc6 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Bg7 e5 {101 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Bg7 e5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Nc6 {-41 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 c5 dxc5 {123 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 c5 dxc5 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 e5 Nd7 {81 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 e5 dxe5 {-51 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 e5 dxe5 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 e5 {-5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 e5 dxe5 fxe5 Nd5 Nxd5 + Qxd5 c3 {15 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 e5 dxe5 fxe5 Nd5 Nxd5 + Qxd5 c3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 d5 {140 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 h3 {-115 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 f3 e6 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 Nf6 f3 e6 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 g6 Nc3 Bg7 Be3 c6 Nf3 Nf6 Bd3 {14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d6 e4 g6 Nc3 Bg7 Be3 c6 Nf3 Nf6 Bd3 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d6 e4 g6 Nc3 Bg7 Be3 Nf6 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d5 Bg5 c6 Nf3 Qb6 b3 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 Bg5 h6 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 Bg5 h6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 {35 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 Nbd7 Nf3 e6 Nc3 Be7 Bd3 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 Nbd7 {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 Nbd7 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nb6 Bb5+ {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nc6 Ne2 Nb6 Bd3 Be6 Nbc3 Qd7 + Ne4 {24 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nc6 Ne2 Nb6 Bd3 Be6 Nbc3 Qd7 + Ne4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Bc5 {30 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Bb4+ Bd2 Bxd2+ Nbxd2 Nc6 O-O + Nf6 e5 Ng4 h3 Ngxe5 {79 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 Nf3 f5 Nc3 {36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 Nf3 f5 c4 Nf6 Nc3 Bb4 Qb3 a5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 Ne2 dxe4 a3 Be7 Nxe4 Nf6 N2c3 {0 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 Ne2 dxe4 a3 Bxc3+ Nxc3 Nc6 Bb5 {-16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 exd5 exd5 Nf3 Ne7 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 exd5 exd5 Qf3 Nc6 Bb5 {114 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {53 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 Qc7 Qxg7 Rg8 + Qxh7 cxd4 Ne2 Nbc6 f4 dxc3 Nxc3 {-7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 Qc7 Qxg7 Rg8 + Qxh7 cxd4 Ne2 Nbc6 f4 dxc3 Qd3 Nf5 {34 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Bd7 Bg5 {-31 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Bd7 Bg5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Nbc6 Be2 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 O-O {12 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 O-O {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 Bd7 {-18 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 Bd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 Nf3 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 Qg4 g6 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Bf4 {22 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Bf4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Qg4 {113 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Qh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Nb5 {-3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Bb4 e5 h6 exf6 hxg5 fxg7 Rg8 Qh5 {-5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Nf3 h6 Nxf6+ Nxf6 Be3 + {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Nf3 h6 Nxf6+ Nxf6 Bd2 + {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 {22 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 O-O Qd2 {33 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 O-O Qd2 {300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bb4 {-39 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bc5 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bc5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nc3 {88 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nc3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Ne5 {-44 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Be2 f6 exf6 Qxf6 Nf1 {30 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {-22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Nb4 {-62 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Nb4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 {480 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Ba7 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Ba7 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {373 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {-104 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O cxd4 {-5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O Qb6 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Nxd5 {218 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Nxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Qxd5 Bc4 {36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 Be3 {-28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 Bb3 {3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ {68 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 exd5 exd5 Nf3 Bg4 {-20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 exd5 exd5 Nf3 Nc6 Bb5 Nf6 {-36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 Nge7 dxc5 {-43 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 f6 O-O Qb6 dxc5 Bxc5 b4 + Be7 Bf4 {51 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4 Nbd2 Na5 Rb1 {-11 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4 Be2 Bd7 O-O Nge7 Nbd2 + Na5 Rb1 Qc7 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 f5 Nf3 Nf6 g3 e6 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 f5 Nf3 Nf6 g3 Nc6 {-10 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 f5 Nf3 Nf6 g3 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 f5 g3 Nf6 Bg2 g6 Nc3 {-33 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 f5 g3 Nf6 Bg2 g6 c4 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 f5 g3 Nf6 Bg2 g6 c4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + d4 g6 e4 Bg7 Nc3 c6 Nf3 d5 exd5 cxd5 Ne5 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + d4 g6 e4 Bg7 Nc3 c6 h4 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nc6 Nf3 d5 {107 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nc6 Nf3 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 Nc6 Nf3 Nf6 e5 {0 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nf6 Nc3 d5 exd5 Nxd5 Ne4 {-25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 Nf6 Nc3 d5 exd5 Nxd5 Bc4 e6 Qf3 Nb4 Bb3 N8c6 Nge2 Na5 {66 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 h3 Bh5 Nc3 + O-O exd6 cxd6 Bd3 {-21 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 Nc3 {-23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 Nc3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Ng5 e6 f4 dxe5 fxe5 + c5 Qf3 {48 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Ng5 e6 f4 dxe5 fxe5 + c5 Qf3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Ng5 e6 f4 Nc6 {7 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 dxe5 fxe5 Nc6 Nf3 Bg4 Be3 e6 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 dxe5 fxe5 Nc6 Nf3 Bg4 Be3 e6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 Bf5 {-32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {321 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 f5 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 Nf6 Nxf6+ exf6 g3 {-92 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d3 d5 Nd2 e5 Ngf3 Bd6 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d3 d5 Nd2 e5 Ngf3 Bd6 {32 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 c3 {25 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 a4 Bd6 {-42 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 a4 Bd6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 Nbd7 Ngf3 Qc7 O-O {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 {-74 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Bc4 {61 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Bc4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Bc4 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 Nf3 Nd7 Nh4 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 Nf3 Nd7 Bd3 Qa5+ {-11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 Ngf6 O-O-O O-O-O {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 Ngf6 O-O-O O-O-O {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 e6 O-O-O Ngf6 Ne4 O-O-O g3 Nxe4 Qxe4 Nf6 Qe2 + {57 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 Bd2 Qb6 {-13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 Bd2 e6 O-O-O Ng4 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qc7 O-O-O {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qc7 O-O-O {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qb6 {62 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 {82 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 Bf5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 Bg4 Be2 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Nf3 Bg4 {-23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Nf3 Bg4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Bc4 {18 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {456 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Nd7 {-76 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Bb4 {-64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Bb4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Na6 {79 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Na6 {22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Na6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 Nge2 e5 Ng3 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 Nge2 e5 Nd5 Nf6 {83 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d6 Bb5 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d5 {-74 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d5 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Be3 e6 Nf3 {-18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Be3 Nf6 {-44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O Be3 + Qb6 {6 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O Be3 + Qb6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nd4 {-18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nf6 d4 cxd4 Nxd4 Qb6 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 d6 g3 g6 d4 {18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Nc3 d6 g3 g6 d4 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Nc3 d6 g3 Nc6 Nf3 Nf6 Bg2 {9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 Ne2 Nf6 Nbc3 d5 e5 {-42 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Ne2 Nf6 Nbc3 e5 {11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 Ne2 Nf6 Nbc3 e5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 Bc4 Nb6 Bb3 d5 cxd4 Bg4 Nc3 + {8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 Bc4 Nb6 Bb3 dxc3 Nxc3 d6 + {23 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 c3 d5 exd5 Qxd5 d4 Nf6 Nf3 Bg4 Be2 cxd4 cxd4 Nc6 O-O Qd6 + Nc3 e6 Be3 {30 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Be3 cxd4 cxd4 Bb4+ Nc3 Qa5 + {-13 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Na3 Bd6 {-155 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Na3 Bd6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 c3 e6 d4 d5 exd5 Qxd5 Nf3 Nf6 Be3 cxd4 cxd4 Nc6 Nc3 Qd6 + Ne5 {-30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 c3 e6 d4 d5 exd5 Qxd5 Nf3 Nf6 Bd3 cxd4 cxd4 Nc6 Nc3 Qa5 + {2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 d4 {40 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 d4 cxd4 {32 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 c5 f4 d5 exd5 Nf6 c4 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 f4 d5 exd5 Qxd5 Nc3 Qe6+ {36 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 c5 f4 d5 exd5 Qxd5 Nc3 Qe6+ {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bf5 Ne5 c6 Bc4 e6 g4 {-30 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bf5 Ne5 c6 Bc4 e6 g4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bf5 Ne5 Nbd7 {83 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 d5 exd5 Nf6 d4 Nxd5 c4 Nf6 {32 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 d5 exd5 Nf6 d4 Nxd5 Be2 {38 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 d5 exd5 Nf6 d4 Nxd5 Be2 {-300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e6 d3 d5 Nd2 Nc6 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e6 d3 d5 Nd2 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Nxe4 {31 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Nxe4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Qf3 Bc5 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Bc4 Nf6 d3 c6 Bb3 {14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Bc4 Nf6 d3 c6 Bb3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Bd3 {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Nxd4 exd4 e5 dxc3 exf6 cxd2+ Bxd2 + Qxf6 O-O Be7 Bc3 Qg5 Re1 {-342 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Nxd4 exd4 e5 dxc3 exf6 cxd2+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 Qe7 + Qe2 {-6 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 Be6 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Bxe2 {-27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Bxe2 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Bxe2 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 Bxb4 c3 Ba5 Qb3 {-33 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 Bxb4 c3 Bd6 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Bc5 c3 Nf6 d3 d6 {-26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Bc5 c3 Nf6 d3 d6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 Ng5 d5 exd5 Nxd5 Qf3 {-54 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 Ng5 d5 exd5 Nxd5 d4 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Nc3 {-9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Bb3 d5 exd5 Nxd5 h3 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 Nxd4 {-6 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 O-O Nxe4 Re1 d5 Bxd5 Qxd5 Nc3 Qc4 + {18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 O-O Nxe4 Re1 d5 Bxd5 Qxd5 Nc3 Qc4 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {-1 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {2 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Bc5 c3 a6 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Bc5 c3 Nf6 d4 exd4 e5 {120 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Be7 d5 {-19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Bg5+ {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Rd1+ {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {-45 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 c5 Nf5 {-7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 c5 Nf5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 Ne7 Be3 Qd6 + {105 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 b5 Bb3 Bc5 a4 Rb8 axb5 axb5 + Nc3 O-O {-26 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 Bc5 {-35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 Nc3 Be7 O-O {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 Nc3 Be7 O-O {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 c3 b5 {18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 b5 Bb3 {46 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 b5 e5 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 O-O + Nc4 f6 Be3 {-13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 O-O + Nc4 f6 Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 {13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 bxa4 {-15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 Na5 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 Na5 {19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 Na5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 exd4 {-49 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 exd4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 Rc8 {63 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 Rc8 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 c5 {5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {-6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 axb5 + {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 d5 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 d5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 Nbd2 cxd4 cxd4 Bb7 Nf1 {-28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {17 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {12 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {-85 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Na3 {-12 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Na3 {300 5 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Nbd2 Bb7 Nf1 Kh8 {46 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 dxc5 dxc5 Nbd2 Bb7 Nf1 Kh8 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {38 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Be7 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Be7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Na5 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 cxd4 Nb4 Bb1 {-2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 cxd4 Nb4 Bb1 {-40 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 cxd4 Nb4 Bb1 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 Bxb3 axb3 exd4 Nxd4 {1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 Bxb3 axb3 exd4 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 {11 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 bxa4 {-22 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 bxa4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 Bb7 Na3 exd4 cxd4 Kh8 {30 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {-23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Nc6 {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Qc7 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Qc7 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 Bd5 + {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Bf3 + Qf1 Qxf1+ {68 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Nxe3 + Rxe3 Rae8 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 d4 {19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 c3 b5 Bb3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 cxd4 cxd4 {13 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Nbd2 + Nc5 c3 Bg4 Bc2 Be7 h3 Bh5 {-118 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Nbd2 + Nc5 c3 g5 {25 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + Be7 c4 {93 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + {19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Nxe4 {96 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Qe2 Nc5 Nd4 Nxd4 cxd4 {31 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Qe2 Nc5 Nd4 Nxd4 cxd4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 Bf5 Nxe4 {51 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 f5 Nb3 Bb6 Nfd4 Nxd4 Nxd4 Qe8 {37 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Ng5 {154 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Re1 Na5 {35 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 Re1 Na5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 d4 b5 dxe5 dxe5 Qxd8+ Nxd8 + Bb3 Bd6 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 d3 b5 Bb3 Bg4 {11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 exd4 Qxd4 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 Nf6 {24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 Nf6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 Nf6 d5 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 Nc3 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 c3 Nf6 Re1 b5 {3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 c3 Nf6 Re1 b5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 Bd7 dxe5 {66 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 exd4 Qxd4 Ne7 Bg5 {-47 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 exd4 Qxd4 Ne7 Bg5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 Nf6 exf5 Nd4 Bd3 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 Nf6 exf5 Nd4 Bd3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 O-O {18 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 O-O {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {-17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {-130 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Bc4 Bc5 Ng5 Nh6 Nxf7 Nxf7 Bxf7+ Kxf7 Qh5+ + g6 {-44 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Bc4 Qe7 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 f3 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 Bc4 Ne5 Be2 d5 + {22 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 e5 Qe7 Qe2 Nd5 Qe4 {74 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 e5 Qe7 Qe2 Nd5 Qe4 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 e5 Qe7 Qe2 Nd5 c4 Ba6 + Qe4 Qc5 {-110 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 e5 Qe7 Qe2 Nd5 c4 Ba6 + Qe4 Qc5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 Bg4 Nd4 Bxe2 Ncxe2 Nc6 {-5 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 O-O O-O-O {-34 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Be7 O-O Nc6 Re1 Bg4 + Bxe4 dxe4 Rxe4 Bxf3 Qxf3 Nxd4 {22 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Be7 O-O Nc6 Re1 Bf5 + Nbd2 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 Be6 cxd5 + Bxd5 {-35 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 Re8 {43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 Re8 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Bb4+ {3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Bb4+ {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Nc6 Nxc6 bxc6 Qe2 {125 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 d6 d4 Nd7 Nc3 {-7 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 Nf3 d6 d4 Nd7 Nc3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 Nf3 d6 d4 exd4 Nxd4 c5 {51 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 d4 exd4 Qxd4 Nc6 Qc4 {386 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 d4 exd4 Qxd4 Nc6 Qc4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 d4 exd4 Qxd4 Nc6 Qc4 {19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 f4 d5 exd5 exf4 Qe2+ {-51 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 f4 d5 exd5 Qxd5 {12 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 f4 exf4 Bc4 d5 exd5 {-23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 f4 exf4 Bc4 d5 exd5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 f4 exf4 Bc4 Qh4+ Kf1 Nc6 {61 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 f4 exf4 Nf3 g5 h4 {94 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + e4 e5 f4 exf4 Nf3 g5 h4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + e4 e5 f4 exf4 Nf3 g5 h4 g4 Ne5 h5 Bc4 Nh6 d4 {-81 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + f4 c5 Nc3 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + f4 c5 Nc3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + f4 Nc6 {10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + g3 c5 Nf3 b6 {-2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + g3 c5 Nf3 b6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + g3 c5 Bg2 Nc6 e4 Nf6 {-32 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + g3 c5 Bg2 Nc6 e4 Nf6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + g3 d5 Bg2 e5 d4 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + g3 d5 Bg2 Nf6 Nf3 Nc6 {16 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + g3 e5 d4 {-30 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + g3 e5 Bg2 d5 c4 {2 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + g3 g6 Bg2 Bg7 d4 Nf6 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + g3 g6 Bg2 Bg7 e4 Nc6 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d6 {100 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d5 Ne5 Nbd7 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Qc8 {39 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Be2 b4 {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 e6 d4 Nbd7 Bd3 dxc4 Bxc4 b5 Be2 b4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {57 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {7 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {-32 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O e4 Bg6 e5 Nd5 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + Ne4 g4 {-21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {-26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 Qc2 dxc4 Bxf6 + Nxf6 {-45 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {-2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 Bb4 O-O + {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 dxc4 Bxc4 + Nb6 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {79 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + Be7 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {27 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {135 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 Nb6 {4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Qb6 Be4 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {-58 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 e6 Nc3 Bd6 {20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {37 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Ne5 Bb4 {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Ne5 Bb4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {-11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 e6 e3 Bd6 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 e6 Nh4 {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 Nbd7 {42 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 dxc4 Bxc4 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 Na6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 Na6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 {-14 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 {29 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 a6 Ne5 {-22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 c4 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Be3 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Be3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {-30 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 Ng5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 b6 d4 cxd4 Nxd4 e5 {6 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 b6 d4 cxd4 Nxd4 e5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 cxd4 e6 e4 Nc6 + a3 {-14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {43 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 e4 Nxc3 dxc3 Qxd1+ Kxd1 Nc6 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 g6 d4 {-30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 e6 Bg2 Nc6 O-O Be7 d4 Qa5 {41 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Be2 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Bd3 cxd4 exd4 dxc4 Bxc4 Bd6 + O-O O-O Re1 {13 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Bd3 cxd4 exd4 dxc4 Bxc4 Bd6 + O-O O-O Re1 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + Qxd5 {40 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + Qxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + Qxd5 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 g6 d4 cxd4 Nxd4 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 Nc3 g6 d4 cxd4 Nxd4 d6 e4 Nc6 Be2 Bd7 {-28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bc5 {146 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 {24 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Nc3 g6 d4 {-31 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 e6 O-O Be7 d4 Nxc3 + bxc3 {36 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 d6 Nc3 {-5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 d6 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 d6 Nc3 {12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O d4 d5 {-22 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O {8 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 e5 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 Qe2 Na6 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 Ne4 Qc2 Nxc3 bxc3 {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 O-O O-O d5 Ne5 Nbd7 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 c5 dxc5 {-25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 dxc4 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 Qc2 Re8 cxd5 + exd5 Bd3 h6 {47 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 c5 {8 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {-15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {86 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {-168 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {-10 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Qxd4 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 c5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {71 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Qb3 + Nxc3 bxc3 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Bd3 + Nxc3 bxc3 Nc6 {21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 cxd5 + Nxd5 Bxe7 Qxe7 Bd3 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O Re8 Qd3 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 cxd5 {-19 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 Rc1 dxc4 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {36 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 Qa4+ Nc6 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Bxc3+ {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Qxf6 Qb3 {6 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Qb6 {-31 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Qb6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Nf6 Be3 {31 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Bxd2+ Qxd2 O-O Bc4 Nd7 O-O Nb6 {54 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Qa5 {33 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {82 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {29 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e4 Bb4 Bg5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {32 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-5 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {67 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 Be7 e3 d5 Bd3 {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 O-O a3 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 {18 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 O-O Nc3 d5 e3 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 h6 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 {-24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 Bxd2+ {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 Bxd2+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 e3 d6 {23 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 Be7 e3 c5 {18 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 h6 {31 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {64 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 dxc4 {19 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Bd6 + {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 Qxc3 f6 + {14 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 Qxc3 f6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + c5 Bb5+ {-16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {20 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 Nxg3 hxg3 g4 {72 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 Nxg3 hxg3 g4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 f5 {-172 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 c5 Bf4 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 Ba5 {43 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {-28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {11 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-58 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O dxc4 Bxc4 a6 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {-185 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-9 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 Bd6 {-1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {30 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 d6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qa4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qb3 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bd6 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bb7 Bg2 {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {-14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Qe7 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O {27 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O e4 d5 cxd5 + Bxf1 Rxf1 {-19 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O e4 d5 cxd5 + Bxf1 Rxf1 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {13 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 cxd5 {-24 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 Nxd7 Nd2 O-O O-O {19 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {-22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Bg5 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Bd2 Nc6 e3 O-O {44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Nh5 + {23 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Nh5 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 Qxc3 {-20 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 e4 O-O Be2 + Re8 O-O a6 {5 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 e4 O-O Be2 + Re8 O-O a6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 Qe7 {-9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 Qe7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 a6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-9 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-64 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {24 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 {-9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 {-31 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + Bc6 Nxc6 Nxc6 e3 Na5 Nd2 c6 {3 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Ne5 + Bc6 Nxc6 Nxc6 e3 Na5 Nd2 c6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ {-1 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {-28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {-7 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {2 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-22 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O {-13 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {4 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {26 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Re8 f3 Ne5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Ne5 {21 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 {29 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + exd4 Nxd4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 h3 {55 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 h3 {50 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + c6 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {180 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Re8 Nd5 Nxd5 cxd5 {23 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 {100 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 O-O Nc5 Qc2 + Bd7 {33 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 O-O Nc5 Qc2 + Bd7 {-300 3 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {43 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 Rb1 f5 b4 Kh8 {-3 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 Rb1 f5 b4 Kh8 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 {0 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 {128 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 c5 Bd7 {34 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {2 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {16 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 a5 {-11 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {49 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 Bg7 Bf4 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 {9 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {-13 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O e3 c6 h3 {16 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qa4+ {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 h6 + {2 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {96 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Qb3 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + Qb3 Nb6 {58 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + Be2 Nb6 Qd3 Nc6 Rd1 {-80 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + Be2 Nb6 Qd3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {35 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 cxd4 + {17 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Rb1 O-O + Be2 Nc6 Be3 {-18 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 e4 {-21 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Bc4 Nb6 Bb3 Nc6 + {25 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d6 Qb3 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d5 cxd5 Nxd5 {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Bf4 {-46 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Qc2 {-33 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 Qb3 {-8 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 b3 {8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Nxd4 + Ne5 {118 5 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Nxd4 + Ne5 {300 5 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Qxd4 + {37 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Qxd4 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 e5 {-14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 Bd7 {-12 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 Bd7 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 {-25 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 e4 Bd7 + {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 e4 Bd7 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {14 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {46 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + Be3 {-12 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + Be3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {60 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 {67 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 d5 Na5 {-11 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 c5 d5 b5 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 c5 d5 b5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 c5 d5 b5 {15 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 exd4 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {187 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {99 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {28 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 Nc3 + Nbd7 Rd1 Qc7 e4 cxd4 Nxd4 b4 {51 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bd6 {-17 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bc5 {8 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nc3 b5 Bd3 {15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nbd2 O-O Nb3 {24 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {-12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 Nc6 {36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 d5 e3 Nc6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bf4 d5 Nc3 {-10 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-58 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bf4 Bb4+ {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 h6 Bxf6 Qxf6 Nbd2 cxd4 Nxd4 {-5 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 h6 Bxf6 Qxf6 Nbd2 cxd4 Nxd4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 cxd4 {7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 h6 Bf4 {-13 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 Bg5 h6 Bxf6 Qxf6 e3 Nc6 {15 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {2 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b6 {1 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Nc6 {33 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O c5 Na3 {-19 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O Na6 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {12 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 O-O Bd3 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {16 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 d5 {56 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {112 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bf5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 h6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e4 {-11 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e3 d5 Bd3 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-8 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-25 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c3 bxc3 {8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 Nc6 {14 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {-3 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {14 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d3 Nbd7 Nbd2 {22 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d4 Nbd7 Nc3 {-8 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d4 Nbd7 Nbd2 {34 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 {-3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 {8 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 Nf6 Nc3 Bg7 f3 O-O e4 Nc6 Be3 d6 Nxc6 + {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 {35 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Nc3 Nf6 d4 cxd4 Nxd4 d6 Bb5 {-16 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Nc3 Nf6 Bc4 {-7 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O {-1 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 Nc3 a6 {-6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 Nc3 O-O d4 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-36 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 a6 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nb5 Qe5 {91 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nb5 Qd8 {10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nb5 Qd8 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {-4 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Nxd4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Bd7 {29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Bd7 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + {27 0 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-15 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {5 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 Ne4 Nxe4 Bxe4 + Bf4 {-10 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d5 Ne5 Nbd7 {29 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-16 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-244 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {20 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {24 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nc6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {-10 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {9 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 {-2 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 d4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-7 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Qc8 {39 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 {32 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 cxd5 d4 Nc6 Bf4 {21 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 cxd5 d4 Nc6 Bf4 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {57 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 cxd5 {20 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {7 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + gxf6 Nxc4 {300 6 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {-32 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Bg5 h6 Bxf6 + {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O e4 Bg6 e5 Nd5 {-17 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + Ne4 g4 {-21 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {3 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 e5 Nd5 {15 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {-26 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 Qc2 dxc4 Bxf6 + Nxf6 {-45 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Rg8 {0 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {28 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 Bb4 O-O + {-5 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 dxc4 Bxc4 + Nb6 {30 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {28 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {0 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {79 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {44 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + Be7 {-15 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {27 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 Nc5 {135 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {5 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {-14 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {-11 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {46 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-29 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {69 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {134 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + Nc6 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + Nc6 {-8 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {-14 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {39 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {120 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {-11 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {10 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 O-O {25 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 b3 g6 Bb2 Bg7 e3 Nc6 {11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 Ne4 Qc2 Nxc3 Qxc3 + c5 dxc5 {-18 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d5 Ne5 Nbd7 {39 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 Nc3 O-O d4 d5 Ne5 Nbd7 {-300 6 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {-9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 c5 dxc5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Nxe4 Bxe4 + Ne1 Bxg2 Nxg2 d5 Qa4 Qd7 {62 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {134 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {30 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Bd2 Nxd2 {-300 3 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Nd7 {-16 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 Bb7 Bg2 e6 O-O Be7 d4 O-O Nc3 Ne4 Qc2 Nxc3 Qxc3 + c5 Rd1 d6 b3 Bf6 Bb2 Na6 {42 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 O-O Bb2 d6 Qc2 + {-17 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 b3 {6 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-13 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-143 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 Be7 d4 cxd4 Qxd4 d6 Rd1 + {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 {-10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 {-64 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O e6 Nc3 a6 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-13 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 b6 g3 c5 Bg2 Bb7 O-O g6 b3 Bg7 Bb2 O-O Nc3 Nc6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 cxd5 d4 e6 Bf4 Nc6 e3 Nh5 Bg5 Qb6 {132 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 Nc3 d5 cxd5 cxd5 d4 e6 Bf4 Nc6 e3 Nh5 Bg5 Qb6 {-300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 Nc3 d5 e3 dxc4 {36 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 c5 e6 {184 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 c5 e6 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 a6 c5 Bf5 {28 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 e4 Bxe4 fxe4 + Nxe4 Nxf7 {-62 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 Ne5 e6 f3 Bb4 Nxc4 O-O Bg5 + h6 Bh4 c5 dxc5 Qxd1+ Rxd1 Nd5 {13 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O e4 Bg6 Bd3 c5 {128 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + O-O e4 Bg6 Bd3 c5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O Nbd7 Qe2 + Ne4 Nxe4 Bxe4 Rd1 {18 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg4 {-18 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 Bd3 c5 {0 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 dxc4 a4 Bf5 e3 e6 Bxc4 Bb4 O-O O-O Qe2 + Nbd7 e4 Bg6 Bd3 c5 {-300 7 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 Bb4 cxd5 {-26 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 Nbd7 e3 Qa5 Nd2 dxc4 Bxf6 Nxf6 + Nxc4 {49 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {42 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 dxc4 e4 b5 e5 h6 Bh4 g5 Nxg5 hxg5 + Bxg5 Nbd7 Qf3 Bb7 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 Bb4 a3 + {0 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 Bg5 h6 Bxf6 Qxf6 e3 Nd7 Bd3 dxc4 Bxc4 + Qg6 {20 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bb4 {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 cxd5 exd5 Bg5 Bd6 {-2 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Nb6 {44 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Qc2 Bd6 Be2 O-O O-O dxc4 Bxc4 + Qc7 {25 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + Be7 {14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 Bb7 O-O + b4 Ne4 Nxe4 Bxe4 Qc7 {69 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 c4 Bc2 b4 {72 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 d5 exd5 {-1 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb4+ {94 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb4+ {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Nc3 e6 e3 Nbd7 Bd3 dxc4 Bxc4 b5 Bd3 a6 e4 + c5 e5 cxd4 Nxb5 axb5 exf6 Bb7 {1 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 e6 cxd5 exd5 Nc3 Na6 a3 Nc7 Bg5 g6 e4 + {-67 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 Qc2 dxc4 Qxc4 Na6 {14 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Qb3 {3 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {45 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 Bf5 e3 e6 Bb5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 {-48 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 cxd5 cxd5 Nc3 Nc6 Bf4 {6 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 Nc3 e6 Nh4 {-6 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 e3 Bf5 cxd5 cxd5 Qb3 Qc8 Bd2 Nc6 {23 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 Bd6 {-4 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c6 d4 d5 e3 e6 Bd3 Na6 {-4 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {-72 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 d4 cxd4 Nxd4 e6 g3 Qb6 Nb3 {4 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 {-29 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 a3 a6 {26 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 a6 Ne5 {-19 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 a6 Ne5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 e3 e6 d4 d5 cxd5 exd5 Be2 c4 {69 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 e5 O-O Be7 Be3 + {-3 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nc7 d3 Nd5 {107 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 b6 e4 d6 e5 {-34 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 {32 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 cxd4 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 e4 Nxc3 {23 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 g6 Nxd5 {-27 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 g6 Nxd5 {-300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 d5 cxd5 Nxd5 g3 Nc6 Bg2 Nxc3 {60 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 Bd3 Bd6 cxd5 {-26 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 e6 e3 Nc6 d4 d5 cxd5 exd5 Be2 c4 {57 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + exd5 dxc5 Bxc5 Qc2 Be7 {-20 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 e6 g3 d5 cxd5 Nxd5 Bg2 Nc6 O-O Be7 d4 O-O Nxd5 + Qxd5 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 g6 d4 cxd4 Nxd4 Bg7 e4 O-O {-33 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 d6 Be2 Bg7 d4 cxd4 Nxd4 Nc6 Be3 Bd7 O-O + O-O f4 {34 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 Nc3 g6 e4 d6 Be2 Bg7 d4 cxd4 Nxd4 Nc6 Be3 Bd7 O-O + O-O f4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 Qa5 + {15 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 Nc3 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 Qa5 + {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 e3 e5 {14 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 d4 cxd4 Nxd4 e6 e3 e5 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 d3 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 c5 g3 d5 cxd5 Nxd5 Bg2 Nc6 Nc3 Nxc3 {36 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 d6 Nc3 e5 d4 {-17 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 d6 Nc3 {36 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O {-21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 Bb4 Qc2 O-O {6 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 e5 {0 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 e5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 b6 e4 Bb7 Qe2 Na6 {22 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 Ne4 Qc2 Nxc3 Qxc3 O-O + O-O c5 dxc5 {-27 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 b6 g3 Bb7 Bg2 Be7 d4 Ne4 Bd2 Nxd2 {10 14 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 h6 Bh4 Re8 {-7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 h6 cxd5 {-51 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Qc2 h6 cxd5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 Qc2 {-21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 a6 c5 {9 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {85 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {300 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 Bg5 Be7 e3 O-O Rc1 c6 Bd3 dxc4 Bxc4 + Nd5 Bxe7 Qxe7 O-O {46 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 {-6 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Nbd7 cxd5 exd5 Bf4 c6 e3 Be7 h3 {15 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 cxd5 + {-80 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bf4 O-O e3 c5 dxc5 Bxc5 Qc2 Nc6 a3 + {43 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 Qe7 Qc2 {-4 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bxf6 Bxf6 e3 O-O Rc1 c6 Bd3 + Nd7 O-O dxc4 Bxc4 e5 Ne4 exd4 Nxf6+ Nxf6 Nxd4 Bd7 {148 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 Ne4 Bxe7 Qxe7 + cxd5 {17 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {-15 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O Rc1 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Qc2 + Nxc3 {-30 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Qc2 + Nxc3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 Ne4 Bxe7 Qxe7 Qc2 + Nxc3 Qxc3 Nc6 {15 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {372 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Rc1 Bb7 Bd3 + dxc4 Bxc4 {54 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O Re8 Qb3 {-14 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Be2 Bb7 Bxf6 + Bxf6 cxd5 exd5 O-O c5 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 cxd5 {-17 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 Bd3 Bb7 O-O + Nbd7 Rc1 dxc4 {27 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {-16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Be7 Bg5 h6 Bh4 O-O e3 b6 cxd5 Nxd5 Bxe7 + Qxe7 Rc1 Bb7 Bd3 {31 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 {0 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 Bg5 h6 Bxf6 Qxf6 e3 dxc4 {59 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Bxc3+ {-24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 Bb4 cxd5 exd5 Bg5 h6 Bxf6 Qxf6 Qb3 {9 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 Be7 O-O O-O Nxd5 + Qxd5 e4 Qd7 {-4 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Nf6 Ne4 {13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e3 Nc6 Bd3 cxd4 exd4 Bb4 + Bd2 Nf6 Ne4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Bxd2+ Qxd2 O-O Be2 {-28 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 c5 cxd5 Nxd5 e4 Nxc3 bxc3 cxd4 cxd4 Bb4+ + Bd2 Be7 {43 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e3 a6 Bxc4 Bd6 {-11 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 Nc3 d5 d4 dxc4 e3 Nbd7 {0 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {-41 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 b6 a3 Bxd2+ Bxd2 {4 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {-47 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 {7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 d5 Qa4+ Nc6 a3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O e3 d5 a3 {6 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Nbd2 O-O a3 Be7 e3 d5 Bd3 {-73 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 d5 a3 Bxc3 Bxc3 {6 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 d5 a3 Bxc3 Bxc3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 {4 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Qe7 g3 Nc6 Nc3 {-300 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 Nc6 {15 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 Nc6 {-16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 {-20 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 c5 {23 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 a5 g3 d6 Bg2 c5 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 Nbd2 {-6 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 Bb4+ Bd2 c5 Bxb4 cxb4 e3 Nc6 {17 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 Be7 e3 Ne4 Bxe7 Qxe7 {-21 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 Bg5 h6 {78 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 Bd6 {19 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 Bg5 dxc4 {37 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Qd5 + {-14 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Qd5 + {-300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Nd7 + {-24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 Qc2 Nxc3 bxc3 Nd7 + {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + {-6 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + Nxc3 bxc3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 Nxd5 e3 Be7 Bb5+ c6 Bd3 + {-16 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {-16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 d5 cxd5 exd5 g3 {8 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {-22 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb7 a3 g6 {32 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Nd2 Nxg3 hxg3 Nd7 {-20 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Bg5 Bb7 e3 h6 Bh4 g5 Bg3 Ne4 Qc2 + Bxc3+ bxc3 d6 Bd3 f5 {-114 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 c5 a3 Ba5 Bg5 {64 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 c5 a3 Ba5 Bg5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 Nc3 Bb4 Qb3 Ba5 {13 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {-21 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 Bxc5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 a3 Ba6 Qc2 Bb7 Nc3 c5 dxc5 bxc5 Bf4 {23 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-30 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 a3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 a3 {-9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O dxc4 Bxc4 a6 {-12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O dxc4 Bxc4 a6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {3 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 e3 Bb7 Bd3 d5 O-O Nc6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {-7 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Be7 Nc3 Ne4 Bd2 Bf6 O-O {21 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Bxd2+ Nbxd2 O-O O-O d6 + {-11 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb7 Bg2 Bb4+ Bd2 Nc6 {37 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 Be7 O-O O-O Nb3 {-16 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb7 Bg2 Bd6 {46 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 a3 {-7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Nbd2 Bb4 Qb3 {62 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Be7 Nc3 {46 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Be7 Nc3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 Qa4 Bb7 Bg2 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + d5 {-1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb7 Bg2 Bb4+ Bd2 a5 O-O O-O Nc3 + Nc6 {-17 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O Bg2 {56 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 O-O Bg2 Bb7 O-O + {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Nc3 {15 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Nbd2 + O-O O-O Qd6 {4 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Ba6 b3 Bb4+ Bd2 Be7 Bg2 c6 Bc3 d5 Ne5 + Nfd7 Nxd7 Nxd7 Nd2 O-O O-O {17 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {2 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 b6 g3 Bb4+ Bd2 Bxd2+ Qxd2 Ba6 b3 d5 Bg2 {-45 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 Qa5 + {15 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 Nc3 cxd4 Nxd4 Bb4 Nb5 O-O a3 Bxc3+ Nxc3 Qa5 + {2 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 Bg4 + a5 {65 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 O-O + Be2 Nh5 {28 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Bf4 a6 a4 Bg7 e4 O-O + Be2 Nh5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 Qxc3 {-18 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 bxc3 b5 Nb2 f6 {40 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 Nd2 Bg7 Nc4 O-O Bf4 + Ne8 Qd2 Bxc3 bxc3 b5 Nb2 f6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 Qe7 {72 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 Qe7 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 e4 Bg7 Be2 O-O O-O + Re8 Nd2 a6 {-72 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Re1 {-24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 c5 d5 d6 Nc3 exd5 cxd5 g6 g3 Bg7 Bg2 O-O O-O + Re8 Bf4 {46 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {-18 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O Nbd7 Qc2 {26 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 {-9 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 {3 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O c6 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 {-33 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 Qxc4 b5 Qc2 + Bb7 Bd2 Be4 Qc1 Nc6 Be3 {128 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Qxc4 + Bc6 Bf4 Nbd7 Nc3 Nb6 Qd3 {-1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Be7 Bg2 O-O O-O dxc4 Qc2 a6 a4 Bd7 Qxc4 + Bc6 Bf4 Nd5 {5 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ {-2 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 Bb4+ Bd2 {2 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {-19 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 a6 {37 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O Nc6 Qa4 Bd7 Qxc4 cxd4 + Nxd4 Rc8 Nc3 Qa5 {-31 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O Nc6 Qa4 Bd7 Qxc4 cxd4 + Nxd4 Rc8 Nc3 Qa5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 d4 d5 g3 dxc4 Bg2 c5 O-O Nc6 Qa4 Nd7 {26 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {-16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 Be7 O-O O-O b3 Nc6 {11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Bd6 {-20 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 e6 g3 d5 Bg2 dxc4 Qa4+ Nbd7 Qxc4 Nb6 {33 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Re8 f3 Ne5 {213 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Be3 exd4 Nxd4 + Ne5 {13 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 {22 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Nbd7 O-O e5 Re1 c6 Bf1 + {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {-29 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 Bg4 O-O Nc6 {16 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 O-O {92 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + Nc6 d5 Ne7 O-O {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 Be3 Ng4 Bg5 f6 Bh4 + c6 {-84 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {44 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Bg4 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Re8 Nd5 Nxd5 cxd5 {-85 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 {-23 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 Nbd7 O-O Nb6 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 Nbd7 h3 Nc5 + Qc2 {-10 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 d5 a5 Bg5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {534 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Na6 dxe5 {28 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {-7 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 Bc1 exd4 {-46 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 Be3 Ng4 Bg5 + f6 Bc1 exd4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 Rb1 f5 b4 Kh8 {-3 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 Rb1 f5 b4 Kh8 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Nd2 + a5 a3 Nd7 Rb1 f5 b4 Kh8 Qc2 axb4 {23 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nd3 {-40 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 Nd3 {-300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Be3 f5 f3 f4 Bf2 g5 {37 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 Qb3 {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 Ne1 + Nd7 Nd3 f5 Bd2 Nf6 f3 f4 c5 Bd7 {30 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + c5 Nf4 Bxf4 exf4 Qb3 {-4 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + c5 f5 {13 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O Be2 e5 O-O Nc6 d5 Ne7 b4 Nh5 + c5 f5 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 a5 {-50 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {27 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 Bg7 e4 d6 d4 O-O h3 e5 d5 Na6 Be3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 d4 Nxc3 bxc3 c5 e3 Bg7 Qb3 O-O + {-17 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Ba3 {29 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O Nxd5 {31 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bf4 O-O e3 c6 h3 Qb6 a3 {29 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 exd5 + Qe3+ Kf8 Qf4 Bf6 {-1 14 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 exd5 + Qe3+ Kf8 Qf4 Bf6 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Bg5 Ne4 cxd5 Nxg5 Nxg5 e6 Qd2 h6 + {16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Na6 Be2 c5 d5 + {5 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + Qb3 Nb6 {-23 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 Qb3 dxc4 Qxc4 O-O e4 Bg4 Be3 Nfd7 + O-O-O Nc6 h3 {22 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {29 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Qa5 + Bd2 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Be3 Nc6 + {4 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 cxd5 Nxd5 e4 Nxc3 bxc3 c5 Rb1 O-O + Be2 Nc6 e5 {-19 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Be2 {29 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Be2 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 Nc3 d5 e3 O-O cxd5 Nxd5 Bc4 Nb6 Bb3 Nc6 + {43 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d6 O-O Nbd7 e4 {54 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 c6 Nc3 d5 cxd5 Nxd5 {53 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Na4 Qa6 {-3 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Na4 Qb4 {-53 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 c6 h3 Qb6 + c5 dxc5 dxe5 Ne8 Na4 Qb4 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 b3 {-8 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 b3 {43 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 e4 exd4 Nxd4 + Ne5 b3 {-300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Nxd4 + Ne5 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nbd7 O-O e5 h3 exd4 Nxd4 + Nb6 {28 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 e5 {-22 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O a6 h3 e5 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 {-15 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 Nc6 O-O e5 d5 Ne7 e4 Bd7 + {14 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {55 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d6 Nc3 c6 O-O Qa5 {20 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + Be3 {-35 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 d4 Bg7 g3 O-O Bg2 d5 cxd5 Nxd5 O-O Nb6 Nc3 Nc6 + d5 {26 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 c4 g6 g3 Bg7 Bg2 O-O O-O d6 Nc3 e5 d4 Nc6 d5 Na5 {12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 c5 d5 b5 c4 bxc4 Nc3 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 c5 d5 b5 c4 bxc4 Nc3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 c5 d5 b5 c4 Qa5+ {39 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 b6 {49 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 b6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 Be7 Be2 {14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d6 c4 Nbd7 Nc3 e5 e4 Be7 Be2 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Bxf3 gxf3 c5 Qxb7 Nbd7 + Nc3 cxd4 exd4 Bd6 {-13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 Bg4 Bxc4 e6 Qb3 Qc8 {23 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 dxc5 + {-43 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 Qe2 b5 Bb3 Bb7 Nc3 + Nbd7 Rd1 Qc7 e4 cxd4 Nxd4 b4 {-124 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Bd6 {15 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 a4 Nc6 Qe2 cxd4 Rd1 + Qc7 {52 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nbd2 Nc6 a3 {33 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 c4 dxc4 e3 e6 Bxc4 c5 O-O a6 dxc5 Qxd1 Rxd1 Bxc5 + Nbd2 Nc6 b3 {4 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 e3 e6 Nc3 {-15 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 d5 e3 Nc6 {31 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bf4 d5 Nc3 {-4 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bf4 Nc6 {24 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 Qb6 Bxf6 gxf6 b3 {-11 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 Qb6 Bxf6 gxf6 b3 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bg5 c5 e3 cxd4 {-27 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bg5 h6 Bd2 {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 Bg5 h6 Bxf6 Qxf6 e4 Nc6 {42 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-14 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 e3 c5 Bd3 Nc6 {-13 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Be7 Nc3 {-17 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Be7 Nc3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 b6 Bg2 Bb7 O-O Nc6 {-24 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O c5 Bg5 {111 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O c5 Bg5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 b5 Bg2 Bb7 O-O Na6 {0 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 {-7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {0 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 e6 g3 c5 Bg2 Nc6 O-O Qb6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {39 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {22 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Nc3 d5 Bf4 Bg7 e3 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {57 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 Nh5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bf4 Bg7 e3 d5 {46 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 Bg4 {72 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 h6 {5 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 d5 e3 h6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e4 {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 Bg5 Bg7 Nbd2 O-O e4 {10 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 c3 Bg7 Bf4 {23 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 c3 Bg7 Bg5 d5 {11 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c3 bxc3 {-15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c3 bxc3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 d4 g6 g3 Bg7 Bg2 O-O O-O d5 c4 dxc4 Na3 c5 {39 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O e6 d4 Be7 Nc3 {-8 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 g3 b6 Bg2 Bb7 O-O Nc6 {18 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {-4 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bf5 d3 Nbd7 Nbd2 {34 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O Bg4 d4 Nbd7 Nc3 {-4 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 g3 d5 Bg2 c6 O-O {63 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 Nc3 {-8 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 Nc3 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 O-O {7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 Nf6 g3 g6 b3 Bg7 Bb2 O-O Bg2 d5 O-O {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 Nf6 Nc3 Bg7 e4 O-O {-27 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 c4 g6 d4 cxd4 Nxd4 {18 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Nc3 Nf6 d4 cxd4 Nxd4 d6 Be2 e5 Nxc6 {-12 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Nc3 e5 Bc4 Bd6 {13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Nc3 e5 Bc4 Bd6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 Ba4 {2 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Bb5 e6 O-O Nge7 Nc3 Ng6 {-61 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nf6 e5 Nd5 Nc3 Nc7 Ba4 {-15 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 Bb5 g6 O-O Bg7 Re1 Nh6 {17 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 e6 Ndb5 {144 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 e6 Ndb5 {300 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Qc7 Nc3 Nf6 {39 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 e5 Nxc6 {-28 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be3 Ng4 Bb5 Nxe3 fxe3 Bd7 + O-O {-5 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {-6 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 Bd7 Be2 Qa5 Bxf6 gxf6 + O-O Rg8 {7 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 a5 Bb5 {-43 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + Nb3 {32 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qa5 {0 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 Be7 O-O-O O-O + f4 h6 Bh4 Qb6 Bf2 {50 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 Nf3 b5 e5 b4 exd6 {-37 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 Be7 Nf3 h6 {55 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 e5 {-23 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O Bd7 + f4 b5 Bxf6 gxf6 Kb1 b4 {49 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {-34 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Bf4 Bd7 Nxc6 Bxc6 f3 {3 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {-42 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bg5 e6 Qd2 a6 O-O-O h6 + Be3 Be7 {29 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Be7 {-9 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Be7 {15 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 e5 Nf3 Be7 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bd7 Be3 Bg7 + f3 {-21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bd7 {5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Be2 g6 O-O Bd7 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 {-1 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 Qc7 + f4 {-9 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 Qb6 Nb3 e6 Be3 Qc7 + f4 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Nxd4 + {-12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 d6 Bc4 e6 Be3 Be7 Qe2 Bd7 + {22 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Be6 {23 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Bg5 Be2 {20 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Nd5 Be7 Bxf6 Bxf6 c3 O-O Nc2 Bg5 Be2 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Bxf6 gxf6 Nd5 f5 Bd3 Be6 O-O Bg7 c4 {-5 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Bxf6 gxf6 Nd5 f5 Bd3 Be6 O-O Bh6 {72 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 Nf6 Nc3 e6 Ndb5 d6 Bf4 e5 Bg5 a6 Na3 + b5 Bxf6 gxf6 Nd5 f5 Bd3 Be6 O-O Bh6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O b5 Nxc6 + Qxc6 {-8 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be3 a6 Bd3 Nf6 O-O Bd6 + Nxc6 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Na4 O-O Nxc6 bxc6 Nb6 Rb8 Nxc8 Rfxc8 Bxa6 Rd8 {-28 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 Be2 a6 O-O Nf6 Be3 Bb4 + Nxc6 {25 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Be7 Be3 + {0 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 Qc7 g3 a6 Bg2 Nf6 O-O Nxd4 + Qxd4 Bc5 Bf4 d6 Qd2 O-O {20 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 {41 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 Be2 Nge7 {22 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 d6 {-10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 a6 g3 Qb6 {24 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 Be2 Be7 O-O O-O + Nxc6 {-6 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 {27 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nc3 d6 Be3 Nf6 f4 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 f4 {-36 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 f4 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e6 Nb5 d6 c4 Nf6 N1c3 a6 Na3 Be7 Be2 + O-O O-O b6 Be3 Bb7 Qb3 Nd7 {16 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Be2 {24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 e5 Nb5 d6 Bg5 {30 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 Na5 + {255 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 Na5 + {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 Nc3 Bg7 Be3 Nf6 Bc4 O-O Bb3 b6 + {60 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {0 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 Ng4 Qxg4 Nxd4 + Qd1 Nc6 {37 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 d6 Nxc6 + {2 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Bg7 Be3 Nf6 Nc3 O-O Be2 d6 O-O + Nxd4 {30 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Be2 Bg7 + c5 {66 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Be2 Bg7 + c5 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 Nxd4 Qxd4 d6 Be2 Bg7 + O-O O-O Qd3 Be6 Bd2 Nd7 b3 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + c5 {-41 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 Nc6 d4 cxd4 Nxd4 g6 c4 Nf6 Nc3 d6 Be2 Nxd4 Qxd4 Bg7 + O-O O-O Qd3 Be6 Bd2 {47 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 a6 Nc3 b5 {124 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 a6 Nc3 b5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 a6 Nc3 Nc6 {3 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Be2 Be7 O-O O-O f4 + Nbd7 {-38 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e6 Qd2 {36 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Be7 Be2 O-O {0 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nb3 Be6 Qd2 Nc6 {47 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 Be7 Nd5 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be3 e5 Nf3 {-113 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 e5 dxe5 fxe5 Nfd7 {-55 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Qb6 Qd2 Qxb2 Rb1 + Qa3 f5 h6 {-32 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {-87 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bg5 e6 f4 Be7 Qf3 Qc7 O-O-O + Nbd7 g4 b5 Bxf6 Nxf6 g5 Nd7 {17 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 {14 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e6 f4 Be7 O-O O-O Kh1 + Qc7 a4 Nc6 Be3 Bd7 {25 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {-2 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Be2 e5 Nb3 Be7 O-O O-O Be3 + {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qd3 + {-4 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qd3 + {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 Bc4 e6 Bb3 b5 O-O Be7 Qf3 + Bb7 {6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 Nc6 Bc4 {18 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 a4 e5 Nf3 Qa5 {42 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Be2 {-23 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 Qc7 Bd3 Nc6 Nxc6 {31 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 Nbd7 Be3 {-27 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 Nbd7 Be3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e6 Qf3 e5 {35 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Be7 a5 + {-42 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Be7 a5 + {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 f4 e5 Nf3 Nbd7 a4 Qa5 {47 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 e5 Nb3 Be7 f3 {-18 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 a6 g3 Nc6 {36 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Nxc6 + {-15 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Nxc6 + {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 Be2 Be7 O-O O-O f4 Nc6 Kh1 + Qb6 Ndb5 Qd8 Be3 a6 Nd4 Bd7 Qe1 Nxd4 Bxd4 Bc6 Qg3 g6 {23 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Nc6 h4 + {11 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Nc6 h4 + {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 g5 hxg5 Bxg5 Nc6 Qd2 + Bd7 {28 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 g5 {-5 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 g5 {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 e6 g4 h6 h4 Nc6 Rg1 h5 g5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nxd4 Bxd4 {420 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O Bc4 + Bd7 h4 Nh5 {146 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O O-O-O + Nxd4 Bxd4 Be6 Nd5 Bxd5 exd5 Qc7 Re1 {-21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be3 Bg7 f3 Nc6 Qd2 O-O O-O-O + Nxd4 Bxd4 Be6 g4 Qa5 a3 Rfc8 h4 Bc4 {60 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Be3 Nc6 + f3 d5 {0 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Be3 Nc6 + f3 d5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Nc3 Nf6 d4 cxd4 Nxd4 g6 Be2 Bg7 O-O O-O Be3 Nc6 + Qd2 Ng4 Bxg4 Bxg4 Nxc6 bxc6 Bh6 Qb6 {14 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Nd7 c3 a6 {-10 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Nd7 d4 a6 {11 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Nc3 {61 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Nxd7 O-O Ngf6 Qe2 e6 b3 Be7 Bb2 O-O + c4 Kh8 {17 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O {-9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Bd7 Bxd7+ Qxd7 O-O Nf6 e5 dxe5 Nxe5 {26 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 {-17 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 Nc3 Nf6 d4 cxd4 Nxd4 a6 {13 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 Bb5+ Nc6 O-O Bd7 Nc3 Nf6 d4 cxd4 Nxd4 a6 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-13 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 c3 Nf6 Be2 Nc6 {-41 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Nc6 Bb5 e5 {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Nc6 Bb5 Bd7 Bxc6 Bxc6 c4 {7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 d6 d4 cxd4 Qxd4 Nc6 Bb5 Bd7 Bxc6 Bxc6 c4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 O-O b5 {283 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 O-O b5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 a6 d4 cxd4 Nxd4 Qc7 Bd3 Nf6 O-O Bb4 {7 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 d4 cxd4 Nxd4 d6 {-21 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 d4 cxd4 Nxd4 d6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 a6 g3 Nc6 {-6 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 Nf6 Bg5 Be7 {98 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 Nc3 d6 d4 cxd4 Nxd4 Nf6 Be2 {16 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 d4 Nf6 Qe2+ {-78 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 c3 d5 exd5 exd5 {-106 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d3 Nc6 g3 Nf6 {-36 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Bd6 {-12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Ba7 O-O {22 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Bc5 Nb3 Ba7 O-O {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Nf6 O-O d6 Nc3 Be7 {408 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Nf6 O-O d6 Nc3 Be7 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 Bd3 Nf6 O-O d6 Be3 {1 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Nf6 Nc3 Bb4 {-52 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 e6 d4 cxd4 Nxd4 a6 c4 Bb4+ {21 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 e4 g6 d4 Bg7 dxc5 Qa5+ {157 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 e4 g6 d4 cxd4 Nxd4 e5 {79 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 c5 g3 Nc6 Bg2 e5 Nc3 {-23 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 c5 g3 Nc6 Bg2 e5 O-O d5 c4 {-31 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d6 d4 Bg4 c4 Nd7 Nc3 e5 {1 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d6 d4 Bg4 c4 Nd7 Nc3 e5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d6 d4 Bg4 c4 Nd7 {20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d6 d4 Bg4 c4 Nd7 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d6 d4 Bg4 e4 Nf6 Nc3 d5 {116 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d6 d4 Bg4 e4 Nf6 h3 Bh5 Bd3 Nc6 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d6 d4 g6 Nc3 Bg7 e4 Nf6 e5 {-17 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d6 d4 g6 c4 Nf6 g3 {11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 b3 e6 {-16 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 b3 Nc6 {8 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 c4 c6 d4 e6 cxd5 {-25 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 c4 c6 d4 e6 Nc3 dxc4 a4 Bb4 Bd2 c5 dxc5 Bxc5 e3 Nf6 Bxc4 + Nc6 O-O {96 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 e6 d4 Be7 Bd3 {-2 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 c4 c6 e3 Nf6 Nc3 dxc4 {41 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 c4 d4 e3 {-20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 c4 d4 d3 {-44 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 Qb3 Na5 Qa4 {-54 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 a3 {-32 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O Bg5 + cxd4 Nxd4 h6 Be3 Re8 a3 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 {-20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 c4 e6 d4 c5 cxd5 exd5 g3 Nc6 Bg2 Nf6 O-O Be7 Nc3 O-O dxc5 + Bxc5 Bg5 d4 Ne4 Be7 Bxf6 {49 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 d4 c5 c4 dxc4 e3 cxd4 Bxc4 Qc7 Qxd4 {258 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 d4 c5 c4 dxc4 e3 cxd4 Bxc4 Qa5+ {-2 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 d4 c5 c4 dxc4 e3 cxd4 Bxc4 Qa5+ {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 g3 Bg4 Bg2 Nc6 d4 Qd7 Nc3 {-29 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 g3 Bg4 Bg2 Nc6 {27 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 g3 c6 Bg2 Bg4 {-13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 g3 c6 Bg2 Bg4 O-O Nf6 {31 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 d5 g3 c5 Bg2 Nc6 Nc3 {-12 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 d5 g3 c5 Bg2 Nc6 d4 cxd4 {51 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 e6 d4 Nf6 Nc3 {-25 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 e6 g3 Nc6 {-43 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 f5 g3 Nf6 Nc3 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 f5 g3 Nf6 Bg2 Nc6 {1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 f5 g3 Nf6 Bg2 Nc6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 Nf6 e4 O-O h3 e5 dxe5 dxe5 Qxd8 Rxd8 + Bg5 Be6 {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 Nf6 e4 O-O Be2 c5 O-O cxd4 Nxd4 Bd7 Be3 + Nc6 Nc2 Be6 {-34 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 g6 c4 Bg7 d4 d6 Nc3 Nf6 e4 O-O Be2 c5 O-O cxd4 Nxd4 Bd7 Be3 + Nc6 Nc2 Be6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O Bg4 Be3 Nc6 Qd2 e5 d5 + Ne7 h3 {-8 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O Bg4 Be3 Nc6 Qd2 e5 d5 + Ne7 Rad1 Bd7 Ne1 Ng4 Bxg4 Bxg4 f3 Bd7 f4 Bg4 Nf3 exf4 {-37 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 e5 {-33 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 Be2 O-O O-O c6 Re1 Qb6 {12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 h3 O-O Be3 Nc6 {45 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + Nf3 g6 e4 Bg7 d4 d6 Nc3 Nf6 h3 O-O Be3 c6 a4 d5 {33 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + b3 e5 Bb2 Nc6 e3 Nf6 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + b3 e5 Bb2 Nc6 e3 d5 {-298 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + b3 e5 Bb2 Nc6 e3 d5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 c5 g3 e5 {-9 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 c5 g3 Nc6 Bg2 e6 Nf3 d5 cxd5 exd5 d4 Be6 O-O {22 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 Qb3 Nc6 Ba3 {-20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 Qb3 Nc6 Ba3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 Qb3 Nc6 Nf3 {21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 d5 cxd5 Nxd5 g3 g6 Bg2 Nxc3 bxc3 Bg7 Qb3 Nc6 Nf3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 d5 {6 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 g3 d5 {1 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 exd5 {-31 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Bg5 h6 Bh4 c5 d5 g5 {21 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Bf4 Na6 Bd6 Re8 O-O-O {-46 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Bf4 Na6 Bd6 Re8 O-O-O {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 c5 dxc5 O-O Bf4 Bxc5 {10 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 {-18 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 d5 cxd5 exd5 Bg5 h6 {14 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O Nf3 d5 {21 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Be3 + {-7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qc2 O-O a3 Bxc3+ Qxc3 b6 Bg5 Bb7 f3 h6 Bh4 + Nc6 {61 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {21 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Qb3 Nc6 Nf3 {8 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 {-20 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 {52 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 g3 cxd4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Qc2 {7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Bd3 e5 Qc2 g6 {21 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O Nc6 a3 Bxc3 bxc3 + dxc4 Bxc4 Qc7 Bd3 e5 Qc2 g6 {-300 3 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 cxd4 exd4 Nb6 {29 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 cxd4 exd4 Nb6 {13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 Nf3 c5 e3 O-O Bd3 d5 O-O dxc4 Bxc4 Nbd7 + Qe2 cxd4 exd4 Nb6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 {-11 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 a3 Bxc3+ bxc3 c5 e3 Nc6 Bd3 e5 {-58 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Bxc3 bxc3 d6 {-15 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Bxc3 bxc3 d6 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Bd3 Bb7 Nf3 O-O O-O Nc6 {75 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 {-31 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 b6 Ne2 Ba6 {14 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 Qc2 {-5 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 e4 O-O O-O + e5 {14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Nf3 Bxc3+ bxc3 d6 e4 O-O O-O + e5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 {-2 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Bd3 Nc6 Ne2 cxd4 exd4 d5 cxd5 Nxd5 + O-O Qh4 {13 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 O-O {-31 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 Ne4 Bd2 {-111 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 d5 c5 Ne4 Bd2 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Qc2 {-40 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 c5 Ne2 cxd4 exd4 O-O a3 Be7 Nf4 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Bd2 dxc4 Bxc4 + {-10 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Bd2 {-16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 Nf3 b6 O-O Bb7 Bd2 {-300 4 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 Bxc3+ bxc3 {-33 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Bd3 d5 a3 dxc4 Bxc4 Bd6 Nf3 Nc6 b4 + {22 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 c5 Bd2 {-29 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 c5 Bd2 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 {18 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Nf3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 Nxd5 e4 {14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 exd5 Nf4 {12 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 e3 O-O Ne2 d5 a3 Be7 cxd5 exd5 Nf4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 Qd2 cxd4 + {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 dxc5 Qa5 + e4 Qxc3+ {44 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 Bb4 f3 d5 a3 Bxc3+ bxc3 c5 cxd5 Nxd5 dxc5 Qa5 + e4 Qxc3+ {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 Qa5 Qb3 {40 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 Qa5 Qb3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Nbd7 e3 c6 Nf3 Qa5 Nd2 Bb4 Qc2 dxc4 Bxf6 + Nxf6 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Qc2 {-3 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Qc2 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Rc1 {-54 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 h6 Bh4 O-O Rc1 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 Nc6 {32 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 h6 Bh4 {52 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 Bg5 Be7 e3 O-O Rc1 h6 Bh4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 Be6 {-9 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 Be7 e3 O-O Bd3 h6 {44 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Bb4 {-3 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 d4 d5 cxd5 exd5 Bg5 c6 e3 Be6 {48 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 e4 c5 e5 {17 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 Nf3 d6 exd6 {-76 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 e4 c5 e5 Ng8 Nf3 d6 exd6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 e4 d5 cxd5 {41 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 e4 d5 cxd5 exd5 e5 {-20 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e6 e4 d5 cxd5 exd5 e5 {300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {-2 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {7 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 d3 Bc5 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 O-O Bd3 {33 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 O-O Bd3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 e3 Bb4 Qc2 Ba5 {38 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 e4 {-9 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Nd5 Ba5 {70 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {-9 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {-7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 Bb4 Bg2 O-O O-O d6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 O-O + b4 {-22 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 Nf3 Nc6 g3 d5 cxd5 Nxd5 Bg2 Nb6 O-O Be7 a3 Be6 + b4 {4 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O a3 Bxc3 dxc3 {-38 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 e5 g3 Bb4 Bg2 O-O e4 Nc6 d3 d6 Nf3 Bg4 {-23 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Nf3 h6 {90 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 Nbd7 Nf3 h6 {45 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 c5 d5 h6 Bf4 Re8 {64 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 c5 d5 h6 Be3 {11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 Nbd7 Qd2 c5 d5 + Kh7 {90 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Be2 O-O Bg5 h6 Be3 Na6 {23 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 {-5 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Bd3 Nc6 {-108 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 O-O f3 c5 Be3 Nc6 dxc5 {-62 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 Nge2 Na6 {17 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 g4 {-18 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 Nc6 Nge2 a6 h4 Bd7 {61 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 {50 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 {14 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 c5 dxc5 dxc5 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Bd7 {-23 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 Nge2 Na6 {61 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 {45 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 Nh5 Qd2 Na6 {67 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Bd3 {37 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Bd3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Be3 e5 d5 c6 Bd3 {12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 h6 Be3 e5 {59 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 h6 Be3 e5 {300 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 c6 Qd2 {58 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f3 O-O Bg5 c6 Qd2 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c5 d5 e6 e5 {-24 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 f4 O-O Nf3 c5 d5 Na6 {22 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 e5 d5 Na6 Be3 Nc5 Qc2 {-32 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 e5 Be3 {-36 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 d6 h3 O-O Nf3 e5 Be3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 O-O e5 Ne8 f4 d6 {-11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 e4 O-O Nf3 d6 Be2 c5 d5 Na6 {16 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 O-O Nf3 d5 cxd5 Nxd5 {-60 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 Bg7 g3 O-O Bg2 c6 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O cxd5 {-42 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 Bf4 Bg7 e3 O-O Nf3 c6 h3 Qb6 a3 {28 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 f3 {-9 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Bg4 f3 {56 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {0 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 c5 Ne2 Nc6 + Be3 O-O O-O Qc7 Rc1 {51 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 O-O Ne2 Qd7 + {13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 d4 d5 cxd5 Nxd5 e4 Nxc3 bxc3 Bg7 Bc4 O-O Ne2 Qd7 + O-O b5 {34 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 Nc6 {-14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O d4 c6 Nf3 d5 cxd5 Nxd5 {-52 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Bf5 {-15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Bf5 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Be2 O-O O-O Qc7 {39 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Bd3 O-O O-O a6 Bd2 Bg4 {37 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c6 Nc3 d5 e3 g6 Nf3 Bg7 Bd3 O-O O-O Na6 {28 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 Nf3 bxc4 Nc3 {19 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 Nf3 bxc4 Nc3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 Nf3 Qa5+ {43 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e6 {48 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 Bxa6 Nc3 e6 {69 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 Bg7 e4 Bxf1 Rxf1 + {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 bxa6 g6 Nc3 Bxa6 Nf3 d6 e4 Bxf1 Kxf1 + Bg7 h3 Nfd7 {47 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 d6 Nf3 {199 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 b5 cxb5 a6 e3 e6 Nc3 {50 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Bg4 {47 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Bg4 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Bd3 O-O Nf3 Na6 {36 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Bg4 Qb3 {-4 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Bg4 Qb3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Qe7 {32 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 d6 Nc3 g6 e4 Bg7 Nf3 O-O Be2 e6 O-O exd5 cxd5 + Qe7 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 O-O a3 {47 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 c5 d5 e5 Nc3 d6 e4 Be7 Nf3 {15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 b6 {48 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 Be7 {14 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 d6 Nc3 Nbd7 e4 e5 Nf3 Be7 Be2 {300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Nc6 {0 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 Bb4+ Bd2 Bxd2+ Qxd2 {21 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Nc3 O-O Bg2 Bxc3+ {11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 Bb4+ Nc3 O-O Bg2 Bxc3+ {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 c5 Nf3 cxd4 Nxd4 d5 Bg2 dxc4 {16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 {22 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 g6 Bg2 Na6 {13 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 c5 d5 exd5 cxd5 d6 Nc3 g6 Bg2 Na6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Bc6 Nf3 Bd5 Qa4+ {-12 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e6 g3 d5 Bg2 dxc4 Qa4+ Bd7 Qxc4 Nc6 {-45 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e5 {-9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 e5 dxe5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e5 dxe5 {-371 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 e5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 Nxc3 bxc3 O-O Qb3 {-20 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 {12 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 g6 g3 Bg7 Bg2 d5 cxd5 Nxd5 Nc3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 g6 g3 c6 Nf3 Bg7 Nc3 O-O Bg5 {-16 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 d4 g6 g3 c6 Nf3 Bg7 Nc3 O-O Bg5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 d4 g6 g3 c6 Nf3 d5 cxd5 cxd5 Bg2 Nc6 Nc3 Qb6 {17 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 g3 c6 Nc3 {96 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 Nf6 g3 c6 Nc3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 Nf6 g3 c6 Nf3 Na6 {27 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 b6 Nc3 Nf6 Nf3 Bb7 d4 e6 Bf4 Bb4 Qb3 {1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 b6 Nf3 Nf6 g3 Nc6 {85 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 d4 d5 e3 Nf6 Nc3 e6 Nf3 Be7 Bd3 {73 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c6 d4 d5 e3 Nf6 Nf3 Bf5 cxd5 cxd5 Qb3 Qc8 Bd2 Nc6 {21 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 {-49 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 cxd5 Nf6 Nc3 {33 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 Nc6 Bg5 dxc4 d5 Ne5 Qd4 Nd3+ + Bxd3 cxd3 Nf3 {28 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 {9 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Be7 cxd5 Nxd5 Bd3 Nc6 + O-O O-O Re1 {27 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Bd2 O-O + Bd3 Nc6 O-O Be7 a3 {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 e6 Nf3 Bb4 cxd5 Nxd5 Bd2 Nc6 + Bd3 Nf6 Ne4 {-1 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 Bg5 {-10 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 Bg5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c6 e4 d5 exd5 cxd5 d4 Nf6 Nc3 g6 cxd5 {7 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c5 Nc3 Nc6 Nf3 Nd4 e3 Nxf3+ Qxf3 g6 {3 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 Nc6 Nf3 Nf6 d4 cxd4 Nxd4 d6 {48 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 d6 O-O Bd7 {-13 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 d6 O-O Nf6 {18 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 Nf3 d6 O-O Nf6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 {9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 {15 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 a3 Nf6 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 Nf6 d4 O-O Nge2 d6 {48 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 Nf6 {10 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 c5 Nc3 g6 g3 Bg7 Bg2 Nc6 e3 Nf6 Nge2 d6 O-O {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 {-27 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e6 Nc3 d5 d4 Be7 cxd5 exd5 Bf4 c6 e3 Bf5 Nge2 Qb6 {20 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 Nf6 Nf3 Nc6 {14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 {14 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e6 d4 Bb4+ Bd2 Bxd2+ Qxd2 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 O-O Nc3 d6 O-O Qe8 Bd2 {63 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e6 d4 f5 g3 Nf6 Bg2 Be7 Nf3 d6 O-O {15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 Nf3 f5 d4 {64 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 Nf3 f5 d4 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 Nf3 f5 d4 {41 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 a5 Nf3 d6 d3 Nf6 O-O O-O Qb3 + {-15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 a5 Nf3 d6 d3 Nf6 O-O O-O Qb3 + {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 Rb1 d6 b4 Nge7 {9 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Nf3 Nf6 O-O O-O {-50 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 Nf6 Nf3 O-O O-O d6 {8 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 Nf6 {33 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 Nf6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 Nc3 Nc6 g3 g6 Bg2 Bg7 e3 d6 Nge2 Nge7 d4 {23 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 Bb4 {-56 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 Nc3 Bb4 {28 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 d6 g3 g6 d4 Nc6 d5 Nce7 {77 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 Nc3 d6 g3 g6 d4 Nc6 d5 Nce7 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 Nc3 d6 g3 Nc6 Bg2 Nf6 d3 {37 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 g3 Nf6 Bg2 Bc5 {-10 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 e5 g3 Nf6 Bg2 Bc5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 e5 g3 Nf6 Bg2 d5 cxd5 Nxd5 Nf3 Nc6 O-O e4 {15 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 f5 d4 e6 Nc3 Nf6 Nf3 Bb4 Bd2 {30 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 f5 d4 e6 Nc3 Nf6 Nf3 Bb4 Bd2 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 f5 d4 e6 Nc3 Nc6 {20 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 d5 {121 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 dxe5 Bxe5 {29 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 g6 Nc3 Bg7 d4 d6 e4 e5 dxe5 Bxe5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 g6 Nc3 Bg7 g3 Nf6 Bg2 O-O d4 Nc6 Nf3 d6 O-O Bf5 d5 Na5 Nd4 + Bd7 Qd3 c5 {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 g6 Nc3 Bg7 g3 Nf6 Bg2 d6 Nf3 c6 {14 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 g6 Nc3 Bg7 g3 Nf6 Bg2 d6 Nf3 c6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + c4 g6 g3 Bg7 Bg2 Nf6 Nc3 O-O d4 Nc6 {-29 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 g6 g3 Bg7 Bg2 Nc6 Nf3 Nf6 O-O d5 cxd5 Nxd5 d4 Nb6 e3 O-O Nc3 + {2 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + c4 g6 g3 Bg7 Bg2 Nc6 Nf3 Nf6 O-O d5 cxd5 Nxd5 d4 Nb6 e3 O-O Nc3 + {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 Nf6 Nc3 d5 Bg5 e6 e4 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 O-O Bc4 Be7 + {11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 Nf6 Nc3 d5 Bg5 Bf5 e3 {1 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 Nf6 Bg5 Ne4 Bf4 d5 f3 Nf6 g4 {-24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 Nf6 Bg5 Ne4 Bf4 g5 {28 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 c5 d5 Nf6 Nc3 {0 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 c5 d5 Nf6 Nc3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 c5 d5 Nf6 Nc3 d6 e4 {144 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 c4 e5 Nf3 Nd7 Nc3 g6 dxe5 {-5 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 c4 e5 Nf3 exd4 Nxd4 Bd7 {14 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 e6 {45 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 c6 Nf3 Bg4 h3 Bxf3 {35 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 Be3 Bg7 Nf3 O-O Be2 {-7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 Be3 Nc6 {31 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Bg7 e5 {-14 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 Bg7 e5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 Bg5 h6 {26 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 c5 dxc5 Qa5 e5 {-11 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 c5 dxc5 Qa5 Bd3 Qxc5 Qe2 O-O Be3 + {133 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 {61 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Na6 {65 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 {-7 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 f4 Bg7 Nf3 O-O Bd3 Nc6 O-O Bg4 Be3 {18 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O exd4 {-15 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O exd4 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 Nc3 g6 g3 Bg7 Bg2 O-O Nge2 e5 O-O Nc6 {32 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 f3 e6 {-26 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 f3 Nc6 {8 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 Nf6 f3 Nc6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 g6 Nc3 Bg7 Be3 Nf6 Nf3 O-O Be2 {-16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d6 e4 g6 Nc3 Bg7 Be3 Nf6 Nf3 O-O Be2 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d6 e4 g6 Nc3 Bg7 Be3 Nf6 Qd2 Ng4 {27 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 Bg5 c6 Nf3 Qb6 b3 {-22 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d5 Bg5 f6 {-8 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 {-45 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 Nf3 a6 e3 b5 a4 Bb7 axb5 axb5 Rxa8 Bxa8 b3 {30 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 e6 Nf3 c5 Ne5 {-20 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e3 Nf6 Bxc4 Nbd7 {21 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nb6 Bb5+ {-1 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e4 Nf6 e5 Nd5 Bxc4 Nb6 Bd3 Nc6 Ne2 Bg4 Be3 Nd5 + {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e4 e5 Nf3 Bb4+ Bd2 Bxd2+ Qxd2 exd4 Qxd4 Qxd4 Nxd4 + Nf6 Nc3 Bd7 Bxc4 Nc6 Nxc6 Bxc6 f3 {-9 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e4 e5 Nf3 Bb4+ Bd2 Bxd2+ Qxd2 exd4 Qxd4 Qxd4 Nxd4 + Nf6 Nc3 Bd7 Bxc4 Nc6 Nxc6 Bxc6 f3 {-300 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Nc6 O-O {-53 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 d5 c4 dxc4 e4 e5 Nf3 exd4 Bxc4 Nc6 O-O {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 Nf3 f5 Nc3 {0 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 Nf3 f5 Nc3 {300 7 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 Nf3 f5 c4 Nf6 Nc3 Ne4 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 Ne2 dxe4 a3 Bxc3+ Nxc3 {73 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 Ne2 dxe4 a3 Bxc3+ Nxc3 {55 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 exd5 exd5 Qe2+ {-39 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {-24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Qd7 {38 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 Qc7 Qxg7 Rg8 + Qxh7 cxd4 Ne2 Nbc6 f4 dxc3 Nxc3 {-20 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 Qc7 Qxg7 Rg8 + Qxh7 cxd4 Ne2 Nbc6 f4 dxc3 Qd3 Nf5 {38 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {-1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Qg4 O-O {18 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Nbc6 Be2 {-3 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 Nf3 Nbc6 Be2 {6 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 O-O {-16 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 O-O {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 Bd7 {63 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 Ne7 a3 Bxc3+ bxc3 c5 a4 Bd7 {300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {660 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 b6 Qg4 g6 {41 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 Qg4 Ne7 Qxg7 Rg8 Qxh7 cxd4 b4 + dxc3 bxa5 Nbc6 Nf3 Qc7 Bf4 {-38 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Ba5 b4 cxb4 {40 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Nf3 Bd7 c4 {-53 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Qg4 f5 Qg3 g6 {8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Bb4 e5 c5 a3 Bxc3+ bxc3 Qc7 Qg4 f5 Qg3 g6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Qh5 {101 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Qh5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Nb5 {3 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Be7 e5 Nfd7 Bxe7 Qxe7 Nb5 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Bb4 e5 h6 exf6 hxg5 fxg7 {0 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 Bb4 e5 h6 exf6 hxg5 fxg7 Rg8 h4 gxh4 + Qh5 Qf6 Nf3 {-25 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Bd3 {-66 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Nxf6+ Nxf6 Nf3 Qd5 {-28 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Nbd7 Nxf6+ Nxf6 Nf3 Qd5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 O-O Nxf6+ + {-19 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 Bg5 dxe4 Nxe4 Be7 Bxf6 Bxf6 Nf3 {17 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bb4 {-13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 Nf6 e5 Nfd7 f4 c5 Nf3 Nc6 Be3 cxd4 Nxd4 Bc5 {7 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Ne5 Qd5 a3 + {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Ne5 {21 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {20 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nc6 Ngf3 Nf6 e5 Nd7 Nb3 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {-32 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {-98 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 Nf6 e5 Nfd7 Bd3 c5 c3 Nc6 Ne2 cxd4 cxd4 f6 Nf4 + Qe7 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 dxc5 Bxc5 Nb3 Be7 {23 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 Be2 Nf6 {-17 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 a6 Ngf3 c5 exd5 exd5 Be2 Nf6 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {-60 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 dxc5 Bxc5 O-O Ne7 + Nb3 Bd6 Re1 O-O Bg5 Bg4 {24 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O cxd4 Nb3 Ne7 + {-3 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O cxd4 Nb3 Ne7 + {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nc6 exd5 exd5 Bb5 Bd6 O-O Qb6 {0 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Nxd5 {-16 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 Nxd5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 Nf6 exd5 exd5 Bb5+ Bd7 Bxd7+ Nbxd7 O-O + Be7 dxc5 Nxc5 Nd4 O-O Re1 {10 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 c3 Qc7 Bb3 Bd6 f4 {-18 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 c3 Qc7 Bb3 Bd6 f4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 c3 {-51 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 Ngf3 cxd4 exd5 Qxd5 Bc4 Qd6 O-O Nf6 Nb3 Nc6 + Nbxd4 Nxd4 Nxd4 a6 c3 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 a4 {-20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 a4 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 Nd2 c5 exd5 exd5 Bb5+ Bd7 Qe2+ Qe7 Bxd7+ Nxd7 dxc5 + {18 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 exd5 exd5 Nf3 Bd6 Nc3 {-1 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 exd5 exd5 Nf3 Nc6 Bb5 Qe7+ {8 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 Nge7 Na3 cxd4 Nb5 {-25 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 f6 O-O cxd4 {-3 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Bd7 Be2 f6 O-O cxd4 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4 Nbd2 Na5 Be2 Bd7 Rb1 {-2 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 c4 Nbd2 Na5 Be2 Bd7 Rb1 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 e6 e4 d5 e5 c5 c3 Nc6 Nf3 Qb6 a3 f6 {-45 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 f5 Nf3 Nf6 g3 e6 {-3 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 f5 Nf3 Nf6 g3 e6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 f5 Nf3 Nf6 g3 e6 Bg2 Nc6 {10 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 f5 g3 Nf6 Bg2 g6 Nc3 {-26 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 f5 g3 Nf6 Bg2 g6 Nc3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 f5 g3 Nf6 Bg2 g6 Nh3 d5 {26 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + d4 g6 e4 Bg7 Nc3 c6 Nf3 d5 exd5 cxd5 Bf4 {5 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + d4 g6 e4 Bg7 Nc3 c6 Nf3 d6 Be2 Nf6 O-O O-O Re1 Nbd7 Bf4 Nb6 {39 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nc6 Nf3 d5 {64 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 Nc6 Nf3 d5 {30 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nf6 Nc3 d5 e5 d4 exf6 dxc3 fxg7 {-1 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nf6 Nc3 d5 e5 d4 exf6 dxc3 fxg7 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 Nf6 Nc3 d5 e5 d4 exf6 dxc3 fxg7 cxd2+ Bxd2 Bxg7 Qf3 {121 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 h3 Bh5 c5 {-16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 Bg4 Be2 e6 O-O Be7 c4 Nb6 h3 Bh5 Nc3 + O-O Be3 Nc6 exd6 {25 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Nc3 {340 13 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Nc3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 Nf3 g6 Bc4 Nb6 Bb3 Bg7 Ng5 e6 f4 h6 {7 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 e6 {-12 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 Nf6 e5 Nd5 d4 d6 c4 Nb6 f4 Bf5 {-6 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {179 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {-111 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 Bg4 h3 Bxf3 Qxf3 d4 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 Nf6 Nxf6+ exf6 d4 Bg4 {11 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 Nf6 Nxf6+ exf6 d4 Bg4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 f5 {-13 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 Nc3 d5 Nf3 dxe4 Nxe4 f5 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d3 d5 Nd2 e5 Ngf3 Bd6 Qe2 Nf6 {-66 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d3 d5 Nd2 e5 Ngf3 Bd6 {19 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d3 d5 Nd2 e5 Ngf3 Bd6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 {5 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Ng5 Ngf6 Bd3 e6 N1f3 {0 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 c3 {37 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bb3 h6 + N5f3 a5 a3 a4 Bc4 {10 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 Nbd7 Ngf3 Qc7 O-O {-12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 Nbd7 Ngf3 Qc7 O-O {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 Nbd5 {31 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Bc4 Ngf6 Ng5 e6 Qe2 Nb6 Bd3 h6 + N5f3 c5 dxc5 Bxc5 Ne5 Nbd5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 Bc4 {63 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nd7 Nf3 Ngf6 Nxf6+ Nxf6 c3 Bg4 h3 {44 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 Nf3 Nd7 Nh4 {2 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 Nf3 Nd7 Bd3 Ngf6 O-O e6 + c4 Be7 Re1 {31 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 O-O-O {1 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Qc7 Bd2 e6 O-O-O Ngf6 Ne4 O-O-O g3 Nxe4 Qxe4 Nf6 Qe2 + {55 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 O-O {-15 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 Ngf6 Bd2 e6 O-O-O Bd6 {42 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Qc7 O-O-O {-4 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Bf5 Ng3 Bg6 h4 h6 Nf3 Nd7 h5 Bh7 Bd3 + Bxd3 Qxd3 e6 Bd2 Ngf6 O-O-O Ng4 {32 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 Bf5 {-12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 Bf5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ gxf6 Nf3 Bg4 Be2 {28 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Nf3 Bd6 {3 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Nf3 Bd6 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 Nc3 dxe4 Nxe4 Nf6 Nxf6+ exf6 Bc4 {50 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nf6 Nf3 {-3 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nf6 Nf3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 exd5 cxd5 Bd3 Nc6 {52 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Qh4 {19 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 e5 Bf5 Nc3 e6 g4 Bg6 Nge2 Nd7 {43 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Nd7 Nc3 {-25 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c6 d4 d5 e5 Bf5 Nf3 e6 Be2 Nd7 O-O {32 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 Nge2 e5 Ng3 {-11 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 Nge2 e5 Nd5 Nf6 {12 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d6 Bb5 {3 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 f4 e6 Nf3 d5 {16 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Be3 e5 {-16 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 Be3 Nf6 {33 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O Bd2 + Nd4 {101 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O Bd2 + Nd4 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Nc3 Nc6 g3 g6 Bg2 Bg7 d3 d6 f4 e6 Nf3 Nge7 O-O O-O Be3 + Qb6 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nd4 {85 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nd4 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Nc3 d6 f4 Nc6 Nf3 Nf6 {28 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Nc3 d6 g3 Nc6 {-26 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Nc3 d6 g3 Nc6 {24 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Ne2 Nf6 Nbc3 d5 exd5 Nxd5 Nxd5 Qxd5 {26 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 Ne2 Nf6 Nbc3 d5 exd5 Nxd5 Nxd5 Qxd5 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 Ne2 Nf6 Nbc3 e5 {45 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 cxd4 d6 Na3 {28 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 cxd4 d6 Na3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 c3 Nf6 e5 Nd5 d4 cxd4 Nf3 Nc6 cxd4 d6 Bc4 Nb6 Bb5 a6 Bxc6+ + bxc6 Nc3 {52 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 c3 d5 exd5 Qxd5 d4 Nf6 Nf3 Bg4 Be2 cxd4 cxd4 Nc6 Nc3 Qa5 + O-O e6 a3 {145 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Na3 Nc6 Nb5 Qd8 dxc5 Bxc5 + Qxd8+ Kxd8 Bg5 Ke7 {-12 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 c3 d5 exd5 Qxd5 d4 e6 Nf3 Nf6 Bd3 cxd4 cxd4 Bb4+ Nc3 Qd8 + O-O Nc6 a3 {33 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 c3 e6 d4 d5 exd5 Qxd5 Nf3 Nf6 Na3 a6 Nc4 Nbd7 Bf4 b5 Ne3 + Qc6 {-12 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 c3 e6 d4 d5 exd5 Qxd5 Nf3 Nf6 Bd3 cxd4 cxd4 Be7 Nc3 Qd6 + Be3 a6 O-O {7 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 d4 cxd4 {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 d4 cxd4 {19 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 c5 f4 d5 e5 Nc6 {-13 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 c5 f4 e5 {70 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bg4 {269 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Bg4 h3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 d5 exd5 Qxd5 Nc3 Qa5 d4 Nf6 Nf3 Nc6 Bb5 Bd7 O-O {130 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 d5 exd5 Nf6 d4 Nxd5 c4 Nf6 {-16 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 d5 exd5 Nf6 d4 Nxd5 c4 Nf6 {18 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e6 d3 d5 Nd2 c5 exd5 {-39 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e6 d3 d5 Nd2 Nc6 {9 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Nf3 Be7 d4 O-O Bd3 {-11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nc3 Nf6 f4 d5 fxe5 Nxe4 Qf3 Nxc3 {34 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Bc4 Nf6 d3 c6 Nf3 Be7 Nc3 {-21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Bc4 Nf6 d3 d5 exd5 Nxd5 Nf3 Nc6 O-O Bg4 h3 Bh5 Nbd2 {-9 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Bc4 Nf6 d3 d5 exd5 Nxd5 Nf3 Nc6 O-O Bg4 h3 Bh5 Nbd2 {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Bc4 Bc5 Nxe5 Qe7 {55 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Nd4 Ba4 c6 Nxe5 {63 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 Qe7 + Kh1 {13 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 Qe7 + Kh1 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 Bb5 Bb4 O-O O-O d3 d6 Bg5 Bxc3 bxc3 h6 + Bh4 g5 {46 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Bxe2 {1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Kxe2 cxd5 Nb5 Kd8 Bg5 {21 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Nc3 Nf6 d4 exd4 Nxd4 Bb4 Nxc6 bxc6 Bd3 d5 exd5 + Qe7+ Qe2 Qxe2+ Kxe2 cxd5 Nb5 Kd8 Bg5 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 Bxb4 c3 Ba5 O-O Nf6 {-43 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 Bxb4 c3 Bd6 {0 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Bc5 b4 Bxb4 c3 Bd6 {-300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Bc5 c3 Nf6 d3 d6 {-23 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Bc5 c3 Nf6 d3 d6 b4 Bb6 O-O a6 Nbd2 {2 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 Ng5 d5 exd5 Nxd5 Qh5 {-2 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Nc3 {-34 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Nc3 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d3 Be7 O-O O-O Bb3 d5 exd5 Nxd5 h3 {21 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 Nxd4 {-25 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 e5 Ne4 {57 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bc4 Nf6 d4 exd4 e5 Ne4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {10 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {-8 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nd4 Nxd4 exd4 O-O {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Bc5 c3 Nf6 d4 exd4 e5 {-8 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Bc5 c3 Nf6 d4 exd4 e5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Bc5 c3 Qe7 O-O Bb6 {36 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Be7 Re1 {-5 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Be7 Qe2 Nd6 Bxc6 bxc6 dxe5 + Nb7 Nc3 {26 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 Nf6 O-O Nxe4 d4 Nd6 Bxc6 dxc6 dxe5 Nf5 Qxd8+ + Kxd8 Rd1+ Ke8 Nc3 {-12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {55 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {300 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O Qd6 d4 {-111 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 {-36 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Bxc6 dxc6 O-O f6 d4 exd4 Nxd4 c5 Nb3 Qxd1 + Rxd1 Bd6 Na5 b5 c4 Ne7 Be3 f5 Nc3 {-99 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 b5 Bb3 Bc5 a4 Rb8 axb5 axb5 + Nc3 O-O {1 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 b5 Bb3 Bc5 a4 Rb8 axb5 axb5 + Nc3 O-O {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 Qe2 Bc5 {12 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 Nc3 Be7 O-O O-O Be3 b5 Bb3 + Na5 h3 {-33 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d3 d6 c3 b5 {28 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 O-O e5 Nd5 Bb3 + {47 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 O-O e5 Nd5 Bb3 + {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 d4 exd4 O-O Be7 Re1 {17 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {-24 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Qe2 b5 Bb3 O-O {11 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 O-O + Nc4 {28 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 O-O + Nc4 {-300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Bxc6 dxc6 d3 Nd7 Nbd2 {18 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 b4 {-17 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 b4 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 a4 b4 {8 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 exd4 cxd4 Na5 Bc2 Nc4 Bc1 c5 b3 Nb6 Bb2 {-23 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 Be3 Na5 {34 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 c6 h3 Bxf3 Qxf3 cxd5 exd5 Nc4 g4 {-3 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 c5 {8 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O d4 + Bg4 d5 Na5 Bc2 c5 {300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 Bg5 h6 + Be3 Nc5 Qc1 {132 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 Bg5 h6 + Be3 Nc5 Qc1 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 Bg5 Qc7 + {21 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nb8 d4 Nbd7 Nbd2 Bb7 Bc2 Re8 Nf1 Bf8 Ng3 g6 a4 c5 d5 c4 Bg5 Qc7 + {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 d5 {-11 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 d5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 Nbd2 cxd4 cxd4 Qc7 Nb3 {-89 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nc6 Nbd2 cxd4 cxd4 Qc7 Nb3 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na7 {89 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na7 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {-61 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Nc6 d5 Na5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {-12 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {40 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 Bd7 Nf1 Rfe8 d5 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {83 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Qc7 Nbd2 cxd4 cxd4 Nc6 Nb3 {-6 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 b4 {-95 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Na5 Bc2 c5 d4 Nd7 Nbd2 cxd4 cxd4 Bb7 {3 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {-6 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 Bc2 exd4 {12 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Be7 {-11 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Na5 {-79 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a3 Na5 {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 {-1 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 {-300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Bb7 d4 Re8 Nbd2 Bf8 a4 h6 Bc2 exd4 {0 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d3 {27 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Be6 d4 {10 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 bxa4 {-11 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 Bb7 Na3 b4 {-78 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + Nd7 d4 Bf6 a4 Bb7 Na3 b4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {-16 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {6 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 d6 c3 O-O h3 + h6 d4 Re8 Nbd2 Bf8 Nf1 {300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Nc6 {38 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 Bb7 d3 + d6 Nc3 Na5 Ba2 b4 Ne2 c5 c3 Nc6 {6 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {0 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {54 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O a4 b4 d4 + {300 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Bf5 + {140 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Bf5 + {300 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 b5 Bb3 O-O c3 d5 exd5 + Nxd5 Nxe5 Nxe5 Rxe5 c6 d4 Bd6 Re1 Qh4 g3 Qh3 Be3 Bg4 Qd3 Nxe3 + Rxe3 Rae8 {89 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 Bxc6+ bxc6 d4 exd4 + Nxd4 Bd7 c4 {-7 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 c3 Bd7 d4 O-O Nbd2 + b5 Bb3 {15 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Be7 Re1 d6 c3 Bd7 d4 O-O Nbd2 + b5 Bb3 {300 8 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Nbd2 + Nc5 c3 Bg4 Bc2 Be7 h3 Bh5 {-20 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Nbd2 + Nc5 c3 g5 {19 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Nbd2 + Nc5 c3 g5 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + Be7 c4 {-88 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + {-16 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 Qe2 + {-300 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Nd4 Nxd4 cxd4 Nxd2 Bxd2 c5 dxc5 Bxc5 Rc1 Rc8 Rxc5 + Rxc5 Bb4 Rc8 {-16 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Be7 Nbd2 O-O Re1 Nc5 Nf1 Nxb3 axb3 {2 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 Bf5 Nb3 Bg6 Nxc5 {-6 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O Nxe4 d4 b5 Bb3 d5 dxe5 Be6 c3 + Bc5 Nbd2 O-O Bc2 Bf5 Nb3 Bb6 {20 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 {-46 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O b5 Bb3 Bb7 {5 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 d4 b5 Bb3 Bg4 c3 Be7 d5 {-15 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 Nf6 O-O d6 Re1 b5 Bb3 Bg4 c3 {33 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 exd4 Qxd4 Nf6 Bg5 {-10 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 exd4 Qxd4 Nf6 Bg5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 Bxc6+ bxc6 d4 exd4 Qxd4 {118 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 {158 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 c3 Bd7 d4 Nf6 Nbd2 {28 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 Nc3 {-1 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 Nc3 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 a6 Ba4 d6 O-O Bd7 d4 {63 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 Bd7 d5 Nce7 {1 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 d6 d4 exd4 Nxd4 Bd7 Nc3 Nf6 O-O Nxd4 {54 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 Nf6 Qe2 Qe7 Qd3 {-35 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 f5 Nc3 fxe4 Nxe4 a6 {43 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {128 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 Bb5 g6 c3 Nf6 {40 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Bc4 Bc5 Ng5 Nh6 Nxf7 Nxf7 Bxf7+ Kxf7 Qh5+ + g6 Qxc5 d6 Qb5 Re8 {-70 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Bc4 Nf6 Ng5 {-8 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 f4 {-51 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 Bc4 Ne5 Be2 d5 + {24 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Bc5 Be3 Qf6 c3 Nge7 Bc4 Ne5 Be2 d5 + {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 Nc3 Bb4 Qd4 {-44 8 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nc6 d4 exd4 Nxd4 Nf6 Nxc6 bxc6 Bd3 d5 e5 Ng4 Bf4 Bc5 + O-O Qe7 {47 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 Bg4 Nd4 Bxe2 Ncxe2 O-O {-1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 h6 Be3 Nc6 O-O {7 12 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 Qe2 Qe7 d3 Nf6 Bg5 Qxe2+ Bxe2 + Be7 Nc3 h6 Be3 Nc6 O-O {-300 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Be7 O-O Nc6 Re1 Bg4 + Bxe4 dxe4 Rxe4 Bxf3 Qxf3 Nxd4 {3 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Be7 O-O Nc6 Re1 f5 c4 + Nb4 {59 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 Be6 cxd5 + Bxd5 Nc3 Nxc3 {0 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 Nxe5 d6 Nf3 Nxe4 d4 d5 Bd3 Bd6 O-O O-O c4 c6 Qc2 + f5 Qb3 Bc7 {28 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Bb4+ {1 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 Nf6 d4 Nxe4 Bd3 d5 Nxe5 Qh4 {162 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 Nf3 d6 d4 f5 dxe5 fxe4 Ng5 d5 {-46 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 Nf3 d6 d4 exd4 Qxd4 Nc6 Bb5 Bd7 Bxc6 Bxc6 Bg5 f6 Bh4 {25 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 d4 exd4 Qxd4 Nc6 Qe3 Nf6 Nc3 Bb4 Bd2 O-O Bd3 {-96 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 d4 exd4 Qxd4 Nc6 Qc4 {-48 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 f4 d5 exd5 exf4 Qe2+ {-101 13 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 f4 d5 exd5 Qxd5 {20 11 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 f4 exf4 Bc4 Nf6 d3 {-2 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 f4 exf4 Bc4 Qh4+ Kf1 Nc6 {21 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 f4 exf4 Nf3 g5 h4 g4 Ne5 d5 exd5 {-4 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + e4 e5 f4 exf4 Nf3 g5 h4 g4 Ne5 d5 exd5 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + e4 e5 f4 exf4 Nf3 g5 h4 g4 Ne5 Qe7 d4 {61 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + f4 e5 fxe5 d6 Nf3 dxe5 Nxe5 Bd6 Nf3 Nf6 d4 {-21 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + f4 Nc6 {33 12 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + g3 c5 Nf3 Nf6 d3 {-21 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + g3 c5 Nf3 Nf6 d3 {300 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + g3 c5 Bg2 Nc6 Nf3 d5 d4 cxd4 {-9 10 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + g3 c5 Bg2 Nc6 Nf3 d5 d4 cxd4 {-300 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + g3 d5 Bg2 e5 d3 Nc6 c3 {-18 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + g3 d5 Bg2 e5 c4 {3 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + g3 e5 d4 {-38 11 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + g3 e5 Bg2 Nc6 {-83 10 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + g3 g6 Bg2 Bg7 d4 Nf6 {-4 9 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] + g3 g6 Bg2 Bg7 d4 Nf6 {300 9 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] + g3 g6 Bg2 Bg7 d4 d5 Nf3 {-55 11 0} diff --git a/src/autoplayer/main.cpp b/src/autoplayer/main.cpp new file mode 100644 index 0000000..a548558 --- /dev/null +++ b/src/autoplayer/main.cpp @@ -0,0 +1,741 @@ + +/* + * INCLUDES + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * GLOBALS + */ + +int start_time; +bool pipe_logging = false; +int only_opening = -1; +FILE *pgn_log = NULL; +FILE *match_log = NULL; + + + + +/* + * Misc + */ + +void strip_newline(char *s) +{ + int i; + + for (i = 0;; ++i) + { + if (!s[i] || s[i] == '\r' || s[i] == '\n') + { + s[i] = 0; + return; + } + } +} + +void copy_result(char *to, char *from) +{ + int i; + + for (i = 0; i < strlen(from); ++i) + if (from[i] == '0' || from[i] == '1') + break; + strcpy(to, &from[i]); + for (i = 0; i < strlen(to); ++i) + if (to[i] == '}') + break; + to[i + 1] = 0; +} + + + + +/* + * MyLock + */ + +#include +#include + +class MyLock +{ +public: + MyLock(); + void get(); + void release(); + +private: + pthread_mutex_t the_lock; +}; + +MyLock::MyLock() +{ + pthread_mutex_init(&the_lock, NULL); +} + +void MyLock::get() +{ + for (;;) + { + if (pthread_mutex_lock(&the_lock) == 0) // EBUSY?? + break; + usleep(1); + } +} + +void MyLock::release() +{ + pthread_mutex_unlock(&the_lock); +} + +MyLock glock; + + + + +/* + * Settings + */ + +class Settings +{ +public: + Settings() { count = 0; }; + bool read(char *filename); + char * get(char *name); + +private: + char map[20][2][1000]; + int count; +}; + +Settings settings; + +bool Settings::read(char *filename) +{ + FILE *f; + char line[1000]; + char var[1000]; + + printf("Reading settings file: %s\n", filename); + count = 0; + f = fopen(filename, "r"); + if (!f) + { + printf("Couldn't open file.\n"); + return false; + } + for (;;) + { + line[0] = 0; + fgets(line, 1000, f); + if (!line[0]) + break; + strip_newline(line); + sscanf(line, "%s", var); + strcpy(map[count][0], var); + strcpy(map[count][1], line + strlen(var) + 1); + count++; + } + fclose(f); + return true; +} + +char * Settings::get(char *name) +{ + int i; + + for (i = 0; i < count; ++i) + if (!strcmp(map[i][0], name)) + return map[i][1]; + printf("Setting not found: %s\n", name); + exit(1); +} + + + + +/* + * ChildProc + */ + + + + + +/* + * ChessEngine + */ + +class ChessEngine : private ChildProc +{ +public: + void start(char *cmd_line, char *init_str_arg); + void stop(); + void new_game(); + void send_move(char *move); + void get_move(char *move); + bool is_game_over() { return game_over; } + char * get_result() { return result; } + +private: + bool game_over; + char result[100]; + char init_str[1000]; +}; + +void ChessEngine::start(char *cmd_line, char *init_str_arg) +{ + ChildProc::start(cmd_line); + send("xboard\n"); + strcpy(init_str, init_str_arg); +} + +void ChessEngine::stop() +{ + send("quit\n"); + ChildProc::stop(); +} + +void ChessEngine::new_game() +{ + char temp[1000]; + + // stop the engine and flush leftover output + // only necessary when reusing the engine + /*send("?\n"); + usleep(100000); + flush();*/ + + send("new\n"); + send("easy\n"); + sprintf(temp, "%s\n", init_str); + send(temp); + send("force\n"); + + game_over = false; +} + +void ChessEngine::send_move(char *move) +{ + char s[100]; + + if (game_over) + return; + sprintf(s, "%s\n", move); + send(s); +} + +void ChessEngine::get_move(char *move) +{ + char line[1000]; + char tok[1000]; + + move[0] = 0; + while (poll()) // does the engine think the game is over? + { + receive(line, 1000); + if (strchr(line, '{')) + { + game_over = true; + copy_result(result, line); + } + } + if (game_over) + return; + send("go\n"); + for (;;) + { + receive(line, 1000); + if (!line[0]) + { + usleep(1000); + continue; + } + if (strchr(line, '{')) + { + game_over = true; + copy_result(result, line); + break; + } + sscanf(line, "%s", tok); + if (!strcmp(tok, "move")) + { + sscanf(line, "move %s", move); + break; + } + } + if (!game_over) + send("force\n"); +} + + + + +/* + * WorkItems + */ + +const int max_work_items = 5000; +const int max_game_ply = 400; + +struct WorkItem +{ + volatile int status; + bool printed; + + int white_engine; + int opening_id; + char opening[200]; + char move[max_game_ply + 2][10]; + int moves; + char result[100]; +}; + +WorkItem *work_item[max_work_items]; +int work_items; + +bool make_work_items(char *filename) +{ + FILE *f; + char line[1000]; + int openings = 0; + WorkItem *w; + + printf("Creating work items from file: %s\n", filename); + work_items = 0; + f = fopen(filename, "r"); + if (!f) + { + printf("Couldn't open file.\n"); + return false; + } + for (;;) + { + line[0] = 0; + fgets(line, 1000, f); + if (!line[0]) + break; + strip_newline(line); + openings++; + + if (only_opening != -1 && openings != only_opening) + continue; + + w = new WorkItem; + w->status = 0; + w->opening_id = openings; + strcpy(w->opening, line); + w->white_engine = 1; + work_item[work_items++] = w; + + w = new WorkItem; + w->status = 0; + w->opening_id = openings; + strcpy(w->opening, line); + w->white_engine = 2; + work_item[work_items++] = w; + } + fclose(f); + printf("%d work items created.\n", work_items); + return true; +} + +void print_game(WorkItem *w) +{ + char white_name[100]; + char black_name[100]; + char line[1000]; + char short_result[100]; + char *temp; + int m, i, line_break; + + if (w->white_engine == 1) + { + strcpy(white_name, settings.get("engine1")); + strcpy(black_name, settings.get("engine2")); + } + else + { + strcpy(white_name, settings.get("engine2")); + strcpy(black_name, settings.get("engine1")); + } + sprintf(line, "Opening: %d, %s vs. %s, result: %s\n", + w->opening_id, + white_name, + black_name, + w->result); + printf(line); + fprintf(match_log, line); + fflush(match_log); + + strcpy(short_result, w->result); + temp = strchr(short_result, ' '); + if (temp) + *temp = 0; + fprintf(pgn_log, "[Round \"%d.%d\"]\n", w->opening_id, w->white_engine); + fprintf(pgn_log, "[White \"%s\"]\n", white_name); + fprintf(pgn_log, "[Black \"%s\"]\n", black_name); + fprintf(pgn_log, "[Result \"%s\"]\n", short_result); + fprintf(pgn_log, "\n"); + m = 0; + line_break = 0; + for (i = 1;; ++i) + { + if (m == w->moves) + { + fprintf(pgn_log, "%s\n", w->result); + break; + } + fprintf(pgn_log, "%d. %s ", i, w->move[m++]); + if (m < w->moves) + fprintf(pgn_log, "%s ", w->move[m++]); + if (m > line_break + 8) + { + fprintf(pgn_log, "\n"); + line_break = m; + } + } + fprintf(pgn_log, "\n"); + fflush(pgn_log); + + w->printed = true; +} + +void print_stats(int items) +{ + int i; + int win = 0, lose = 0, draw = 0; + int games = 0; + double percent; + double elo; + char elo_sign = '+'; + int elapsed_time; + int min, sec; + double spg = 10.0; + double percent_done; + double eta; + int eta_min, eta_sec; + + for (i = 0; i < items; ++i) + { + if (work_item[i]->status != 2) // shouldn't happen + break; + if (strstr(work_item[i]->result, "1-0")) + { + if (work_item[i]->white_engine == 1) + win++; + else + lose++; + } + if (strstr(work_item[i]->result, "0-1")) + { + if (work_item[i]->white_engine == 1) + lose++; + else + win++; + } + if (strstr(work_item[i]->result, "1/2-1/2")) + draw++; + } + games = win + lose + draw; + + percent = (double)win + (0.5 * (double)draw); + percent /= (double)games; + if (percent > 0.99999) + elo = 400.0; + else if (percent < 0.00001) + elo = -400.0; + else + elo = -400.0 * log(1.0 / percent - 1.0) / log(10.0); + if (elo < 0.0) + { + elo_sign = '-'; + elo = -elo; + } + elapsed_time = time(NULL) - start_time; + sec = elapsed_time; + min = sec / 60; + sec -= min * 60; + if (elapsed_time) + spg = (double)(time(NULL) - start_time) / (double)games; + percent_done = (double)games / (double)work_items; + eta = (double)work_items - (double)games; + eta *= spg; + eta_sec = (int)eta; + eta_min = eta_sec / 60; + eta_sec -= eta_min * 60; + + printf("%s vs. %s: +%d -%d =%d, %.2f%c, ELO: %c%d\n", + settings.get("engine1"), + settings.get("engine2"), + win, lose, draw, + (float)(percent * 100.0), '%', + elo_sign, (int)elo); + printf("%d games in %d:%02d, %.2f seconds/game, %.1f%c done, ETA: %d:%02d\n", + games, min, sec, (float)spg, + (float)(percent_done * 100.0), '%', + eta_min, eta_sec); + printf("\n"); +} + + + +/* + * WorkerThread + */ + +class WorkerThread +{ +public: + void do_work(int id_arg); + void do_item(WorkItem *w); + +private: + void do_opening(WorkItem *w); + void add_move(WorkItem *w, char *move); + + int id; + ChessEngine engine1, engine2; +}; + +void WorkerThread::do_work(int id_arg) +{ + int i; + + id = id_arg; + for (;;) + { + glock.get(); + for (i = 0; i < work_items; ++i) + if (work_item[i]->status == 0) + break; + if (i != work_items) + work_item[i]->status = 1; + glock.release(); + + if (i == work_items) + break; + do_item(work_item[i]); + } +} + +void WorkerThread::do_item(WorkItem *w) +{ + char move[100]; + ChessEngine *etm; // engine to move + ChessEngine *etw; // engine to wait + ChessEngine *temp; + + w->printed = false; + w->moves = 0; + + engine1.start(settings.get("cmd1"), settings.get("init1")); + engine2.start(settings.get("cmd2"), settings.get("init2")); + engine1.new_game(); + engine2.new_game(); + do_opening(w); + + etm = &engine1; + etw = &engine2; + if ((w->moves & 1) == 1 && w->white_engine == 1) + { + etm = &engine2; + etw = &engine1; + } + if ((w->moves & 1) == 0 && w->white_engine == 2) + { + etm = &engine2; + etw = &engine1; + } + for (;;) + { + etm->get_move(move); + if (etm->is_game_over()) + { + strcpy(w->result, etm->get_result()); + break; + } + etw->send_move(move); + add_move(w, move); + if (w->moves >= max_game_ply) + { + strcpy(w->result, "1/2-1/2 {Game too long}"); + break; + } + temp = etm; + etm = etw; + etw = temp; + } + + engine1.stop(); + engine2.stop(); + w->status = 2; +} + +void WorkerThread::do_opening(WorkItem *w) +{ + char move[100]; + int i = 0, j = 0; + + for (;;) + { + move[i] = w->opening[j]; + if (!move[i] || move[i] == ' ') + { + move[i] = 0; + engine1.send_move(move); + engine2.send_move(move); + add_move(w, move); + i = -1; + } + if (!w->opening[j]) + break; + i++; + j++; + } +} + +void WorkerThread::add_move(WorkItem *w, char *move) +{ + strcpy(w->move[w->moves++], move); +} + + + + +/* + * threads + */ + +WorkerThread *worker[100]; +pthread_t *mythread[100]; +volatile int thread_count = 0; + +void * thread_proc(void *arg) +{ + int id; + + glock.get(); + id = thread_count++; + glock.release(); + worker[id] = new WorkerThread; + worker[id]->do_work(id); + delete worker[id]; + pthread_exit(&mythread[id]); + delete mythread[id]; // ? +} + + +void start_threads(int count) +{ + int i; + int x = 0; + + printf("Starting threads...\n"); + for (i = 0; i < count; ++i) + { + mythread[i] = new pthread_t; + pthread_create(mythread[i], NULL, thread_proc, (void *)&x); + } + printf("Started %d threads.\n", i); +} + + + + +/* + * main + */ + +main(int argc, char *argv[]) +{ + int i; + char settings_filename[100]; + int threads = 1; + + start_time = time(NULL); + strcpy(settings_filename, "settings.txt"); + + for (i = 1;;) + { + if (i >= argc) + break; + if (!strcmp(argv[i], "-l")) + { + pipe_logging = true; + } + else if (!strcmp(argv[i], "-o")) + { + only_opening = atoi(argv[++i]); + } + else if (!strcmp(argv[i], "-t")) + { + threads = atoi(argv[++i]); + } + else if (argv[i][0] == '-') + { + printf("Usage: shiai [options] [settings file]\n"); + printf("\n"); + printf(" -h : Display this screen\n"); + printf(" -l : Display I/O with engines (\"log\")\n"); + printf(" -o # : Run opening number #\n"); + printf(" -t # : Run with # threads\n"); + printf("\n"); + exit(0); + } + else + { + strcpy(settings_filename, argv[i]); + } + i++; + } + + if (!settings.read(settings_filename)) + exit(1); + if (!make_work_items(settings.get("openings"))) + exit(1); + + + pgn_log = fopen(settings.get("pgnlog"), "w"); + if (!pgn_log) + { + printf("Couldn't open %s for writing.\n", settings.get("pgnlog")); + exit(1); + } + + match_log = fopen(settings.get("matchlog"), "w"); + if (!match_log) + { + printf("Couldn't open %s for writing.\n", settings.get("matchlog")); + exit(1); + } + + if (threads <= 0 || threads > 16) + threads = 1; + start_threads(threads); + for (i = 0; i < work_items; ++i) + { + while (work_item[i]->status != 2) + sleep(1); + print_game(work_item[i]); + print_stats(i + 1); + } + + fclose(pgn_log); + fclose(match_log); + return 0; +} diff --git a/src/autoplayer/openings.txt b/src/autoplayer/openings.txt new file mode 100644 index 0000000..70862b0 --- /dev/null +++ b/src/autoplayer/openings.txt @@ -0,0 +1,500 @@ +g1f3 g8f6 b2b3 g7g6 c1b2 f8g7 +g1f3 g8f6 c2c4 b7b6 g2g3 c8b7 f1g2 e7e6 e1g1 f8e7 b1c3 e8g8 +g1f3 g8f6 c2c4 b7b6 g2g3 c8b7 f1g2 e7e6 e1g1 f8e7 d2d4 e8g8 b1c3 f6e4 c3e4 b7e4 f3e1 e4g2 e1g2 d7d5 d1a4 +g1f3 g8f6 c2c4 b7b6 g2g3 c8b7 f1g2 e7e6 e1g1 f8e7 d2d4 e8g8 b1c3 f6e4 c1d2 +g1f3 g8f6 c2c4 b7b6 g2g3 c8b7 f1g2 e7e6 e1g1 f8e7 d2d4 e8g8 b1c3 f6e4 d1c2 e4c3 c2c3 c7c5 f1d1 d7d6 b2b3 e7f6 c1b2 +g1f3 g8f6 c2c4 b7b6 g2g3 c7c5 f1g2 c8b7 e1g1 e7e6 b1c3 f8e7 b2b3 +g1f3 g8f6 c2c4 b7b6 g2g3 c7c5 f1g2 c8b7 e1g1 e7e6 b1c3 f8e7 d2d4 c5d4 d1d4 d7d6 f1d1 a7a6 +g1f3 g8f6 c2c4 b7b6 g2g3 c7c5 f1g2 c8b7 e1g1 e7e6 b1c3 a7a6 +g1f3 g8f6 c2c4 b7b6 g2g3 c7c5 f1g2 c8b7 e1g1 g7g6 b2b3 f8g7 c1b2 e8g8 b1c3 +g1f3 g8f6 c2c4 c7c6 b1c3 d7d5 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 a7a6 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 d5c4 a2a4 c8f5 f3e5 e7e6 f2f3 f8b4 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 d5c4 a2a4 c8f5 e2e3 e7e6 f1c4 f8b4 e1g1 b8d7 d1e2 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 d5c4 a2a4 c8f5 e2e3 e7e6 f1c4 f8b4 e1g1 e8g8 d1e2 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 c1g5 b8d7 e2e3 d8a5 f3d2 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 c1g5 d5c4 e2e4 b7b5 e4e5 h7h6 g5h4 g7g5 f3g5 h6g5 h4g5 b8d7 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 c1g5 h7h6 g5f6 d8f6 e2e3 b8d7 f1d3 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 c4d5 e6d5 c1g5 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 e2e3 b8d7 d1c2 f8d6 f1e2 e8g8 e1g1 d5c4 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 e2e3 b8d7 f1d3 d5c4 d3c4 b7b5 c4d3 c8b7 e1g1 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 e2e3 b8d7 f1d3 d5c4 d3c4 b7b5 c4d3 a7a6 e3e4 c6c5 d4d5 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 b1c3 e7e6 e2e3 b8d7 f1d3 d5c4 d3c4 b7b5 c4d3 a7a6 e3e4 c6c5 e4e5 c5d4 c3b5 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 d1c2 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 c4d5 c6d5 b1c3 b8c6 c1f4 c8f5 e2e3 e7e6 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 c4d5 c6d5 b1c3 b8c6 c1f4 e7e6 e2e3 f8d6 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 e2e3 c8f5 +g1f3 g8f6 c2c4 c7c6 d2d4 d7d5 e2e3 e7e6 f1d3 +g1f3 g8f6 c2c4 c7c5 b1c3 b8c6 d2d4 c5d4 f3d4 e7e6 g2g3 d8b6 d4b3 +g1f3 g8f6 c2c4 c7c5 b1c3 b8c6 e2e3 e7e6 d2d4 d7d5 a2a3 a7a6 +g1f3 g8f6 c2c4 c7c5 b1c3 b8c6 e2e3 e7e6 d2d4 d7d5 c4d5 e6d5 f1e2 +g1f3 g8f6 c2c4 c7c5 b1c3 b8c6 g2g3 d7d5 c4d5 f6d5 f1g2 d5c7 +g1f3 g8f6 c2c4 c7c5 b1c3 b7b6 +g1f3 g8f6 c2c4 c7c5 b1c3 d7d5 c4d5 f6d5 d2d4 +g1f3 g8f6 c2c4 c7c5 b1c3 d7d5 c4d5 f6d5 e2e4 +g1f3 g8f6 c2c4 c7c5 b1c3 d7d5 c4d5 f6d5 g2g3 +g1f3 g8f6 c2c4 c7c5 b1c3 e7e6 e2e3 +g1f3 g8f6 c2c4 c7c5 b1c3 e7e6 g2g3 d7d5 c4d5 f6d5 f1g2 b8c6 e1g1 f8e7 d2d4 e8g8 +g1f3 g8f6 c2c4 c7c5 b1c3 g7g6 +g1f3 g8f6 c2c4 c7c5 d2d4 c5d4 f3d4 e7e6 +g1f3 g8f6 c2c4 c7c5 g2g3 d7d5 c4d5 f6d5 +g1f3 g8f6 c2c4 d7d6 +g1f3 g8f6 c2c4 e7e6 b1c3 f8b4 d1c2 e8g8 +g1f3 g8f6 c2c4 e7e6 b1c3 b7b6 e2e4 c8b7 +g1f3 g8f6 c2c4 e7e6 b1c3 b7b6 g2g3 c8b7 f1g2 f8e7 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 b8d7 c1g5 f8e7 e2e3 e8g8 d1c2 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 b8d7 c1g5 f8e7 e2e3 e8g8 a1c1 a7a6 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 b8d7 c1g5 f8e7 e2e3 e8g8 a1c1 c7c6 f1d3 d5c4 d3c4 f6d5 g5e7 d8e7 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 b8d7 c4d5 e6d5 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1f4 e8g8 e2e3 c7c5 d4c5 e7c5 d1c2 b8c6 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5f6 e7f6 e2e3 e8g8 a1c1 c7c6 f1d3 b8d7 e1g1 d5c4 d3c4 e6e5 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5h4 e8g8 a1c1 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5h4 e8g8 e2e3 f6e4 h4e7 d8e7 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5h4 e8g8 e2e3 b7b6 a1c1 c8b7 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5h4 e8g8 e2e3 b7b6 f1e2 c8b7 h4f6 e7f6 c4d5 e6d5 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5h4 e8g8 e2e3 b7b6 f1d3 c8b7 e1g1 b8d7 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c1g5 h7h6 g5h4 e8g8 e2e3 b7b6 c4d5 f6d5 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8b4 c1g5 h7h6 g5f6 d8f6 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 f8b4 c4d5 e6d5 c1g5 h7h6 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 c7c5 c4d5 f6d5 e2e3 b8c6 f1d3 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 c7c5 c4d5 f6d5 e2e4 d5c3 b2c3 c5d4 c3d4 f8b4 c1d2 +g1f3 g8f6 c2c4 e7e6 b1c3 d7d5 d2d4 d5c4 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 b1d2 b7b6 a2a3 b4d2 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 b1d2 d7d5 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 b1d2 e8g8 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 c1d2 d8e7 g2g3 b8c6 b1c3 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 c1d2 b4d2 d1d2 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 c1d2 a7a5 g2g3 +g1f3 g8f6 c2c4 e7e6 d2d4 f8b4 c1d2 c7c5 d2b4 c5b4 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 c8b7 c1g5 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 c8b7 a2a3 d7d5 c1g5 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 c8b7 a2a3 d7d5 c4d5 f6d5 d1c2 d5c3 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 c8b7 a2a3 d7d5 c4d5 f6d5 e2e3 f8e7 f1b5 c7c6 b5d3 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 c8b7 a2a3 d7d5 c4d5 e6d5 g2g3 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 c8b7 a2a3 g7g6 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 f8b4 c1g5 c8b7 e2e3 h7h6 g5h4 g7g5 h4g3 f6e4 d1c2 b4c3 b2c3 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 b1c3 f8b4 d1b3 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 a2a3 c8a6 d1c2 a6b7 b1c3 c7c5 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 a2a3 c7c5 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 e2e3 c8b7 f1d3 d7d5 e1g1 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8b7 f1g2 f8e7 b1c3 f6e4 c1d2 e7f6 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8b7 f1g2 f8b4 c1d2 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8a6 b1d2 a6b7 f1g2 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8a6 b1d2 f8b4 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8a6 d1a4 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8a6 b2b3 a6b7 f1g2 f8b4 c1d2 a7a5 e1g1 e8g8 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8a6 b2b3 f8b4 c1d2 b4e7 b1c3 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 c8a6 b2b3 f8b4 c1d2 b4e7 f1g2 c7c6 d2c3 d7d5 +g1f3 g8f6 c2c4 e7e6 d2d4 b7b6 g2g3 f8b4 c1d2 b4d2 d1d2 c8a6 +g1f3 g8f6 c2c4 e7e6 d2d4 c7c5 b1c3 c5d4 f3d4 f8b4 +g1f3 g8f6 c2c4 e7e6 d2d4 c7c5 d4d5 d7d6 b1c3 e6d5 c4d5 g7g6 c1f4 a7a6 a2a4 f8g7 e2e4 +g1f3 g8f6 c2c4 e7e6 d2d4 c7c5 d4d5 d7d6 b1c3 e6d5 c4d5 g7g6 f3d2 f8g7 +g1f3 g8f6 c2c4 e7e6 d2d4 c7c5 d4d5 d7d6 b1c3 e6d5 c4d5 g7g6 e2e4 f8g7 f1e2 e8g8 e1g1 f8e8 f3d2 +g1f3 g8f6 c2c4 e7e6 d2d4 c7c5 d4d5 d7d6 b1c3 e6d5 c4d5 g7g6 g2g3 f8g7 f1g2 e8g8 e1g1 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 f8e7 f1g2 e8g8 e1g1 b8d7 d1c2 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 f8e7 f1g2 e8g8 e1g1 c7c6 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 f8e7 f1g2 e8g8 e1g1 d5c4 d1c2 a7a6 c2c4 b7b5 c4c2 c8b7 c1d2 b7e4 c2c1 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 f8e7 f1g2 e8g8 e1g1 d5c4 d1c2 a7a6 a2a4 c8d7 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 f8b4 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 d5c4 f1g2 a7a6 +g1f3 g8f6 c2c4 e7e6 d2d4 d7d5 g2g3 d5c4 f1g2 c7c5 e1g1 +g1f3 g8f6 c2c4 e7e6 g2g3 d7d5 f1g2 f8e7 e1g1 e8g8 b2b3 +g1f3 g8f6 c2c4 e7e6 g2g3 d7d5 f1g2 d5c4 d1a4 b8d7 a4c4 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 b8d7 e1g1 e7e5 c1e3 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 b8d7 e1g1 e7e5 f1e1 c7c6 e2f1 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 c8g4 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 c1e3 f6g4 e3g5 f7f6 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 d4e5 d6e5 d1d8 f8d8 c1g5 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 d4d5 b8d7 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 d4d5 a7a5 c1g5 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 e1g1 b8a6 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 e1g1 b8c6 c1e3 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 e1g1 b8c6 d4d5 c6e7 f3d2 a7a5 a2a3 f6d7 a1b1 f7f5 b2b4 g8h8 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 e1g1 b8c6 d4d5 c6e7 f3e1 f6d7 c1e3 f7f5 f2f3 f5f4 e3f2 g6g5 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 e1g1 b8c6 d4d5 c6e7 f3e1 f6d7 e1d3 f7f5 c1d2 d7f6 f2f3 f5f4 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 f1e2 e7e5 e1g1 b8c6 d4d5 c6e7 b2b4 f6h5 +g1f3 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 d2d4 e8g8 h2h3 e7e5 d4d5 +g1f3 g8f6 c2c4 g7g6 b1c3 d7d5 c4d5 f6d5 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 c1f4 e8g8 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 c1g5 f6e4 c4d5 e4g5 f3g5 e7e6 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 d1b3 d5c4 b3c4 e8g8 e2e4 b8a6 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 d1b3 d5c4 b3c4 e8g8 e2e4 c8g4 c1e3 f6d7 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 c4d5 f6d5 e2e4 d5c3 b2c3 c7c5 c1e3 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 c4d5 f6d5 e2e4 d5c3 b2c3 c7c5 a1b1 e8g8 f1e2 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 b1c3 d7d5 e2e3 e8g8 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 c7c6 b1c3 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d6 b1c3 b8d7 e1g1 e7e5 e2e4 c7c6 h2h3 d8b6 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d6 b1c3 b8d7 e1g1 e7e5 e2e4 e5d4 f3d4 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d6 b1c3 b8d7 e1g1 e7e5 h2h3 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d6 b1c3 b8c6 e1g1 a7a6 h2h3 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d6 b1c3 b8c6 e1g1 e7e5 d4d5 c6e7 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d6 b1c3 c7c6 e1g1 d8a5 +g1f3 g8f6 c2c4 g7g6 d2d4 f8g7 g2g3 e8g8 f1g2 d7d5 c4d5 f6d5 e1g1 d5b6 b1c3 b8c6 +g1f3 g8f6 c2c4 g7g6 g2g3 f8g7 f1g2 e8g8 e1g1 d7d6 b1c3 e7e5 +g1f3 g8f6 d2d4 c7c5 d4d5 b7b5 +g1f3 g8f6 d2d4 d7d6 c2c4 b8d7 b1c3 e7e5 e2e4 +g1f3 g8f6 d2d4 d7d5 c2c4 d5c4 e2e3 c8g4 f1c4 e7e6 +g1f3 g8f6 d2d4 d7d5 c2c4 d5c4 e2e3 e7e6 f1c4 c7c5 e1g1 a7a6 d1e2 b7b5 c4b3 c8b7 +g1f3 g8f6 d2d4 d7d5 c2c4 d5c4 e2e3 e7e6 f1c4 c7c5 e1g1 a7a6 a2a4 b8c6 d1e2 c5d4 f1d1 +g1f3 g8f6 d2d4 d7d5 c2c4 d5c4 e2e3 e7e6 f1c4 c7c5 e1g1 a7a6 d4c5 +g1f3 g8f6 d2d4 d7d5 e2e3 +g1f3 g8f6 d2d4 e7e6 c1f4 +g1f3 g8f6 d2d4 e7e6 c1g5 c7c5 e2e3 +g1f3 g8f6 d2d4 e7e6 c1g5 h7h6 +g1f3 g8f6 d2d4 e7e6 e2e3 c7c5 f1d3 +g1f3 g8f6 d2d4 e7e6 g2g3 b7b6 f1g2 c8b7 +g1f3 g8f6 d2d4 e7e6 g2g3 b7b5 f1g2 c8b7 e1g1 +g1f3 g8f6 d2d4 e7e6 g2g3 c7c5 f1g2 +g1f3 g8f6 d2d4 g7g6 b1c3 d7d5 c1f4 f8g7 e2e3 +g1f3 g8f6 d2d4 g7g6 c1f4 f8g7 e2e3 +g1f3 g8f6 d2d4 g7g6 c1g5 f8g7 b1d2 d7d5 e2e3 +g1f3 g8f6 d2d4 g7g6 c1g5 f8g7 b1d2 e8g8 +g1f3 g8f6 d2d4 g7g6 c2c3 f8g7 +g1f3 g8f6 d2d4 g7g6 g2g3 f8g7 f1g2 e8g8 e1g1 d7d5 c2c4 d5c4 b1a3 +g1f3 g8f6 g2g3 b7b6 f1g2 c8b7 e1g1 +g1f3 g8f6 g2g3 d7d5 f1g2 c7c6 e1g1 c8f5 +g1f3 g8f6 g2g3 d7d5 f1g2 c7c6 e1g1 c8g4 +g1f3 g8f6 g2g3 g7g6 b2b3 f8g7 c1b2 e8g8 f1g2 +g1f3 c7c5 c2c4 g7g6 d2d4 c5d4 f3d4 +g1f3 c7c5 e2e4 b8c6 b1c3 +g1f3 c7c5 e2e4 b8c6 f1b5 e7e6 e1g1 g8e7 +g1f3 c7c5 e2e4 b8c6 f1b5 g7g6 e1g1 f8g7 f1e1 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 d8c7 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1e3 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 c8d7 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 e7e6 d1d2 f8e7 e1c1 e8g8 d4b3 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 e7e6 d1d2 f8e7 e1c1 e8g8 f2f4 h7h6 g5h4 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 e7e6 d1d2 a7a6 e1c1 c8d7 f2f4 f8e7 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 e7e6 d1d2 a7a6 e1c1 c8d7 f2f4 b7b5 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 e7e6 d1d2 a7a6 e1c1 h7h6 g5f4 c8d7 d4c6 d7c6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 c1g5 e7e6 d1d2 a7a6 e1c1 h7h6 g5e3 f8e7 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 f1e2 e7e5 d4f3 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 f1e2 g7g6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 f1c4 d8b6 d4b3 e7e6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6 f1c4 e7e6 c1e3 f8e7 d1e2 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 e7e6 d4b5 d7d6 c1f4 e6e5 f4g5 a7a6 b5a3 b7b5 c3d5 f8e7 g5f6 e7f6 c2c3 e8g8 a3c2 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 e7e6 d4b5 d7d6 c1f4 e6e5 f4g5 a7a6 b5a3 b7b5 g5f6 g7f6 c3d5 f6f5 f1d3 c8e6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 b1c3 d8c7 c1e3 a7a6 f1d3 g8f6 e1g1 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 b1c3 d8c7 f1e2 a7a6 e1g1 g8f6 c1e3 f8b4 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 b1c3 d8c7 g2g3 a7a6 f1g2 g8f6 e1g1 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 b1c3 a7a6 f1e2 g8e7 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 b1c3 a7a6 g2g3 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 b1c3 d7d6 c1e3 g8f6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e6 d4b5 d7d6 c2c4 g8f6 b1c3 a7a6 b5a3 f8e7 f1e2 e8g8 e1g1 b7b6 c1e3 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 e7e5 d4b5 d7d6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g7g6 b1c3 f8g7 c1e3 g8f6 f1c4 e8g8 c4b3 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4 f8g7 c1e3 g8f6 b1c3 f6g4 d1g4 c6d4 g4d1 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4 f8g7 c1e3 g8f6 b1c3 e8g8 f1e2 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4 g8f6 b1c3 c6d4 d1d4 d7d6 +g1f3 c7c5 e2e4 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4 g8f6 b1c3 d7d6 f1e2 c6d4 d1d4 f8g7 +g1f3 c7c5 e2e4 a7a6 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 c1e3 e7e6 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 c1e3 e7e5 d4b3 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 c1e3 e7e5 d4f3 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 c1g5 e7e6 f2f4 d8b6 d1d2 b6b2 a1b1 b2a3 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 c1g5 e7e6 f2f4 f8e7 d1f3 d8c7 e1c1 b8d7 g2g4 b7b5 g5f6 d7f6 g4g5 f6d7 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 f1e2 e7e6 f2f4 f8e7 e1g1 e8g8 g1h1 d8c7 a2a4 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 f1e2 e7e5 d4b3 f8e7 e1g1 e8g8 c1e3 c8e6 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 f1c4 e7e6 c4b3 b7b5 e1g1 f8e7 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 a2a4 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 f2f4 d8c7 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 f2f4 e7e6 d1f3 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 f2f4 e7e5 d4f3 b8d7 a2a4 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 a7a6 g2g3 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 e7e6 f1e2 f8e7 e1g1 e8g8 f2f4 b8c6 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 e7e6 g2g4 h7h6 g4g5 h6g5 c1g5 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 e7e6 g2g4 h7h6 h2h4 b8c6 h1g1 h6h5 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 g7g6 c1e3 f8g7 f2f3 b8c6 d1d2 e8g8 f1c4 c8d7 h2h4 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 g7g6 c1e3 f8g7 f2f3 b8c6 d1d2 e8g8 e1c1 +g1f3 c7c5 e2e4 d7d6 b1c3 g8f6 d2d4 c5d4 f3d4 g7g6 f1e2 f8g7 e1g1 +g1f3 c7c5 e2e4 d7d6 f1b5 b8d7 +g1f3 c7c5 e2e4 d7d6 f1b5 c8d7 b5d7 b8d7 e1g1 g8f6 +g1f3 c7c5 e2e4 d7d6 f1b5 c8d7 b5d7 d8d7 e1g1 +g1f3 c7c5 e2e4 d7d6 f1b5 b8c6 e1g1 c8d7 +g1f3 c7c5 e2e4 d7d6 c2c3 g8f6 f1e2 +g1f3 c7c5 e2e4 d7d6 d2d4 c5d4 d1d4 +g1f3 c7c5 e2e4 e7e6 b1c3 a7a6 d2d4 c5d4 f3d4 d8c7 f1d3 +g1f3 c7c5 e2e4 e7e6 b1c3 a7a6 g2g3 +g1f3 c7c5 e2e4 e7e6 b1c3 d7d6 d2d4 c5d4 +g1f3 c7c5 e2e4 e7e6 c2c3 d7d5 +g1f3 c7c5 e2e4 e7e6 d2d3 b8c6 g2g3 +g1f3 c7c5 e2e4 e7e6 d2d4 c5d4 f3d4 a7a6 f1d3 f8c5 +g1f3 c7c5 e2e4 e7e6 d2d4 c5d4 f3d4 a7a6 f1d3 g8f6 e1g1 d7d6 +g1f3 c7c5 e2e4 e7e6 d2d4 c5d4 f3d4 a7a6 c2c4 +g1f3 c7c5 e2e4 g7g6 d2d4 +g1f3 c7c5 g2g3 b8c6 f1g2 +g1f3 d7d6 d2d4 c8g4 c2c4 b8d7 +g1f3 d7d6 d2d4 c8g4 e2e4 +g1f3 d7d6 d2d4 g7g6 +g1f3 d7d5 b2b3 +g1f3 d7d5 c2c4 c7c6 d2d4 e7e6 +g1f3 d7d5 c2c4 c7c6 e2e3 g8f6 b1c3 +g1f3 d7d5 c2c4 d5d4 +g1f3 d7d5 c2c4 e7e6 d2d4 c7c5 c4d5 e6d5 g2g3 b8c6 f1g2 g8f6 e1g1 f8e7 b1c3 e8g8 c1g5 c5d4 f3d4 h7h6 g5e3 f8e8 +g1f3 d7d5 c2c4 e7e6 d2d4 c7c5 c4d5 e6d5 g2g3 b8c6 f1g2 g8f6 e1g1 f8e7 b1c3 e8g8 d4c5 e7c5 c1g5 d5d4 +g1f3 d7d5 d2d4 c7c5 c2c4 +g1f3 d7d5 g2g3 c8g4 f1g2 +g1f3 d7d5 g2g3 c7c6 f1g2 c8g4 +g1f3 d7d5 g2g3 c7c5 f1g2 b8c6 +g1f3 e7e6 +g1f3 f7f5 g2g3 +g1f3 g7g6 c2c4 f8g7 d2d4 d7d6 b1c3 +g1f3 g7g6 e2e4 f8g7 d2d4 d7d6 b1c3 g8f6 f1e2 e8g8 e1g1 c8g4 c1e3 b8c6 d1d2 e7e5 +g1f3 g7g6 e2e4 f8g7 d2d4 d7d6 b1c3 g8f6 f1e2 e8g8 e1g1 c7c6 +g1f3 g7g6 e2e4 f8g7 d2d4 d7d6 b1c3 g8f6 h2h3 e8g8 c1e3 +b2b3 e7e5 c1b2 +c2c4 g8f6 b1c3 c7c5 g2g3 +c2c4 g8f6 b1c3 d7d5 c4d5 f6d5 g2g3 g7g6 f1g2 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 g2g3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 c1g5 h7h6 g5h4 c7c5 d4d5 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 d1c2 c7c5 d4c5 e8g8 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 d1c2 d7d5 c4d5 e6d5 c1g5 h7h6 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 d1c2 e8g8 g1f3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 d1c2 e8g8 a2a3 b4c3 c2c3 b7b6 c1g5 c8b7 f2f3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 d1b3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 g1f3 c7c5 g2g3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 g1f3 c7c5 e2e3 e8g8 f1d3 d7d5 e1g1 b8c6 a2a3 b4c3 b2c3 d5c4 d3c4 d8c7 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 g1f3 c7c5 e2e3 e8g8 f1d3 d7d5 e1g1 d5c4 d3c4 b8d7 d1e2 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 a2a3 b4c3 b2c3 c7c5 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 b7b6 f1d3 c8b7 g1f3 e8g8 e1g1 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 b7b6 g1e2 c8a6 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 c7c5 f1d3 b8c6 g1f3 b4c3 b2c3 d7d6 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 c7c5 f1d3 b8c6 g1e2 c5d4 e3d4 d7d5 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 c7c5 g1e2 c5d4 e3d4 d7d5 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 c7c5 g1e2 c5d4 e3d4 e8g8 a2a3 b4e7 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 e8g8 f1d3 d7d5 g1f3 b7b6 e1g1 c8b7 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 e8g8 f1d3 d7d5 a2a3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 e8g8 g1f3 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 e2e3 e8g8 g1e2 d7d5 a2a3 b4e7 c4d5 +c2c4 g8f6 b1c3 e7e6 d2d4 f8b4 f2f3 d7d5 a2a3 b4c3 b2c3 c7c5 c4d5 f6d5 +c2c4 g8f6 b1c3 e7e6 d2d4 d7d5 c1g5 b8d7 e2e3 c7c6 +c2c4 g8f6 b1c3 e7e6 d2d4 d7d5 c1g5 f8e7 e2e3 h7h6 g5h4 e8g8 +c2c4 g8f6 b1c3 e7e6 d2d4 d7d5 c1g5 f8e7 e2e3 e8g8 a1c1 +c2c4 g8f6 b1c3 e7e6 d2d4 d7d5 c4d5 e6d5 c1g5 f8e7 e2e3 e8g8 f1d3 +c2c4 g8f6 b1c3 e7e6 d2d4 d7d5 c4d5 e6d5 c1g5 c7c6 e2e3 +c2c4 g8f6 b1c3 e7e6 e2e4 c7c5 e4e5 f6g8 +c2c4 g8f6 b1c3 e7e6 e2e4 d7d5 +c2c4 g8f6 b1c3 e7e5 g1f3 b8c6 d2d3 +c2c4 g8f6 b1c3 e7e5 g1f3 b8c6 e2e3 f8b4 d1c2 +c2c4 g8f6 b1c3 e7e5 g1f3 b8c6 g2g3 f8b4 c3d5 +c2c4 g8f6 b1c3 e7e5 g1f3 b8c6 g2g3 f8b4 f1g2 e8g8 e1g1 +c2c4 g8f6 b1c3 e7e5 g1f3 b8c6 g2g3 d7d5 c4d5 f6d5 f1g2 d5b6 e1g1 f8e7 a2a3 +c2c4 g8f6 b1c3 e7e5 g2g3 f8b4 f1g2 e8g8 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f1e2 e8g8 c1g5 b8d7 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f1e2 e8g8 c1g5 c7c5 d4d5 h7h6 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f1e2 e8g8 c1g5 h7h6 g5e3 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f1d3 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 g1e2 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f3 e8g8 c1e3 b8c6 g1e2 a7a6 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f3 e8g8 c1e3 c7c5 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f3 e8g8 c1e3 e7e5 g1e2 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f3 e8g8 c1e3 e7e5 d4d5 f6h5 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f3 e8g8 c1e3 e7e5 d4d5 c7c6 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f3 e8g8 c1g5 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 f2f4 e8g8 g1f3 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 d7d6 h2h3 e8g8 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 e2e4 e8g8 +c2c4 g8f6 b1c3 g7g6 d2d4 f8g7 g2g3 +c2c4 g8f6 b1c3 g7g6 d2d4 d7d5 c1f4 f8g7 e2e3 e8g8 +c2c4 g8f6 b1c3 g7g6 d2d4 d7d5 c4d5 f6d5 e2e4 d5c3 b2c3 f8g7 f1c4 c7c5 g1e2 b8c6 c1e3 e8g8 e1g1 c8g4 f2f3 +c2c4 g8f6 b1c3 g7g6 d2d4 d7d5 c4d5 f6d5 e2e4 d5c3 b2c3 f8g7 f1c4 c7c5 g1e2 b8c6 c1e3 e8g8 e1g1 d8c7 a1c1 +c2c4 g8f6 b1c3 g7g6 d2d4 d7d5 c4d5 f6d5 e2e4 d5c3 b2c3 f8g7 f1c4 e8g8 g1e2 +c2c4 g8f6 b1c3 g7g6 g2g3 f8g7 f1g2 e8g8 +c2c4 g8f6 d2d4 c7c6 b1c3 d7d5 e2e3 g7g6 g1f3 f8g7 f1e2 e8g8 e1g1 +c2c4 g8f6 d2d4 c7c6 b1c3 d7d5 e2e3 g7g6 g1f3 f8g7 f1d3 e8g8 e1g1 +c2c4 g8f6 d2d4 c7c5 d4d5 b7b5 g1f3 +c2c4 g8f6 d2d4 c7c5 d4d5 b7b5 c4b5 a7a6 b5a6 c8a6 b1c3 +c2c4 g8f6 d2d4 c7c5 d4d5 b7b5 c4b5 a7a6 b5a6 g7g6 b1c3 c8a6 +c2c4 g8f6 d2d4 c7c5 d4d5 b7b5 c4b5 a7a6 e2e3 +c2c4 g8f6 d2d4 c7c5 d4d5 d7d6 b1c3 g7g6 e2e4 f8g7 f1d3 e8g8 +c2c4 g8f6 d2d4 c7c5 d4d5 d7d6 b1c3 g7g6 e2e4 f8g7 g1f3 e8g8 f1e2 e7e6 e1g1 +c2c4 g8f6 d2d4 c7c5 d4d5 e7e5 b1c3 d7d6 e2e4 f8e7 +c2c4 g8f6 d2d4 d7d6 b1c3 b8d7 e2e4 e7e5 +c2c4 g8f6 d2d4 e7e6 g2g3 f8b4 c1d2 +c2c4 g8f6 d2d4 e7e6 g2g3 c7c5 g1f3 c5d4 f3d4 +c2c4 g8f6 d2d4 e7e6 g2g3 c7c5 d4d5 e6d5 c4d5 d7d6 b1c3 g7g6 +c2c4 g8f6 d2d4 e7e6 g2g3 d7d5 f1g2 d5c4 d1a4 +c2c4 g8f6 d2d4 e7e5 d4e5 f6g4 +c2c4 g8f6 d2d4 g7g6 g2g3 f8g7 f1g2 d7d5 c4d5 f6d5 +c2c4 g8f6 d2d4 g7g6 g2g3 c7c6 +c2c4 g8f6 g2g3 c7c6 +c2c4 b7b6 +c2c4 c7c6 d2d4 d7d5 e2e3 g8f6 +c2c4 c7c6 e2e4 d7d5 e4d5 c6d5 c4d5 g8f6 b1c3 f6d5 +c2c4 c7c6 e2e4 d7d5 e4d5 c6d5 d2d4 g8f6 b1c3 b8c6 c1g5 +c2c4 c7c6 e2e4 d7d5 e4d5 c6d5 d2d4 g8f6 b1c3 e7e6 g1f3 f8e7 c4d5 f6d5 f1d3 b8c6 e1g1 e8g8 f1e1 +c2c4 c7c6 e2e4 d7d5 e4d5 c6d5 d2d4 g8f6 b1c3 e7e6 g1f3 f8b4 c4d5 +c2c4 c7c6 e2e4 d7d5 e4d5 c6d5 d2d4 g8f6 b1c3 g7g6 +c2c4 c7c5 b1c3 b8c6 +c2c4 c7c5 b1c3 g7g6 g2g3 f8g7 f1g2 b8c6 g1f3 +c2c4 c7c5 b1c3 g7g6 g2g3 f8g7 f1g2 b8c6 a2a3 +c2c4 c7c5 b1c3 g7g6 g2g3 f8g7 f1g2 b8c6 e2e3 +c2c4 e7e6 b1c3 d7d5 d2d4 f8e7 c4d5 e6d5 c1f4 c7c6 e2e3 +c2c4 e7e6 d2d4 f8b4 c1d2 +c2c4 e7e6 d2d4 f7f5 g2g3 g8f6 f1g2 f8e7 +c2c4 e7e5 b1c3 b8c6 g1f3 f7f5 +c2c4 e7e5 b1c3 b8c6 g2g3 g7g6 f1g2 f8g7 a1b1 +c2c4 e7e5 b1c3 b8c6 g2g3 g7g6 f1g2 f8g7 d2d3 +c2c4 e7e5 b1c3 b8c6 g2g3 g7g6 f1g2 f8g7 e2e3 d7d6 g1e2 +c2c4 e7e5 b1c3 f8b4 +c2c4 e7e5 b1c3 d7d6 g2g3 +c2c4 e7e5 g2g3 g8f6 f1g2 +c2c4 f7f5 +c2c4 g7g6 b1c3 f8g7 d2d4 d7d6 e2e4 e7e5 +c2c4 g7g6 b1c3 f8g7 g2g3 +c2c4 g7g6 g2g3 f8g7 f1g2 +d2d4 g8f6 b1c3 d7d5 c1g5 +d2d4 g8f6 c1g5 f6e4 g5f4 +d2d4 c7c5 d4d5 +d2d4 d7d6 c2c4 e7e5 g1f3 +d2d4 d7d6 e2e4 g8f6 b1c3 c7c6 +d2d4 d7d6 e2e4 g8f6 b1c3 g7g6 c1e3 +d2d4 d7d6 e2e4 g8f6 b1c3 g7g6 c1g5 +d2d4 d7d6 e2e4 g8f6 b1c3 g7g6 f2f4 f8g7 g1f3 c7c5 +d2d4 d7d6 e2e4 g8f6 b1c3 g7g6 f2f4 f8g7 g1f3 e8g8 f1d3 b8a6 +d2d4 d7d6 e2e4 g8f6 b1c3 g7g6 f2f4 f8g7 g1f3 e8g8 f1d3 b8c6 +d2d4 d7d6 e2e4 g8f6 b1c3 g7g6 g2g3 f8g7 f1g2 e8g8 g1e2 e7e5 +d2d4 d7d6 e2e4 g8f6 f2f3 +d2d4 d7d6 e2e4 g7g6 b1c3 f8g7 c1e3 +d2d4 d7d5 c1g5 +d2d4 d7d5 c2c4 d5c4 g1f3 a7a6 e2e3 +d2d4 d7d5 c2c4 d5c4 e2e3 g8f6 f1c4 +d2d4 d7d5 c2c4 d5c4 e2e4 g8f6 e4e5 f6d5 f1c4 +d2d4 d7d5 c2c4 d5c4 e2e4 e7e5 g1f3 +d2d4 e7e6 g1f3 f7f5 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 g1e2 d5e4 a2a3 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4d5 e6d5 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 d8d7 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 g8e7 a2a3 b4c3 b2c3 c7c5 d1g4 d8c7 g4g7 h8g8 g7h7 c5d4 g1e2 b8c6 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 g8e7 a2a3 b4c3 b2c3 c7c5 d1g4 e8g8 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 g8e7 a2a3 b4c3 b2c3 c7c5 g1f3 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 g8e7 a2a3 b4c3 b2c3 c7c5 a3a4 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 b7b6 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4a5 +d2d4 e7e6 e2e4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 +d2d4 e7e6 e2e4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7 g5e7 d8e7 +d2d4 e7e6 e2e4 d7d5 b1c3 g8f6 c1g5 f8b4 +d2d4 e7e6 e2e4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 b8d7 +d2d4 e7e6 e2e4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 f8e7 g5f6 e7f6 g1f3 +d2d4 e7e6 e2e4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3 c5d4 f3d4 +d2d4 e7e6 e2e4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 +d2d4 e7e6 e2e4 d7d5 b1d2 b8c6 g1f3 g8f6 e4e5 f6d7 +d2d4 e7e6 e2e4 d7d5 b1d2 g8f6 e4e5 f6d7 f1d3 c7c5 c2c3 b8c6 g1e2 c5d4 c3d4 f7f6 +d2d4 e7e6 e2e4 d7d5 b1d2 a7a6 g1f3 c7c5 e4d5 e6d5 +d2d4 e7e6 e2e4 d7d5 b1d2 c7c5 g1f3 b8c6 e4d5 e6d5 f1b5 f8d6 d4c5 d6c5 e1g1 g8e7 d2b3 c5d6 f1e1 e8g8 c1g5 c8g4 +d2d4 e7e6 e2e4 d7d5 b1d2 c7c5 g1f3 b8c6 e4d5 e6d5 f1b5 f8d6 e1g1 +d2d4 e7e6 e2e4 d7d5 b1d2 c7c5 g1f3 g8f6 e4d5 +d2d4 e7e6 e2e4 d7d5 b1d2 c7c5 g1f3 c5d4 e4d5 d8d5 f1c4 d5d6 e1g1 g8f6 d2b3 b8c6 b3d4 c6d4 f3d4 a7a6 +d2d4 e7e6 e2e4 d7d5 b1d2 c7c5 e4d5 e6d5 f1b5 c8d7 d1e2 +d2d4 e7e6 e2e4 d7d5 e4d5 e6d5 g1f3 +d2d4 e7e6 e2e4 d7d5 e4e5 c7c5 c2c3 b8c6 g1f3 c8d7 f1e2 +d2d4 e7e6 e2e4 d7d5 e4e5 c7c5 c2c3 b8c6 g1f3 d8b6 a2a3 +d2d4 f7f5 g1f3 g8f6 g2g3 +d2d4 f7f5 g2g3 g8f6 f1g2 g7g6 +d2d4 g7g6 e2e4 f8g7 b1c3 c7c6 +e2e4 b8c6 g1f3 +e2e4 g8f6 b1c3 d7d5 +e2e4 g8f6 e4e5 f6d5 d2d4 d7d6 g1f3 c8g4 f1e2 e7e6 e1g1 f8e7 c2c4 d5b6 +e2e4 g8f6 e4e5 f6d5 d2d4 d7d6 g1f3 g7g6 f1c4 d5b6 c4b3 f8g7 +e2e4 g8f6 e4e5 f6d5 d2d4 d7d6 c2c4 d5b6 f2f4 +e2e4 c7c6 b1c3 d7d5 g1f3 c8g4 h2h3 g4f3 d1f3 +e2e4 c7c6 b1c3 d7d5 g1f3 d5e4 c3e4 +e2e4 c7c6 d2d3 d7d5 b1d2 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 e4g5 g8f6 f1d3 e7e6 g1f3 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 f1c4 g8f6 e4g5 e7e6 d1e2 d7b6 c4b3 h7h6 g5f3 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 f1c4 g8f6 e4g5 e7e6 d1e2 d7b6 c4d3 h7h6 g5f3 c6c5 d4c5 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 e4f6 d7f6 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 c8f5 e4g3 f5g6 g1f3 b8d7 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 c8f5 e4g3 f5g6 h2h4 h7h6 g1f3 b8d7 h4h5 g6h7 f1d3 h7d3 d1d3 d8c7 c1d2 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 c8f5 e4g3 f5g6 h2h4 h7h6 g1f3 b8d7 h4h5 g6h7 f1d3 h7d3 d1d3 g8f6 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 c8f5 e4g3 f5g6 h2h4 h7h6 g1f3 b8d7 h4h5 g6h7 f1d3 h7d3 d1d3 e7e6 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 e4f6 g7f6 +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 e4f6 e7f6 +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5 f1d3 +e2e4 c7c6 d2d4 d7d5 e4e5 c8f5 b1c3 e7e6 g2g4 f5g6 g1e2 +e2e4 c7c6 d2d4 d7d5 e4e5 c8f5 g1f3 e7e6 f1e2 +e2e4 c7c5 b1c3 b8c6 g1e2 +e2e4 c7c5 b1c3 b8c6 f2f4 +e2e4 c7c5 b1c3 b8c6 g2g3 g7g6 f1g2 f8g7 d2d3 d7d6 c1e3 +e2e4 c7c5 b1c3 b8c6 g2g3 g7g6 f1g2 f8g7 d2d3 d7d6 f2f4 e7e6 g1f3 g8e7 e1g1 e8g8 +e2e4 c7c5 b1c3 d7d6 f2f4 +e2e4 c7c5 b1c3 d7d6 g2g3 +e2e4 c7c5 g1e2 +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 g1f3 b8c6 +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 g8f6 g1f3 +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 e7e6 g1f3 g8f6 +e2e4 c7c5 c2c3 e7e6 d2d4 d7d5 e4d5 +e2e4 c7c5 d2d4 c5d4 +e2e4 c7c5 f2f4 +e2e4 d7d5 e4d5 d8d5 b1c3 d5a5 d2d4 +e2e4 d7d5 e4d5 g8f6 d2d4 f6d5 +e2e4 e7e6 d2d3 d7d5 b1d2 +e2e4 e7e5 b1c3 g8f6 f2f4 d7d5 f4e5 f6e4 +e2e4 e7e5 f1c4 g8f6 d2d3 +e2e4 e7e5 g1f3 b8c6 b1c3 g8f6 f1b5 c6d4 +e2e4 e7e5 g1f3 b8c6 b1c3 g8f6 f1b5 f8b4 e1g1 e8g8 d2d3 d7d6 c1g5 b4c3 b2c3 +e2e4 e7e5 g1f3 b8c6 b1c3 g8f6 d2d4 e5d4 f3d4 f8b4 d4c6 b7c6 f1d3 d7d5 e4d5 +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 b2b4 +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d3 d7d6 +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5 d7d5 e4d5 +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 f8e7 e1g1 e8g8 +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d4 e5d4 +e2e4 e7e5 g1f3 b8c6 f1b5 c6d4 f3d4 e5d4 e1g1 +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4 d2d4 f8e7 +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4 d2d4 e4d6 b5c6 d7c6 d4e5 d6f5 d1d8 e8d8 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 d8d6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 e5d4 f3d4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d1e2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d2d3 d7d6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d2d4 e5d4 e1g1 f8e7 f1e1 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 d1e2 b7b5 a4b3 e8g8 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 a4c6 d7c6 d2d3 f6d7 b1d2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 a2a4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 d2d4 c8g4 c1e3 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 d2d4 c8g4 d4d5 c6a5 b3c2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c6b8 d2d4 b8d7 b1d2 c8b7 b3c2 f8e8 d2f1 e7f8 f1g3 g7g6 a2a4 c7c5 d4d5 c5c4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c6a5 b3c2 c7c5 d2d4 a5c6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c6a5 b3c2 c7c5 d2d4 d8c7 b1d2 a5c6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c6a5 b3c2 c7c5 d2d4 d8c7 b1d2 c8d7 d2f1 f8e8 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c6a5 b3c2 c7c5 d2d4 d8c7 b1d2 c5d4 c3d4 a5c6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c6a5 b3c2 c7c5 d2d4 f6d7 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c8b7 d2d4 f8e8 b1d2 e7f8 b3c2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c8b7 d2d4 f8e8 b1d2 e7f8 a2a3 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c8b7 d2d4 f8e8 b1d2 e7f8 a2a4 h7h6 b3c2 e5d4 c3d4 c6b4 c2b1 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 c8e6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 f6d7 d2d4 e7f6 a2a4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8 h2h3 h7h6 d2d4 f8e8 b1d2 e7f8 d2f1 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 e8g8 a2a4 c8b7 d2d3 d7d6 b1c3 c6a5 b3a2 b5b4 c3e2 c7c5 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 e8g8 a2a4 b5b4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 e8g8 c2c3 d7d5 e4d5 f6d5 f3e5 c6e5 e1e5 c7c6 d2d4 e7d6 e5e1 d8h4 g2g3 h4h3 c1e3 c8g4 d1d3 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 d7d6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4 d2d4 b7b5 a4b3 d7d5 d4e5 c8e6 b1d2 e4c5 c2c3 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4 d2d4 b7b5 a4b3 d7d5 d4e5 c8e6 d1e2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4 d2d4 b7b5 a4b3 d7d5 d4e5 c8e6 c2c3 f8e7 b1d2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4 d2d4 b7b5 a4b3 d7d5 d4e5 c8e6 c2c3 f8c5 b1d2 e8g8 b3c2 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 b7b5 a4b3 c8b7 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 d7d6 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 a4c6 b7c6 d2d4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 c2c3 c8d7 d2d4 +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 e1g1 c8d7 +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 +e2e4 e7e5 g1f3 b8c6 f1b5 g7g6 c2c3 +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 c1e3 d8f6 c2c3 g8e7 +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6 d4c6 b7c6 +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3 f6e4 d1e2 d8e7 d2d3 e4f6 c1g5 e7e2 f1e2 f8e7 +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3 f6e4 d2d4 d6d5 f1d3 f8e7 e1g1 b8c6 f1e1 +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3 f6e4 d2d4 d6d5 f1d3 f8d6 e1g1 +e2e4 e7e5 g1f3 g8f6 d2d4 f6e4 f1d3 d7d5 f3e5 +e2e4 e7e5 g1f3 d7d6 d2d4 +e2e4 e7e5 d2d4 e5d4 +e2e4 e7e5 f2f4 d7d5 e4d5 +e2e4 e7e5 f2f4 e5f4 f1c4 +e2e4 e7e5 f2f4 e5f4 g1f3 g7g5 +f2f4 +g2g3 c7c5 +g2g3 d7d5 f1g2 +g2g3 e7e5 +g2g3 g7g6 f1g2 f8g7 diff --git a/src/autoplayer/position.bin b/src/autoplayer/position.bin new file mode 100644 index 0000000..c2a9155 Binary files /dev/null and b/src/autoplayer/position.bin differ diff --git a/src/autoplayer/position.lrn b/src/autoplayer/position.lrn new file mode 100644 index 0000000..ac15f7f --- /dev/null +++ b/src/autoplayer/position.lrn @@ -0,0 +1,3701 @@ +position +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq3r/4bkpp/ppnp1n/3N/2P2B/4Q1P/PP2PPKP/R2R/ b +{102 76013 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq3r/n3bkpp/pp1pQ/3P/5B/6P/PP2PPKP/R2R/ b +{35 16245 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq1k1r/4b1pp/pp1pQ/1n1P/5B/5RP/PP2PPKP/R/ b +{-13 16189 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qkb1r/1b1p1ppp/pp2pn/2p/2PP/2N2NP/PP2PPBP/R1BQ1RK/ b kq +{-80 23293 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rn2kb1r/1bq2ppp/p2ppn/2p/2P/1QN2NP/PP2PPBP/R1B2RK/ w kq +{13 22338 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1bqnbppp/p2ppn/2p/2P2B/1QN2NP/PP2PPBP/R2R2K/ w kq +{1 29329 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/2q1bp/p1bpp2p/2p1n1p/2P3n/2NRBNP/PPQ1PPBP/3R2K/ w kq +{-81 76053 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3kb1r/p2n1ppp/q1p1pn//Np1P/4PN/PP3PPP/R1BQ1RK/ w kq +{37 5128 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqkb1r/1p2pppp/p1p2n/3P/3P/2N2N/PP2PPPP/R1BQKB1R/ b KQkq +{-50 43245 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr2r/pp1q1p/n1p1ppb/7p/P1NPPQ/2P2PP/7P/2KR1B1R/ b +{23 6257 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr2r/p2q1p/n1p1ppb/Np5p/P2PPQ/2P2PP/7P/2KR1B1R/ b +{-12 6509 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr2r/p2q1p/n1p1p1b/Np1P1p1p/P3PQ/2P2PP/7P/2KR1B1R/ b +{-120 11880 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rn2k2r/5ppb/ppN1p2p/1B/P2PP/q4P/6PP/1R1Q1R1K/ w kq +{-46 77418 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qk2r/pp1n1ppp/2p1p1b//PbBPn1P/2N1PN/1P2QP1P/R1B2RK/ w kq +{-13 75538 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pp1n1ppp/2p1p1b/3nP/PbBP/2N2N/1P1BQPPP/R4RK/ b +{-38 6647 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2rk/pp1nBppp/4p/b2q/1p1P/P3PP/3N2PP/R2QKB1R/ b KQ +{78 37913 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2k/pp1n1ppp/4p/3q/Q2P/p3PP/3K2PP/R4B1R/ b +{41 31139 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2qkb1r/pb1n1p/2p1pP/1p4B/2pP/2N2Q/PP3PPP/R3KB1R/ b KQkq +{-117 30779 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqk2r/pp3ppp/2pb1n/3p2B/3P/2N1PN/PP3PPP/R2QKB1R/ b KQkq +{-18 16316 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/pp3ppp/2p2n/3p2B/1b1P/2NBPN/PPQ2PPP/R3K2R/ b KQ +{-35 7159 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1pqn1p1p/p1pbbnp/3p2B/3P/2NQPN/PP2BPPP/R1R3K/ w kq +{29 24834 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pp1b1ppp/1npbpn//3PP/2NB1N/PPQ2PPP/R1B2RK/ b +{-99 23851 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/1pqb1ppp/p1pbp//1n1PP/PBN2N/1P1BQPPn/2R2RK/ w +{176 24837 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2qkb1r/pb1n1ppp/2p1pn/1p/3P/2NBPN/PP3PPP/R1BQ1RK/ b kq +{-48 23869 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3kb1r/5ppp/p3bP/2n/2p/2p2N/PPB2PPP/R1BR2K/ b kq +{-97 37458 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3kb1r/5ppp/p3bP/2n/2p/5N/PBB2PPP/R2R2K/ b kq +{-147 39798 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/3n1ppp/4pP/1p/3p/3B1N/PP3PPP/R1BQK2R/ b KQkq +{-74 31355 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3kb1r/1B1n1ppp/1q2pP/1p/3p/5N/PP3PPP/R1BQK2R/ b KQkq +{-104 195689 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3kb1r/1b1n1ppp/4pq/1p/3p/3B1N/PP3PPP/R1BQ1RK/ w kq +{-16 21267 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3kb1r/3n1ppp/4pq/1p/3p/5b/PP2BPPP/R1BQ1RK/ w kq +{-55 185676 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard 1r2k2r/3n1ppp/4p/1pbq/3p1P/3Q/PP2B1PP/R1BR2K/ w k +{-59 5705 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/p4ppp/2p1pB/1p/3P/1Q3N/PP2PPPP/R3KB1R/ b KQ +{-14 195451 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3kb1r/5ppp/pqp1pn/3p1b/Q2P1B/2N1PN/PP3PPP/R3K2R/ w KQkq +{52 12676 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1q1nbppp/b1p1p/p2p/N2P1B/1P2PN/P1Q2PPP/R2R2K/ w kq +{96 24704 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1q1rk/pp3ppp/2p1pn/3p1N/1bPP/2N1PP/PP4PP/R1BQKB1R/ b KQ +{22 72044 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1r1k/pp1nqpp/2pb1n1p/4p/3PN/2NBP/PPQ2PPP/R1B2RK/ b +{-12 23723 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3kb1r/ppq2ppp/2p1b//3Pn/3Q1N/PP3PPP/R1B1R1K/ w kq +{10 96019 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1k2r/pp1p1ppp/4pn/q/Nb1N/nP4P/P3PPBP/R1BQ1RK/ w kq +{-41 21058 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard 2kr3r/1bq1bppp/p1n1p/1pp1P/1P1P2n/P1N2N/B2B1PPP/2RQ1RK/ w +{65 39065 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/1p3ppp/p1n2n/2ppN/3P/2N1P/PP2BPPP/R1BQK2R/ b KQkq +{-57 23869 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r4rk/ppnqbpp/2B4p/2p1p1N/Q5bP/2NPB1P/PP2PP/R4RK/ b +{-40 170673 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/p2qb2p/2p2p/2pnp/4N1p/1P1PBNPb/P2QPP1P/R3R1K/ w +{-34 43164 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rqkb1r/1b1p1ppp/ppnN1n/4p/2P4B/2N1P/PP3PPP/R2QKB1R/ b KQk +{-52 88829 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2rk/pp1q1ppp/1bn1p//2BPP/P1B2N/1Q3PPP/R3K2R/ b KQ +{49 28413 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1kb1r/pp3ppp/2n1p/2p/4P/2P1BN/PP3PPP/R2K1B1R/ w kq +{4 12931 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq1rk/pp2ppbp/2n1b1p//Q2PP/4BNPP/P4P/1R2KB1R/ b K +{77 31995 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/pp2bppp/2N/1qP/Nn2P/1b4P/PP1B1PBP/R4RK/ w +{94 175402 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 3r2k/pprb1ppp/2n1pbq/2P3P//1Q2BN1P/PP2PPB/R2R2K/ b +{-127 23853 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pp2ppbp/2Np1np//2P1P/2N1BP/PP4PP/R2QKB1R/ b KQ +{-25 72369 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/p3ppbp/2p3p/3Pn//2N1BP/PP2B1PP/R2QK2R/ b KQ +{30 39146 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqkb1r/pp2pp1p/2np1np//2PNP/2N/PP3PPP/R1BQKB1R/ w KQkq +{0 21253 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qk2r/pp1b1pbp/3p1np/4p/1nPNP/2N2Q/PP2BPPP/R1B2RK/ w kq +{-36 10331 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/pp1p1ppp/4pn/1Nb/1PP/P1N/4PPPP/R1BQKB1R/ b KQ +{7 23842 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/pp1pbppp/4pn/1N/1PP2B/P1N/4PPPP/R2QKB1R/ b KQ +{-28 10937 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppBpbppp/2n1pn/1N/1PP/P1N/4PPPP/R2QKB1R/ b KQ +{-67 32571 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1qrk/pp1p1ppp/2nBpn//1PP/P1N/4PPPP/R2QKB1R/ b KQ +{-183 6769 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq1rk/pp2ppbp/2n1b1p//Q2PP/4BNPP/P4P/1R2KB1R/ b K +{77 31995 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3r1k/pppn1p1p/6p/3p3P/3P1qn/B1PBP2R/P1Q2PP/R3K/ b Q +{31 31581 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rnbq1rk/pppp1ppp/4pn//1bP/2N2N/PPQPPPPP/R1B1KB1R/ w KQ +{-43 5900 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqr1k/1ppnbppp/p3pn/3P2B/3P/2N1PN/PPQ2PPP/2R1KB1R/ b K +{-34 39148 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqk2r/pppn1ppp/3B1n/3p/3P/2N2N/PP2PPPP/R2QKB1R/ b KQkq +{-33 170738 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1k2r/pp1n1ppp/1q1p1n/3p/3P/2N1PN/PPQ2PPP/R3KB1R/ b KQkq +{-96 16316 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1k2r/pp3ppp/5n/q1np/1b3B/1QN2N/PP2PPPP/2KR1B1R/ w kq +{-116 29329 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pp1n1pp/2p2b1p/4p/2BPN/4PN/PP3PPP/2RQ1RK/ b +{-44 38628 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/1pp2pp/2P1pn1p/p2p/2PP3B/2N1PN/5PPP/2Q1KB1R/ b K +{-55 39601 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/2p2p/2p1p2p/p2p/2PPn2B/2N2N/5PPP/2Q1KB1R/ b K +{-89 7029 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b2r/pp1n1pk/2pbp2p/q5p/2QPN1P/5N/PP2PPP/2R1KB1R/ w K +{-4 8917 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnb2rk/pp2qpp/2p1p2p/3p/2PP/1QPBPN/P4PPP/R3K2R/ b KQ +{-12 38563 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 3r2k/pbprqppB/1pn1p/4P/3P3p/P1P2N/2Q2PPP/RR5K/ b +{-40 16254 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1r3k/2p1q1p/1p3p1p/p2pN/1n1P/P3P/1P2QPPP/R1R3K/ w +{21 10148 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2rk/pp1n1pp/4pq1p/2p/2BP/P1P1PN/2Q2PPP/R3K2R/ b KQ +{-3 10867 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1k2r/ppp2pp/2n1pq1p/3p/QbPP/2N2N/PP2PPPP/R3KB1R/ w KQkq +{-61 10517 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/pppb1pp/2n1pq1p/3pN/QbPP/2N/PP2PPPP/R3KB1R/ w KQkq +{-121 76452 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1ppb1pp/2N2q1p/p2p/Qb1P/2N/PP2PPPP/R3KB1R/ w KQkq +{-112 24768 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/1pp2p/6pp/1b1p/pb1P3q/2N1P/PPQ2PPP/3R1RK/ w +{1 174162 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqk2r/ppp2pp/5B1p/3p/3P/2P2N/P3PPPP/R2QKB1R/ b KQkq +{-3 195451 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn3rk/p4pp/2pq3p//Q2P2b/3BPN/5PPP/R3K2R/ b KQ +{37 87390 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/pp3ppp/2n1p/3n/3P/2NB1N/PP3PPP/R1BQK2R/ b KQkq +{-13 22141 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1k2r/pp3ppp/1qn1p/3n/1b1P/2NB1N/PP1B1PPP/R2Q1RK/ b kq +{-74 23833 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1k2r/pp3ppp/2n1p/q2n/1b1P/2NBBN/PPQ2PPP/R3K2R/ w KQkq +{16 12676 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pp1n1ppp/4p//2BPP/5N/P2Q1PPP/R4RK/ b +{-42 10867 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r4rk/p2n1ppp/p3pq/1B/1Q1PP/5N/5PPP/R1R3K/ b +{-43 170088 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rnb2rk/p4ppp/4p/qp/1b1PP/3B1N/P2B1PPP/R2QK2R/ w KQ +{20 24704 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1br2k/pppnbpp/4p2p/4P/2BP1q/P2Q1N/1P2NPPP/R4RK/ b +{-83 30621 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1q1rk/pbp2ppp/1p2pn/3P/3P/P3PN/1PQB1PPP/R3KB1R/ b KQ +{-29 63739 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r5k/pb2Qppp/1p2pn/3qn1N/3P3P/P1B1P/1Pr2PP/R3KB1R/ b KQ +{-18 28472 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr3r/ppp2ppp/2b1p//3P3Q/4B/PP2P1PP/2Kn1B1R/ b +{25 173315 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/ppp1bppp/4pn/3p/2PP/P3PN/1PQN1PPP/R1B1KB1R/ b KQ +{16 11513 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnb2rk/p1p1bppp/1pPqpn/3pN/1P1P/P3P/2QN1PPP/R1B1KB1R/ b KQ +{-3 6192 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnb2rk/2p1bppp/1pPqpn/pP1pN/3P/P3P/2QN1PPP/R1B1KB1R/ b KQ +{-56 6647 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnb1r1k/2p1bpp/1pPqpn/pP1pN2p/P2P/4P/2QNBPPP/R1B2RK/ b +{-118 6119 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r4rk/p1p1qppp/b1p1p/B2p/2PPn/P5P/1P2PPBP/R2QK2R/ b KQ +{21 6314 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 5rk/prp1qppp/b3p/B1P/2P1p/PP4P/4PP1P/R2Q1RK/ b +{-20 28413 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bkn2r/1p1p1ppp/p1npq/1NP/1P1Q/2B1PpP/1P3P1P/R3KB1R/ w KQ +{69 30683 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/ppp2ppp/4p/3p/2PP/2Q1PN/PP3PPP/R3KB1R/ b KQ +{-25 11513 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2q1rk/ppp2pp/6np/1b1pP2n/3PB/5N/P2Q1PPP/RN2R1K/ w +{55 88988 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qk2r/1p1n1ppp/n1p/p3p/2P1P1b/2Q3P/PP1N1PBP/RN1R2K/ w kq +{26 21838 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1r3k/1p1b1ppp/2q1pn/p3N/P2P/Q3P/1P3PPP/R3KB1R/ b KQ +{-38 30506 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qr1k/p1p2pp/bp1b3p/3N/3Pn/P3BNPB/1PQ1PP1P/R3K2R/ b KQ +{-16 23656 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qr1k/pbp2pp/1p1b3p//3P/P1Q1BNPB/1P2PP1P/R3K2R/ b KQ +{-80 23089 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard b4rk/p2n2p/1p1Qpq1p//2B/P3P/1P3P1P/2KR/ w +{77 64299 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qk2r/pbp2ppp/1p1bp//3PP/P1P2N/2Q2PPP/R1B1KB1R/ b KQkq +{-2 11513 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1q1rk/5ppp/pp2pb/2Pn/3N/P2NP/1P3PPP/R1BQK2R/ b KQ +{-1 39081 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn2r1k/pb2qppp/1p3n/2ppN/3P/P3B1PB/1P2PP1P/R2QK2R/ b KQ +{97 38626 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3r1k/pb2qppp/1pN2n/3p/3B/P5PB/1P2PP1P/R2QK2R/ b KQ +{50 88753 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2Qr1k/pb3pbp/1pn3p/1B2p/5P/P1N2N/1P3P1P/R4RK/ b +{188 257784 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3k2r/p1pn1p/1p2pq1p/3B/3P2pN/2P1P1P/P1Q2PP/2KR3R/ b kq +{-45 170220 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/pbpn/1p1ppq/5pp/P1PP2p/2PBP1B/2Q2PPP/R4RK/ w kq +{-100 6168 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/p1pn/Ppbp1q/3p2p/2P2pp/2PBP1B/2Q2PPP/R4RK/ w kq +{-237 39130 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/p4ppp/1p2p/2pP/3PnB/PQP1PN/5PPP/R3KB1R/ b KQ +{5 39148 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rnbqkb1r/p2p1ppp/1p2pn/6B/2Pp/P4N/1P2PPPP/RN1QKB1R/ w KQkq +{-39 29891 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1bp1bppp/p/3pq/PB4n/1Q1BP/1P3PPP/RNR3K/ w kq +{-265 187673 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard 1r1q2k/p1p2rpp/1p/4n//4P1P/PP1N1PbP/2RQ1RK/ w +{-14 177030 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2q1b1r/pb1k2p/np1pp2p/2p1n2Q/2P1P2N/PN2B1P/1P3PBP/R4RK/ w +{95 29479 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/2p2pp/bp1q1n1p/p2p/3nP1P/1P3Q/PB1N1PBP/R1R3K/ w +{69 87753 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1q1rk/2p1bppp/1p/3pP/pP1P/2B2NP/P1Q2P1P/2KR1R/ b +{32 6322 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qk2r/2p1bppp/bp1ppn/n/2PPP/2NB1NP/P2B1P1P/R2QK2R/ w KQkq +{-14 30211 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/3qb1pp/bRp1pn/n/Q1P1p/2NB1NP/P2B1P1P/4K2R/ w Kkq +{42 55059 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard q4rk/pbr1bppp/np/3pP/6Q/1PB1N1P/P4PBP/R2R2K/ b +{-62 6647 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bq1rk/pp1p1ppp/2n1pn//1bPN/2N1P/PP1B1PPP/R2QKB1R/ w KQ +{-33 8859 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn2k2r/1pq2pbp/p2p1np/P1pPP/5Bb/2N2N/1PQ2PPP/R3KB1R/ b KQkq +{-64 32050 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qrbk/1p3p/p2p1npp/1NpP1b/1nN/4BBP/PP2PP1P/R2Q1RK/ w +{-81 9377 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/pp1nbppp/1qp2n/3p1b/3P/2N2NPP/PP1BPPB/2RQ1RK/ w +{-14 5193 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2q1rk/2p1bppp/p1n1pn/1p/3Pb/5NP/PP1BPPBP/RNQ2RK/ w +{-37 5388 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1q1rk/1p1bbppp/p3pn/2P1N/P1p/6P/1PQ1PPBP/RNB2RK/ b +{-40 32443 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/1p1n1ppp/4p/p1p/1N1P/1Q2PNP/PP3P1P/R3KB1R/ b KQ +{5 71264 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/2pb1pp/p1n1p2p/1p2P/5Pn/2N3P/PP1BP1BP/RQ3RK/ b +{-33 32059 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1kb1r/1pqn1ppp/p3pn/2P//N1P2NP/P3PPBP/R1BQ1RK/ w kq +{-6 22914 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1k2r/1pb2p1p/p4p/2n1p//2P2NP/P3PPBP/RN1R2K/ w kq +{-17 26819 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp1bppp/2n1pn/3p/2P/1P3NP/P2PPPBP/RNBQ1RK/ w +{-34 5835 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pppb1ppp/1n2pn/4P//2N3P/PPQ1PPBP/R1B1K2R/ b KQ +{-18 10477 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1q1r1k/pp1b1ppp/1np/3pP/4PP/4B1P/PPQ3BP/R4RK/ b +{-31 9897 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4r1k/ppp2pbp/2n1bnp/2N3B/4P/2N/PP1qBPPP/3R1RK/ w +{78 250598 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/ppp3bp/3p1pp/4p/2PPP1nB/2N2N/PP2BPPP/R2QK2R/ b KQ +{-47 10937 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rr2k/pp1n1pbp/5np/3Np1B/2P1P1b/5N/PP2BPPP/R3K2R/ b KQ +{-105 28475 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2r1r1k/p2n1pbp/4bnp/1p1Np1B/2P1P/1P5P/P2NBPP/R3K2R/ b KQ +{-130 7159 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2r1r1k/p4pb/4bNpp/1pn1p/2P1P/1P2B2P/P2NBPP/R3K2R/ b KQ +{-197 88950 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pppn1pbp/3p1np/3Pp/2P1P/2N2N/PPQ1BPPP/R1B1K2R/ b KQ +{-33 10867 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1qrk/p4pbp/n1p2np/2PpN/1P2P/2N/P1Q1BPPP/1RBR2K/ w +{155 5965 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1b1qrk/p4pbp/n1p3p/2PpN/1P2nP/2N/P1Q1B1PP/1RBR2K/ w +{116 75538 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/1pp2pbp/3p1np/p2Pp1B/2P1P/2N2N/PP2BPPP/R2QK2R/ b KQ +{-40 22458 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp2pbp/n2p1np/4P/2P1P/2N2N/PP2BPPP/R1BQ1RK/ b +{-68 39211 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp3bp/2np1pp/4p/2PPP1nB/2N2N/PP2BPPP/R2Q1RK/ b +{-48 23802 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bq2k/ppp2rbp/3p1p/6p/2PQP1nB/2N/PP2BPPP/3R1RK/ w +{8 87948 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1r1k/1ppnn1bp/3p2p/p2Ppp/1PP1P/P1N/1B1NBPPP/1R1Q1RK/ b +{-45 38496 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp1n1bp/3p1np/3Pp/2P1Pp/1QNN1P/PP1BB1PP/R4RK/ b +{-35 6834 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pp2n1bp/3p1np/2PPp/5p/1QNN1P/PP1BB1PP/R4RK/ b +{-74 22906 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 3q2k/Q3nrbp/3p1np/2rPp/1P3p/2NB1P/P2B2PP/2R2RK/ b +{-112 43252 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard 2r2rk/qpNbn1bp/3p2p/p2PN/4np/1Q3P/PP1BB1PP/2R2R1K/ w +{99 43940 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp1npbp/3p2p/3Pp2n/1PP1P/2N1BN/P3BPPP/R2Q1RK/ b +{-38 10087 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqkb1r/ppp1pp1p/6p//3P/2P2N/P3PPPP/R1BQKB1R/ b KQkq +{-29 23997 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnb2rk/pppqppbp/6p//3P1B/1QP1PN/P4PPP/R3KB1R/ b KQ +{4 10937 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2r/pp1npp1p/5kp/3q/1Q1Pb/1P2PN/P1r2PPP/R2BK2R/ b KQ +{11 6192 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rn3rk/pp2ppbp//q2p1p/3P1B/2n1PN1P/PPQ2PP/R4RK/ w +{57 70793 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/ppp1ppbp/5np/4P/3P/1QN2N/PP3PPP/R1B1KB1R/ b KQ +{-24 10157 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp1ppbp/2n3pn/3PP/5B/1QN2N1P/PP3PP/R3KB1R/ b KQ +{-49 10282 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/ppp1ppbp/6pn/n2PP/5B/2N2N1P/PP3PP/R2QKB1R/ b KQ +{-112 6322 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pppnppbp/1n4p/3P/4P1b/1QN1BN/PP2BPPP/R3K2R/ b KQ +{-19 87222 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pppnpp1p/1n4p/3P/4P1b/2Q1BN/PP2BPPP/R3K2R/ b KQ +{-68 11123 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 4r1k/pp3p1p/1nr2npB/2q1p/4P1b/1Q3N/PP2BPPP/2R2R1K/ b +{-59 32034 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/ppp1p1bp/1nn3p//3qPp/2NQ1B/PP1B1PPP/3R1RK/ w +{-42 29459 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2rk/pp2ppbp/2n3p/q1pP/4P/1QP2N/P2B1PPP/R3KB1R/ b KQ +{-5 10538 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqN1k/1p1npp1p/p5p/6B/2Pb2n/Q5P/PP2PPBP/R4RK/ b +{47 98107 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3r1k/pp3pb/2p4p/q3pPp/2P1n/1P4P/P1Q2PBP/R4RK/ w +{14 87822 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1q1r2k/1ppb1pbp/3p1np/2P1n/p2N1PP/BPN4P/P2QP1B/4RRK/ b +{-237 23542 20} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2q1rk/3bppb/p2p1npp/nppP/2P2BP/2NQ1N1P/PP2PPB/R4RK/ w +{-1 39002 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard B1b2rk/p1q1npbp/6p/1pP1p1N//1Q4PP/PP3P/R4RK/ b +{72 7159 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1r1k/pp1qnpbp/2pp1np/3P2N/2P1p1P/1QN4P/PP1BPPB/R4RK/ b +{-15 39146 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1r1k/pp1qnpb/3p1npp/3P/4N1P/1QN4P/PP1BPPB/R4RK/ b +{-84 43252 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qkb1r/p1n1pppp/3p1n/2pP/1p2P/3Q1N/PPP2PPP/RNB1K2R/ w KQkq +{55 21762 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/pppn1ppp/3p1n//2PQP/2N2N/PP3PPP/R1B1KB1R/ b KQkq +{-35 23869 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqkb1r/pp4pp/2ppnp/4n/2P1P/2NQ1N1P/PP1B1PP/R3KB1R/ w KQkq +{37 76053 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnq1k2r/ppp2ppp/3bpn/4Nb/2BP/1QN1PP/PP4PP/R1B1K2R/ b KQkq +{-63 16316 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnq2rk/ppp2ppp/3bpn/4Nb/2BPP/1QN2P/PP4PP/R1B1K2R/ b KQ +{-194 6322 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnq2rk/pp3ppp/3bpn/2p1NP/2BP/1QN2P/PP4PP/R1B1K2R/ b KQ +{-268 38626 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1q1kb1r/pp1n1ppp/2p1pn/4N2b/2BP/1Q2P/PP1B1PPP/RN3RK/ w kq +{59 5965 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqkb1r/1p3ppp/p3pn/2P/2B/4PN/PP3PPP/RNBQ1RK/ b kq +{-97 258299 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rnb1k2r/1p3ppp/p3pn/2b/2B/4PN/PP3PPP/RNBR2K/ w kq +{0 8897 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2qr1k/1ppb1ppp/2n1p/p2p/2PPn/PQBBPN/1P3PPP/R3K2R/ b KQ +{-3 32059 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqk2r/ppppbppp/2n1p/4N/3P1n/2PBP/PP3PPP/RN1QK2R/ w KQkq +{-22 71508 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqk2r/ppp1bppp/4p/4p/3P2Q/2PB/PP3PPP/RN2K2R/ w KQkq +{-83 64926 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/pp1p1ppp/2n1pn/2p/3P/2NBPN/PPP2PPP/R1BQK2R/ b KQkq +{-50 38626 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2q1rk/3b1ppp/p1nbp/3p/2pP/2N1PN/P1PnQPPP/1R2RBK/ w +{-74 94924 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qkb1r/pb1p1ppp/4pn/1pp/3P/N4NP/PPP1PPBP/R1BQ1RK/ b kq +{-65 6704 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqk2r/ppppppbp/5np//3P1B/4PN/PPP2PPP/RN1QKB1R/ b KQkq +{-40 10733 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqk/ppp1p1bN/2n2n/3p/3P2P/4P2P/PPP2P/RN1QK2R/ w KQq +{171 29891 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pQpnppbp/5np/3p1bB/2PP/4PN/PP1N1PPP/R3KB1R/ b KQ +{-58 28280 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 3q1rk/Q1p1p1bp/5pp/3n1b/3PP2B/5N/Pr1N1PPP/R3K2R/ b KQ +{-161 9827 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rnb1k2r/pp2pp/1q4pp/3p/2Pb/3BP/PP1N1PPP/R2Q1RK/ w kq +{-6 169684 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 1r1q1rk/pppbppb/2n2npp//3PN/NQP2PP/P3P1BP/1RB2RK/ b +{37 22899 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 1r1q1rk/ppp1ppb/2n2Npp/5b/3P/NQP2PP/P3P1BP/1RB2RK/ b +{-3 72564 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3kb1r/pp1n1ppp/1q3n/3pp/6b/3P1NP/PPPN1PBP/R1BQR1K/ w kq +{39 5583 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qkb1r/pp2pppp/2p2n/3p/3P2b/5NP/PPP1PPBP/RNBQ1RK/ b kq +{-42 11513 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qkb1r/pp1npppp/2p2n/3p/3P2b/5NP/PPP1PPBP/RNBQ1RK/ w kq +{0 8897 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/pp1qbppp/5n/3p/4n/5NP/PPP1QPBP/R1B1R1K/ w kq +{122 10517 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqkbnr/pp1ppp1p/6p//2PN//PP2PPPP/RNBQKB1R/ b KQkq +{-37 11134 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pp2ppbp/2Np1np//2P1P/2N1BP/PP4PP/R2QKB1R/ b KQ +{-25 72369 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qk2r/pp3pbp/3ppnp/1Pn/3QP/2N/PP2BPPP/R1B2RK/ w kq +{95 22914 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2qkb1r/pp1bpppp/2np1n/1B4B/3NP/2N/PPP2PPP/R2QK2R/ b KQkq +{-64 75498 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqk2r/pp2bppp/2n2n/1Bp/3p/2N2N/PPPP1PPP/R1BQR1K/ w kq +{11 10002 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/pp1pnppp/2n1p/1Bp/3PP/5N/PPP2PPP/RNBQ1RK/ b kq +{-97 38626 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1kb1r/pp2nppp/1qp1p//4P//PPP1BPPP/RNBQ1RK/ b kq +{-108 23802 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqkb1r/1p3ppp/p1n1p/2pn//2N2N/PPPPBPPP/R1BQ1RK/ w kq +{34 75986 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bq1rk/pp1pppbp/2n2np/1Bp/3PP/2N2N/PPP2PPP/R1BQR1K/ b +{-37 38626 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r1bqk2r/3pppbp/p1n3p/4P/p2p2n/5N/1PP1BPPP/RNBQR1K/ w kq +{-24 42709 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b1kbnr/ppqppppp/2n/1N/4P//PPP2PPP/RNBQKB1R/ b KQkq +{-79 31026 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rq2k1nr/1p1b1p1p/p1p3p/4pP/4P1Q/B1P/P1P3PP/2KR1B1R/ b kq +{-114 31929 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/pp2pppp/2np1n//3NP/2N1B/PPP2PPP/R2QKB1R/ b KQkq +{-70 75498 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qkb1r/pp2pppp/2bp//4P1n/2NQB/PPP2PPP/R3KB1R/ w KQkq +{45 12420 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1p3ppp/p1bbp/q3P//4Q/PPP2PPP/2KR1B1R/ w kq +{78 170724 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2r2k/1p3ppp/p1bPp//1Q//qPP2PPP/2KR1B1R/ w +{-32 22149 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2qkb1r/pp1bpppp/2np1n/1B4B/3NP/2N/PPP2PPP/R2QK2R/ b KQkq +{-64 75498 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 3r2k/1p2bppp/3pq/1Q/4P/2B/rPP2PPP/3R1RK/ b +{-111 28283 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn3rk/p3bppp/1p2p1q/1QP/1P1p1B/6P/P3PPNP/R4RK/ b +{8 31214 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn3rk/p3bppp/1p2p/1QPq/1P1pPB/5PP/P5NP/R4RK/ b e3 +{47 31843 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r5k/pN1nbp1p/1pp1r1p/3p/3P1B/4P1P/PP3P1P/R4RK/ w +{-244 6038 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard q4rk/p1pp2pp/bp1b/n4p//2N1P1P/PPQN1P1P/R4RK/ w +{64 24773 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2r3k/p2r1ppp/1p2pP//2Pp1Q/PP4P/5PbP/1R4K/ b +{-734 26867 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq3r/4bkpp/ppnp1n/3N/2P2B/4Q1P/PP2PPKP/R2R/ b +{102 76013 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq3r/n3bkpp/pp1pQ/3P/5B/6P/PP2PPKP/R2R/ b +{35 16245 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2rq1k1r/4b1pp/pp1pQ/1n1P/5B/5RP/PP2PPKP/R/ b +{-13 16189 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rn1qkb1r/1b1p1ppp/pp2pn/2p/2PP/2N2NP/PP2PPBP/R1BQ1RK/ b kq +{-80 23293 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rn2kb1r/1bq2ppp/p2ppn/2p/2P/1QN2NP/PP2PPBP/R1B2RK/ w kq +{13 22338 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1bqnbppp/p2ppn/2p/2P2B/1QN2NP/PP2PPBP/R2R2K/ w kq +{1 29329 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/2q1bp/p1bpp2p/2p1n1p/2P3n/2NRBNP/PPQ1PPBP/3R2K/ w kq +{-81 76053 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqkb1r/1p2pppp/p1p2n/3P/3P/2N2N/PP2PPPP/R1BQKB1R/ b KQkq +{-50 43245 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr2r/pp1q1p/n1p1ppb/7p/P1NPPQ/2P2PP/7P/2KR1B1R/ b +{23 6257 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr2r/p2q1p/n1p1ppb/Np5p/P2PPQ/2P2PP/7P/2KR1B1R/ b +{-12 6509 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2kr2r/p2q1p/n1p1p1b/Np1P1p1p/P3PQ/2P2PP/7P/2KR1B1R/ b +{-120 11880 24} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard rn2k2r/5ppb/ppN1p2p/1B/P2PP/q4P/6PP/1R1Q1R1K/ w kq +{-46 77418 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r2qk2r/pp1n1ppp/2p1p1b//PbBPn1P/2N1PN/1P2QP1P/R1B2RK/ w kq +{-13 75538 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pp1n1ppp/2p1p1b/3nP/PbBP/2N2N/1P1BQPPP/R4RK/ b +{-38 6647 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2rk/pp1nBppp/4p/b2q/1p1P/P3PP/3N2PP/R2QKB1R/ b KQ +{78 37913 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1b2k/pp1n1ppp/4p/3q/Q2P/p3PP/3K2PP/R4B1R/ b +{41 31139 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r1bqkb1r/p2n1p/2p1pn/1p2P1B/2pP/2N2Q/PP3PPP/R3KB1R/ b KQkq +{-123 28607 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard 2bqkb/Q4pr/1n2p/1N2P2n/2pP3P//PP3PP/R3KB1R/ b KQ +{-141 22141 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbqk2r/pp3ppp/2pb1n/3p2B/3P/2N1PN/PP3PPP/R2QKB1R/ b KQkq +{-18 16316 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard rnbq1rk/pp3ppp/2p2n/3p2B/1b1P/2NBPN/PPQ2PPP/R3K2R/ b KQ +{-35 7159 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r3k2r/1pqn1p1p/p1pbbnp/3p2B/3P/2NQPN/PP2BPPP/R1R3K/ w kq +{29 24834 24} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2q1rk/pp1b1ppp/1npbpn//3PP/2NB1N/PPQ2PPP/R1B2RK/ b +{-99 23851 28} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.02"] +setboard r4rk/1pqb1ppp/p1pbp//1n1PP/PBN2N/1P1BQPPn/2R2RK/ w +{176 24837 28} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r2qkb1r/pb1n1ppp/2p1pn/1p/3P/2NBPN/PP3PPP/R1BQ1RK/ b kq +{-48 23869 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3kb1r/5ppp/p3bP/2n/2p/2p2N/PPB2PPP/R1BR2K/ b kq +{-97 37458 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.02"] +setboard r3kb1r/5ppp/p3bP/2n/2p/5N/PBB2PPP/R2R2K/ b kq +{-147 39798 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2q1rk/pbp1bp/1p2p/3PP1pp/2P2B/2N3PP/PP3nB/R2Q1RK/ w +{117 90949 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2q1rk/pbpnbppp/1p1pP//2P/2N2NP/PP1QPPBP/R4RK/ b +{-113 39733 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r4r1k/p1R3pp/1n3b/1p1p1p/3P1B1P/4N1P/PP2PP/2R3K/ w +{216 22813 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r4rk/pbq2ppp/1p1ppB//2P1n/1P3NP/P2QPPBP/R2R2K/ w +{80 30539 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2q1rk/pbp1bp/1p2p/3PP1pp/2P2B/2N3PP/PP3nB/R2Q1RK/ w +{117 90949 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2q1rk/p2p1ppp/1p2pb/1Pn1N/2P2B/2Q3P/P3PPKP/3R1R/ b +{17 6582 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2q1rk/3p1p1p/pp2pb/1PB1N1p/2P/2Q3P/P3PPKP/3R1R/ b +{-9 170153 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2q1rk/pbp1bp/1p2p/3PP2p/4Ppn/2N3PP/PP3PB/R2Q1RK/ w +{1 71575 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2q1rk/pbp1bp/1p2p/3PP2P/4P/2N/PP3pB/R2Q1RK/ w +{76 45894 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2q1r1k/p1p2p/bp2p/2bPP2P/4P1Q/2N/PP3KB/R2R/ w +{22 12557 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2q1rk/pbpnbppp/1p1pP//2P/2N2NP/PP1QPPBP/R4RK/ b +{-113 39733 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard q4rk/p1ppb1pp/bp/4np//1NN1P1P/PPQ2P1P/R2R2K/ w +{77 10450 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r3k2r/1bq1bppp/pp1ppn/4n1B/2PQ/2N2NP/PP3PBP/R2R2K/ w kq +{-87 76053 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r4rk/2q1bppp/pp2pn/4p1B/2P/2N1Q1P/PP3PKP/R2R/ w +{-130 88934 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2qkb1r/1b1p1ppp/ppn1pn/2p/2P/1QN2NP/PP1PPPBP/R1B2RK/ w kq +{7 9746 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard 1r2kb1r/3p1ppp/4pn/n1p/N/P2b1NP/1P1P1PBP/R1B1R1K/ w k +{-54 10517 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1b1kb1r/pp3ppp/1qn1p/1B1p2Bn/3P/2N1PN/PP3PPP/R2QK2R/ b KQkq +{-44 7029 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1b1kb1r/pp4pp/1qn1pp/1B1p2Bn/3P/2N1P/PP1N1PPP/R2QK2R/ b KQkq +{-79 7094 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1b1k2r/pp5p/1qB1p1P/3p2p/3P/2b1P/PP1N1P1P/R2QK2R/ b KQkq +{-120 170673 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbqkb1r/1p2pppp/p1p2n/2Pp/3P/2N2N/PP2PPPP/R1BQKB1R/ b KQkq +{-35 6964 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnb1kb1r/5ppp/pqp1p/3p3n/3P/2N2N/PPQBPPPP/R3KB1R/ b KQkq +{-74 23293 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnb1k2r/5ppp/pqpbp/3p3n/3PP/2N2N/PPQB1PPP/R3KB1R/ b KQkq +{-123 22379 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbqk2r/5ppp/p1p1p/3pP2n/N2P1b/5N/PPQB1PPP/R3KB1R/ b KQkq +{-136 185053 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbq1rk/6pp/p1p1p/3pPpNn/N2P//PP1QBPPP/R3K2R/ b KQ +{-195 7159 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2q1r/p2n1pk/3bp1p//P/1Q3N/1Pp2PPP/R1B2RK/ b +{-26 31931 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r4r/p1qn1pk/3bp1p//P/1Q3N/1PpB1PPP/R4RK/ b +{-122 28344 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2qkb1r/pb1n1p/2p1pP/1p4B/2pP/2N2Q/PP3PPP/R3KB1R/ b KQkq +{-94 30779 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbqk2r/pp3ppp/2p2n/3p2B/3P/2Q2N/PP2PPPP/R3KB1R/ b KQkq +{-13 16316 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2qkb1r/pb1n1ppp/2p1pn/1p/3P/2NBPN/PP3PPP/R1BQ1RK/ b kq +{-48 23869 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r3kb1r/1b1nq1p/p3pn1p//N1pQP/1P3N/1PB2PPP/R1B1K2R/ b KQkq +{-66 37978 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1bqk2r/3n1ppp/4pP/1p/1b1p/3B1N/PP1B1PPP/R2QK2R/ b KQkq +{-72 185049 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard 2rq1rk/1p1b1ppp/p1n1p/3p/Q2PnP/2N2N/PP2BPPP/4RRK/ b +{101 31931 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1bqkb1r/pp3ppp/n1p2n/3p/3P/3BPN/PP3PPP/RNBQK2R/ w KQkq +{15 21186 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1b1kb1r/pp1p1ppp/1q2pn/4n/2P/1NN3P/PP2PP1P/R1BQKB1R/ w KQkq +{-55 21381 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2qk2r/pp3ppp/2nb1n/3N/2pPP1b/P4N/2QBBPPP/R4RK/ w kq +{132 22923 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1bq1rk/ppn1b1pp/5p/2p/2Nn1B/2NP2P/PP2P1BP/R2Q1RK/ b +{-33 16382 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard rqbnkb1r/3p2pp/1p2p/1ppP1p/2P1QB/5N/PP2BPPP/R4RK/ w kq +{56 29980 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard 2k2b1r/pp4pp/2P1b/q4p/2p/2P1B1P/P4PBP/R2rNRK/ w +{168 40042 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbqk2r/pp1pppbp/5np//2PNP/2N/PP3PPP/R1BQKB1R/ b KQkq +{-33 16316 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r4rk/pp2ppb/2bp1np/q4P1p/2P1P/2NQB/PP2B1PP/R4RK/ w +{86 10450 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r3r1k/p3Rpb/3p2p/3P1P1p/b1P/3QB/q3B1PP/5RK/ w +{49 27764 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1b1r1k/pp1p1ppp/n1q1p//1PP/P1N1P/5PPP/R2QKB1R/ b KQ +{-14 11432 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1bq1rk/pppnbpp/4pn/3P2p/3P/2N1PN/PPQ2PPP/R3KB1R/ w KQ +{-173 39715 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard 4r/pp1r1kpp/1np1pp/5P/3P/1BP1P/P5PP/2R2RK/ b +{-66 10473 52} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r1bq1rk/pp1n1pp/2p2b1p/4p/2BPN/4PN/PP3PPP/2RQ1RK/ b +{-42 38628 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbq1rk/ppp1Bpp/4p2p/3p/2PPn/2N2N/PP2PPPP/2RQKB1R/ b K +{9 195899 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1bq1r1k/ppp1bp/2n1p2p/3p2p/2PPn/2N1PNB/PP2BPPP/2RQK2R/ w K +{-15 75538 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rn1q1rk/pbp1bp/1p5p/3N2pn/2B/4PNB/PP3PPP/2RQK2R/ b K +{-54 173479 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rn1q1rk/pbp1bp/7p/1p1N2p//1B2PNP/PP3PP/2RQK2R/ b K +{-176 6834 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rn3rk/pb2qp/2p4R/1p4p//1B2PNP/PP3PP/2RQK/ b +{-296 15806 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1bqk2r/pp2bppp/4p//3Nn/3B/PP1B1PPP/R2Q1RK/ w kq +{-46 22091 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rnbqkb1r/1pp2ppp/p3pn//2BP/2N1PN/PP3PPP/R1BQK2R/ b KQkq +{-34 23293 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1b1kb1r/p1q2ppp/2p2n/1p2n/3PP/2NB/PP3PPP/R1BQ1RK/ w kq +{55 22338 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2qk2r/ppp2ppp/2b1p/3P/3P/1Q/PP1KPPPP/R4B1R/ b kq +{92 55530 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1bqk2r/ppp2ppp/2n1pn/3p/QbPP/5N/PP1NPPPP/R1B1KB1R/ w KQkq +{-62 5128 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r3qrk/nppb1ppp/1n2p/pP/PbBPP/5N/2QN1PPP/1RB2RK/ w +{-20 21594 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r3qrk/np1b1ppp/1np1p/pP/Pb1PP/1B3N/2QN1PPP/1RB2RK/ w +{-73 39585 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard 3r1rk/1ppbq1pp/p1n1pp//1P1P/P1Q1P1P/3N1PBP/R4RK/ b +{-43 24371 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard 1r1q1k1r/5ppp/2Bppn1b/p1p/2P/6P/PP2PP1P/RN1Q1RK/ w +{36 29315 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r1bqk2r/pp1pnppp/4pn/3P/1pP/4PN/PP3PPP/RN1QKB1R/ w KQkq +{-10 6883 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rn1qk2r/pbp2ppp/1p1bpn/3P2B/3P/P1N2N/1P2PPPP/R2QKB1R/ b KQkq +{-11 39148 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r3k2r/1bqnbppp/p3p//p2NP/2PBB/2Q2PPP/R4RK/ w kq +{-24 58880 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard rq3r1k/p2nb1pp/1p2p/2p2P/1P1P/P1QB1b/3B1PPP/R4RK/ w +{11 169294 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2qk2r/pbpn/1p1pp/5ppp/2PPn/2PBPNB/P1Q2PPP/1R3RK/ w kq +{-111 5583 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard rn1q1rk/pb1p1p/1p1Npn1p/6p/2P4B/P1Q/1P2PPPP/R3KB1R/ b KQ +{-39 10029 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard r2q1rk/p2n1p/1p2p2p/3p2p/2P1b/P1Q2PB/1P2P1PP/3RKB1R/ b K +{-101 23452 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r2qkb1r/1b3ppp/ppn2n/2ppN/3P/P1N1P/1P2BPPP/R1BQK2R/ w KQkq +{11 12676 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard 3r1rk/1bpqbppp/pp3n/4N/1PB/P3P/2QBNPPP/4RR1K/ b +{-13 193267 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.03"] +setboard 3r1rk/1bp1bppp/pp3n/4N/1PB/PQ2P/3qNPPP/4RR1K/ b +{-165 22769 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.03"] +setboard r3kb1r/3b1ppp/p2q/2pp/6n/2BBP/PPQ2PPP/RNR3K/ w kq +{14 5518 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 3rr1k/pbp2ppp/1pn2q/3p/Q2PnB/P4NP/1P2PPBP/3RR1K/ b +{-10 27964 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3k2r/p1pq1ppp/bpn1pn/b2p/Q1PP/5NP/PP1NPPBP/R1B2RK/ w kq +{19 24640 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/pbp1bppp/1p1pPn//1nP/1PN2NP/P2BPPBP/RQ3RK/ b +{-51 39733 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2qk2r/p4ppp/b3p/2pn2N/3n/1PN3P/P2QPPBP/R3K2R/ w KQkq +{50 10022 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2rqk2r/p4ppp/b3p/2p/1n1nN/1PN3P/P2QPPBP/2KR3R/ w k +{-41 12866 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1r1k/pp1p1ppp/n1q1p//1PP/P1N1P/5PPP/R2QKB1R/ b KQ +{-14 11432 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2r1k/1pq2pbp/p2p1np/P1pP/4PB/1QN2B1P/1P3PP/R3K2R/ b KQ +{7 11513 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r1k/1pq2pbp/p2p1np/P2Pn/1Qp1PB/2N4P/1P2BPP/R4RK/ b +{-65 28408 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/p4p1p/3p1np/1ppP/4PB/2Q/PP1N1PPP/R3KB1R/ b KQ +{-31 5729 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1r1k/pp1nqpbp/3p2pn/1NpP/P3PP/1Q3B1P/1P1N2P/R1B2RK/ b +{-55 28412 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqr1k/1p1n1pbp/p2p2p/2pP/P1N1n/2N/1P2BPPP/R1BQ1RK/ w +{-29 75538 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq2k/1p3pbp/pn1N2p/2pP/P2r//1PQ1BPPP/R1B2RK/ w +{-47 175787 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2bp1p/n1p/3p2p/3P1B/1N2P1Pn/PP3PBP/RN1Q1R1K/ w +{-52 6038 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rn1q1rk/1pp1bppp/p1b1p/3n/P1QP1B/5NP/1P2PPBP/RN3RK/ w +{-33 9345 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp1bppp/2n1pn/3p/2P/1P3NP/P2PPPBP/RNBQ1RK/ w +{-33 5835 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqr2k/ppp3pp/3b1p/3B/3P3Q/2B3P/PP1KPP1P/R6R/ b +{-7 32059 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r1k/1p3pbp/p1qpbnp/2p1n1B/2P1PP/1QN1N/PP2B1PP/R3R1K/ b +{-56 10148 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r2k/1p3pbp/p1qpbnp/2pN1PB/2P1P1n/1Q2N/PP2B1PP/R3R1K/ b +{-120 39278 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r2k/1p3pbp/p1qpbn/2pN1PB/2P3n/1Q2N/PP2B1PP/R3R1K/ b +{-194 75038 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1q1rk/ppp1ppbp/3p1np//2PPP1b/2N2N/PP2BPPP/R1BQ1RK/ b +{-37 10937 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 1r1qr1k/Q1p2pbp/3p1np/4n/2P1P1b/2N1BN/PP2BPPP/R4RK/ b +{-32 57977 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 3qr1k/Q1p2pbp/3p1np//2PNP/4Bb/P4P1P/1R3RK/ b +{82 55061 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp3bp/2np1pp/3Pp/2P1P1nB/2N2N/PP2BPPP/R2QK2R/ b KQ +{-54 11562 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1qrk/pp3nbp/n1pp2p/4Pp/2PQ/2N2NBP/PP2BPP/3R1RK/ w +{-13 30683 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1qrk/pp3nbp/n1p3p/4p/P1P2p1Q/2N2NBP/1P2BPP/3R1RK/ w +{-77 21462 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbr2k/ppp2pbp/5np/4p1B/2P1P/2N2N/PP2BPPP/R3K2R/ b KQ +{-51 22458 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2r2k/pp1n1pb/2pPb1pp/4p/4P/P3BN/1P2BPPP/2KR3R/ w +{3 8917 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2r2k/pp3pb/1npPb1pp/4p/4P/P3B/1P1NBPPP/2KR3R/ w +{-37 9547 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp2pbp/n2p1np/4P/2P1P/2N2N/PP2BPPP/R1BQ1RK/ b +{-78 39211 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1br3k/ppp4p/5ppB/2P/1nB1N//Pb3PPP/1R2R1K/ b +{-449 8857 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp3bp/2np1pp/4p/2PPP1nB/2N2N/PP2BPPP/R2Q1RK/ b +{-53 38628 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp3bp/2np1pp//2PpP1n/2N2N/PP2BPPP/R1BQ1RK/ w +{5 10322 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqr1k/ppp3bp/3p2p/1N3P/2Pn2n//PP2BPPP/R1BQ1RK/ w +{-45 75489 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1r1k/1ppnn1bp/3p2p/p2Ppp/1PP1P/P1N/1B1NBPPP/1R1Q1RK/ b +{-47 11123 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1r1k/1ppqnpbp/6p/pP1P/2B1Pp/1QN2N/P4PPP/4RRK/ b +{-55 28412 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1br2k/2p1npbp/1p1q2p/pP1PP/P1B2p/1QN2N1P/5PP/4RRK/ b +{-31 30315 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rBr3k/pp2ppbp/6p/q4b/3P/4PN/PP1Q1PPP/R3KB1R/ b KQ +{-29 258784 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1k1r/ppp2p1p/5bp/3p2N/3P1Q1P/2N/PP2PPP/R3KB1R/ b KQ +{-51 15805 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r1k/pp2Bpbp/3P2p/q1p2b/1n/2N2P/PP1Q1P1P/R2K1B1R/ b +{196 10905 32} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/1p1nppbp/p5p/2pPP/1nQ2B/2N2N/PP2BPPP/1R3RK/ w +{72 5640 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1q1rk/pp2ppbp/1np3p/3P/4P1b/1QN1BN/PP2BPPP/R3K2R/ b KQ +{-17 39146 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/ppp1ppbp/6p/1q1P/Nn2P/1B1b1N/PP1Q1PPP/R3R1K/ w +{101 24704 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqr1k/1p4bp/1npp2p/p4p1n/P1PN/1PN3PP/1B1QPPB/3R1RK/ w +{17 43675 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/ppp2ppp/4pn//2BP2b/1Q2PN/PP3PPP/RNB1K2R/ b KQkq +{-46 87390 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnq1kb1r/ppp2ppp/4p/4n2b/2BP/1Q2P2P/PP1B1PP/RN2K2R/ w KQkq +{-14 71963 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/1pp2ppp/pq2p/4P2b//1Q2P2P/PP1B1PP/RNR3K/ w kq +{29 260689 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/1b1n1ppp/pn2p//Bp1N1N//PP3PPP/R1BR2K/ w kq +{-96 89304 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/1p3ppp/p3pn/2P/2B/4PN/PP3PPP/RNBQ1RK/ b kq +{-68 258299 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2qkb1r/pp1b1ppp/2n1pn/1Bpp/3P/4PN/PPP2PPP/RNBQ1RK/ w kq +{2 9345 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1q1rk/2p1bp1p/ppbpp2B//3P3p/P2Q1NP/1PP1PP/R4RKB/ b +{14 28477 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/pb1p1ppp/4pn/1pp3B/3P/5NP/PPP1PPBP/RN1Q1RK/ b kq +{-78 7159 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/p4p1p/b2qpp/1p1p//1P1QP1P/P1P2PBP/RN3RK/ w kq +{1 24773 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1rk/1pp1ppbp/p5p/3p1b/1n1P1P1P/2N1QN/PPP1BPP/2KR3R/ w +{10 25283 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qk2r/ppp1ppb/3p2pp/7n/2BP2bB/2N1PN1P/PPP2PP/R2QK2R/ b KQkq +{-70 23774 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn3r1k/p3p1bp/1ppq2p/3P2p/P1BP/1Q3N1P/1P3PP/R4RK/ b +{-88 30571 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/p1p2pbp/1pn3p/3q1p/3P/2PB1N/PP1N1PPP/R2QR1K/ b +{-1 23802 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3k2r/pp1n1ppp/3b1n/q2pp2b/2P4N/3P2P/PP1NQPBP/R1B2RK/ w kq +{49 29964 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/pp2pppp/2p2n/3p/3P2b/5NP/PPP1PPBP/RNBQ1RK/ b kq +{-39 11513 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/pp1pppbp/5np//2PNP/2N/PP3PPP/R1BQKB1R/ b KQkq +{-33 16316 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp1pnppp/2n1p/2p/B3P/5N/PPPP1PPP/RNBQ1RK/ b kq +{-34 11188 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k2r/2qp2pp/2p1pp/p/1bnNP/2N1B/PPPQ1PPP/3RR1K/ w kq +{-56 28811 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk2r/ppnpppbp/2n3p/2p1P/B/2N2N/PPPP1PPP/R1BQR1K/ b kq +{-41 9962 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kbnr/ppqp1ppp/2n1p/1N/4P/2N/PPP2PPP/R1BQKB1R/ b KQkq +{-82 32370 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kb1r/1p1p1ppp/p1N1pn/4q/N3P/4B/PPP2PPP/R2QKB1R/ b KQkq +{-102 72371 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp2pppp/2np1n//3NP/2N1B/PPP2PPP/R2QKB1R/ b KQkq +{-41 6452 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 1rq1kb/p2b2p/4pp1r/N3p2p//2N1P1Q/PPP3PP/1R3RK/ w +{28 9312 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 1rq1kb/p2b2p/4pp1r/4p/7p/1NN1P1Q/PPP3PP/1R3RK/ w +{-5 30614 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkb1r/pp1bpppp/2np1n/1B4B/3NP/2N/PPP2PPP/R2QK2R/ b KQkq +{-48 6452 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kbr/pp1bpp1p/3p1p/q3n/3NPN/5B/PPP2PPP/R2Q1RK/ w q +{28 12742 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2bppp/2nppn/6B/4P/1NN/PPPQ1PPP/2KR1B1R/ b +{-34 6192 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r5k/1p1bbppp/1qnppn/1B/4PB/rNN2P/P1PQ2PP/1K1R3R/ b +{121 6444 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2bpp/2nppn1p//3NPP1B/2N/PPPQ2PP/2KR1B1R/ b +{-63 30779 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qk2r/3bbppp/p1nppn/1p2P1B/5P/2N2N/PPPQ2PP/2KR1B1R/ b kq +{-89 5729 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4k1r/1p2qpp/p1bNp/4P2p/3Q2n/P/1PP3PP/2KR1B1R/ w +{136 25283 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkb1r/3b1ppp/p1nppn/1p2P1B/3N1P/2N/PPPQ2PP/2KR1B1R/ b kq +{-75 39211 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4b1r/1n1k1p1p/p2qp/5p/1p3P/3Q/PPP1N1PP/1K1R1B1R/ w +{140 9932 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkb1r/1p3pp/p1bppn1p//4PB/2N2P/PPPQ2PP/2KR1B1R/ b kq +{-53 6444 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2qkb1r/1p3pp/p1b1pn1p/4B/4p/2N2P/PPPQ2PP/2KR1B1R/ w kq +{36 29515 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk2r/1p2bpp/p1Nppn1p//4P/2N1B/PPPQ1PPP/2KR1B1R/ b kq +{-55 72369 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 1r3rk/4bpp/Q2pbn1p/p3p/1qp1P/PBN1BPP/1PP4P/2KR3R/ b +{46 31833 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp2pp1p/2np1np//3NP/2N/PPP1BPPP/R1BQ1RK/ b kq +{-51 23802 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kb1r/pp3ppp/1qnppn//2B1P/1NN1B/PPP2PPP/R2QK2R/ b KQkq +{-44 32489 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 5rk/nq4pp/3pb/pB1NpPb/2P/N/1P3PPP/3Q1RK/ b +{-17 88300 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/6pp/p1np/1p1Nppb/4P/2P/PPN1BPPP/R2QK2R/ w KQ +{-33 9507 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qk2r/5pbp/p1npb/1p1Npp/2P1P/N2B/PP3PPP/R2Q1RK/ b kq +{-47 38561 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 1r1q1rk/5p1p/2npb2b/1N1Np/4B//PP3PPP/R2Q1RK/ w +{212 11427 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kb1r/3p1ppp/p1q1pn/1p/4P/2NBBQ/PPP2PPP/R4RK/ b kq +{-45 23674 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/1p1pnppp/p1n1p/6B/3NP/2N/PPP1BPPP/R2QK2R/ b KQkq +{-118 30779 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/1p1p1ppp/p1n1p/q1b/4P2P/P1N3Q/1PPBBPP/R3K2R/ b KQ +{-84 22242 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/1p3ppp/p1npp//3NP/2N3P/PPP1BP1P/R1BQK2R/ b KQkq +{-34 23869 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp1pppbp/5np/n3P/3N/1BN1B/PPP2PPP/R2QK2R/ b KQ +{-97 173152 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp1ppp1p/6p/3N/3Q/4B/PPN2PPP/4K2R/ b K +{-124 6899 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2pp1p/3p2pB/3N/3Q//PPN2PPP/4K2R/ b K +{-208 6452 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk2r/pp1pppbp/6p//2PnP/2N1B/PP3PPP/R2QKB1R/ b KQkq +{-37 10907 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2ppbp/2Np1np//2P1P/2N1B/PP2BPPP/R2QK2R/ b KQ +{-33 72369 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2r/pR1bppkp/3p2p/q2P/4P/3Q/P3BPPP/5RK/ w +{73 24709 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp2pp1p/3p1np//2PQP/2N/PP2BPPP/R1B1K2R/ b KQkq +{-39 23997 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2ppbp/3P1np//3QP/2N/PP2BPPP/R1B1K2R/ b KQ +{-48 64251 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2r1n1rk/pp2Bp1p/3pb1p//4P/2P/PK2BPPP/3R3R/ b +{-95 27322 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/1p1ppppp/p/2p/4P/2N2N/PPPP1PPP/R1BQKB1R/ b KQkq +{-84 6257 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqkbnr/1p1p1ppp/p1n/2p1p/4P/2N2N/PPPPBPPP/R1BQK2R/ w KQkq +{59 5323 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 1r1qk2r/3bbppp/p2p2n/1PpPp/P/1Q1P1N/1P2BPPP/R1B2RK/ w k +{34 21762 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/1p3ppp/p2ppn//3NP/2N1B/PPP1BPPP/R2QK2R/ b KQkq +{-47 23869 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1kb1r/1p2qppp/p2p/3P2N/2Bnp//PPPBQPPP/R3K2R/ w KQkq +{-42 28876 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1kb1r/5ppp/p2p/1p1Pq1N/2Bnp//PPP2PPP/R1BQK2R/ w KQkq +{-87 5258 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnb2b1r/1p2k/p2ppp1p//2BNP/q1N/P1PQ2PP/1R2K2R/ w K +{-32 29899 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/2qnbppp/p2pp/1p4PQ/3NPP/2NR/PPP4P/2K2B1R/ b +{-14 6379 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1r2nk/2q1bp1p/4p1pQ/pB1pP1P/1p1N1P/P6R/1PP4P/2K4R/ b +{282 22708 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2k1r/1b1nb2p/p2p1n/1p3N/1q1BP/2N2Q/PPP2PPP/R4RK/ w +{38 24768 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1kb1r/1pq1pppp/p2p1n//3NPP/2N/PPP1B1PP/R1BQK2R/ b KQkq +{-42 6452 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/1p1n1ppp/p2ppn//3NPP/2N1BQ/PPP3PP/R3KB1R/ b KQkq +{-63 6444 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/1b3ppp/p2b/2pP3Q/1p/4B/PPP1B1PP/2KR3R/ b +{62 28477 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1b1r/1p3kp/p2pn/3N1p1p/P2Q1B/5B/1PP3PP/4RRK/ w +{156 29915 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/4bppp/p1np1n/4p/1pQ1P/1PN1BPPB/PP5P/2KR3R/ b +{3 70809 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp3pp/2nppn/6B/3NP2P/2N/PPP2P/R2QKB1R/ b KQkq +{-53 23869 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk2r/4bpp/p2ppn/2p3B/4P2P/2NQ/PPP1BP/R3K2R/ b KQkq +{-88 31355 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp3pp/2nppn/6Pp/3NP2P/2N/PPP2P/R1BQKBR/ b Qkq +{-69 10157 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b2b/p4kp/1qppp//4P1pr/2N/PPP2P/R1BQK1R/ w Q +{-5 5193 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3nrk/ppq1pp1p/2bp2pQ//4P1P/1BN2P/PPP/R3K2R/ b KQ +{-223 11132 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2ppbp/3p1np//3BP/2N2P/PPPQ2PP/2KR1B1R/ b +{-34 23354 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 1r4k/5pbp/3p1np/pP1P/3B/2P2P/2KQ2PP/q4B1R/ b +{16 28473 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pp2ppbp/2N2np/3p/4P/2N1BP/PPP1B1PP/R2Q1RK/ b +{-38 72369 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/pp1npppp/3p/1Bp/4P/2P2N/PP1P1PPP/RNBQK2R/ b KQkq +{-48 6704 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2kbnr/pp1qpppp/3p/2p/4P/5N/PPPP1PPP/RNBQ1RK/ b kq +{-44 6452 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkbnr/pp1bpppp/2np/1Bp/3PP/5N/PPP2PPP/RNBQ1RK/ b kq +{-63 38626 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/3bppp/p1pp/q/4P1np/2N3Q/PPP1BPPP/R1B2RK/ w kq +{55 30550 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/pp2pppp/2np/1B/3QP/5N/PPP2PPP/RNB1K2R/ b KQkq +{-59 6452 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/pp1qpppp/2bp1n//2PQP/2N2N/PP3PPP/R1B1K2R/ w KQkq +{-13 10450 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1kbnr/1pqp1ppp/p3p//3NP/2NB/PPP2PPP/R1BQK2R/ b KQkq +{-63 11134 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1kb1r/2qp1ppp/p3pn/1p/3NP/2NB1Q/PPP2PPP/R1B2RK/ b kq +{-96 23674 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2nrk/1bqp1ppp/p/4pN/Nb2P2B/2PB1Q/1P3PPP/R4RK/ b +{-165 23257 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2nrk/1bqp1ppp/p2b/4pN/N3P2B/2PBQ/1P3PPP/R4RK/ b +{-233 23217 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/1p1p1ppp/p3p/2p/4P/2N2NP/PPPP1P1P/R1BQKB1R/ b KQkq +{-50 10937 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/1p3ppp/p1npp//3NP/2N1B1P/PPP2P1P/R2QKB1R/ b KQkq +{-54 11134 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/pp3ppp/3pp//3NP/2N/PPP2PPP/R1BQKB1R/ b KQkq +{-44 11134 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2r1k/pp3ppp/3Bp/1N//P/1nP2PPP/1R3RK/ b +{-76 9865 52} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqr1k/pp2bppp/5n/3pN/3P1B//PP1NQPPP/R3KB1R/ b KQ +{203 31355 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1r1k/pp3ppp/1q3n/3pN/1b1P1B/5N/PP2QPPP/R2K1B1R/ b +{244 22458 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rn1qkbnr/pp1b1ppp//1Bpp//2P2N/PP1P1PPP/RNBQK2R/ w KQkq +{36 187617 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2qk2r/pp2nppp/1n1b/3p/2pP/1QP2N/PP3PPP/RNB1R1K/ w kq +{-51 30801 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk1nr/1p1p1ppp/p3p/2b/4P/1N1B/PPP2PPP/RNBQK2R/ b KQkq +{-73 23266 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/1p2bppp/p2ppn//3NP/2NBB/PPP2PPP/R2Q1RK/ b kq +{-35 16316 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/2qnbppp/p2pp/1p3PPQ/3BP/2NB/PPP4P/R4RK/ b +{-89 6444 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/2qnbppp/p2p/1p1NpPPQ/3BP/3B/PPP4P/R4RK/ b +{-141 32498 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/3nbppp/p2p1P/1p1Np1PQ/3BP/3B/PPP4P/R4RK/ b +{-330 56180 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1k1nr/pp1pppbp/6p/q1P/4P/2P2N/PP3PPP/RNBQKB1R/ b KQkq +{-68 63648 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1knr/pp1p1p1p/2n3p/1N2p/4P/P1P/2P2PPP/R1BQKB1R/ w KQ +{82 10977 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2kr1b1r/pp1qnppp/2n/2p/4bN/2NP2P/PP3P1P/R1BQR1K/ w +{-24 169747 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkbnr/pppn1ppp/3p/4p/2PP2b/2N2N1P/PP2PPP/R1BQKB1R/ b KQkq +{-63 38628 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkbnr/ppp1pppp/3p//3PP1b/5N/PPP2PPP/RNBQKB1R/ b KQkq +{-50 11134 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/ppp1pppp/5n/3p/3PP1b/2N2N1P/PPP2PP/R1BQKB1R/ b KQkq +{-78 87390 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/ppp1pp1p/3p2p//3P/2N2N/PPP1PPPP/R1BQKB1R/ b KQkq +{-53 23997 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqr1k/1pp2ppp//p2pP/4n/PP2PN/2PB1PPP/R2QKB1R/ b KQ +{2 22458 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqr1k/pp2bpp/2n2n1p/3p/3N/1QN1B1P/PP2PPBP/R4RK/ b +{-40 10282 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1q1r1k/pp1bbpp/2n2n/3p3P/3N/P1N1B2P/1P2PPB/R2Q1RK/ w +{-19 43218 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1kbnr/ppq1pppp///2BQ/4PN/PP3PPP/RNB1K2R/ b KQkq +{-79 23354 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kbnr/ppq1pppp/2n1b/1N/2BQ/4PN/PP3PPP/R1B1K2R/ b KQkq +{-111 30770 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kbnr/pp2pppp/4b/BN/2B/4PP/PP3P1P/R3K2R/ b KQkq +{-202 186028 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rq2kb1r/1p1b1ppp/p1n1pn/1N//1QNBP/PP1B1PPP/R4RK/ w kq +{20 9953 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkbnr/pp2pppp/2p/3p/3P2b/5NP/PPP1PPBP/RNBQK2R/ b KQkq +{-39 11513 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2qk2r/1ppb1ppp/p1n1p1n/2b1P/2Bp/3P1NP/PPPN1P1P/R1BQ1RK/ w kq +{-32 9995 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1rk/pp1bppbp/2np1np//2PNP/2N1B/PP2BPPP/R2Q1RK/ w +{0 8859 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/ppp1npbp/3p1np/3Pp/4P1b/2N1BN1P/PPPQBPP/R4RK/ b +{-42 87390 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1rk/pp3pbp/2nB2p//4P/2N2b/PPPQ2PP/3R1RK/ w +{-21 189765 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/pp2ppbp/2pp1np/4P/3P/2N2N/PPP1BPPP/R1BQ1RK/ b +{-60 39211 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/ppp1ppbp/3p1np//3PP/2N1BN1P/PPP2PP/R2QKB1R/ b KQ +{-52 10937 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3k1nr/p1p2ppp/2pb//4p1q/1PN1PbP/PBP1NP1P/R2Q1RK/ w kq +{-249 42770 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqr1k/ppp1npbp/6p/3Pp/4P/BQP3P/P4PBP/R3K1NR/ b KQ +{17 6574 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/ppp2ppp/4pn//Q1pP/P1P3P/4PPBP/R1B1K1NR/ b KQ +{16 12077 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbqk2r/ppp2ppp/4pn/3p/1bPP/2N3P/PP2PP1P/R1BQKBNR/ w KQkq +{-68 29891 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 4r1k/pb3ppp/qprppB/2n/1QP2N/2P2P/P2RP1PP/2K2B1R/ b +{107 170870 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbq1rk/pp1p1ppp/4pn/2b/2P2B/2N/PPQ1PPPP/R3KBNR/ w KQ +{-37 5388 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb2rk/ppp1qpp/5n1p/3p/3P/P1B2N/1PQ1PPPP/R3KB1R/ b KQ +{16 28477 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbqk2r/ppp2pp/5n1p/3p2B/1b1P/2N/PPQ1PPPP/R3KBNR/ w KQkq +{-41 88934 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbq1rk/ppp2ppp/4pn/3p/1bPP/2N2N/PPQ1PPPP/R1B1KB1R/ w KQ +{-43 5388 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3r1k/p1pp1pp/bp5p/P2p/2P/P3PP/n1R2KPP/5BNR/ w +{162 90634 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp1bppp/2nppn//2PPP/PQNB1N/1P3PPP/R1B1K2R/ b KQ +{-5 28477 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/pppp1ppp/2n1pn//1bPP/1QN2N/PP2PPPP/R1B1KB1R/ w KQ +{-40 22914 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk2r/pp1p1ppp/2n1pn//1bP/2NQ1NP/PP2PP1P/R1B1KB1R/ b KQkq +{24 6387 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2rq1rk/1p2bppp/pn/4p/3B/PQN2NP/1P2PP1P/R3K2R/ b KQ +{3 169700 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbqk2r/pp1p1ppp/4pn//1bPp/2N2NP/PP2PP1P/R1BQKB1R/ w KQkq +{-48 63171 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qr1k/pb1p1ppp/1pnBpn/1N/2PP/P/1PQ2PPP/R3KB1R/ b KQ +{5 28344 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1k1r/p1p2pNp/bp1p1n/3p/2P2Pn/2Q1P/PP4PP/R1B1KB1R/ w KQ +{1 10614 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqk2r/pp3ppp/2n1p/2Pp/1b1Pn/2N/PP1BNPPP/R2QKB1R/ w KQkq +{-36 75538 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b2rk/p4ppp/3Npq/1pP/2Bn/P/1P3PPP/R2QK2R/ w KQ +{-101 21274 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqr1k/ppp2ppp/5n/n2p/P1PP/3BPN/Q4PPP/R1B1K2R/ b KQ +{67 38563 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1r1k/ppq2ppp/2n/2PpN/1B1P1Pn/P2B/1P4PP/R2QK2R/ b KQ +{43 6192 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/ppp1bppp/4p//3PP/P1N/1P3PPP/R1BQKB1R/ b KQ +{10 6517 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k2r/p2n1ppp/1qQ2n/4p/4P/P1B2P/4N1PP/R3KB1R/ w KQkq +{34 228906 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kb1r/pp1n1p/2p4p/q2p/3P2p/PQN1P1B/1P1K1PPP/R4B1R/ b kq +{-17 23869 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/pp2bp/1np4p/q2pB/3P2p/PQNBP2P/1P1K1PP/R6R/ b +{-90 9897 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/1pp1npp/p2q1b1p/3p/3PP/1QNB1b/PP3PPP/2R2RK/ w +{-32 6428 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2kr3r/1p1n1p/pqpBb2p/b2p2pn/3P/2NBP/1PQ1NPPP/R4RK/ w +{109 10322 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/pp1p1ppp/4p/2p1P/2P/2N2N/PP1P1PPP/R1BQKB1R/ b KQkq +{-42 6899 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rbb1r1k/1p3ppp/p3nn/2p1p/2P/2NP1N/PP2BPPP/R1B1R1K/ w +{-64 10450 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1r1k/1pp2ppp/1pnp1n/6N/1PP1p/P3P2P/1BQPKPP/R6R/ b +{-33 6379 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp2ppp/2n/1N1n//P2Q2P/1P2PP1P/R1B1KB1R/ b KQ +{36 6704 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2r2rk/ppp2ppp/3p1nq/4p1N/2PBP/P2P2P/1P3P1P/R2Q1RK/ b +{-35 169700 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bq1rk/pppp1ppp/2n2n/4p/1bP1P/2N3P/PP1P1PBP/R1BQK1NR/ w KQ +{-35 5323 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pppnppb/3p1npp//2PPP/2N1BN/PP2BPPP/R2QK2R/ b KQ +{-38 6452 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1r1k/pp3pb/1q1p2pp/2p4n/2P1PBPP/2N2P1N/PP1QB/R3K2R/ b KQ +{-64 173927 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/ppp1ppb/3p1npp//2PPP/2N1B/PP2BPPP/R2QK1NR/ b KQ +{-33 11513 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1r/pp1nppbk/3p1npp/2pP/2P1P/2N1B2P/PP1QBPP/R3K1NR/ b KQ +{-50 28477 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r4n/p1qbrpbk/1p1p1npp/3P/1PP3P/2NBBN1P/3Q1P/4RRK/ b +{-100 28472 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1rk/pppb1pb/3p/3Pp1pp/1nP1P1nP/2NB2B/PP1QNPP/R4RK/ w +{-47 5453 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1rk/pppb1pb/3p/3Pp2p/1nP1P1np/2NB1PB/PP1QN1P/R4RK/ w +{-99 71573 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/pp1bppbn/nq1p2p/2pP2Bp/2P1P/2N3N/PP2BPPP/1R1Q1RK/ w +{26 21222 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2r2k/ppq1ppbp/2n1bnp/3N/2P1P/Q3BP/PP4PP/R3KBNR/ b KQ +{-20 31986 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2r2k/pp1qppbp/4bnp/3Nn/2PNP/Q3BP/PP4PP/R3KB1R/ b KQ +{-56 10916 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1r1k/pppb1pbp/2n2np/3Np/2P1P1P/4BP/PP1QN2P/R3KB1R/ b KQ +{-12 6192 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r4b1k/1ppb1p1p/2n3p/p2Pp/2P3Pq/5P/PP1QN2P/R2K1B1R/ b +{34 22141 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3r1k/pp1nppb/nqppb1pp/4P/2PP/2N2NP/PP1BQPBP/3R1RK/ w +{42 6363 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/ppq1ppbp/2n3p/2p/2BPP/2P1B/P3NPPP/2RQ1RK/ b +{-33 22458 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 3r2k/1pqbppbp/r5p/p1pPn/2P1PP/1BN1B2P/P2Q2P/2R2RK/ b +{-96 5664 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb2rk/pppqppbp/6p//2BPP/2P1B/P3NPPP/R2QK2R/ b KQ +{-42 30643 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/pp2ppbp/2p2np/3p/2PP/2N1PN/PP2BPPP/R1BQ1RK/ b +{-49 22906 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/1p2ppbp/p1p2np/3p/2PP/2NBPN/PP1B1PPP/R2Q1RK/ b +{-70 22458 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 3q1r1k/1b2Bpbp/1p4p/1p1p/3Pn/r3PN/PPR2PPP/1N3RK/ w +{36 253684 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/3ppppp/b4n/2pP//2N/PP2PPPP/R1BQKBNR/ b KQkq +{-139 6964 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rr4k/3nbp1p/q2ppp1Q/2pP/4P/2N2N/PP1R1PPP/2K3R/ b +{-98 27704 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/3ppp1p/b4np/2pP//2N2N/PP2PPPP/R1BQKB1R/ b KQkq +{-139 23997 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/4pppp/p2p1n/1PpP//4PN/PP3PPP/RNBQKB1R/ b KQkq +{-149 23802 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/pp1bbp/nq1p3p/2pPp2n/2P1P1p/1PNQ/PB1NBPPP/2R2RK/ w +{24 29331 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1r1k/pp2qp1p/3p2p/2pP3n/3BP/2N3P/PPQN1P1P/R3KB1R/ b KQ +{-8 169698 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r1k/pp1bqp1p/n2p1np/3P/3NP/6P/PPQN1PBP/R4RK/ b +{-35 28344 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r1k/ppp2ppp/2n1pq/3n/3Pb/BQP2NPP/P3PPB/2RR2K/ b +{13 10851 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2rqkb1r/3b1ppp/p3pn/1pp1N/1n1P/1Q4P/PP2PPBP/RNB2RK/ w k +{32 5128 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2rqkb1r/3b1ppp/p1n1pn/1pp1N/3P/PQ4P/1P2PPBP/RNB2RK/ w k +{-41 175332 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 3rkb1r/ppq2ppp/4bn//1nP/7P/PP2PPP/RNBQKBNR/ w KQk +{-252 8897 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/pp2ppbp/2p2np/3P2B/3P/2N2NP/PP2PP1P/R2QKB1R/ b KQ +{-19 31355 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1k2r/pp1n1p1p/2p1p1pB/3pP/2PP/q1P3P/P4P1P/R1Q1KBNR/ b KQkq +{-88 30736 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/pp2bppp/2p1pn/3p/2PP/2NBPN/PP3PPP/R1BQK2R/ b KQkq +{-33 38563 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/pb1nbppp/2N1pn/1p/3P/2NBPQ/PP3PPP/R1B1K2R/ b KQ +{-51 88753 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2r2k1r/pp3p1p/5p/5b//2NQ/Pq3PPP/R4RK/ w +{45 194899 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqk2r/pp3ppp/4pb//3n/3B1N/PP1B1PPP/R2Q1RK/ w kq +{13 21643 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/pp2pp1p/5np/3p2B/2PP/2N/PP3PPP/R2QKBNR/ b KQkq +{-39 11513 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/pp1ppp1p/6p/2p/2P/2N1PQ/PP1PBPPP/R1B1K2R/ b KQkq +{-67 23997 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/pp2pp1p/2n3p/q1p2bN/2P/PPb3P/R1Q1PPBP/2BR2K/ w +{4 5900 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r4rk/pp2ppbp/2nqbnp/2p/Q1P/2N1P1P/PP2NPBP/R1BR2K/ b +{-26 31019 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk1nr/p1pp2pp/2p/5Q/2P/2P/P3PPBP/R1B1K2R/ b KQkq +{-54 11582 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 1rq2rk/2p2pbp/p2p2p/4pbPn/Q1PB3P/2N2N/PP2PPB/RR4K/ b +{147 169700 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/pppnnp1p/3p2p/3P2B/2PQ/2P2NPB/P3P2P/R3K2R/ b KQ +{-59 28477 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqr1k/1p2np1p/2pp2pB/p2Pn/2P2QP/2P2N1B/P3P2P/R4RK/ b +{-183 11492 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 1rbqr1k/ppp2ppp/1bnp1n//2PP/P1NQ2P/1P2NPBP/R1B2RK/ b +{-42 7094 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk1nr/ppp2pbp/3p2p/3Pp/2P1P/2N/PP3PPP/R1BQKBNR/ b KQkq +{-38 6517 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qk1nr/ppp3bp/3p2p/2nP/2P1N/5N/PPQ2PPP/R1B1K2R/ b KQkq +{-110 32059 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3r1k/pBp2p1p/5npB/4b//2N3Pb/PP2PP/3RR1K/ b +{20 28280 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/ppp2ppp/4pn/3p/3P1BP/2N2P/PPP1P2P/R2QKBNR/ b KQkq +{-21 23293 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/pp1ppppp//2pP///PPP1PPPP/RNBQKBNR/ b KQkq +{-36 11134 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/pppn1p1p/3p2p/4P/2P/2N2N/PP2PPPP/R1BQKB1R/ b KQkq +{-56 39211 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/pp2pppp/2pp1n//3PP/2N2N/PPP2PPP/R1BQKB1R/ b KQkq +{-69 6964 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/ppp1pp1p/3p1np//3PP/2N1B/PPP2PPP/R2QKBNR/ b KQkq +{-42 23997 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1qnk2r/pppnpp1p/5bpP//2Bp/2N1BQ/PPP2PP/2KR3R/ w kq +{83 54996 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/ppp1pp1p/3p1np/6B/3PP/2N/PPP2PPP/R2QKBNR/ b KQkq +{-36 23997 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/pp2ppbp/3p1np/2P/4PP/2N2N/PPP3PP/R1BQKB1R/ b KQkq +{-67 30779 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bq1rk/ppp1ppbp/2np1np/3P/4PP/2NB1N/PPP3PP/R1BQK2R/ b KQ +{-33 9834 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/ppp1ppbp/3p1np//3PP/2N1BN/PPP1BPPP/R2QK2R/ b KQ +{-37 10157 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2r2rk/ppqn1ppp/3bpn/1B/P2P/2N1B1P/1PQ2P1P/R3K2R/ b KQ +{52 10477 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk1nr/ppp2ppp//4p/2pPP/5N/PP1Q1PPP/RN2KB1R/ b KQkq +{1 38628 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k1nr/2p2ppp/pbpq/4N/3pPB//PPQ2PPP/RN3RK/ w kq +{99 44388 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k1nr/2p2Npp/pbp//3pPq//PPQ2PPP/RN3RK/ w kq +{27 208885 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3k2N/2p1n1pp/pbp//3pPqb//PP2QPPP/RN3RK/ w q +{-49 29388 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/pppp2pp/4p/5p/3P/2N2N/PPP1PPPP/R1BQKB1R/ b KQkq +{-59 22141 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/ppp3pp/4p/3B1p/3PpB/P1N/1PP2PPP/R2QK2R/ b KQkq +{-60 170220 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1k1nr/pppq1ppp/4p/3pP/1b1P2Q/2N/PPP2PPP/R1B1KBNR/ b KQkq +{-38 87193 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kn1r/p1pq2pp/1pn1p/3pPpBP/1b1P/6Q/PPP1NPP/2KR2NR/ w kq +{98 22502 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1k1r/ppq1np1Q/2n1p/3pP/5P/P1N/2P3PP/R1B1KB1R/ b KQq +{-113 9962 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb2rk/pp2nppp/4p/3pP/q1pP/P1P4Q/2PB1PPP/R2BK1NR/ b KQ +{17 30808 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rn1qk2r/pp1bnppp/4p/2ppP/P2P/2P/2P2PPP/R1BQKBNR/ w KQkq +{-43 21253 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk1nr/p1p2ppp/1p2p/3pP/1b1P2Q/2N/PPP2PPP/R1B1KBNR/ b KQkq +{-57 7094 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1rk/p3np1p/1p2pBp/3pP/1b1N3Q/2N/PPP2PPP/R3KB1R/ b KQ +{-189 6647 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbq1r/p3np1k/1p2pBp/3pP1Qp/1b1N/2NB/PPP2PPP/R3K2R/ b KQ +{-1104 10612 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3k1nr/p1R2p/qp2p1pp/3pP/1b1P2Q/3nBN/PP1RNPPP/6K/ w kq +{129 9356 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kr/pp1b1p1Q/2n1pqn/3p2N/7P/P1R/2PB1PP/1R1K1B/ b q +{92 62317 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbqk1nr/pp3ppp/4p/b2pP/1p1P/P1N/2P2PPP/R1BQKBNR/ w KQkq +{-71 10322 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k1nr/pp5p/4p1p/2qpPpB/3n/P1P3Q/2P2PPP/R3KB1R/ w KQkq +{-13 71378 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2r3nr/pp1k3p/4p1p/3pPpB/3q/P5Q/2P2PPP/R4RK/ w +{-28 24773 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb2rk/ppNn1ppp/4p/3pP2Q/3p/5N/PqP2PPP/2RK1B1R/ b +{12 10867 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard n1b2rk/pp3pp/2n1p2p/3pP1PQ/3p/3B1N/PqP2P1P/2RK3R/ b +{-101 9834 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard n1b2rk/pp3pp/4p2P/3pP2Q/1n1p/3B1N/PqP2P1P/2RK3R/ b +{-146 7094 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/ppp2ppp/4pn/3pP1B/1b1P/2N/PPP2PPP/R2QKBNR/ b KQkq +{-52 7159 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k1r/pp2bpq/n3p/3p/3N3Q/5N/PPP2PP/2KR1B1R/ w q +{125 22597 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r5r/pp1kbpq/n3p/3p/3N3Q/5N/PPP2PP/2KR3R/ w +{21 31199 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r5r/pp1k1pq/n3pb/3p3Q/3N/5N/PPP2PP/2KR3R/ w +{-25 29671 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/pppb1pp/4p2p/3q2N/3P3P/3B/PPP2PP/R2Q1RK/ w kq +{-26 22291 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2kr2r/1b1n3p/1pp1pp/3pP1p/5P/2N2BP/PPP2K1P/3R2R/ w +{-9 39780 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pppn1ppp/4pN//3P/5N/PPP2PPP/R1BQKB1R/ b KQkq +{-34 76659 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1k2r/ppp2ppp/3bpn/4N/2PPq/P3B/1P3PPP/R2QKB1R/ b KQkq +{13 16316 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqk2r/4b1pp/4pn/p1pp/P/1N1Q1N/1PP2PPP/R1B1R1K/ w kq +{32 29971 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b2b1r/pp1n1kpp/2n1pp/3pP/3P1N/3B/PP1N1PPP/R1B1K2R/ w KQ +{-75 39780 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkbnr/1p3ppp/p/2Pp//5N/PPPN1PPP/R1BQKB1R/ b KQkq +{-51 55485 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqkb1r/1p3ppp/p1n2n/2pp/3P/2P2N/PP1NBPPP/R1BQK2R/ w KQkq +{7 10517 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/pp2nppp/2nb/1B1p2B/6b/1N3N1P/PPP2PP/R2QR1K/ b +{-46 23006 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk1nr/pp3ppp/2nb/1Bpp/3P/5N/PPPN1PPP/R1BQ1RK/ b kq +{-33 38626 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/pp3ppp/4pn/2pP/3P/5N/PPPN1PPP/R1BQKB1R/ b KQkq +{-34 43245 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2k2r/ppqbbppp/4p/3n/2BNN/1QP/PP3PPP/R1B1K2R/ b KQkq +{22 10937 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kb1r/1p3ppp/p2qpn//2BN/2P/PP3PPP/R1BQ1RK/ b kq +{-41 31915 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2rr2k/1bq2ppp/pp/2b1pPN/4n/1BP1B2Q/PP4PP/R4R1K/ b +{29 76188 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r5k/1pq2pp/p3pn1p/4b//1BP1BQ/PP1r1PP/3R3K/ w +{-83 221891 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2kr3r/pp1bn1pp/4p/3NP/3Q/4P/P3q1PP/R4RK/ w +{7 77091 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1kbnr/pp3ppp/1q2p/n2pP/2pP/P1P2N/1P1NBPPP/R1BQK2R/ b KQkq +{-46 23802 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1kbnr/pp4pp/1qn1p/3p2N//P1p/1P2BPPP/RNBQK2R/ w KQ +{-31 38025 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/ppppp2p/5np/5p/3P/2N3P/PPP1PPBP/R1BQK1NR/ b KQkq +{-50 23997 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk1nr/pp2ppbp/2p3p/3P/3P/2N2N/PPP2PPP/R1BQKB1R/ b KQkq +{-60 39146 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kbnr/ppp1pppp//1B1P1q/1n4b/2N2N/PPP2PPP/R1BQK2R/ b KQkq +{10 6834 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 3rkbnr/p3pppp/2p/5q/Bn4b/2N2N/PPP1QPPP/R1B1K2R/ b KQk +{-64 27387 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 4kbnr/p3pppp/2pr/3N1q/B5b/P4N/1PP1QPPP/R1B1K2R/ b KQk +{-74 96485 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/ppp1ppPp////2p/PPPP1PPP/R1BQKBNR/ b KQkq +{-57 56765 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1k2r/ppp2pbp/3q//3P/5N/P1P2PPP/R1BQKB1R/ b KQkq +{-63 10937 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2k4r/pppr1pbp/2n3Q/3b/3PN/2P1B/P4PPP/R3KB1R/ b KQ +{-46 236471 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnbqk2r/ppp1pp1p////5Q/PbPB1PPP/R3KBNR/ w KQkq +{-38 24640 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k2r/pppnpp1p/1q///2P2Q/Pb1BNPPP/1R2KB1R/ w Kkq +{44 9932 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqk2r/ppp1ppbp/1n1p2p/4P/3P/1BN2N/PPP2PPP/R1BQK2R/ b KQkq +{-50 39211 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1q1rk/1pp2pbp/1n2p1p/p3Nb/P2P1BP/1BN/1PP2P1P/R2Q1RK/ b +{-219 88374 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2kr1b1r/ppp1q2p/1nn1pp//2PPQ/5N/PP4PP/RNB1R1K/ w +{-6 6298 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkbnr/pp2pppp/2p/3p/4P/2N2Q1P/PPPP1PP/R1B1KB1R/ b KQkq +{-51 5859 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkb1r/pp2pppp/2p2n/4P/2Bp/2N2Q1P/PPPP1PP/R1B1K2R/ b KQkq +{-105 70811 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3k2r/pp1n1pp/1q3n1p/4p/1b1pP/3P1Q1P/PP1BBPP/R2N1RK/ w kq +{-70 185931 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2r1k2r/pp1n1pp/5n1p/4p/1q1pP/3P1Q1P/PP2BPP/1R1N1RK/ w k +{-122 5193 52} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1r1k/1p3ppp/p2b/q2pN/3Pn/1QP2N/PP3PPP/R1B1KB1R/ b KQ +{113 7029 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp3pp/2p1pn1p/4Q/3P/3B1N/P1PB1PPP/R4RK/ w kq +{1 30116 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqkb1r/1p3pp/1np1pn1p//p2P/PB3N/1PP1QPPP/R1B1K1NR/ w KQkq +{-48 22161 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1k2r/ppqn1pp/4pn1p/2b1N//3B1N/PPP1QPPP/R1B2RK/ b kq +{-63 16316 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1br2k/ppq3p/3bpp1p/3nN/2P/P2Q1NB/1P3PPP/3RR1K/ b +{-92 10851 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/pp2pppp/2p2n//2BP/5N/PPP2PPP/R1BQK2R/ b KQkq +{-45 6964 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkbnr/pp1npppp/2p3b//3P3N/6N/PPP2PPP/R1BQKB1R/ b KQkq +{-36 30779 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kbnr/ppqnppp/2p4p/7P/3P/3Q1NN/PPPB1PP/R3K2R/ b KQkq +{-38 16060 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qkbnr/pp1n1pp/2p1p2p/7P/3P/3Q1NN/PPPB1PP/R3K2R/ b KQkq +{-38 31931 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnbqkb1r/pp2pp1p/2p2p//3P/5N/PPP2PPP/R1BQKB1R/ b KQkq +{-50 22906 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 2kr3r/p4ppp/2n2p/bp/3P/2P1B/1P2NPPP/R4RK/ w +{142 5778 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2kr1bnr/pp1nqb1p/2p1p1p/3pP2P/3P1BP/P1N/1PP3N/R2QKB1R/ b KQ +{-8 23549 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn1qkbnr/pp3ppp/2p1p/3pPb/3P/5N/PPP1BPPP/RNBQK2R/ b KQkq +{-34 11513 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2qkb1r/1p2nppp/p1n/2p2b/3p1P/2N2N/PPPPB1PP/R1BQR1K/ w kq +{21 9746 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2q1rk/pp3pbp/3pb1p/2p3P/3NPp1P/2NP/PPP2PB/R2Q1RK/ b +{14 87798 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r4rk/1pqb1pbp/2npp1p/1P/2NpPP/3P2P/2PB2BP/R2Q1R1K/ b +{-92 11562 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/pp1b1pbp/nq2p1p/2ppPn/4NP/P2PBNP/1PP3BP/1RQ2RK/ w +{-14 9052 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1kb1r/pp2pppp//2pq//2N/PPPP1PPP/R1BQKB1R/ b KQkq +{-37 31011 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4b1r/2q2k/pnppppp//3P2Q/2N/PP1B1PPP/R4RK/ w +{133 24837 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/pp3ppp/2n1pn/q/3P2b/2N2N/PP2BPPP/R1BQ1RK/ w kq +{0 5128 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard q1k2b1r/Bp3ppp/2n1pn/1N1r/1P4b/P4N/4BPPP/R1Q2RK/ w +{243 23152 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqk2r/pp3ppp/2n1pn//1b1P/2NB1N/PP3PPP/R1BQ1RK/ w kq +{0 5128 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2r/pp3kpp/2n/b//P4N/1P3PPP/R1BR2K/ w +{87 21762 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rnb1k2r/1p2bppp/p2qpn//3P/2NBBN/PP3PPP/R2QK2R/ w KQkq +{0 12676 0} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rnb1kb1r/ppp1pppp/5n/q/3P/2N2N/PPP2PPP/R1BQKB1R/ b KQkq +{-33 22458 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard rn2kb1r/ppp1pppp/5n/q3Nb/3P/2N4P/PPP2PP/R1BQKB1R/ b KQkq +{-96 11513 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kb1r/pppnpppp/5n/q4b/2NP/2N4P/PPP2PP/R1BQKB1R/ b KQkq +{-192 31264 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3kb1r/pppnpppp/4qn/5b/3P1B/2N1N2P/PPP2PP/R2QKB1R/ b KQkq +{-195 23461 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3kb1r/pppbp1pp/5p/2qP/1n3B/1PN2N/P1PQ1PPP/R4RK/ w kq +{386 5128 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard rn1qkb1r/ppp2ppp/4pn//2PP2b/5N/PP2BPPP/RNBQK2R/ w KQkq +{26 12676 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r3qrk/ppp2p/2npbn1p/1B4p/3pP/2P2NB/P1P1QPPP/R4RK/ w +{3 38610 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2kr/p1pb1ppp/5n/1N1p2B/1b/3B2K/PPP2PPP/R6R/ w +{45 9377 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk1nr/pppp1ppp/2n/4p/1bB1P/2P2N/P2P1PPP/RNBQK2R/ b KQkq +{0 22553 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqk1nr/pppp1ppp/2nb/4p/2B1P/2P2N/P2P1PPP/RNBQK2R/ w KQkq +{-79 12676 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k2r/pppp1np/2n//4P1Q/2p/P4PPb/RNB2R1K/ w kq +{-62 9217 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b2rk/1pp2Npp/1bnp/p3p/PPB1P1nq/1QPP2P/5P1P/RNB1K2R/ b KQ +{-3 54121 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkb1r/ppp2ppp/2n2n/3Pp1N/2B//PPPP1PPP/RNBQK2R/ b KQkq +{-72 43245 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b2b1r/pp4pp/2p1k/q2np/1nB1Q/P1N/1PPP1PPP/R1B1K2R/ w KQ +{-46 12676 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r6r/ppp1b1kp/6p/3p1b/4n/3NBP/PPP3PP/RN2K2R/ b KQ +{29 11100 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqkb1r/ppp2ppp/2n/3pP/2Bpn/5N/PPP2PPP/RNBQ1RK/ w kq d6 +{9 39652 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqkbnr/pppp1ppp//1B/3pP//PPPP1PPP/RNBQ1RK/ b kq +{-66 31163 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1b1k1nr/pp2bppp/2pp2q/5P/B1PpP/3P/PP4PP/RNBQ1RK/ b kq +{-49 31598 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bqk1nr/pppp1ppp/2n/1Bb1p/4P/2P2N/PP1P1PPP/RNBQK2R/ b KQkq +{-35 11134 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1bqk2r/ppppbppp/2nn/1B2p/3P/5N/PPP1QPPP/RNB2RK/ w kq +{0 88737 0} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/p1p3pp/b1p1P/3p3q/1P1NpB1b/4Q/P1P2PPP/R2R2K/ w +{62 21917 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r1bk1b1r/ppp2ppp/2p/4Pn//5N/PPP2PPP/RNBR2K/ b +{-75 16187 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2b1kb1r/ppp1npp/2p1P2p/2N/6P/1P3N/P1P2P1P/2BR2K/ b +{3 10484 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3k1nr/1pp1bppp/p1p1P1q//3Q1B/5N/PPbN1PPP/R4RK/ b kq +{-18 39733 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k2r/1pp2ppp/pbp3n/4P/2P2B/PN1q/1P1N1PPP/R2Q1RK/ w kq +{-67 6298 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 5rk/2p3pp/b/5p/2p1P//Pp1N1PPP/R2R2K/ w +{-3 24640 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 5rk/2p3pp/b/5p/4P/2p/Pp1N1PPP/1R1R2K/ w +{-50 57921 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard 5rk/2p3pp/b/5p/4P//Pp1N1PPP/3R2K/ w +{-83 24643 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 1rbq1rk/2pp1ppp/2n2n/1Nb1p/4P/1B3N/1PPPQPPP/R1B1K2R/ b KQ +{-48 42797 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b1k2r/2p1bppp/p2q/1p1n/3n/1BP/PP3PPP/RNBQR1K/ w kq +{68 95939 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 3r1rk/2q1bppp/pn2b/1pp1P/1n2B/1PN2N1P/PB3PP/RQ2R1K/ b +{49 7094 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/2p1bp1p/p3qnp/1p2n1B/3P2b/1P/P1BQ1PPP/RN2R1K/ w +{93 5583 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r2qrbk/1b3p/p2p1npp/1pnPp/P1p1P/2P1BNNP/1PB2PP/R1Q1R1K/ b +{-51 31931 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r3rbk/1bq2p/p2p1npB/1pnPp/P1p1P/2P2NNP/1PB2PP/R1Q1R1K/ b +{-112 38433 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b2rk/2q1bppp/p1np1n/1p2p/3PP/5N1P/PPBN1PP/R1BQR1K/ w +{-36 9291 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r4rk/1bq1bppp/pn1p1n/1ppPNN/4P/2P4P/PPB2PP/R1BQR1K/ b +{-81 71979 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/2qbb2n/p2p1pp/np1Pp1Pp/2p1P2P/1PP2N/PBBN1P/R2QR2K/ w +{-24 39782 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/2qbb/p2p1np/np1Pp2p/2p1P2P/1PP2N/PBBN1P/R2QR2K/ w +{-61 5713 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard r4rk/1bqnbppp/p2p/1p/3NP/7P/PPBB1PP/2RQR1K/ b +{-59 10547 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r1b2rk/2q1bppp/2np1n/pp2p/3PP/1N3N1P/PPB2PP/R1BQR1K/ w +{-46 21706 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r4rk/4bppp/bq1p1n/1p1Pp/pn2P/3B1N1P/PPQN1PP/R1B1R1K/ w +{-84 29834 48} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.04"] +setboard 2rq1rk/1b1n1ppp/p2p/1p/1P1QP/P1N4P/2B2PP/R3R1K/ b +{258 26298 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.04"] +setboard r2q1rk/1b1nbppp/p2p/np2p/3PP/5N1P/PPBN1PP/R1BQR1K/ w +{-34 5193 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r2nr1k/1bpqbppp/p4n/1p2P1N//P6P/BP1N1PP/R1BQR1K/ b +{6 10477 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r3q1k/1b3p1p/3b1np/np/2pP3N/7P/1PBN1PP/R1BQ2K/ w +{-60 12742 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard b3rbk/2pq1pp/7p/1p2P/1n1N1n/5N1P/1P3PP/1BBQR1K/ b +{5 87416 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2q1rk/1b3ppp/p2p1b/n1p1n/P3P/2P2N1P/B1N2PP/R1BQR1K/ w +{-71 22728 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r4rk/5ppp/p1pb/1p1n/3P2b/1BPQB1Pq/PP3P1P/RN2R1K/ b +{-35 22878 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard 1r3rk/4bppp/Q1p/p/P2PN1b/1BP1R1Pq/5P1P/R5K/ w +{126 22161 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2qkb1r/2p2p1p/p1n1b/1p1pP1p//1BPn1N/PP1N1PPP/R1BQR1K/ w kq +{-14 25348 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2q1b1r/3k3p/4p/1pppn/6p/2Pn/1PBNRPPP/R1BQ2K/ w +{-6 224768 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2qr1k/2p1bppp/p1n1b/1p1pP//1PP2N/1P3PPP/R1BQRNK/ w +{-38 29891 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r2q1rk/2p2ppp/p1n3b/1pNpP/4n/2P2N/PPB2PPP/R1BQ1RK/ b +{-51 75932 48} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard 4rrk/2pb1ppp/pb/1p2P/3NpB1q/2P/PP1Q1PPP/R4RK/ w +{-47 24837 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2q3r/1bp2kpp/p2b/1p1np/2Pn/1B/PP1P1PPP/RNBQR1K/ w +{33 71898 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard q3kb1r/5ppp/3p1n/np1Pp/2p1P1b/2P2N/1PB2PPP/1NBQR1K/ w k +{41 22914 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r1bqkbnr/2p2ppp/p1pp/4p/3PP/5N/PPP2PPP/RNBQK2R/ b KQkq +{-49 38628 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r2q1rk/2pbbppp/p1n2n/1p2P//2N2N/PPB2PPP/R1BQ1RK/ b +{-79 10157 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r2q1rk/2pbbppp/p/1p2P/1n4n/2N2N1P/PPB1QPP/R1B2RK/ b +{-114 172697 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r1bqkbnr/ppp2ppp/2np/1B2p/3PP/5N/PPP2PPP/RNBQK2R/ b KQkq +{-61 23802 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r1bqkbnr/pppp1p1p/2n3p/1B2p/4P/2P2N/PP1P1PPP/RNBQK2R/ b KQkq +{-69 11134 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r1b1k2r/1ppnqp1p/p1p2bpB//2N1P/2P2N/PP3PPP/R2Q1RK/ b kq +{-103 30900 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1b1k2r/1pp2p/p1p3pp/4P/4n/2P1B/PP3PPP/RN1R2K/ w kq +{96 6095 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1b1k2r/ppp1nppp/5q/2bpn/3NP/2P1B/PP2BPPP/RN1QK2R/ w KQkq +{-80 10331 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1b1k2r/ppp1nppp//1N1pn/4P2q/2P1P/PP2B1PP/RN1QK2R/ w KQkq +{-90 12612 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2k2r/1p3p1p/p/2pnQ/2p1P1bq/4P/PP4PP/RN3K1R/ w +{-23 96484 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard rn2k2r/ppp1bppp/3p1n/6B/3N2b/2NP/PPP1BPPP/R3K2R/ b KQkq +{-42 185118 44} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard rn1qr1k/ppp3p/3b1B/3b3Q/3P/2PB/P4PPP/R4RK/ b +{1 54251 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard rnbq1rk/ppp2p1p/3b2pQ/3pN/3P/2PB/PP1B1PPP/R3K2R/ b KQ +{-50 88363 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard rnbqkbnr/ppp3pp//3pP1N/4p/2N/PPP2PPP/R1BQKB1R/ b KQkq +{-195 6834 32} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r1b3k/ppp2ppp/2P//1q/3BP1P/PPP1K2P/R5NR/ b +{283 62041 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1bqk2r/2pp1pp/p1n2n1p/1pb/4P/2N/PPPBQPPP/R3KBNR/ w KQkq +{-3 12420 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard rnb1kbnr/ppp2ppp//6q//2N/PPPPB1PP/R1BQK1NR/ w KQkq +{-4 5323 36} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard rnbqkb1r/ppp2ppp///2B/3PQ/PPP3PP/RN2K1NR/ b KQkq +{8 32059 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1b1kbnr/pppp1ppp/2n//2B1Pp1q//PPPP2PP/RNBQ1KNR/ w kq +{-84 9542 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard rnb1k2r/ppp1b2p/7n/3P1p/2N4P/5R1B/PPPP/RNB3K/ b kq +{19 28607 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1bk1b1r/ppppqB1p/2n2n/4N/3PPppP//PPP3P/RNBQK2R/ w KQ +{51 55106 40} +[White "unknown"] +[Black "Crafty 20.14"] +[Date "2008.07.05"] +setboard r3r1k/p1p2ppp/1pnq1n//3P2b/1QP2N/PP1BP1PP/R3KB1R/ b KQ +{25 28408 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1bqkbnr/p4ppp/2p/4p/3pP/6P/PPP2PBP/RNBQK2R/ w KQkq +{15 5965 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard rnbqkbnr/ppp2ppp//4p/2p/6P/PP1PPPBP/RNBQK1NR/ w KQkq +{-46 30211 36} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1bqkb1r/pppp1ppp/2n2n//4p/2N2NP/PPPPPPBP/R1BQK2R/ w KQkq +{-59 10645 44} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r1bqkb1r/ppp2pp/2n2n1p/3p2N/4p/2NP2P/PPP1PPBP/R1BQK2R/ w KQkq +{-83 9702 40} +[White "Crafty 20.14"] +[Black "unknown"] +[Date "2008.07.05"] +setboard r2qk2r/pp2ppb/2n3pp/2pp1b1n/3P/2N1B1P/PPPQPPBP/R3NRK/ w kq +{-50 9540 32} diff --git a/src/autoplayer/settings.txt b/src/autoplayer/settings.txt new file mode 100644 index 0000000..b567012 --- /dev/null +++ b/src/autoplayer/settings.txt @@ -0,0 +1,9 @@ +engine1 Typhoon +cmd1 ../typhoon --hash 128m --cpus 1 --logfile - --book - --egtbpath - +init1 sn 100000;set resignthreshold -700;set verboseposting false +engine2 Crafty +cmd2 crafty +init2 sn 100000 +openings openings.txt +pgnlog log_crafty.pgn +matchlog log_crafty.txt diff --git a/src/autoplayer/settings2.txt b/src/autoplayer/settings2.txt new file mode 100644 index 0000000..6b7073b --- /dev/null +++ b/src/autoplayer/settings2.txt @@ -0,0 +1,9 @@ +engine1 Typhoon +cmd1 ../typhoon --hash 128m --cpus 1 --logfile - --book - --egtbpath - +init1 sn 100000;set resignthreshold -700;set verboseposting false +engine2 Fruit +cmd2 /home/scott/fruit/fruit +init2 sn 100000 +openings openings.txt +pgnlog log_fruit.pgn +matchlog log_fruit.txt diff --git a/src/autoplayer/settings3.txt b/src/autoplayer/settings3.txt new file mode 100644 index 0000000..eb5aff4 --- /dev/null +++ b/src/autoplayer/settings3.txt @@ -0,0 +1,9 @@ +engine1 Typhoon +cmd1 ../typhoon --hash 16m --cpus 1 --logfile - --book - --egtbpath - +init1 sn 10000;set resignthreshold -700;set verboseposting false +engine2 Fruit +cmd2 /home/scott/fruit/fruit +init2 sn 10000 +openings openings.txt +pgnlog log_fruit_tiny.pgn +matchlog log_fruit_tiny.txt diff --git a/src/autoplayer/settings4.txt b/src/autoplayer/settings4.txt new file mode 100644 index 0000000..d2367b6 --- /dev/null +++ b/src/autoplayer/settings4.txt @@ -0,0 +1,9 @@ +engine1 Typhoon +cmd1 ../typhoon --hash 16m --cpus 1 --logfile - --book - --egtbpath - +init1 st 1;set resignthreshold -700;set verboseposting false +engine2 Crafty +cmd2 crafty +init2 st 1 +openings openings.txt +pgnlog log_crafty_fast.pgn +matchlog log_crafty_fast.txt diff --git a/src/baseline.dna b/src/baseline.dna new file mode 100644 index 0000000..185d863 --- /dev/null +++ b/src/baseline.dna @@ -0,0 +1,129 @@ +# BEGIN MUTATION ALLOWED +# Trade pieces/pawns +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +# END MUTATION ALLOWED +# Reduced material down scaler +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +# Reduced material up scaler +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +# Passer material up scaler +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +# Pawn centrality bonus by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0,-10,0,0,0,0,0,0,0,0,-10,0,5,5,5,5,0,-10,0,0,0,0,0,0,0,0,-10,0,5,9,9,5,0,-10,0,0,0,0,0,0,0,0,-10,0,5,9,9,5,0,-10,0,0,0,0,0,0,0,0,-10,0,5,5,5,5,0,-10,0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0,-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Backward shielded by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Backward exposed by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Doubled pawn penalty by count +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-48,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-14,-25,-39,-55,-73,-95,-121 +# Isolated pawn penalty by count +0,-3,-7,-9,-16,-35,-50,-85,-100 +# Isolated pawn penalty by board file +0,-8,-9,-10,-11,-11,-10,-9,-8 +# Isolated exposed base score +-6 +# Isolated doubled base score +-18 +# BEGIN MUTATION ALLOWED +# Passer pawn by rank/color (reduced if enemy controls sq ahead) +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +# Candidate passer pawn by rank/color +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +# Connected passer pawn by rank/color (x2, one for each pawn) +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +# Supported passer pawn by rank/color +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +# END MUTATION ALLOWED +# Outside passer pawn by how far outside +0,0,7,14,21,28,34,41,55 +# BEGIN MUTATION ALLOWED +# Passer bonus as material comes off +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# END MUTATION ALLOWED +# Unstoppable passer +800 +# Undeveloper minors in the opening +0,-6,-10,-16,-22 +# Bishop over knight in the endgame by how open is the board +33 +# Bishop pair value by number of pawns +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41 +# BEGIN MUTATION ALLOWED +# Stationary pawns on bishop color +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-5,-7,-7,-7,-7,-7,-7,-5,0,0,0,0,0,0,0,0,-7,-7,-8,-8,-8,-8,-7,-7,0,0,0,0,0,0,0,0,-8,-9,-10,-12,-12,-10,-9,-8,0,0,0,0,0,0,0,0,-8,-9,-10,-12,-12,-10,-9,-8,0,0,0,0,0,0,0,0,-7,-7,-8,-8,-8,-8,-7,-7,0,0,0,0,0,0,0,0,-5,-7,-7,-7,-7,-7,-7,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Transient pawns on bishop color +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Bishop mobility by num squares +-22,-15,-13,-8,-3,0,2,4,7,11,15,17,18,19 +# Bishop mobility num-in-a-row bonus +-14,-6,1,4,6,7,9,11 +# END MUTATION ALLOWED +# Outposted bishop by distance from eking +0,38,30,18,8,4,0,-10,-16 +# Bishop in a closed position bonus +15,15,15,15,14,14,13,12,11,10,9,7,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Knight centrality by location +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +# Knight-eking tropism bonus +0,15,12,9,5,0,0,0,0 +# Knight value as pawns come off +-30,-24,-18,-12,-6,0,6,12,18 +# Outposted knight by distance from eking +0,40,33,22,10,3,0,0,0 +# Knight on interesting square by rank/color +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +# BEGIN MUTATION ALLOWED +# Knight mobility +-17,-10,-6,0,3,6,8,9,10 +# Knight with N pawns supporting +0,7,11 +# END MUTATION ALLOWED +# Knight in a closed position +0,0,0,0,0,0,2,4,6,8,9,10,11,12,13,14,16,18,19,20,20,21,21,22,22,23,23,24,24,25,25,26,27 +# Rook on full open file by distance from eking +24,22,17,14,13,13,12,12 +# Rook on half open file with enemy pawn by distance from eking +12,11,9,9,8,8,8,7 +# Rook on half open file with friend pawn by distance from eking +13,12,11,11,9,9,9,8 +# Rook behind own passer by passer rank/color +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +# Rook leading own passer by passer rank/color +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +# King trapping friend rook +-40 +# Rook trapping eking +22 +# Rook value as pawns come off +55,44,33,22,11,0,-12,-24,-36 +# Rooks connected vertically (x2) +7 +# Rooks connected horizontally (x2) +4 +# BEGIN MUTATION ALLOWED +# Rook mobility by squares +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +# Rook mobility by n-in-a-row +-15,-6,0,4,8,8,8,8 +# Queen mobility by squares +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +# END MUTATION ALLOWED +# Queen out too early by num unmoved minors +0,-14,-22,-26,-33 +# Queen eking tropism +0,39,35,28,24,17,16,15 +# Queen attacking square next to eking (x #squares) +8 +# Initial king safety counter by location/color +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +# Bring king to center by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# BEGIN MUTATION ALLOWED +# King pawn shield (x #pawns) +15 +# King safety by counter +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-140,-160,-180,-200,-225,-250,-275,-300,-333,-366,-399,-433,-466,-499,-533,-566,-599,-600,-600,-600,-600,-600,-600,-600,-600,-600,-600 +# END MUTATION ALLOWED +# King missing one castle option +-23 diff --git a/src/bench.c b/src/bench.c new file mode 100644 index 0000000..e8fbe91 --- /dev/null +++ b/src/bench.c @@ -0,0 +1,100 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + bench.c + +Abstract: + + Engine speed benchmarking code. This is the same test that crafty + uses to benchmark. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 28 Jun 2004 + +Revision History: + + $Id: bench.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +COMMAND(BenchCommand) +/** + +Routine description: + + Run a benchmark + +Parameters: + + (hidden) CHAR *szInput + (hidden) ULONG argc + (hidden) CHAR *argv[] + (hidden) POSITION *pos + +Return value: + +**/ +{ + typedef struct _BENCH_NODE + { + CHAR *szFen; + ULONG uDepth; + } + BENCH_NODE; + static BENCH_NODE x[] = + { + { + "3r1k2/4npp1/1ppr3p/p6P/P2PPPP1/1NR5/5K2/2R5 w - - 0 0", 11 + }, + { + "rnbqkb1r/p3pppp/1p6/2ppP3/3N4/2P5/PPP1QPPP/R1B1KB1R w KQkq - 0 0", 11 + }, + { + "4b3/p3kp2/6p1/3pP2p/2pP1P2/4K1P1/P3N2P/8 w - - 0 0", 13 + }, + { + "r3r1k1/ppqb1ppp/8/4p1NQ/8/2P5/PP3PPP/R3R1K1 b - - 0 0", 11 + }, + { + "2r2rk1/1bqnbpp1/1p1ppn1p/pP6/N1P1P3/P2B1N1P/1B2QPP1/R2R2K1 b - - 0 0", 11 + }, + { + "r1bqk2r/pp2bppp/2p5/3pP3/P2Q1P2/2N1B3/1PP3PP/R4RK1 b kq - 0 0", 11 + } + }; + ULONG u; + double dStart; + double dEnd; + UINT64 u64Nodes = 0; + +#ifdef DEBUG + Trace("You know this is a DEBUG build, right?\n"); +#endif + dStart = SystemTimeStamp(); + for (u = 0; + u < ARRAY_LENGTH(x) && (FALSE == g_fExitProgram); + u++) + { + VERIFY(PreGameReset(FALSE)); + VERIFY(SetRootPosition(x[u].szFen)); + pos = GetRootPosition(); + g_Options.u64NodesSearched = 0ULL; + g_Options.uMaxDepth = x[u].uDepth; + Think(pos); + u64Nodes += g_Options.u64NodesSearched; + } + dEnd = SystemTimeStamp(); + ASSERT(dStart < dEnd); + ASSERT(u64Nodes > 0); + + Trace("Searched %"COMPILER_LONGLONG_UNSIGNED_FORMAT + " nodes in %4.1f sec.\n", u64Nodes, (dEnd - dStart)); + Trace("BENCHMARK>> %8.1f nodes/sec\n", (double)u64Nodes / (dEnd - dStart)); + VERIFY(PreGameReset(TRUE)); +} diff --git a/src/bitboard.c b/src/bitboard.c new file mode 100755 index 0000000..0478fc1 --- /dev/null +++ b/src/bitboard.c @@ -0,0 +1,398 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + bitboard.c + +Abstract: + + Routines dealing with bitboards. If you build with the + testbitboard.c code enabled it will give you a rough benchmark of + these routines' speeds. Here are some typical results (from a + 1.5ghz Athlon): + + SLOWCOOR_TO_BB: 10 cycles/op + COOR_TO_BB: 5 cycles/op + SlowCountBits: 82 cycles/op + CountBits: 2 cycles/op + SlowLastBit: 158 cycles/op + LastBit: 2 cycles/op + SlowFirstBit: 22 cycles/op + FirstBit: 2 cycles/op + + As you can see the inline assembly language code is quite a bit + faster so use it if you can. And if, on the off chance, you are + porting this code to another hardware platform, it might be worth + your time to research what your instruction set has in the way of + bit twiddling opcodes. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 19 Jun 2004 + +Revision History: + + $Id: bitboard.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + + +// +// Mapping from square -> bit +// +BITBOARD BBSQUARE[64] = +{ + 0x1ULL, // 1 + 0x2ULL, // 2 + 0x4ULL, // 3 + 0x8ULL, // 4 + 0x10ULL, // 5 + 0x20ULL, // 6 + 0x40ULL, // 7 + 0x80ULL, // 8 + 0x100ULL, // 9 + 0x200ULL, // 10 + 0x400ULL, // 11 + 0x800ULL, // 12 + 0x1000ULL, // 13 + 0x2000ULL, // 14 + 0x4000ULL, // 15 + 0x8000ULL, // 16 + 0x10000ULL, // 17 + 0x20000ULL, // 18 + 0x40000ULL, // 19 + 0x80000ULL, // 20 + 0x100000ULL, // 21 + 0x200000ULL, // 22 + 0x400000ULL, // 23 + 0x800000ULL, // 24 + 0x1000000ULL, // 25 + 0x2000000ULL, // 26 + 0x4000000ULL, // 27 + 0x8000000ULL, // 28 + 0x10000000ULL, // 29 + 0x20000000ULL, // 30 + 0x40000000ULL, // 31 + 0x80000000ULL, // 32 +//-------------------------------------------------- + 0x100000000ULL, // 33 + 0x200000000ULL, // 34 + 0x400000000ULL, // 35 + 0x800000000ULL, // 36 + 0x1000000000ULL, // 37 + 0x2000000000ULL, // 38 + 0x4000000000ULL, // 39 + 0x8000000000ULL, // 40 + 0x10000000000ULL, // 41 + 0x20000000000ULL, // 42 + 0x40000000000ULL, // 43 + 0x80000000000ULL, // 44 + 0x100000000000ULL, // 45 + 0x200000000000ULL, // 46 + 0x400000000000ULL, // 47 + 0x800000000000ULL, // 48 + 0x1000000000000ULL, // 49 + 0x2000000000000ULL, // 50 + 0x4000000000000ULL, // 51 + 0x8000000000000ULL, // 52 + 0x10000000000000ULL, // 53 + 0x20000000000000ULL, // 54 + 0x40000000000000ULL, // 55 + 0x80000000000000ULL, // 56 + 0x100000000000000ULL, // 57 + 0x200000000000000ULL, // 58 + 0x400000000000000ULL, // 59 + 0x800000000000000ULL, // 60 + 0x1000000000000000ULL, // 61 + 0x2000000000000000ULL, // 62 + 0x4000000000000000ULL, // 63 + 0x8000000000000000ULL, // 64 +}; + + + +// +// The white colored squares on the board +// +BITBOARD BBWHITESQ = ( + SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A6) | + SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B3) | + SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C2) | + SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C6) | SLOWCOOR_TO_BB(C8) | + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(D5) | + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E4) | + SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F1) | + SLOWCOOR_TO_BB(F3) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F7) | + SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G6) | + SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H3) | + SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H7) + ); + +// +// The black colored squares on the board +// +BITBOARD BBBLACKSQ = ~( + SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A6) | + SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B3) | + SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C2) | + SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C6) | SLOWCOOR_TO_BB(C8) | + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(D5) | + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E4) | + SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F1) | + SLOWCOOR_TO_BB(F3) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F7) | + SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G6) | + SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H3) | + SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H7) + ); + + +// +// A way to select one file +// +BITBOARD BBFILE[8] = { + BBFILEA, + BBFILEB, + BBFILEC, + BBFILED, + BBFILEE, + BBFILEF, + BBFILEG, + BBFILEH +}; + +// +// A way to select one rank +// +BITBOARD BBRANK[9] = { + 0, + BBRANK11, + BBRANK22, + BBRANK33, + BBRANK44, + BBRANK55, + BBRANK66, + BBRANK77, + BBRANK88 +}; + +// +// Two files: A and H +// +BITBOARD BBROOK_PAWNS = BBFILEA | BBFILEH; + + +ULONG CDECL +SlowCountBits(BITBOARD bb) +/** + +Routine description: + + Strictly-C implementation of bit counting. How many bits are + asserted in a particular bitboard? + +Parameters: + + BITBOARD bb : the bitboard to count + +Return value: + + ULONG : number of bits set in bb + +**/ +{ + ULONG uCount = 0; + while(bb) + { + uCount++; + bb &= (bb - 1); + } + return(uCount); +} + + +static const int foldedTable[] = { + 63,30, 3,32,59,14,11,33, + 60,24,50, 9,55,19,21,34, + 61,29, 2,53,51,23,41,18, + 56,28, 1,43,46,27, 0,35, + 62,31,58, 4, 5,49,54, 6, + 15,52,12,40, 7,42,45,16, + 25,57,48,13,10,39, 8,44, + 20,47,38,22,17,37,36,26, +}; + +ULONG CDECL +DeBruijnFirstBit(BITBOARD bb) +{ + int folded; + if (bb == 0ULL) return(0); + bb ^= (bb - 1); + folded = ((int)bb) ^ ((int)(bb >> 32)); + return foldedTable[(folded * 0x78291ACF) >> 26] + 1; +} + +ULONG CDECL +SlowFirstBit(BITBOARD bb) +/** + +Routine description: + + Strictly-C implementation of "find the number of the first (lowest + order) asserted bit in the bitboard". + +Parameters: + + BITBOARD bb : the bitboard to test + +Return value: + + ULONG : the number of the first bit from the low order side of the + bb that is asserted. The lowest order bit is #1. + +**/ +{ + static ULONG uTable[16] = + { // 0000 0001 0010 0011 0100 0101 0110 0111 + 0, 1, 2, 1, 3, 1, 2, 1, + // 1000 1001 1010 1011 1100 1101 1110 1111 + 4, 1, 2, 1, 3, 1, 2, 1 }; + ULONG uShifts = 0; + ULONG u; + + while(bb) + { + u = (ULONG)bb & 0xF; + if (0 != u) + { + return(uTable[u] + (uShifts * 4)); + } + bb >>= 4; + uShifts++; + } + return(0); +} + + +ULONG CDECL +SlowLastBit(BITBOARD bb) +/** + +Routine description: + + Strictly-C implementation of "find the number of the last (highest + order) bit asserted in the bitboard". + + Note: On every system benchmarked this code sucked. Using the x86 + bsr instruction is way faster on modern x86 family processors. + +Parameters: + + BITBOARD bb : the bitboard to test + +Return value: + + ULONG : the number of the first bit from the high order side of bb + that is asserted. The highest order bit is #64. + +**/ +{ + static ULONG uTable[16] = + { // 0000 0001 0010 0011 0100 0101 0110 0111 + 0, 1, 2, 2, 3, 3, 3, 3, + // 1000 1001 1010 1011 1100 1101 1110 1111 + 4, 4, 4, 4, 4, 4, 4, 4 }; + ULONG uShifts = 15; + ULONG u; + + while(bb) + { + u = (ULONG)((bb & 0xF000000000000000ULL) >> 60); + if (0 != u) + { + return(uTable[u] + (uShifts * 4)); + } + bb <<= 4; + uShifts--; + ASSERT(uShifts < 15); + } + return(0); +} + +COOR +CoorFromBitBoardRank8ToRank1(BITBOARD *pbb) +/** + +Routine description: + + Return the square cooresponding to the first asserted bit in the + bitboard or ILLEGAL_COOR if there are no bits asserted in the + bitboard. If a valid COOR is returned, clear that bit in the + bitboard. + +Parameters: + + BITBOARD *pbb + +Return value: + + COOR + +**/ +{ + COOR c = ILLEGAL_COOR; + ULONG uFirstBit = FirstBit(*pbb); + + ASSERT(uFirstBit == SlowFirstBit(*pbb)); + if (0 != uFirstBit) + { + uFirstBit--; // bit 1 is 1 << 0 + c = BIT_NUMBER_TO_COOR(uFirstBit); + ASSERT(c == SLOW_BIT_NUMBER_TO_COOR(uFirstBit)); + ASSERT(IS_ON_BOARD(c)); + *pbb &= (*pbb - 1); + } + return(c); +} + + +COOR +CoorFromBitBoardRank1ToRank8(BITBOARD *pbb) +/** + +Routine description: + + Return the square cooresponding to the last asserted bit in the + bitboard or ILLEGAL_COOR if there are no bits asserted in the + bitboard. If a valid COOR is returned, clear that bit in the + bitboard. + +Parameters: + + BITBOARD *pbb + +Return value: + + COOR + +**/ +{ + COOR c; + ULONG uLastBit = LastBit(*pbb); + ASSERT(SlowLastBit(*pbb) == uLastBit); + + c = ILLEGAL_COOR; + if (0 != uLastBit) + { + ASSERT(*pbb); + uLastBit--; + *pbb &= (*pbb - 1); + c = BIT_NUMBER_TO_COOR(uLastBit); + ASSERT(c == SLOW_BIT_NUMBER_TO_COOR(uLastBit)); + ASSERT(IS_ON_BOARD(c)); + } + return(c); +} diff --git a/src/bitboard.s b/src/bitboard.s new file mode 100644 index 0000000..d73e039 --- /dev/null +++ b/src/bitboard.s @@ -0,0 +1,623 @@ +# GNU C version 4.0.1 (Apple Inc. build 5465) (i686-apple-darwin9) +# compiled by GNU C version 4.0.1 (Apple Inc. build 5465). +# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +# options passed: -D__DYNAMIC__ -fPIC -mmacosx-version-min=10.5.1 -m64 +# -mtune=generic -march=apple -auxbase -fverbose-asm +# options enabled: -fPIC -falign-jumps-max-skip -falign-loops +# -falign-loops-max-skip -fargument-alias -fasynchronous-unwind-tables +# -fbranch-count-reg -fcommon -feliminate-unused-debug-types -ffunction-cse +# -fgcse-lm -fident -fivopts -fkeep-static-consts -fleading-underscore +# -flocal-alloc -floop-optimize2 -fpeephole -freg-struct-return +# -fsched-interblock -fsched-spec -fsched-stalled-insns-dep +# -fsplit-ivs-in-unroller -ftree-loop-im -ftree-loop-ivcanon +# -ftree-loop-optimize -funwind-tables -fverbose-asm +# -fzero-initialized-in-bss -m80387 -mhard-float -mno-soft-float -mieee-fp +# -mfp-ret-in-387 -maccumulate-outgoing-args -mmmx -msse -msse2 -msse3 +# -m128bit-long-double -m64 -mtune=generic64 -march=apple +# -mmacosx-version-min=10.5.1 + +# Compiler executable checksum: 0a7d9e41e786877ed5cbeb90e063cdab + +.globl _BBSQUARE + .data + .align 5 +_BBSQUARE: + .quad 1 + .quad 2 + .quad 4 + .quad 8 + .quad 16 + .quad 32 + .quad 64 + .quad 128 + .quad 256 + .quad 512 + .quad 1024 + .quad 2048 + .quad 4096 + .quad 8192 + .quad 16384 + .quad 32768 + .quad 65536 + .quad 131072 + .quad 262144 + .quad 524288 + .quad 1048576 + .quad 2097152 + .quad 4194304 + .quad 8388608 + .quad 16777216 + .quad 33554432 + .quad 67108864 + .quad 134217728 + .quad 268435456 + .quad 536870912 + .quad 1073741824 + .quad 2147483648 + .quad 4294967296 + .quad 8589934592 + .quad 17179869184 + .quad 34359738368 + .quad 68719476736 + .quad 137438953472 + .quad 274877906944 + .quad 549755813888 + .quad 1099511627776 + .quad 2199023255552 + .quad 4398046511104 + .quad 8796093022208 + .quad 17592186044416 + .quad 35184372088832 + .quad 70368744177664 + .quad 140737488355328 + .quad 281474976710656 + .quad 562949953421312 + .quad 1125899906842624 + .quad 2251799813685248 + .quad 4503599627370496 + .quad 9007199254740992 + .quad 18014398509481984 + .quad 36028797018963968 + .quad 72057594037927936 + .quad 144115188075855872 + .quad 288230376151711744 + .quad 576460752303423488 + .quad 1152921504606846976 + .quad 2305843009213693952 + .quad 4611686018427387904 + .quad -9223372036854775808 +.globl _BBWHITESQ + .align 3 +_BBWHITESQ: + .quad -6172840429334713771 +.globl _BBBLACKSQ + .align 3 +_BBBLACKSQ: + .quad 6172840429334713770 +.globl _BBFILE + .align 5 +_BBFILE: + .quad 72340172838076673 + .quad 144680345676153346 + .quad 289360691352306692 + .quad 578721382704613384 + .quad 1157442765409226768 + .quad 2314885530818453536 + .quad 4629771061636907072 + .quad -9187201950435737472 +.globl _BBRANK + .align 5 +_BBRANK: + .quad 0 + .quad -72057594037927936 + .quad 71776119061217280 + .quad 280375465082880 + .quad 1095216660480 + .quad 4278190080 + .quad 16711680 + .quad 65280 + .quad 255 +.globl _BBROOK_PAWNS + .align 3 +_BBROOK_PAWNS: + .quad -9114861777597660799 + .text +.globl _SlowCountBits +_SlowCountBits: +LFB33: + pushq %rbp # +LCFI0: + movq %rsp, %rbp #, +LCFI1: + movq %rdi, -24(%rbp) # bb, bb + movl $0, -4(%rbp) #, uCount + jmp L2 # +L3: + leaq -4(%rbp), %rax #, tmp63 + incl (%rax) # uCount + movq -24(%rbp), %rdx # bb, D.5028 + decq %rdx # D.5028 + leaq -24(%rbp), %rax #, tmp65 + andq %rdx, (%rax) # D.5028, bb +L2: + cmpq $0, -24(%rbp) #, bb + jne L3 #, + movl -4(%rbp), %eax # uCount, D.5029 + leave + ret +LFE33: + .const + .align 5 +_foldedTable: + .long 63 + .long 30 + .long 3 + .long 32 + .long 59 + .long 14 + .long 11 + .long 33 + .long 60 + .long 24 + .long 50 + .long 9 + .long 55 + .long 19 + .long 21 + .long 34 + .long 61 + .long 29 + .long 2 + .long 53 + .long 51 + .long 23 + .long 41 + .long 18 + .long 56 + .long 28 + .long 1 + .long 43 + .long 46 + .long 27 + .long 0 + .long 35 + .long 62 + .long 31 + .long 58 + .long 4 + .long 5 + .long 49 + .long 54 + .long 6 + .long 15 + .long 52 + .long 12 + .long 40 + .long 7 + .long 42 + .long 45 + .long 16 + .long 25 + .long 57 + .long 48 + .long 13 + .long 10 + .long 39 + .long 8 + .long 44 + .long 20 + .long 47 + .long 38 + .long 22 + .long 17 + .long 37 + .long 36 + .long 26 + .text +.globl _DeBruijnFirstBit +_DeBruijnFirstBit: +LFB34: + pushq %rbp # +LCFI2: + movq %rsp, %rbp #, +LCFI3: + movq %rdi, -24(%rbp) # bb, bb + cmpq $0, -24(%rbp) #, bb + jne L7 #, + movl $0, -28(%rbp) #, D.5036 + jmp L9 # +L7: + movq -24(%rbp), %rdx # bb, D.5037 + decq %rdx # D.5037 + leaq -24(%rbp), %rax #, tmp77 + xorq %rdx, (%rax) # D.5037, bb + movq -24(%rbp), %rax # bb, bb + movl %eax, %edx # bb, D.5038 + movq -24(%rbp), %rax # bb, bb + shrq $32, %rax #, D.5039 + xorl %edx, %eax # D.5038, tmp70 + movl %eax, -4(%rbp) # tmp70, folded + movl -4(%rbp), %eax # folded, folded + imull $2015959759, %eax, %eax #, folded, D.5041 + sarl $26, %eax #, D.5042 + cltq + leaq 0(,%rax,4), %rdx #, tmp73 + leaq _foldedTable(%rip), %rax #, tmp74 + movl (%rdx,%rax), %eax # foldedTable, D.5043 + incl %eax # D.5044 + movl %eax, -28(%rbp) # D.5044, D.5036 +L9: + movl -28(%rbp), %eax # D.5036, + leave + ret +LFE34: + .data + .align 5 +_uTable.5051: + .long 0 + .long 1 + .long 2 + .long 1 + .long 3 + .long 1 + .long 2 + .long 1 + .long 4 + .long 1 + .long 2 + .long 1 + .long 3 + .long 1 + .long 2 + .long 1 + .text +.globl _SlowFirstBit +_SlowFirstBit: +LFB35: + pushq %rbp # +LCFI4: + movq %rsp, %rbp #, +LCFI5: + movq %rdi, -24(%rbp) # bb, bb + movl $0, -8(%rbp) #, uShifts + jmp L12 # +L13: + movq -24(%rbp), %rax # bb, bb + andl $15, %eax #, tmp65 + movl %eax, -4(%rbp) # tmp65, u + cmpl $0, -4(%rbp) #, u + je L14 #, + movl -4(%rbp), %eax # u, u.5 + mov %eax, %eax # u.5, u.5 + leaq 0(,%rax,4), %rdx #, tmp67 + leaq _uTable.5051(%rip), %rax #, tmp68 + movl (%rdx,%rax), %edx # uTable, D.5060 + movl -8(%rbp), %eax # uShifts, uShifts + sall $2, %eax #, D.5061 + addl %eax, %edx # D.5061, + movl %edx, -28(%rbp) #, D.5058 + jmp L16 # +L14: + leaq -24(%rbp), %rax #, tmp72 + shrq $4, (%rax) #, bb + leaq -8(%rbp), %rax #, tmp74 + incl (%rax) # uShifts +L12: + cmpq $0, -24(%rbp) #, bb + jne L13 #, + movl $0, -28(%rbp) #, D.5058 +L16: + movl -28(%rbp), %eax # D.5058, + leave + ret +LFE35: + .data + .align 5 +_uTable.5068: + .long 0 + .long 1 + .long 2 + .long 2 + .long 3 + .long 3 + .long 3 + .long 3 + .long 4 + .long 4 + .long 4 + .long 4 + .long 4 + .long 4 + .long 4 + .long 4 + .text +.globl _SlowLastBit +_SlowLastBit: +LFB36: + pushq %rbp # +LCFI6: + movq %rsp, %rbp #, +LCFI7: + movq %rdi, -24(%rbp) # bb, bb + movl $15, -8(%rbp) #, uShifts + jmp L20 # +L21: + movabsq $-1152921504606846976, %rax #, tmp65 + andq -24(%rbp), %rax # bb, D.5074 + shrq $60, %rax #, D.5075 + movl %eax, -4(%rbp) # D.5075, u + cmpl $0, -4(%rbp) #, u + je L22 #, + movl -4(%rbp), %eax # u, u.6 + mov %eax, %eax # u.6, u.6 + leaq 0(,%rax,4), %rdx #, tmp67 + leaq _uTable.5068(%rip), %rax #, tmp68 + movl (%rdx,%rax), %edx # uTable, D.5078 + movl -8(%rbp), %eax # uShifts, uShifts + sall $2, %eax #, D.5079 + addl %eax, %edx # D.5079, + movl %edx, -28(%rbp) #, D.5076 + jmp L24 # +L22: + leaq -24(%rbp), %rax #, tmp72 + salq $4, (%rax) #, bb + leaq -8(%rbp), %rax #, tmp74 + decl (%rax) # uShifts +L20: + cmpq $0, -24(%rbp) #, bb + jne L21 #, + movl $0, -28(%rbp) #, D.5076 +L24: + movl -28(%rbp), %eax # D.5076, + leave + ret +LFE36: +.globl _CoorFromBitBoardRank8ToRank1 +_CoorFromBitBoardRank8ToRank1: +LFB37: + pushq %rbp # +LCFI8: + movq %rsp, %rbp #, +LCFI9: + subq $32, %rsp #, +LCFI10: + movq %rdi, -24(%rbp) # pbb, pbb + movl $136, -8(%rbp) #, c + movq -24(%rbp), %rax # pbb, pbb + movq (%rax), %rdi #* pbb, D.5088 + call _FirstBit # + movl %eax, -4(%rbp) # D.5089, uFirstBit + cmpl $0, -4(%rbp) #, uFirstBit + je L28 #, + leaq -4(%rbp), %rax #, tmp76 + decl (%rax) # uFirstBit + movl -4(%rbp), %eax # uFirstBit, D.5090 + andl $248, %eax #, D.5090 + leal (%rax,%rax), %edx #, D.5091 + movl -4(%rbp), %eax # uFirstBit, D.5092 + andl $7, %eax #, D.5092 + orl %edx, %eax # D.5091, tmp70 + movl %eax, -8(%rbp) # tmp70, c + movq -24(%rbp), %rax # pbb, pbb + movq (%rax), %rdx #* pbb, D.5093 + movq -24(%rbp), %rax # pbb, pbb + movq (%rax), %rax #* pbb, D.5094 + decq %rax # D.5095 + andq %rax, %rdx # D.5095, D.5096 + movq -24(%rbp), %rax # pbb, pbb + movq %rdx, (%rax) # D.5096,* pbb +L28: + movl -8(%rbp), %eax # c, D.5097 + leave + ret +LFE37: +.globl _CoorFromBitBoardRank1ToRank8 +_CoorFromBitBoardRank1ToRank8: +LFB38: + pushq %rbp # +LCFI11: + movq %rsp, %rbp #, +LCFI12: + subq $32, %rsp #, +LCFI13: + movq %rdi, -24(%rbp) # pbb, pbb + movq -24(%rbp), %rax # pbb, pbb + movq (%rax), %rdi #* pbb, D.5106 + call _LastBit # + movl %eax, -4(%rbp) # D.5107, uLastBit + movl $136, -8(%rbp) #, c + cmpl $0, -4(%rbp) #, uLastBit + je L32 #, + leaq -4(%rbp), %rax #, tmp76 + decl (%rax) # uLastBit + movq -24(%rbp), %rax # pbb, pbb + movq (%rax), %rdx #* pbb, D.5108 + movq -24(%rbp), %rax # pbb, pbb + movq (%rax), %rax #* pbb, D.5109 + decq %rax # D.5110 + andq %rax, %rdx # D.5110, D.5111 + movq -24(%rbp), %rax # pbb, pbb + movq %rdx, (%rax) # D.5111,* pbb + movl -4(%rbp), %eax # uLastBit, D.5112 + andl $248, %eax #, D.5112 + leal (%rax,%rax), %edx #, D.5113 + movl -4(%rbp), %eax # uLastBit, D.5114 + andl $7, %eax #, D.5114 + orl %edx, %eax # D.5113, tmp73 + movl %eax, -8(%rbp) # tmp73, c +L32: + movl -8(%rbp), %eax # c, D.5115 + leave + ret +LFE38: + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 +LSCIE1: + .long 0x0 + .byte 0x1 + .ascii "zR\0" + .byte 0x1 + .byte 0x78 + .byte 0x10 + .byte 0x1 + .byte 0x10 + .byte 0xc + .byte 0x7 + .byte 0x8 + .byte 0x90 + .byte 0x1 + .align 3 +LECIE1: + .globl _SlowCountBits.eh +_SlowCountBits.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 +LASFDE1: + .long LASFDE1-EH_frame1 + .quad LFB33-. + .set L$set$2,LFE33-LFB33 + .quad L$set$2 + .byte 0x0 + .byte 0x4 + .set L$set$3,LCFI0-LFB33 + .long L$set$3 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$4,LCFI1-LCFI0 + .long L$set$4 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE1: + .globl _DeBruijnFirstBit.eh +_DeBruijnFirstBit.eh: +LSFDE3: + .set L$set$5,LEFDE3-LASFDE3 + .long L$set$5 +LASFDE3: + .long LASFDE3-EH_frame1 + .quad LFB34-. + .set L$set$6,LFE34-LFB34 + .quad L$set$6 + .byte 0x0 + .byte 0x4 + .set L$set$7,LCFI2-LFB34 + .long L$set$7 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$8,LCFI3-LCFI2 + .long L$set$8 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE3: + .globl _SlowFirstBit.eh +_SlowFirstBit.eh: +LSFDE5: + .set L$set$9,LEFDE5-LASFDE5 + .long L$set$9 +LASFDE5: + .long LASFDE5-EH_frame1 + .quad LFB35-. + .set L$set$10,LFE35-LFB35 + .quad L$set$10 + .byte 0x0 + .byte 0x4 + .set L$set$11,LCFI4-LFB35 + .long L$set$11 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$12,LCFI5-LCFI4 + .long L$set$12 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE5: + .globl _SlowLastBit.eh +_SlowLastBit.eh: +LSFDE7: + .set L$set$13,LEFDE7-LASFDE7 + .long L$set$13 +LASFDE7: + .long LASFDE7-EH_frame1 + .quad LFB36-. + .set L$set$14,LFE36-LFB36 + .quad L$set$14 + .byte 0x0 + .byte 0x4 + .set L$set$15,LCFI6-LFB36 + .long L$set$15 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$16,LCFI7-LCFI6 + .long L$set$16 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE7: + .globl _CoorFromBitBoardRank8ToRank1.eh +_CoorFromBitBoardRank8ToRank1.eh: +LSFDE9: + .set L$set$17,LEFDE9-LASFDE9 + .long L$set$17 +LASFDE9: + .long LASFDE9-EH_frame1 + .quad LFB37-. + .set L$set$18,LFE37-LFB37 + .quad L$set$18 + .byte 0x0 + .byte 0x4 + .set L$set$19,LCFI8-LFB37 + .long L$set$19 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$20,LCFI9-LCFI8 + .long L$set$20 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE9: + .globl _CoorFromBitBoardRank1ToRank8.eh +_CoorFromBitBoardRank1ToRank8.eh: +LSFDE11: + .set L$set$21,LEFDE11-LASFDE11 + .long L$set$21 +LASFDE11: + .long LASFDE11-EH_frame1 + .quad LFB38-. + .set L$set$22,LFE38-LFB38 + .quad L$set$22 + .byte 0x0 + .byte 0x4 + .set L$set$23,LCFI11-LFB38 + .long L$set$23 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$24,LCFI12-LCFI11 + .long L$set$24 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE11: + .subsections_via_symbols diff --git a/src/board.c b/src/board.c new file mode 100755 index 0000000..5ad0d17 --- /dev/null +++ b/src/board.c @@ -0,0 +1,731 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + board.c + +Abstract: + + Chess-board related functions. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 15 Apr 2004 + +Revision History: + + $Id: board.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +void +SetRootToInitialPosition(void) +/** + +Routine description: + + Sets the root position to the initial position. + +Parameters: + + none + +Return value: + + void + +**/ +{ +#ifdef DEBUG + POSITION *pos; +#endif + + (void)SetRootPosition(STARTING_POSITION_IN_FEN); +#ifdef DEBUG + pos = GetRootPosition(); + + // + // Sanity check the sig system. Note: if this changes then any + // opening books need to be reconstructed. + // + ASSERT(pos->u64NonPawnSig == 0xd46f3e84d897a443ULL); + ASSERT(pos->u64PawnSig == 0xa9341a54d7352d3cULL); + + ASSERT_ASM_ASSUMPTIONS; +#endif +} + + +CHAR * +DrawTextBoardFromPosition(POSITION *pos) +/** + +Routine description: + + Draw a text-based representation of the board configuration in + POSITION pos and returned it as a string. Note: this function is + _NOT_ thread safe. + +Parameters: + + POSITION *pos : position to draw + +Return value: + + static char * : my drawing + +**/ +{ + static char buf[MEDIUM_STRING_LEN_CHAR]; + COOR f, r; + + memset(buf, 0, sizeof(buf)); + strcpy(buf, " 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07\n"); + strcat(buf, " +---------------------------------------+\n"); + for (r = 8; r >= 1; r--) + { + sprintf(buf, "%s %u |", buf, r); + + for (f = A; f <= H; f++) + { + if (IS_WHITE_SQUARE_FR(f, r)) + { + if (IS_EMPTY(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)) + { + sprintf(buf, "%s%s", buf, " |"); + } + else + { + sprintf(buf, "%s %2s |", buf, + PieceAbbrev(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)); + } + } + else + { + if (IS_EMPTY(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)) + { + sprintf(buf, "%s%s", buf, "::::|"); + } + else + { + sprintf(buf, "%s:%2s:|", buf, + PieceAbbrev(pos->rgSquare[FILE_RANK_TO_COOR(f,r)].pPiece)); + } + } + } + sprintf(buf, "%s 0x%x0\n", buf, (8 - r)); + } + strcat(buf, " +---------------------------------------+\n"); + strcat(buf, " A B C D E F G H\n\n"); + return(buf); +} + + +FLAG +VerifyPositionConsistency(POSITION *pos, + FLAG fContinue) +/** + +Routine description: + + Verifies the internal consistency of a POSITION structure. Looks + for defects like bad piece lists, bad piece counts, bad material + counts, etc... + +Parameters: + + POSITION *pos : the position to verify + +Return value: + + FLAG : TRUE if consistent, FALSE otherwise + +**/ +{ + static char *szExplainations[] = { + "Pawn signature mismatch", + "Main signature mismatch", + "Invalid enpassant square", + "Material balance for white != -Material balance for black", + "White castled already and can still castle", + "Black castled already and can still castle", + "Pawn list points to non-pawn square on board", + "Square pointed to by pawn list doesn't point back", + "Piece list points to non-piece square on board", + "Square pointed to by the non-piece list doesn't point back", + "Non-king piece in 0th position of list", + "Invalid piece sitting in non-pawn list entry", + "Counted pawn material != expected material sum", + "Counted piece material != expected material sum", + "Total army material != expected material sum", + "More white square bishops than total bishop count", + "Strange bits flipped in board square", + "More pawns on board than accounted for in pawn material", + "More pieces on board than accounted for in piece material", + "Extra pieces on board that are not accounted for", + "Fifty move counter is too high", + }; + ULONG u, v; + COOR c; + ULONG uPawnMaterial[2] = {0, 0}; + ULONG uPawnCount[2] = {0, 0}; + ULONG uNonPawnMaterial[2] = {0, 0}; + ULONG uNonPawnCount[2][7]; + ULONG uSigmaNonPawnCount[2] = {0, 0}; + ULONG uWhiteSqBishopCount[2] = {0, 0}; + UINT64 u64Computed; + PIECE p; + FLAG fRet = FALSE; + ULONG uReason = (ULONG)-1; + + memset(uNonPawnCount, 0, sizeof(uNonPawnCount)); + u64Computed = ComputeSig(pos); + if (pos->u64NonPawnSig != u64Computed) + { + uReason = 0; + goto end; + } + + u64Computed = ComputePawnSig(pos); + if (pos->u64PawnSig != u64Computed) + { + uReason = 1; + goto end; + } + + if (!VALID_EP_SQUARE(pos->cEpSquare)) + { + uReason = 2; + goto end; + } + + if (pos->iMaterialBalance[WHITE] != -pos->iMaterialBalance[BLACK]) + { + uReason = 3; + goto end; + } + + if (pos->iMaterialBalance[WHITE] != + ((SCORE)(pos->uPawnMaterial[WHITE] + pos->uNonPawnMaterial[WHITE]) - + (SCORE)(pos->uPawnMaterial[BLACK] + pos->uNonPawnMaterial[BLACK]))) + { + uReason = 3; + goto end; + } + + FOREACH_COLOR(u) + { + // + // If a side has already castled it shouldn't have legal castling + // options. + // + if (TRUE == pos->fCastled[u]) + { + if (u == WHITE) + { + if (pos->bvCastleInfo & WHITE_CAN_CASTLE) + { + uReason = 4; + goto end; + } + } + else + { + ASSERT(u == BLACK); + if (pos->bvCastleInfo & BLACK_CAN_CASTLE) + { + uReason = 5; + goto end; + } + } + } + + // + // Make sure the pawns are where they should be + // + for (v = 0; v < pos->uPawnCount[u]; v++) + { + c = pos->cPawns[u][v]; + if (IS_ON_BOARD(c)) + { + if (pos->rgSquare[c].pPiece != ((PAWN << 1) | u)) + { + uReason = 6; + goto end; + } + + if (pos->rgSquare[c].uIndex != v) + { + uReason = 7; + goto end; + } + uPawnMaterial[u] += VALUE_PAWN; + uPawnCount[u]++; + } + } + + // + // Make sure the non-pawns are where they should be + // + for (v = 0; v < 16; v++) + { + c = pos->cNonPawns[u][v]; + if (v < pos->uNonPawnCount[u][0]) + { + if (!IS_ON_BOARD(c)) + { + uReason = 8; + goto end; + } + else + { + p = pos->rgSquare[c].pPiece; + if (pos->rgSquare[c].uIndex != v) + { + uReason = 9; + goto end; + } + + // + // 0th spot must be a king + // + if ((v == 0) && (!IS_KING(p))) + { + uReason = 10; + goto end; + } + + if ((!IS_VALID_PIECE(p)) || (PIECE_COLOR(p) != u)) + { + uReason = 11; + goto end; + } + uNonPawnCount[u][PIECE_TYPE(p)]++; + uNonPawnMaterial[u] += PIECE_VALUE(p); + if ((IS_BISHOP(p)) && + (IS_WHITE_SQUARE_COOR(c))) + { + uWhiteSqBishopCount[u]++; + } + } + } + else + { + // + // The first off-board is the last, the list must not + // have gaps in it followed by good piece data again. + // + break; + } + } + } + + FOREACH_COLOR(u) + { + // + // Make sure the materials and counts match up with what we + // got when walking the piece lists + // + if ((pos->uPawnMaterial[u] != uPawnMaterial[u]) || + (pos->uPawnCount[u] != uPawnCount[u]) || + (pos->uPawnMaterial[u] != pos->uPawnCount[u] * VALUE_PAWN)) + { + uReason = 12; + goto end; + } + + for (v = KNIGHT; v <= KING; v++) + { + if (pos->uNonPawnCount[u][v] != uNonPawnCount[u][v]) + { + uReason = 13; + goto end; + } + uSigmaNonPawnCount[u] += pos->uNonPawnCount[u][v]; + } + + // + // Note: the 0th spot in the array is the sum of all non pawns + // + if (uSigmaNonPawnCount[u] != pos->uNonPawnCount[u][0]) + { + uReason = 14; + goto end; + } + + // + // You can't have more white-square bishops than you have + // bishops. + // + if (pos->uWhiteSqBishopCount[u] > pos->uNonPawnCount[u][BISHOP]) + { + uReason = 15; + goto end; + } + } + + // + // Now walk the actual board and reduce the material counts we got + // by walking the piece lists. If everything is ok then the + // material counts will end up at 0. If there are pieces on the + // board that are not on a list or pieces in a list that are not + // on the board this will catch it. + // + FOREACH_SQUARE(c) + { + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + + if (EMPTY != p) + { + // + // Make sure none of these have strange bits flipped + // + if (p & 0xFFFFFFF0) + { + uReason = 16; + goto end; + } + + u = PIECE_COLOR(p); + if (IS_PAWN(p)) + { + uPawnMaterial[u] -= VALUE_PAWN; + if (pos->rgSquare[c].uIndex > pos->uPawnCount[u]) + { + uReason = 17; + goto end; + } + } + else + { + uNonPawnMaterial[u] -= PIECE_VALUE(p); + if (pos->rgSquare[c].uIndex > pos->uNonPawnCount[u][0]) + { + uReason = 18; + goto end; + } + } + } + } + } + + if ((uPawnMaterial[WHITE] + uPawnMaterial[BLACK] + + uNonPawnMaterial[WHITE] + uNonPawnMaterial[BLACK]) != 0) + { + uReason = 19; + goto end; + } + +// if (pos->uFifty > 101) +// { +// uReason = 20; +// goto end; +// } + + // + // Looks Ok + // + fRet = TRUE; + + end: + if (FALSE == fRet) + { + if (FALSE == fContinue) + { + UtilPanic(INCONSISTENT_POSITION, + pos, szExplainations[uReason], NULL, NULL, + __FILE__, __LINE__); + ASSERT(FALSE); + } + } + return(fRet); +} + + + +FLAG +PositionsAreEquivalent(POSITION *p1, + POSITION *p2) +/** + +Routine description: + + Compare two positions and decide whether they are the same + position. Note: this code is meant to be accessed from test code + or from non-speed critical codepaths. Comparing their signatures + should be sufficient to determine whether they are the same in + production code. + +Parameters: + + POSITION *p1 : first position to compare + POSITION *p2 : second position to compare + +Return value: + + FLAG : TRUE if they are the same position, FALSE otherwise + +**/ +{ + COOR c; + ULONG u; + + if ((p1->u64NonPawnSig != p2->u64NonPawnSig) || + (p1->u64PawnSig != p2->u64PawnSig) || + (p1->uToMove != p2->uToMove) || + (p1->uFifty != p2->uFifty) || + (p1->bvCastleInfo != p2->bvCastleInfo) || + (p1->cEpSquare != p2->cEpSquare)) + { + return(FALSE); + } + + FOREACH_COLOR(u) + { + if ((p1->fCastled[u] != p2->fCastled[u]) || + (p1->uWhiteSqBishopCount[u] != p2->uWhiteSqBishopCount[u])) + { + return(FALSE); + } + } + + FOREACH_SQUARE(c) + { + if (!IS_ON_BOARD(c)) continue; + + if (p1->rgSquare[c].pPiece != p2->rgSquare[c].pPiece) + { + return(FALSE); + } + } + + VerifyPositionConsistency(p1, FALSE); + VerifyPositionConsistency(p2, FALSE); + return(TRUE); +} + + +char * +CastleInfoString(BITV bv) +/** + +Routine description: + + Generate and returns a small string describing the possible + castling choices in the bitvector passed in for use in a friandly + display or in a FEN string representing a position. This function + is _NOT_ thread safe. + +Parameters: + + BITV bv : the castling bitvector + +Return value: + + char * : the string, either '-' signifying none possible or some + combination of: + + K = white kingside possible + Q = white queenside possibe + k = black kingside possible + q = black queenside possible + +**/ +{ + static char buf[5]; + char *p = buf; + + memset(buf, 0, sizeof(buf)); + ASSERT((bv & ~CASTLE_ALL_POSSIBLE) == 0); + + if (bv == 0) + { + *p++ = '-'; + } + else + { + if (bv & CASTLE_WHITE_SHORT) + { + *p++ = 'K'; + } + + if (bv & CASTLE_WHITE_LONG) + { + *p++ = 'Q'; + } + + if (bv & CASTLE_BLACK_SHORT) + { + *p++ = 'k'; + } + + if (bv & CASTLE_BLACK_LONG) + { + *p++ = 'q'; + } + } + return(buf); +} + + +void +DumpPosition(POSITION *pos) +/** + +Routine description: + + Dump an ASCII representation of POSITION pos on stdout. + +Parameters: + + POSITION *pos + +Return value: + + void + +**/ +{ + char *p; +#ifdef DEBUG + ULONG u; + if (!VerifyPositionConsistency(pos, TRUE)) + { + Bug("===========================================================================\n" + " WARNING: The following position seems to be inconsistent. I'll do my best\n" + " to render it but this may not be such a good idea...\n" + "===========================================================================\n\n"); + } +#endif + p = PositionToFen(pos); + if (g_Options.fRunningUnderXboard) + { + Trace("; PositionToFen(pos): %s\n", p); + goto end; + } + else + { + Trace("FEN: %s\n\n", p); + } + +#ifdef DEBUG + Trace("--------------------------------------------------------------------------------\n" + "PositionToFen(pos): %s\n\n" + + "POSITION (@%p):\n" + " +0x%03x u64NonPawnSig : %" + COMPILER_LONGLONG_HEX_FORMAT "\n" + " +0x%03x u64PawnSig : %" + COMPILER_LONGLONG_HEX_FORMAT "\n" + " u64NonPawnSig ^ u64PawnSig: %" + COMPILER_LONGLONG_HEX_FORMAT "\n" + " +0x%03x pSquare[128] : \n\n" + "%s" + " +0x%03x uToMove : 0x%02x (%s)\n" + " +0x%03x uFifty : 0x%02x (%u moves)\n" + " +0x%03x fCastled[2] : W:0x%02x B:0x%02x\n" + " +0x%03x bvCastleInfo : 0x%02x (%s)\n" + " +0x%03x cEpSquare : 0x%02x (%s)\n" + " +0x%03x cPawns[2][8] : \n", + p, + pos, + OFFSET_OF(u64PawnSig, POSITION), pos->u64PawnSig, + OFFSET_OF(u64NonPawnSig, POSITION), pos->u64NonPawnSig, + pos->u64NonPawnSig ^ pos->u64PawnSig, + OFFSET_OF(rgSquare, POSITION), DrawTextBoardFromPosition(pos), + OFFSET_OF(uToMove, POSITION), pos->uToMove, ColorToString(pos->uToMove), + OFFSET_OF(uFifty, POSITION), pos->uFifty, pos->uFifty, + OFFSET_OF(fCastled, POSITION), pos->fCastled[WHITE], pos->fCastled[BLACK], + OFFSET_OF(bvCastleInfo, POSITION), pos->bvCastleInfo, CastleInfoString(pos->bvCastleInfo), + OFFSET_OF(cEpSquare, POSITION), pos->cEpSquare, (IS_ON_BOARD(pos->cEpSquare) ? CoorToString(pos->cEpSquare) : "none"), + OFFSET_OF(cPawns, POSITION)); + + Trace(" W: "); + for (u = 0; u < pos->uPawnCount[WHITE]; u++) + { + Trace("0x%02x[%s] ", + pos->cPawns[WHITE][u], + CoorToString(pos->cPawns[WHITE][u])); + ASSERT(IS_ON_BOARD(pos->cPawns[WHITE][u])); + } + + Trace("\n" + " B: "); + for (u = 0; u < pos->uPawnCount[BLACK]; u++) + { + Trace("0x%02x[%s] ", + pos->cPawns[BLACK][u], + CoorToString(pos->cPawns[BLACK][u])); + ASSERT(IS_ON_BOARD(pos->cPawns[BLACK][u])); + } + + Trace("\n" + " +0x%03x uPawnMaterial[2] : W:0x%02x (%u, pawn=%u)\n" + " : B:0x%02x (%u, pawn=%u)\n" + " +0x%03x uPawnCount[2] : W:%1u pawns B:%1u pawns\n", + OFFSET_OF(uPawnMaterial, POSITION), + pos->uPawnMaterial[WHITE], pos->uPawnMaterial[WHITE], VALUE_PAWN, + pos->uPawnMaterial[BLACK], pos->uPawnMaterial[BLACK], VALUE_PAWN, + OFFSET_OF(uPawnCount, POSITION), + pos->uPawnCount[WHITE], pos->uPawnCount[BLACK]); + + Trace(" +0x%03x cNonPawns[2][16] : \n" + " W: ", OFFSET_OF(cNonPawns, POSITION)); + for (u = 0; u < pos->uNonPawnCount[WHITE][0]; u++) + { + Trace("0x%02x[%s] ", + pos->cNonPawns[WHITE][u], + CoorToString(pos->cNonPawns[WHITE][u])); + ASSERT(IS_ON_BOARD(pos->cNonPawns[WHITE][u])); + } + Trace("\n" + " B: "); + for (u = 0; u < pos->uNonPawnCount[BLACK][0]; u++) + { + Trace("0x%02x[%s] ", + pos->cNonPawns[BLACK][u], + CoorToString(pos->cNonPawns[BLACK][u])); + ASSERT(IS_ON_BOARD(pos->cNonPawns[BLACK][u])); + } + Trace("\n" + " +0x%03x uNonPawnMaterial[2] : W: 0x%02x (%u, pawn=%u)\n" + " : B: 0x%02x (%u, pawn=%u)\n" + " +0x%03x uNonPawnCount[2][7] : WHITE BLACK\n" + " KNIGHT : %u %u\n" + " BISHOP : %u %u\n" + " WHITE SQUARE BISHOP : %u %u\n" + " ROOK : %u %u\n" + " QUEEN : %u %u\n" + " SUM : %u %u\n", + OFFSET_OF(uNonPawnMaterial, POSITION), + pos->uNonPawnMaterial[WHITE], pos->uNonPawnMaterial[WHITE], + VALUE_PAWN, + pos->uNonPawnMaterial[BLACK], pos->uNonPawnMaterial[BLACK], + VALUE_PAWN, + OFFSET_OF(uNonPawnCount, POSITION), + pos->uNonPawnCount[WHITE][KNIGHT], pos->uNonPawnCount[BLACK][KNIGHT], + pos->uNonPawnCount[WHITE][BISHOP], pos->uNonPawnCount[BLACK][BISHOP], + pos->uWhiteSqBishopCount[WHITE], pos->uWhiteSqBishopCount[BLACK], + pos->uNonPawnCount[WHITE][ROOK], pos->uNonPawnCount[BLACK][ROOK], + pos->uNonPawnCount[WHITE][QUEEN], pos->uNonPawnCount[BLACK][QUEEN], + pos->uNonPawnCount[WHITE][0], pos->uNonPawnCount[BLACK][0]); +#else + Trace("\n%s\n", DrawTextBoardFromPosition(pos)); +#endif + + end: + if (NULL != p) + { + SystemFreeMemory(p); + } +} + +// +// TODO: DumpBoard +// diff --git a/src/book.bin b/src/book.bin new file mode 100755 index 0000000..3212478 Binary files /dev/null and b/src/book.bin differ diff --git a/src/book.c b/src/book.c new file mode 100755 index 0000000..217b4ad --- /dev/null +++ b/src/book.c @@ -0,0 +1,3198 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + book.c + +Abstract: + + Opening book routines: everything from probing the opening book to + building a new one to editing the current book. The structure of + a book entry is in book.h. The book is kept on disk and sorted by + position signature. There may be more than one entry per + signature -- there will be one entry per book move from that + positions so for example the initial position will have quite a + few entries. + + Probing the book (BookMove, called from Think in brain.c) entails + binary searching the on disk book file for a matching signature, + reading all entries that match, computing a "weight" for each one, + and then randomly choosing one. + + Building a new book is done with a temporary "membook" buffer in + memory. It requires quite a bit of memory so before the operation + takes place the main hash table and pawn hash table structures are + freed (see movelist.c). A PGN file is read one game at a time and + the moves are made on a POSITION struct. Once the game is over + the signature-move pairs are used to create new entries in the + membook. Finally the membook is sorted and written to disk. The + process can take a while, especially for a large PGN file or on a + machine with limited memory resources. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 27 Jun 2004 + +Revision History: + + $Id: book.c 355 2008-07-01 15:46:43Z scott $ + +**/ + +#include "chess.h" + +static int g_fdBook = -1; // file descriptor for open book +static ULONG g_uMemBookCount = 0; // count of entries in membook +static BOOK_ENTRY *g_pMemBook = NULL; // allocated membook struct +static BOOK_ENTRY *g_pMemBookHead = NULL; // ptr to 1st entry in membook + +// +// Globals exported +// +FLAG g_fTournamentMode = FALSE; // are we in tournament mode +ULONG g_uBookProbeFailures = 0; // how many times have we missed +ULONG g_uMemBookSize = 0x1000000; +OPENING_NAME_MAPPING *g_pOpeningNames = NULL; // opening names file + +static FLAG +_VerifyBook(CHAR *szName) +/** + +Routine description: + +Parameters: + + CHAR *szName + +Return value: + + static FLAG + +**/ +{ + int fd = -1; + int iRet; + ULONG uPos; + ULONG uNum; + ULONG u; + struct stat s; + UINT64 u64LastSig; + ULONG uLastMove; + BOOK_ENTRY be; + FLAG fMyRetVal = FALSE; + + fd = open(szName, O_RDONLY | O_BINARY); + if (fd < 0) + { + Trace("VerifyBook: Can't open %s for read/write.\n", szName); + goto end; + } + + if (0 != stat(szName, &s)) + { + Trace("VerifyBook: Can't stat %s.\n", szName); + goto end; + } + + if ((s.st_size % sizeof(BOOK_ENTRY)) != 0) + { + Trace("VerifyBook: Size of book is not a multiple of entry size.\n"); + goto end; + } + + // + // Foreach book entry... + // + uNum = (s.st_size / sizeof(BOOK_ENTRY)); + u64LastSig = 0; + uLastMove = 0; + for (u = 0; u < uNum; u++) + { + // + // Seek to and read the entry. + // + uPos = u * sizeof(BOOK_ENTRY); + if (uPos != lseek(fd, uPos, SEEK_SET)) + { + Trace("VerifyBook: Can't seek to entry %u (offset %u) in book.\n", + u, uPos); + goto end; + } + iRet = read(fd, &be, sizeof(BOOK_ENTRY)); + if (sizeof(BOOK_ENTRY) != iRet) + { + Trace("VerifyBook: Can't read entry number %u (offset %u) in the " + "book. Read returned %u but I expected %u.\n", + u, uPos, iRet, sizeof(BOOK_ENTRY)); + goto end; + } + + // + // Make sure the book is sorted by signature + // + if (be.u64Sig < u64LastSig) + { + Trace("VerifyBook: Book signatures out-of-order at index %u " + "(offset %u).\n", u, uPos); + goto end; + } + + // + // If our sig is equal to the last entry's then the move here must + // be greater than or equal to the last entry's move. + // + else if (be.u64Sig == u64LastSig) + { + if (be.mvNext.uMove < uLastMove) + { + Trace("VerifyBook: Book moves out-of-order at index %u " + "(offset %u).\n", u, uPos); + goto end; + } + } + + u64LastSig = be.u64Sig; + uLastMove = be.mvNext.uMove; + } + fMyRetVal = TRUE; + + end: + if (-1 != fd) + { + close(fd); + } + return(fMyRetVal); +} + + +static CHAR * +_BookLineToString(UINT64 u64Line) +/** + +Routine description: + + Converts a position signature into an opening name, if known. + +Parameters: + + UINT64 u64Line + +Return value: + + static CHAR + +**/ +{ + ULONG u = 0; + + if (NULL == g_pOpeningNames) return(NULL); + while(g_pOpeningNames[u].szString != NULL) + { + if (g_pOpeningNames[u].u64Sig == u64Line) + { + return(g_pOpeningNames[u].szString); + } + u++; + } + return(NULL); +} + + +static void +_DumpUserOpeningList(void) +/** + +Routine description: + + Called in response to a user "book dump openings" command, this + routine simply shows every named opening in the opening names + file. This file is not the opening book, it's an auxillary disk + file containing a list of moves and a name for the opening. It's + only used to announce the opening line played in a game and + annotate the PGN for a game stored in monsoon's logfile. + +Parameters: + + void + +Return value: + + static void + +**/ +{ + int fd = open(OPENING_LEARNING_FILENAME, + O_RDWR | O_CREAT | O_BINARY | O_RANDOM, + _S_IREAD | _S_IWRITE); + ULONG uNumRecords; + ULONG u; + OPENING_LEARNING_ENTRY ole; + struct stat s; + CHAR *p; + + // + // If we failed to open it, abort. + // + if (fd < 0) goto end; + + // + // Stat it to see how many entries there are. + // + if (0 != stat(OPENING_LEARNING_FILENAME, &s)) + { + ASSERT(FALSE); + Trace("UpdateUserOpeningList: Corrupt %s file.\n", + OPENING_LEARNING_FILENAME); + goto end; + } + if ((s.st_size % sizeof(OPENING_LEARNING_ENTRY)) != 0) + { + ASSERT(FALSE); + Trace("UpdateUserOpeningList: Corrupt %s file.\n", + OPENING_LEARNING_FILENAME); + goto end; + } + uNumRecords = s.st_size / sizeof(OPENING_LEARNING_ENTRY); + Trace("Learned data on %u openings:\n\n", uNumRecords); + + // + // Read each entry looking for a match. + // + for (u = 0; u < uNumRecords; u++) + { + if (sizeof(OPENING_LEARNING_ENTRY) != + read(fd, &ole, sizeof(OPENING_LEARNING_ENTRY))) + { + Trace("UpdateUserOpeningList: Read error.\n"); + goto end; + } + + p = _BookLineToString(ole.u64Sig); + if (NULL != p) + { + Trace("%-45s ww=%u, dr=%u, bw=%u\n", + p, ole.uWhiteWins, ole.uDraws, ole.uBlackWins); + } + } + + end: + if (fd >= 0) + { + close(fd); + } +} + +FLAG +InitializeOpeningBook(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + return(TRUE); +} + +void +ResetOpeningBook(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + void + +**/ +{ + g_uBookProbeFailures = 0; +} + +void +CleanupOpeningBook(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG x = 0; + + // + // If we have read an "opening names" list and created a dynamic memory + // structure for it, free that now. + // + if (NULL != g_pOpeningNames) + { + while (g_pOpeningNames[x].szString != NULL) + { + SystemFreeMemory(g_pOpeningNames[x].szString); + g_pOpeningNames[x].szString = NULL; + g_pOpeningNames[x].u64Sig = 0; + x++; + } + SystemFreeMemory(g_pOpeningNames); + g_pOpeningNames = NULL; + } + + // + // Cleanup membook if they quit in the middle of book building somehow + // + if (NULL != g_pMemBook) + { + ASSERT(FALSE); + SystemFreeMemory(g_pMemBook); + } +} + + +static FLAG +_BookOpen(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + static FLAG + +**/ +{ + // + // Need to have set the book name before calling this. + // + if (!strlen(g_Options.szBookName)) + { + return(FALSE); + } + + // + // Open it. + // + ASSERT(g_fdBook == -1); + g_fdBook = open(g_Options.szBookName, + O_RDWR | O_CREAT | + O_RANDOM | O_BINARY | _S_IREAD | _S_IWRITE); + if (g_fdBook < 0) + { + Bug("_BookOpen: Failed to open book \"%s\".\n", g_Options.szBookName); + return(FALSE); + } + + return((FLAG)(g_fdBook >= 0)); +} + + +static void +_BookClose(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + static void + +**/ +{ + if (-1 != g_fdBook) + { + (void)close(g_fdBook); + } + g_fdBook = -1; +} + + +static FLAG +_BookSeek(ULONG n) +/** + +Routine description: + +Parameters: + + ULONG n + +Return value: + + static FLAG + +**/ +{ + ULONG uPos; + + // + // During normal book operations we have an open file handle and we + // simply calculate and set its file pointer. + // + // However when in the process of building the opening book from a + // file full of PGN games all book commands access a large buffer in + // memory... so instead of setting a file pointer to a byte offset in + // the book file on disk, we set a normal pointer to an offset in + // this large book building buffer. + // + if (g_pMemBook == NULL) + { + uPos = n * sizeof(BOOK_ENTRY); + ASSERT(g_fdBook != -1); + + if (uPos != lseek(g_fdBook, uPos, SEEK_SET)) + { + Trace("_BookSeek: Cannot seek to byte offset %u\n", uPos); + return(FALSE); + } + } + else + { + ASSERT(g_uMemBookSize >= 0); + ASSERT(n < g_uMemBookSize); + g_pMemBookHead = g_pMemBook + n; + } + return(TRUE); +} + +#if 0 +static FLAG +_BookWrite(BOOK_ENTRY *x) +/** + +Routine description: + +Parameters: + + BOOK_ENTRY *x + +Return value: + + static FLAG + +**/ +{ + int iNum; + + // + // If we are building the book, operate on memory + // buffer... otherwise operate on the book file. + // + if (g_pMemBook != NULL) + { + memcpy(g_pMemBookHead, x, sizeof(BOOK_ENTRY)); + } + else + { + ASSERT(g_fdBook != -1); + + iNum = write(g_fdBook, x, sizeof(BOOK_ENTRY)); + if (sizeof(BOOK_ENTRY) != iNum) + { + Trace("_BookWrite: I/O error on fd=%d, got %d and expected %d\n", + g_fdBook, iNum, sizeof(BOOK_ENTRY)); + ASSERT(FALSE); + return(FALSE); + } + } + return(TRUE); +} +#endif + +static FLAG +_BookRead(BOOK_ENTRY *x) +/** + +Routine description: + +Parameters: + + BOOK_ENTRY *x + +Return value: + + static FLAG + +**/ +{ + int iNum; + + if (g_pMemBook != NULL) + { + memcpy(x, g_pMemBookHead, sizeof(BOOK_ENTRY)); + } + else + { + ASSERT(g_fdBook != -1); + + iNum = read(g_fdBook, x, sizeof(BOOK_ENTRY)); + if (sizeof(BOOK_ENTRY) != iNum) + { + Trace("_BookRead: I/O error on fd=%d, got %d and expected %d\n", + g_fdBook, iNum, sizeof(BOOK_ENTRY)); + perror("_BookRead"); + ASSERT(FALSE); + return(FALSE); + } + } + return(TRUE); +} + + +static ULONG +_BookCount(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + static ULONG + +**/ +{ + struct stat s; + + if (NULL != g_pMemBook) + { + return(g_uMemBookCount); + } + else + { + if (!strlen(g_Options.szBookName)) + { + return(0); + } + + if (0 != stat(g_Options.szBookName, &s)) + { + Trace("_BookCount: Stat failed.\n"); + ASSERT(FALSE); + return(0); + } + else + { + if ((s.st_size % sizeof(BOOK_ENTRY)) != 0) + { + Trace("_BookCount: Size is %u... not a mult of %u!\n", + s.st_size, sizeof(BOOK_ENTRY)); + return(0); + } + return(s.st_size / sizeof(BOOK_ENTRY)); + } + } +} + +#if 0 +static FLAG +_BookAppend(BOOK_ENTRY *x) +/** + +Routine description: + +Parameters: + + BOOK_ENTRY *x + +Return value: + + static FLAG + +**/ +{ + if (g_pMemBook != NULL) + { + g_pMemBookHead = g_pMemBook + g_uMemBookCount; + memcpy(g_pMemBookHead, x, sizeof(BOOK_ENTRY)); + g_uMemBookCount++; + return(TRUE); + } + else + { + ASSERT(g_fdBook != -1); + + if (-1 == lseek(g_fdBook, 0, SEEK_END)) + { + ASSERT(FALSE); + return(FALSE); + } + return((FLAG)(sizeof(BOOK_ENTRY) == + write(g_fdBook, x, sizeof(BOOK_ENTRY)))); + } +} +#endif + +static ULONG +_BookFindSig(UINT64 u64Sig, ULONG *puLow, ULONG *puHigh) +/** + +Routine description: + +Parameters: + + UINT64 u64Sig, + ULONG *puLow, + ULONG *puHigh + +Return value: + + static ULONG + +**/ +{ + ULONG uLow = 0; + ULONG uHigh = 0; + ULONG uCurrent; + ULONG uIndex; + ULONG uTotalEntries = _BookCount(); + BOOK_ENTRY entry; + ULONG uRetVal = 0; + FLAG fFound = FALSE; + + // + // Open the book. + // + if (0 == uTotalEntries) + { + Trace("BookFindSig: Opening book \"%s\" is empty.\n", + g_Options.szBookName); + goto end; + } + if (g_fdBook < 0) + { + Trace("BookFindSig: No book is opened!\n"); + goto end; + } + + // + // Perform a a binary search looking for an entry with a signature + // that matches this position's. + // + uLow = 0; + uHigh = uTotalEntries - 1; + + while ((uLow <= uHigh) && + (FALSE == fFound)) + { + uCurrent = (uLow + uHigh) / 2; + _BookSeek(uCurrent); + _BookRead(&entry); + + if (u64Sig == entry.u64Sig) + { + fFound = TRUE; + break; + } + else if (u64Sig < entry.u64Sig) + { + uHigh = uCurrent - 1; + } + else + { + ASSERT(u64Sig > entry.u64Sig); + uLow = uCurrent + 1; + } + } + if (FALSE == fFound) + { + goto end; // not found + } + ASSERT(uCurrent >= 0); + ASSERT(uCurrent < uTotalEntries); + uRetVal = uCurrent; + + // + // Ok, we matched a signature at current. Since there can be many + // entries with the same checksum (many moves from the same board + // position), seek backwards until the first one matching the + // checksum. + // + uIndex = uCurrent - 1; + while (uIndex != (ULONG)-1) + { + _BookSeek(uIndex); + _BookRead(&entry); + + if (entry.u64Sig != u64Sig) + { + uIndex++; +#ifdef DEBUG + ASSERT(uIndex <= uCurrent); + _BookSeek(uIndex); + _BookRead(&entry); + ASSERT(entry.u64Sig == u64Sig); +#endif + break; + } + uIndex--; + } + uLow = uIndex; + + // + // Walk forward until the last book entry with a matching signature. + // + uIndex = uCurrent + 1; + while (uIndex < uTotalEntries) + { + _BookSeek(uIndex); + _BookRead(&entry); + if (entry.u64Sig != u64Sig) + { + uIndex--; +#ifdef DEBUG + ASSERT(uIndex >= uCurrent); + _BookSeek(uIndex); + _BookRead(&entry); + ASSERT(entry.u64Sig == u64Sig); +#endif + break; + } + uIndex++; + } + uHigh = uIndex; + + end: + *puLow = uLow; + *puHigh = uHigh; + return(uRetVal); +} + + +static ULONG _BookComputeWeight(BOOK_ENTRY *e) +/** + +Routine description: + + + Given a book entry, compute its weight. The higher the more + likely it will be chosen and played. Used in BookMove and + BookEdit. The formula is: + + weight(mv) = winningness_coefficient * popularity_factor + + wins + winningness_coefficient = --------------- + (wins + losses) + + popularity_factor = wins + losses + draws + +Parameters: + + BOOK_ENTRY *e + +Return value: + + static ULONG + +**/ +{ + ULONG uRet; // computed return value + double dWinning = 0.0; // winningness coefficient + double dPopular; // popularity factor + + // + // dWinning is 0.0 now. The only way it gets a value is if we've + // seen this line win at least once. + // + if (e->uWins > 0) + { + dWinning = e->uWins; + dWinning /= (double)(e->uWins + e->uLosses); + + // + // dWinning is now the ratio of wins to deterministic games + // (games that were not draws). If this is less than 20% then + // ignore the line (give the move a zero weight). + // + if (dWinning < 0.20) return(0); + } + + // + // If we get here dWinning, the winningness coefficient, has been + // computed and is non-zero. Compute the rest of the weight term + // which is based on the popularity of the move (how many times it + // has been played). + // + dPopular = (double)(e->uWins + e->uLosses + e->uDraws); + uRet = (ULONG)(dPopular * dWinning); + return(uRet); +} + + +static void +_QuickSortBook(ULONG uLeft, ULONG uRight) +/** + +Routine description: + +Parameters: + + ULONG uLeft, + ULONG uRight + +Return value: + + static void + +**/ +{ + UINT64 u64Pivot; + ULONG uPivotSec; + ULONG uL, uR, uMid; + BOOK_ENTRY temp; + + ASSERT(uLeft >= 0); + ASSERT(uLeft < g_uMemBookSize); + ASSERT(uRight >= 0); + ASSERT(uRight < g_uMemBookSize); + if (uLeft < uRight) + { + // + // Select a pivot point. + // + u64Pivot = g_pMemBook[uLeft].u64Sig; + uPivotSec = g_pMemBook[uLeft].mvNext.uMove; + + // + // Partition the space based on the pivot. Everything left of + // it is less, everything right is greater. + // + uL = uLeft; + uR = uRight; + while (uL < uR) + { + while (((g_pMemBook[uL].u64Sig < u64Pivot) || + ((g_pMemBook[uL].u64Sig == u64Pivot) && + (g_pMemBook[uL].mvNext.uMove <= uPivotSec))) && + (uL <= uRight)) + { + uL++; + } + + while (((g_pMemBook[uR].u64Sig > u64Pivot) || + ((g_pMemBook[uR].u64Sig == u64Pivot) && + (g_pMemBook[uR].mvNext.uMove > uPivotSec))) && + (uR >= uLeft)) + { + uR--; + } + + if (uL < uR) + { + temp = g_pMemBook[uL]; + g_pMemBook[uL] = g_pMemBook[uR]; + g_pMemBook[uR] = temp; + } + } + uMid = uR; + + temp = g_pMemBook[uLeft]; + g_pMemBook[uLeft] = g_pMemBook[uMid]; + g_pMemBook[uMid] = temp; + + // + // Recurse on the two halves + // + if (uLeft != uMid) + { + _QuickSortBook(uLeft, uMid - 1); + } + if (uMid != uRight) + { + _QuickSortBook(uMid + 1, uRight); + } + } +} + + +static void +_CompactMemBook(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + static void + +**/ +{ + ULONG uCount = 0; + ULONG i; + ULONG uOccurances; + + Trace("Compacting the opening book... one moment.\n"); + + // + // Lose the blank signatures to reduce the working set. + // + for (i = 0; + i < g_uMemBookSize; + i++) + { + if (0 != g_pMemBook[i].u64Sig) + { + uOccurances = (g_pMemBook[i].uWins + + g_pMemBook[i].uDraws + + g_pMemBook[i].uLosses); + + if (0 != uOccurances) + { + memcpy(&(g_pMemBook[uCount]), + &(g_pMemBook[i]), + sizeof(BOOK_ENTRY)); + uCount++; + } + } + } + + g_uMemBookCount = 0; + if (uCount > 0) + { + g_uMemBookCount = uCount - 1; + } +} + + +static void +_StrainMemBook(ULONG uLimit) +/** + +Routine description: + +Parameters: + + ULONG uLimit + +Return value: + + static void + +**/ +{ + ULONG i; + ULONG uOccurances; + + Trace("Straining out unpopular positions to compact buffer...\n"); + + for (i = 0; + i < g_uMemBookSize; + i++) + { + if (0 != g_pMemBook[i].u64Sig) + { + uOccurances = (g_pMemBook[i].uWins + + g_pMemBook[i].uDraws + + g_pMemBook[i].uLosses); + + if (uOccurances <= uLimit) + { + memset(&(g_pMemBook[i]), + 0, + sizeof(BOOK_ENTRY)); + g_uMemBookCount--; + } + } + } +} + + +//+---------------------------------------------------------------------------- +// +// Function: _BookHashFind +// +// Arguments: BOOK_ENTRY *p - pointer to a book entry +// +// Returns: BOOK_ENTRY * - pointer to a membook location to store in +// +//+---------------------------------------------------------------------------- + + + + + +BOOK_ENTRY *_BookHashFind(BOOK_ENTRY *p) +/** + +Routine description: + + This routine returns a pointer to the membook entry that should be + used to store data about a position-move. It's called while + building a new opening book (BookBuild, see below). It uses a + simple hash-lookup algorthm with linear probing in the event of a + collision. + +Parameters: + + BOOK_ENTRY *p + +Return value: + + BOOK_ENTRY + +**/ +{ + ULONG uKey = (ULONG)((p->u64Sig >> 32) & (g_uMemBookSize - 1)); + BOOK_ENTRY *pBe = g_pMemBook + uKey; +#ifdef DEBUG + ULONG uInitialKey = uKey; + + ASSERT(g_pMemBook != NULL); + ASSERT(p->u64Sig); +#endif + + while(1) + { + // + // If this is an empty book entry, use it. + // + if (pBe->u64Sig == 0) break; + + // + // If this book entry is the same position and move as the one + // we are adding, return it. + // + if ((pBe->u64Sig == p->u64Sig) && + (pBe->mvNext.uMove == p->mvNext.uMove)) + { + break; + } + + // + // Otherwise check the next book entry... if we go off the end + // then loop around. + // + uKey++; + if (uKey >= g_uMemBookSize) uKey = 0; + pBe = g_pMemBook + uKey; + + // + // This should never happen -- it means a totally full book. + // Before we let the membook fill up we should have already + // called the strain routine to drop unpopular position-moves. + // + ASSERT(uKey != uInitialKey); + } + return(pBe); +} + + + +MOVE +BookMove(POSITION *pos, BITV bvFlags) +/** + +Routine description: + + This is a bit confusing. + + The primary purpose of this function is, given a position pointer, + to find and return a book move to play. + + This behavior can be achieved by calling with a good pos pointer + and bvFlags containing BOOKMOVE_SELECT_MOVE. + + If bvFlags doesn't contain this flag then no move will be + returned. + + If bvFlags contains BOOKMOVE_DUMP this function will trace a bunch + of info about move weights. Hence, something like BookDump can be + achieved via: + + (void)BookMove(pos, BOOKMOVE_DUMP); + + This is done so that the code to find all moves from a position + and show them is not duplicated more than once. + +Parameters: + + POSITION *pos, + BITV bvFlags + +Return value: + + MOVE + +*/ +{ + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx = NULL; + UINT64 u64Sig; + ULONG uTotalWeight = 0; + static ULONG uMoveWeights[32]; + static CHAR *szNames[32]; + ULONG uMoveNum; + static BOOK_ENTRY entry; + ULONG uBestWeight = 0; + ULONG uBestIndex = (ULONG)-1; + ULONG uLow, uHigh; + ULONG uIndex; + MOVE mvBook = {0}; + ULONG uRandom; + ULONG uCounter; + ULONG x; + double d; + CHAR *szName = NULL; + FLAG fOldValue = g_Options.fShouldAnnounceOpening; + + g_Options.fShouldAnnounceOpening = FALSE; +#ifdef DEBUG + memset(uMoveWeights, 0, sizeof(uMoveWeights)); +#endif + ctx = SystemAllocateMemory(sizeof(LIGHTWEIGHT_SEARCHER_CONTEXT)); + if (NULL == ctx) + { + Trace("Out of memory.\n"); + goto end; + } + + // + // We cannot probe the opening book if membook is non-NULL (which + // indicates the opening book is currently in-memory and still + // being built. + // + if (g_pMemBook != NULL) + { + Trace("Cannot probe the book while its still being built!\n"); + ASSERT(FALSE); + goto end; + } + if (FALSE == _BookOpen()) + { + Trace("BookMove: Could not open the book file.\n"); + goto end; + } + + // + // Binary search for sig in the book, this sets iLow and iHigh. + // + u64Sig = pos->u64PawnSig ^ pos->u64NonPawnSig; + if (0 == _BookFindSig(u64Sig, &uLow, &uHigh)) + { + Trace("BookMove: Signature not in book.\n", u64Sig); + goto end; + } + ASSERT((uHigh - uLow) < 32); + ASSERT(uLow <= uHigh); + + // + // Consider each entry from iLow to iHigh and determine the chances + // of playing it. + // + for (uIndex = uLow, uMoveNum = 0; + uIndex <= uHigh; + uIndex++, uMoveNum++) + { + _BookSeek(uIndex); + _BookRead(&entry); +#ifdef DEBUG + u64Sig = pos->u64PawnSig ^ pos->u64NonPawnSig; + ASSERT(entry.u64Sig == u64Sig); +#endif + uMoveWeights[uMoveNum] = 0; + szNames[uMoveNum] = NULL; + + // + // Don't consider the move if its flagged deleted or disabled. + // + if ((entry.bvFlags & FLAG_DISABLED) || + (entry.bvFlags & FLAG_DELETED)) + { + continue; + } + + // + // Make sure it's legal and doesn't draw... also get the name + // of this opening. + // + InitializeLightweightSearcherContext(pos, ctx); + if (FALSE == MakeMove((SEARCHER_THREAD_CONTEXT *)ctx, entry.mvNext)) + { + ASSERT(FALSE); + continue; + } + else + { + if (TRUE == IsDraw((SEARCHER_THREAD_CONTEXT *)ctx)) + { + UnmakeMove((SEARCHER_THREAD_CONTEXT *)ctx, entry.mvNext); + continue; + } + + u64Sig = (ctx->sPosition.u64PawnSig ^ + ctx->sPosition.u64NonPawnSig); + szNames[uMoveNum] = _BookLineToString(u64Sig); + UnmakeMove((SEARCHER_THREAD_CONTEXT *)ctx, entry.mvNext); + } + + // + // If one is marked always, just return it. + // + if ((entry.bvFlags & FLAG_ALWAYSPLAY) && + (bvFlags & BOOKMOVE_SELECT_MOVE)) + { + mvBook = entry.mvNext; + szName = szNames[uMoveNum]; + goto end; + } + + // + // Set this move's weight. + // + uMoveWeights[uMoveNum] = _BookComputeWeight(&entry); + uTotalWeight += uMoveWeights[uMoveNum]; + + // + // If we are in tournament mode we will play the top weighted + // move; look for it now. + // + if (uMoveWeights[uMoveNum] > uBestWeight) + { + uBestWeight = uMoveWeights[uMoveNum]; + uBestIndex = uIndex; + } + + } // next book move + + // + // If we threw every move out (there is no total weight) then we + // don't have a book move here. + // + if (0 == uTotalWeight) + { + ASSERT(mvBook.uMove == 0); + goto end; + } + + // + // We are done assigning weights to moves. If we are in tournament + // mode we should have picked a best one. If so, return it. + // + if ((TRUE == g_fTournamentMode) && (bvFlags & BOOKMOVE_SELECT_MOVE)) + { + if (uBestIndex != (ULONG)-1) + { + ASSERT(uBestWeight); + _BookSeek(uBestIndex); + _BookRead(&entry); + mvBook = entry.mvNext; + ASSERT(uBestIndex >= uLow); + szName = szNames[uBestIndex - uLow]; + goto end; + } + } + + // + // We didn't throw everything out... so pick a move randomly based + // on the weights assigned. + // + uRandom = (randomMT() % uTotalWeight) + 1; + if (bvFlags & BOOKMOVE_DUMP) + { + u64Sig = pos->u64PawnSig ^ pos->u64NonPawnSig; + Trace(" BookMove: List of moves in position 0x%" + COMPILER_LONGLONG_HEX_FORMAT ":\n", + u64Sig); + for (x = 0; x < uMoveNum; x++) + { + _BookSeek(uLow + x); + _BookRead(&entry); + ASSERT(entry.u64Sig == u64Sig); + + d = 0.0; + if (uMoveWeights[x] != 0) + { + d = (double)uMoveWeights[x] / (double)uTotalWeight; + d *= 100.0; + } + Trace("%02u. %-4s [+%u =%u -%u] \"%s\" @ %5.3f\n", + x, + MoveToSan(entry.mvNext, pos), + entry.uWins, entry.uDraws, entry.uLosses, + szNames[x], + d); + } + Trace(" Total weight was %u.\n\n", uTotalWeight); + if (!(bvFlags & BOOKMOVE_SELECT_MOVE)) + { + mvBook.uMove = 0; + goto end; + } + } + + // + // Based on the weighted list and the random number we + // selected pick a move. + // + for (uIndex = 0, uCounter = 0; + uIndex < uMoveNum; + uIndex++) + { + uCounter += uMoveWeights[uIndex]; + + if (uCounter >= uRandom) + { + _BookSeek(uLow + uIndex); + _BookRead(&entry); + mvBook = entry.mvNext; + szName = szNames[uIndex]; + goto end; + } + } +#ifdef DEBUG + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +#endif + + end: + g_Options.fShouldAnnounceOpening = fOldValue; + _BookClose(); + + if (mvBook.uMove) + { + ASSERT(bvFlags & BOOKMOVE_SELECT_MOVE); + + // + // We could be probing the book after a predicted ponder move (in + // which case we will have forced fAnnounceOpening to FALSE because + // we don't want to whisper two book moves in a row). + // + if (FALSE != g_Options.fShouldAnnounceOpening) { + Trace("tellothers book move %s [+%u =%u -%u]\n", + MoveToSan(entry.mvNext, pos), + entry.uWins, entry.uDraws, entry.uLosses); + } + } + + if (NULL != ctx) + { + SystemFreeMemory(ctx); + } + return(mvBook); +} + + +#if 0 +//+--------------------------------------------------------------------------- +// +// Function: BookEdit +// +// Synopsis: Giant hack to edit the book. +// +// Arguments: POSITION *pos +// +// Returns: void +// +//+--------------------------------------------------------------------------- +void +BookEdit(POSITION *pos) +{ + int iTotalEntries = _BookCount(); + int iNumMoves; + int iLow, iHigh; + FILE *pfLearn = NULL; + FLAG fFound = FALSE; + static BOOK_ENTRY entry; + int iIndex = 0; + int iCurrent = 0; + int x; + char *pCh, *pArg; + int arg; + int iSum; + int iWeights[64]; + float fl; + FLAG fOldValue = g_Options.fAnnounceOpening; + + g_Options.fAnnounceOpening = FALSE; + + // + // We cannot probe the opening book if membook is non-NULL (which + // indicates the opening book is currently in-memory and still being + // built. + // + if (g_pMemBook != NULL) + { + ASSERT(FALSE); + goto end; + } + + // + // Open the book. + // + iTotalEntries = _BookCount(); + if (0 == iTotalEntries) + { + Trace("BookDump: Opening book \"%s\" is empty.\n", + g_Options.szBookName); + goto end; + } + + ASSERT(g_fdBook == -1); + if (!_BookOpen()) + { + Trace("BookDump: Could not open the book.\n"); + goto end; + } + + // + // Open the learning recorder + // + pfLearn = fopen(BOOK_EDITING_RECORD, "a+b"); + if (NULL == pfLearn) + { + Trace("BookEdit: Warning: can't open %s to save learning.\n", + BOOK_EDITING_RECORD); + } + + if (!_BookFindSig(pos->u64Sig, &iLow, &iHigh)) + { + Trace("BookEdit: Position %I64x is not in the book.\n"); + goto end; + } + + iNumMoves = iHigh - iLow + 1; + iCurrent = 0; + do + { + printf("\n"); + Trace("--EDITING OPENING BOOK--\n\n"); + Trace("There are %u positions in the opening book \"%s\".\n", + iTotalEntries, g_Options.szBookName); + Trace("There are %u book moves in this position, %u to %u:\n", + iNumMoves, iLow, iHigh); + + for (x = 0, iSum = 0; + x < iNumMoves; + x++) + { + _BookSeek(iLow + x); + _BookRead(&entry); + + // + // If the disabled flag is asserted, do not allow this + // move to be played. If the disabled flag is not + // asserted, calculate a weight for this move. + // + if ((entry.bvFlags & FLAG_DISABLED) || + (entry.bvFlags & FLAG_DELETED)) + { + iWeights[x] = 0; + } + else + { + iWeights[x] = _BookComputeWeight(&entry); + } + iSum += iWeights[x]; + } + + for (x = 0; + x < iNumMoves; + x++) + { + _BookSeek(iLow + x); + _BookRead(&entry); + + fl = (float)iWeights[x]; + if (iSum) + { + fl /= (float)iSum; + fl *= 100.0; + } + + if (x == iCurrent) + { + Trace(">> "); + } + else + { + Trace(" "); + } + + Trace("%02u. %6u..%6u = %4s [+%6u =%6u -%6u] @ ~%6.3f%% | %s%s", + x + 1, + 0, + iWeights[x], + MoveToSAN(entry.mvNext, pos), + entry.iWins, + entry.iDraws, + entry.iLosses, + fl, + (entry.bvFlags & FLAG_DISABLED) ? "NEV" : "", + (entry.bvFlags & FLAG_ALWAYSPLAY) ? "ALW" : ""); + + if (x == iCurrent) + { + Trace("<<\n"); + } + else + { + Trace("\n"); + } + } + + _BookSeek(iLow + iCurrent); + _BookRead(&entry); + Trace("Command (q, p, n, +, =, -, h, l, e, a, d, ?): "); + pCh = BlockingRead(); + + switch(tolower(*pCh)) + { + case 'q': + Trace("--DONE EDITING OPENING BOOK--\n\n"); + goto end; + case 'p': + iCurrent--; + if (iCurrent < 0) iCurrent = iNumMoves - 1; + break; + case 'n': + iCurrent++; + if (iCurrent >= iNumMoves) iCurrent = 0; + break; + case '+': + Trace("Enter new wincount: "); + pArg = BlockingRead(); + arg = atoi(pArg); + if (arg) + { + entry.iWins = arg; + _BookSeek(iLow + iCurrent); + _BookWrite(&entry); + if (NULL != pfLearn) + { + fprintf(pfLearn, "%I64x (%x) + %u // %s\n", + entry.u64Sig, + entry.mvNext.move, + arg, + BoardToFEN(pos)); + } + } + SystemFreeMemory(pArg); + break; + case '=': + Trace("Enter new drawcount: "); + pArg = BlockingRead(); + arg = atoi(pArg); + if (arg) + { + entry.iDraws = arg; + _BookSeek(iLow + iCurrent); + _BookWrite(&entry); + if (NULL != pfLearn) + { + fprintf(pfLearn, "%I64x (%x) = %u // %s\n", + entry.u64Sig, + entry.mvNext.move, + arg, + BoardToFEN(pos)); + } + } + SystemFreeMemory(pArg); + break; + case '-': + Trace("Enter new losscount: "); + pArg = BlockingRead(); + arg = atoi(pArg); + if (arg) + { + entry.iLosses = arg; + _BookSeek(iLow + iCurrent); + _BookWrite(&entry); + if (NULL != pfLearn) + { + fprintf(pfLearn, "%I64x (%x) - %u // %s\n", + entry.u64Sig, + entry.mvNext.move, + arg, + BoardToFEN(pos)); + } + } + SystemFreeMemory(pArg); + break; + case 'e': + if (entry.bvFlags & FLAG_DISABLED) + { + entry.bvFlags &= ~FLAG_DISABLED; + } + else + { + entry.bvFlags |= FLAG_DISABLED; + entry.bvFlags &= ~FLAG_ALWAYSPLAY; + } + _BookSeek(iLow + iCurrent); + _BookWrite(&entry); + if (NULL != pfLearn) + { + fprintf(pfLearn, "%I64x (%x) FLAGS %x // %s\n", + entry.u64Sig, + entry.mvNext.move, + entry.bvFlags, + BoardToFEN(pos)); + } + break; + case 'a': + if (entry.bvFlags & FLAG_ALWAYSPLAY) + { + entry.bvFlags &= ~FLAG_ALWAYSPLAY; + } + else + { + entry.bvFlags |= FLAG_ALWAYSPLAY; + entry.bvFlags &= ~FLAG_DISABLED; + } + _BookSeek(iLow + iCurrent); + _BookWrite(&entry); + if (NULL != pfLearn) + { + fprintf(pfLearn, "%I64x (%x) FLAGS %x // %s\n", + entry.u64Sig, + entry.mvNext.move, + entry.bvFlags, + BoardToFEN(pos)); + } + break; + case 'h': + PreferPosition(pos, pfLearn, pos->u64Sig, -1); + Trace("I hate this position.\n"); + break; + case 'i': + PreferPosition(pos, pfLearn, pos->u64Sig, 0); + Trace("I'm indifferent towards this position.\n"); + break; + case 'l': + PreferPosition(pos, pfLearn, pos->u64Sig, 1); + Trace("I love this position!\n"); + break; + case '?': + Trace( +"Commands: \n" +" +) adjust wins =) adjust draws -) adjust losses\n" +" h) hate this pos i) indifferent l) love this pos\n\n" + +" e) enable/disable\n" +" a) always/sometimes play\n\n" + +" p) previous move n) next move q) quit editing\n\n"); + break; + default: + break; + } + SystemFreeMemory(pCh); + } + while(1); + + end: + g_Options.fAnnounceOpening = fOldValue; + + ASSERT(g_fdBook != -1); + _BookClose(); + + if (NULL != pfLearn) + { + fclose(pfLearn); + } +} +#endif + + + + + +static FLAG +_BookBuild(void) +/** + +Routine description: + + Builds a new opening book. This routine is called by + LearnPGNOpenings in movelist.c after it has played through one PGN + game. g_MoveList is loaded with position signatures and move + structs representing this game. Our goal is to parse these and + create/update the membook entries to reflect the game played and + its result. + +Parameters: + + void + +Return value: + + static FLAG + +**/ +{ + BOOK_ENTRY entry; + BOOK_ENTRY *pEntry; + ULONG n; + GAME_MOVE *q; + ULONG u; + double dFull; + GAME_RESULT result = GetGameResult(); + + if (result.eResult != RESULT_WHITE_WON && + result.eResult != RESULT_BLACK_WON && + result.eResult != RESULT_DRAW) { + return(FALSE); + } + + // + // If the membook has not yet been allocated, do it now. + // + if (g_pMemBook == NULL) + { + ASSERT((g_uMemBookSize & (g_uMemBookSize - 1)) == 0); + g_uMemBookCount = 0; + g_pMemBookHead = NULL; + g_pMemBook = (BOOK_ENTRY *) + SystemAllocateMemory(g_uMemBookSize * sizeof(BOOK_ENTRY)); + g_pMemBookHead = g_pMemBook; + ASSERT(g_pMemBook != NULL); + } + + // + // Consider each position in the game we have played up until now. + // + u = 0; + q = GetNthOfficialMoveRecord(u); + while((q != NULL) && (q->mv.uMove != 0)) + { + entry.u64Sig = q->u64PositionSigBeforeMove; + entry.mvNext = q->mv; + entry.u64NextSig = q->u64PositionSigAfterMove; + + // + // Have we ever seen this position before? + // + pEntry = _BookHashFind(&entry); + if (0 != pEntry->u64Sig) + { + // + // Yes we have seen this signature-move before. Update the + // win/draw/loss counter at this entry in the membook. + // + ASSERT(pEntry->u64Sig == entry.u64Sig); + ASSERT(pEntry->mvNext.uMove == entry.mvNext.uMove); + if (((result.eResult == RESULT_BLACK_WON) && + (GET_COLOR(entry.mvNext.pMoved) == BLACK)) || + ((result.eResult == RESULT_WHITE_WON) && + (GET_COLOR(entry.mvNext.pMoved) == WHITE))) + { + pEntry->uWins++; + } + else + { + if (RESULT_DRAW == result.eResult) + { + pEntry->uDraws++; + } + else + { + pEntry->uLosses++; + } + } + } + + // + // Nope never seen this signature-move entry before, create a new + // entry for it and add it to the membook. + // + else + { + memset(pEntry, 0, sizeof(pEntry)); + pEntry->u64Sig = entry.u64Sig; + pEntry->mvNext = entry.mvNext; + pEntry->u64NextSig = entry.u64NextSig; + + if (((result.eResult == RESULT_BLACK_WON) && + (GET_COLOR(entry.mvNext.pMoved) == BLACK)) || + ((result.eResult == RESULT_WHITE_WON) && + (GET_COLOR(entry.mvNext.pMoved) == WHITE)) ) + { + pEntry->uWins = 1; + } + else + { + if (RESULT_DRAW == result.eResult) + { + pEntry->uDraws = 1; + } + else + { + pEntry->uLosses = 1; + } + } + g_uMemBookCount++; + + // + // If the in memory buffer is getting too full, throw out + // all positions that occur only once in it in order to + // compact it. We should try to limit this because it can + // weaken the book. + // + n = 1; + dFull = (double)g_uMemBookCount; + dFull /= (double)g_uMemBookSize; + dFull *= 100.0; + while (dFull > 97.0) + { + _StrainMemBook(n); + n++; + + dFull = (double)g_uMemBookCount; + dFull /= (double)g_uMemBookSize; + dFull *= 100.0; + } + } + u++; + q = GetNthOfficialMoveRecord(u); + } + return(TRUE); +} + + +static FLAG +_BookToDisk(ULONG uStrainLimit) +/** + +Routine description: + +Parameters: + + ULONG uStrainLimit + +Return value: + + static FLAG + +**/ +{ + ULONG i; + int ifd; + CHAR *szTempBook = "tempbook.bin"; + CHAR szCmd[SMALL_STRING_LEN_CHAR]; + BOOK_ENTRY sBe; + ULONG uOldBook = 0; + ULONG uNewBook = 0; + ULONG uOld_BookCount; + ULONG uNew_BookCount; + BOOK_ENTRY *pOldBook = NULL; + BOOK_ENTRY *pNewBook = NULL; + FLAG fMyRetVal = FALSE; + struct stat s; + + if (!strlen(g_Options.szBookName)) + { + return(FALSE); + } + i = g_uMemBookCount; + + // + // Drops all book entries with less than limit occurrances + // + _StrainMemBook(uStrainLimit); + + // + // Drops all unused entries + // + Trace("Stage 2: Compacting the book.\n"); + _CompactMemBook(); + + // + // Sorts the by signature. + // + Trace("Stage 3: Sorting the book.\n"); + _QuickSortBook(0, g_uMemBookCount); + uNew_BookCount = g_uMemBookCount; + + // + // Create the temporary book on the disk. + // + (void)unlink(szTempBook); + if (SystemDoesFileExist(szTempBook)) + { + Trace("_BookToDisk: Can't create a temporary book!\n"); + return(FALSE); + } + + ifd = open(szTempBook, + O_RDWR | O_CREAT | O_BINARY, + _S_IREAD | _S_IWRITE); + if (ifd < 0) + { + Trace("_BookToDisk: Can't create a temporary book!\n"); + return(FALSE); + } +#ifndef _MSC_VER + fchmod(ifd, 0644); +#endif + + // + // Count the entries in the old book on disk. + // + uOld_BookCount = 0; + if ((TRUE == _VerifyBook(g_Options.szBookName)) && (TRUE == _BookOpen())) + { + if (0 == stat(g_Options.szBookName, &s)) + { + uOld_BookCount = (s.st_size / sizeof(BOOK_ENTRY)); + } + } + + // + // Merge the old book (on disk) with the new (in memory) in the + // temp book. + // + Trace("Merging book lines and writing to disk...\n"); + do + { + pOldBook = pNewBook = NULL; + + // + // Read the next old book entry. + // + retry: + if (uOldBook < uOld_BookCount) + { + if ((int)(uOldBook * sizeof(BOOK_ENTRY)) != + lseek(g_fdBook, (uOldBook * sizeof(BOOK_ENTRY)), SEEK_SET)) + { + Trace("_BookToDisk: Cannot seek to byte offset %u in old " + "book.\n", uOldBook * sizeof(BOOK_ENTRY)); + ASSERT(FALSE); + goto end; + } + + if (sizeof(BOOK_ENTRY) != read(g_fdBook, + &sBe, + sizeof(BOOK_ENTRY))) + { + Trace("_BookToDisk: Can't read error in old book, trying " + "to recover...\n"); + uOldBook++; + goto retry; + } + pOldBook = &sBe; + } + + // + // Get the next new book entry + // + if (uNewBook < uNew_BookCount) + { + ASSERT(0 != g_pMemBook[uNewBook].u64Sig); + pNewBook = &(g_pMemBook[uNewBook]); + } + + // + // Decide which to write into the merged (temporary) book we + // are constructing next... + // + if ((NULL == pNewBook) && (NULL == pOldBook)) + { + break; + } + else if ((NULL == pNewBook) && (NULL != pOldBook)) + { + goto writeoldbook; + } + else if ((NULL != pNewBook) && (NULL == pOldBook)) + { + goto writenewbook; + } + else + { + if (pOldBook->u64Sig < pNewBook->u64Sig) + { + goto writeoldbook; + } + else if (pOldBook->u64Sig > pNewBook->u64Sig) + { + goto writenewbook; + } + else + { + ASSERT(pOldBook->u64Sig == pNewBook->u64Sig); + if (pOldBook->mvNext.uMove < pNewBook->mvNext.uMove) + { + goto writeoldbook; + } + else if (pOldBook->mvNext.uMove > pNewBook->mvNext.uMove) + { + goto writenewbook; + } + else + { + // + // Same position and move... + // + pNewBook->uWins += pOldBook->uWins; + pNewBook->uDraws += pOldBook->uDraws; + pNewBook->uLosses += pOldBook->uLosses; + pNewBook->bvFlags |= pOldBook->bvFlags; + uOldBook++; + goto writenewbook; + } + } + } +#ifdef DEBUG + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +#endif + + writeoldbook: + if (-1 == lseek(ifd, 0, SEEK_END)) + { + ASSERT(FALSE); + } + if (sizeof(BOOK_ENTRY) != write(ifd, pOldBook, sizeof(BOOK_ENTRY))) + { + Trace("_BookToDisk: Error writing new book, aborting procedure.\n"); + goto end; + } + uOldBook++; + continue; + + writenewbook: + if (-1 == lseek(ifd, 0, SEEK_END)) + { + ASSERT(FALSE); + } + if (sizeof(BOOK_ENTRY) != write(ifd, pNewBook, sizeof(BOOK_ENTRY))) + { + Trace("_BookToDisk: Error writing new book, aborting procedure." + "\n"); + goto end; + } + uNewBook++; + continue; + } + while(1); + fMyRetVal = TRUE; + + end: + close(ifd); + SystemFreeMemory(g_pMemBook); + g_pMemBook = NULL; + g_pMemBookHead = NULL; + g_uMemBookCount = 0; + _BookClose(); + + // + // Verify the consistency of the new book before klobbering the old one + // + if (FALSE == _VerifyBook(szTempBook)) + { + Trace("_BookToDisk: The book I just wrote is corrupt!!!\n"); + fMyRetVal = FALSE; + ASSERT(FALSE); + } + else + { + // + // HACKHACK: put this in system, use CopyFile in win32 + // +#ifdef _MSC_VER + _snprintf(szCmd, 255, "move %s %s%c", szTempBook, + g_Options.szBookName, 0); +#else + snprintf(szCmd, 255, "/bin/mv %s %s%c", szTempBook, + g_Options.szBookName, 0); +#endif + system(szCmd); + } + + if (TRUE == fMyRetVal) + { + Trace("Book successfully built.\n"); + } + return(fMyRetVal); +} + + +static FLAG +_LearnPgnOpenings(CHAR *szFilename, ULONG uStrainLimit) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + ULONG uStrainLimit + +Return value: + + static FLAG + +**/ +{ + CHAR *p; + FILE *pf = NULL; + struct stat s; + double d; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPgnOpenings: file \"%s\" doesn't exist.\n", + szFilename); + return(FALSE); + } + + if (0 != stat(szFilename, &s)) + { + Trace("LearnPgnOpenings: Can't read file \"%s\".\n", + szFilename); + return(FALSE); + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPgnOpenings: error reading file %s.\n", + szFilename); + return(FALSE); + } + + CleanupHashSystem(); + + Trace("Stage 1: reading and parsing PGN\n"); + while((p = ReadNextGameFromPgnFile(pf)) != NULL) + { + if (TRUE == LoadPgn(p)) + { + _BookBuild(); + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("%u/%u (%5.2f%% done) ", + (unsigned)ftell(pf), (unsigned)s.st_size, d); + d = (double)g_uMemBookCount; + d /= (double)g_uMemBookSize; + d *= 100.0; + printf("[membook %5.2f%% full]\r", d); + } + SystemFreeMemory(p); + } + fclose(pf); + + _BookToDisk(uStrainLimit); + + InitializeHashSystem(); + + return(TRUE); +} + + +#if 0 +static void +_UpdateUserOpeningList(INT iResult) +{ + int fd = open(OPENING_LEARNING_FILENAME, + O_RDWR | O_CREAT | O_BINARY | O_RANDOM, + _S_IREAD | _S_IWRITE); + ULONG uNumRecords; + ULONG u; + OPENING_LEARNING_ENTRY ole; + ULONG uPos; + struct stat s; + + // + // If we failed to open it, abort. + // + if (fd < 0) goto end; + + // + // Stat it to see how many entries there are. + // + if (0 != stat(OPENING_LEARNING_FILENAME, &s)) + { + ASSERT(FALSE); + Trace("UpdateUserOpeningList: Corrupt %s file.\n", + OPENING_LEARNING_FILENAME); + goto end; + } + if ((s.st_size % sizeof(OPENING_LEARNING_ENTRY)) != 0) + { + ASSERT(FALSE); + Trace("UpdateUserOpeningList: Corrupt %s file.\n", + OPENING_LEARNING_FILENAME); + goto end; + } + uNumRecords = s.st_size / sizeof(OPENING_LEARNING_ENTRY); + + // + // Read each entry looking for a match. + // + for (u = 0; u < uNumRecords; u++) + { + if (sizeof(OPENING_LEARNING_ENTRY) != + read(fd, &ole, sizeof(OPENING_LEARNING_ENTRY))) + { + Trace("UpdateUserOpeningList: Read error.\n"); + goto end; + } + + if (ole.u64Sig == g_Options.u64OpeningSig) + { + // + // Found it, so update and write back in place. + // + switch (iResult) + { + case -1: + ole.uBlackWins++; + break; + case 0: + ole.uDraws++; + break; + case 1: + ole.uWhiteWins++; + break; +#ifdef DEBUG + default: + ASSERT(FALSE); + break; +#endif + } + + uPos = u * sizeof(OPENING_LEARNING_ENTRY); + if (uPos != lseek(fd, uPos, SEEK_SET)) + { + Trace("UpdateUserOpeningList: Seek error.\n"); + goto end; + } + if (sizeof(OPENING_LEARNING_ENTRY) != + write(fd, &ole, sizeof(OPENING_LEARNING_ENTRY))) + { + Trace("UpdateUserOpeningList: Write error.\n"); + } + goto end; + } + } + + // + // We never found it, so add one at the end. + // + memset(&ole, 0, sizeof(ole)); + ole.u64Sig = g_Options.u64OpeningSig; + switch(iResult) + { + case -1: + ole.uBlackWins++; + break; + case 0: + ole.uDraws++; + break; + case 1: + ole.uWhiteWins++; + break; +#ifdef DEBUG + default: + ASSERT(FALSE); + break; +#endif + } + + if (-1 == lseek(fd, 0, SEEK_END)) + { + Trace("UpdateUserOpeningList: Seek error.\n"); + goto end; + } + + if (sizeof(OPENING_LEARNING_ENTRY) != + write(fd, &ole, sizeof(OPENING_LEARNING_ENTRY))) + { + Trace("UpdateUserOpeningList: Append error.\n"); + } + + end: + if (fd >= 0) + { + close(fd); + } +} +#endif + + +#if 0 +//+---------------------------------------------------------------------------- +// +// Function: BookLearn +// +// Synopsis: Handles book learning at the end of a game based on the +// result of the game and the calibre of the opponent. +// +// Arguments: int iResult +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void +BookLearn(INT iResult) +{ + ULONG iIndex, x; + unsigned int iChanged = 0; + int iTotalEntries = _BookCount(); + int iLow, iHigh, iCurrent = 0; + BOOK_ENTRY entry; + FLAG fFound = FALSE; + +#ifdef DEBUG + if (g_Options.ePlayMode == I_PLAY_BLACK) + { + Trace("BookLearn: I was playing black\n"); + } + else if (g_Options.ePlayMode == I_PLAY_WHITE) + { + Trace("BookLearn: I was playing white\n"); + } + + if (iResult == -1) + { + Trace("BookLearn: Black won.\n"); + } + else if (iResult == 1) + { + Trace("BookLearn: White won.\n"); + } + else + { + Trace("BookLearn: The game was a draw.\n"); + } +#endif + + // + // Should we learn anything? + // + + // + // Not if the game was bullet + // + if ((g_Options.eGameType == GAME_BULLET) || + (g_Options.eGameType == GAME_UNKNOWN)) + { + Trace("BookLearn: Game was too fast or unknown speed, don't learn.\n"); + goto end; + } + + // + // Not if the game wasn't rated. + // + if ((g_Options.fGameIsRated == FALSE)) + { + Trace("BookLearn: Game was unrated, don't learn.\n"); + goto end; + } + + // + // Not if someone lost on time or because of forfeit. + // + if ((NULL != strstr(g_Options.szDescription, "forfeit")) || + (NULL != strstr(g_Options.szDescription, "time")) || + (NULL != strstr(g_Options.szDescription, "abort"))) + { + Trace("BookLearn: Loss by forfeit/abort, don't learn.\n"); + goto end; + } + + // + // Not if we won but the opponent was weak. + // + if (((g_Options.ePlayMode == I_PLAY_WHITE) && (iResult == 1)) || + ((g_Options.ePlayMode == I_PLAY_BLACK) && (iResult == -1))) + { +#ifdef DEBUG + Trace("BookLearn: I won, my opponent's rating was %u, " + "my rating is %u.\n", + g_Options.iOpponentsRating, + g_Options.iMyRating); +#endif + + if (g_Options.iOpponentsRating < g_Options.iMyRating - 300) + { + Trace("BookLearn: Opponent sucks, not learning.\n"); + goto end; + } + } + + // + // Not if we lost but the opponent was strong. + // + if (((g_Options.ePlayMode == I_PLAY_BLACK) && (iResult == 1)) || + ((g_Options.ePlayMode == I_PLAY_WHITE) && (iResult == -1))) + { + Trace("BookLearn: I lost, my opponent's rating was %u, " + "my rating is %u.\n", + g_Options.iOpponentsRating, + g_Options.iMyRating); + + if (g_Options.iOpponentsRating > g_Options.iMyRating + 300) + { + Trace("BookLearn: Opponent kicks ass, not learning.\n"); + goto end; + } + ToXboard("tellics say Nice game!\n"); + } + + // + // Yes, we have decided to learn. + // + Trace("BookLearn: Revising opening book line...\n"); + + // + // 1. Save the learning on a user-friendly list... + // + UpdateUserOpeningList(iResult); + + // + // 2. Save the learning in the real opening book... + // + if ((0 == iTotalEntries) || + (FALSE == _BookOpen())) + { + Trace("BookLearn: Could not open the book.\n"); + goto end; + } + + // + // Look at the moves in the move list. + // + for (iIndex = 0; + iIndex < g_iMoveNum - 1; + iIndex++) + { + // + // Only learn on the first 30 moves. + // + if (iIndex > 60) break; + + Trace("BookLearn: Seeking %I64x with move %s (%x) in the book.\n", + g_MoveList[iIndex].u64Sig, + MoveToICS(g_MoveList[iIndex + 1].mv), + g_MoveList[iIndex + 1].mv.move); + + // + // Binary search for sig in the book, this sets iLow and iHigh. + // + if (0 != _BookFindSig(g_MoveList[iIndex].u64Sig, &iLow, &iHigh)) + { + Trace("BookLearn: Found a (P) : %I64x at %u.\n", + g_MoveList[iIndex].u64Sig, iCurrent); + + // + // Current now points to the first book entry matching + // the sig... look for the entry matching the move too. + // + for (x = iLow; x <= iHigh; x++) + { + _BookSeek(x); + _BookRead(&entry); + + ASSERT(entry.u64Sig == + g_MoveList[iIndex].u64Sig); + + // + // If we match the move and signature, update the entry + // based on this game's results. + // + if (entry.mvNext.move == g_MoveList[iIndex + 1].mv.move) + { + Trace("BookLearn: Matched mv : %x at %u.\n", + g_MoveList[iIndex + 1].mv.move, x); + iChanged++; + + // + // Did the side making the move win in the end? + // + if (((iResult == -1) && + (IS_BLACK(g_MoveList[iIndex + 1].mv.data.pMoved))) || + ((iResult == 1) && + (IS_WHITE(g_MoveList[iIndex + 1].mv.data.pMoved)))) + { + Trace("BookLearn: Side moving won, enforce this " + "book entry.\n"); + entry.iWins++; + } + else + { + // + // No so it drew or lost. + // + if (0 == iResult) + { + Trace("BookLearn: Game was a draw, increase " + "drawishness of this book entry.\n"); + entry.iDraws++; + } + else + { + Trace("BookLearn: Side moving lost, discourage " + "this book entry.\n"); + entry.iLosses++; + } + } + + // + // Write it back into the book. + // + _BookSeek(x); + _BookWrite(&entry); + + // + // Done looking for this move. + // + break; + + } // entry.move matches + + } // loop to look at all moves on entries w/ matching sig + + } // was sig found in book? + + } // main game move loop + + end: + Trace("BookLearn: Changed %u book positions.\n", iChanged); + _BookClose(); +} + + +//+---------------------------------------------------------------------------- +// +// Function: PreferPosition +// +// Synopsis: Given a position, love, hate or be neutral towards it. +// +// If the position is to be loved, all other book entries +// that lead to it will be flagged "always play". +// +// If the position is to be hated, all other book entries +// that lead to it will be flagged "never play". +// +// A neutral setting will cause all other book entries that +// lead to have their flags cleared. +// +// Arguments: POSITION pos - the pos, needed to make a FEN +// FILE *fd - file to record permanently in +// INT64 i64Targ - the signature to love/hate/neuter +// int i : -1 means hate +// : 0 means neuter +// : 1 means love +// +// Returns: void +// +//+---------------------------------------------------------------------------- +void +PreferPosition(POSITION *pos, FILE *fd, INT64 i64Targ, int i) +{ + int iTotalEntries = _BookCount(); + int x; + int iChanged = 0; + static BOOK_ENTRY entry; + + ASSERT(pos->u64Sig == i64Targ); + + if (g_pMemBook != NULL) + { + ASSERT(FALSE); + return; + } + + iTotalEntries = _BookCount(); + + for (x = 0; + x < iTotalEntries - 1; + x++) + { + if ((x % 10000) == 0) + { + printf("%u / %u\r", x, iTotalEntries); + } + _BookSeek(x); + _BookRead(&entry); + + if (entry.i64NextSig == i64Targ) + { + iChanged++; + + switch(i) + { + case -1: + _BookSeek(x); + entry.bvFlags = FLAG_DISABLED; + _BookWrite(&entry); + if (NULL != fd) + { + fprintf(fd, "%I64x (%x) FLAGS %x // %s\n", + entry.u64Sig, + entry.mvNext.move, + entry.bvFlags, + BoardToFEN(pos)); + } + break; + case 0: + _BookSeek(x); + entry.bvFlags = 0; + _BookWrite(&entry); + if (NULL != fd) + { + fprintf(fd, "%I64x (%x) FLAGS %x // %s\n", + entry.u64Sig, + entry.mvNext.move, + entry.bvFlags, + BoardToFEN(pos)); + } + break; + case 1: + _BookSeek(x); + entry.bvFlags = FLAG_ALWAYSPLAY; + _BookWrite(&entry); + if (NULL != fd) + { + fprintf(fd, "%I64x (%x) FLAGS %x // %s\n", + entry.u64Sig, + entry.mvNext.move, + entry.bvFlags, + BoardToFEN(pos)); + } + break; + } + } + } + + printf("\n\n"); + Trace("PreferPosition: Changed %u lines\n", iChanged); +} + +//+---------------------------------------------------------------------------- +// +// Function: ImportEditing +// +// Synopsis: Affect the opening book file based on an old editing record +// (.EDT file). Apply editing / learning record to the new book +// positions. +// +// Arguments: char *szFile +// +// Returns: FLAG +// +//+---------------------------------------------------------------------------- +FLAG +ImportEditing(char *szFile) +{ + FILE *p = fopen(szFile, "r"); + FLAG fMyRetVal = FALSE; + static char szLine[512]; + char szOpcode[512]; + int iArg; + int iTotalEntries; + INT64 u64Sig; + MOVE mv; + int iLow, iHigh, iCurrent = 0; + int iIndex; + BOOK_ENTRY entry; + BOOK_ENTRY klobber; + + // + // We cannot probe the opening book if membook is non-NULL (which + // indicates the opening book is currently in-memory and still being + // built. + // + if (g_pMemBook != NULL) + { + goto end; + } + + // + // Open the book. + // + iTotalEntries = _BookCount(); + if (0 == iTotalEntries) + { + Trace("BookMove: Opening book \"%s\" is empty.\n", + g_Options.szBookName); + goto end; + } + + if (FALSE == _BookOpen()) + { + Trace("BookMove: Could not open the book.\n"); + goto end; + } + + if (NULL != p) + { + while(fgets(szLine, 511, p)) + { + if (_snscanf(szLine, 511, "%I64x (%x) %s", + &u64Sig, + &mv.move, + &szOpcode) != 3) + { + continue; + } + +#ifdef DEBUG + Trace("Searching for %I64x move %x\n", + u64Sig, mv.move); +#endif + + if (_BookFindSig(u64Sig, &iLow, &iHigh)) + { + // + // Walk forward looking for the right move. + // + memset(&entry, 0, sizeof(entry)); + for (iIndex = iLow; + iIndex <= iHigh; + iIndex++) + { + _BookSeek(iIndex); + _BookRead(&entry); + ASSERT(entry.u64Sig == u64Sig); + + if (entry.mvNext.move == mv.move) break; + } + + // + // Did we find the move? + // + if (entry.mvNext.move != mv.move) + { + Trace("Move %x not present in book at position %I64x\n", + mv.move, u64Sig); + continue; + } + + // + // Yes. What should we do with it? + // + if (!STRNCMP(szOpcode, "FLAGS", 5)) + { + if (_snscanf(szLine, 511, "%I64x (%x) %s %x", + &u64Sig, + &mv.move, + &szOpcode, + &iArg) == 4) + { + if (iArg >= 0) entry.bvFlags = iArg; + } + else + { + Trace("Error\n"); + } + } + else if (!STRNCMP(szOpcode, "+", 1)) + { + if (_snscanf(szLine, 511, "%I64x (%x) %s %u", + &u64Sig, + &mv.move, + &szOpcode, + &iArg) == 4) + { + if (iArg >= 0) entry.iWins = iArg; + } + else + { + Trace("Error\n"); + } + } + else if (!STRNCMP(szOpcode, "=", 1)) + { + if (_snscanf(szLine, 511, "%I64x (%x) %s %u", + &u64Sig, + &mv.move, + &szOpcode, + &iArg) == 4) + { + if (iArg >= 0) entry.iDraws = iArg; + } + else + { + Trace("Error\n"); + } + } + else if (!STRNCMP(szOpcode, "-", 1)) + { + if (_snscanf(szLine, 511, "%I64x (%x) %s %u", + &u64Sig, + &mv.move, + &szOpcode, + &iArg) == 4) + { + if (iArg >= 0) entry.iLosses = iArg; + } + else + { + Trace("Error\n"); + } + } + else + { + Trace("Error\n"); + } + + // + // Write it back to the book + // + _BookSeek(iIndex); + _BookRead(&klobber); + + if ((entry.u64Sig == + klobber.u64Sig) && + (entry.mvNext.move == + klobber.mvNext.move)) + { + _BookWrite(&entry); + } + } + } + } + + fMyRetVal = TRUE; + end: + _BookClose(); + return(fMyRetVal); +} +#endif + + +static FLAG +_FindTerminalPositions(CHAR *szFilename, + ULONG uPlyBeforeMate) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + ULONG uMovesBeforeMate + +Return value: + + static FLAG + +**/ +{ + CHAR *p; + FILE *pf = NULL; + struct stat s; + POSITION *pos; + SEARCHER_THREAD_CONTEXT *ctx; + FLAG fInCheck; + MOVE mv; + ULONG u; + FLAG fRet = FALSE; + + ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT)); + if (NULL == ctx) + { + Trace("Out of memory.\n"); + goto end; + } + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("FindTerminalPositions: file \"%s\" doesn't exist.\n", + szFilename); + goto end; + } + + if (0 != stat(szFilename, &s)) + { + Trace("FindTerminalPositions: Can't read file \"%s\".\n", + szFilename); + goto end; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("FindTerminalPositions: error reading file %s.\n", + szFilename); + goto end; + } + + mv.uMove = 0; + while((p = ReadNextGameFromPgnFile(pf)) != NULL) + { + if (TRUE == LoadPgn(p)) + { + pos = GetRootPosition(); + + fInCheck = InCheck(pos, pos->uToMove); + if (TRUE == fInCheck) + { + InitializeSearcherContext(pos, ctx); + GenerateMoves(ctx, mv, GENERATE_ESCAPES); + if (0 == MOVE_COUNT(ctx, 0)) + { + u = uPlyBeforeMate; + while(u) + { + if (FALSE == OfficiallyTakebackMove()) + { + break; + } + u--; + } + pos = GetRootPosition(); + InitializeSearcherContext(pos, ctx); + DumpPosition(pos); + (void)Eval(ctx, -INFINITY, +INFINITY); + Trace("King safeties: W=%d, B=%d\n", + ctx->sPlyInfo[ctx->uPly].iKingScore[WHITE], + ctx->sPlyInfo[ctx->uPly].iKingScore[BLACK]); + } + } + } + SystemFreeMemory(p); + } + fclose(pf); + fRet = TRUE; + + end: + if (NULL != ctx) + { + SystemFreeMemory(ctx); + } + return(fRet); +} + + + +COMMAND(BookCommand) +{ + CHAR *szOpcode; + CHAR *pDot; + + ASSERT(!STRNCMPI(argv[0], "BOOK", 4)); + if (argc < 2) + { + Trace("Available opening book commands:\n\n" + " book name : set opening book file\n" + " book import : import PGN or EDT data to book file\n" + " book dump learning : show book learning\n" + " book dump moves : show book moves in current position\n" + " book edit : edit book moves in current position\n" + " book tourn : view / toggle tournament mode\n" + " book openings : read opening line names PGN file\n" + " book hackhack : read PGN files looking for mate\n" + "\n"); + return; + } + + szOpcode = argv[1]; + if (!STRNCMPI(szOpcode, "NAME", 4)) + { + // + // book name : set opening book to use + // + if (argc == 2) + { + Trace("Usage: book name \n"); + return; + } + strncpy(g_Options.szBookName, argv[2], SMALL_STRING_LEN_CHAR); + Trace("Opening book name set to \"%s\"\n", argv[2]); + } + else if (!STRNCMPI(argv[1], "DUMP", 4)) + { + // + // book dump : show book dump help + // + if (argc == 2) + { + Trace("Available book dump commands:\n" + " book dump learning : show book learning\n" + " book dump moves : show book moves in current" + "position\n" + "\n"); + return; + } + ASSERT(argc > 2); + + if (!STRNCMPI(argv[2], "LEARNING", 5)) + { + // + // book dump learning : show book learning on stdout + // + _DumpUserOpeningList(); + } + else + { + // + // book dump moves : show book moves in this position + // + BookMove(pos, BOOKMOVE_DUMP); + } + } + else if (!STRNCMPI(argv[1], "TOURNAMENTMODE", 5)) + { + if (argc == 2) + { + // + // book tourn : show current tournament mode setting + // + if (g_fTournamentMode == TRUE) + { + Trace("Tournament mode is currently TRUE.\n"); + } + else + { + Trace("Tournament mode is currently FALSE.\n"); + } + } + else + { + // + // book tourn : set tournament mode on or off + // + if (tolower(*argv[2]) == 't') + { + g_fTournamentMode = TRUE; + Trace("Tournament mode set to TRUE.\n"); + } + else if (tolower(*argv[2]) == 'f') + { + g_fTournamentMode = FALSE; + Trace("Tournament mode set to FALSE.\n"); + } + else + { + Trace("Usage: book tournamentmode []\n"); + } + } + } + +#if 0 + else if (!STRNCMPI(argv[1], "EDIT", 4)) + { + // + // book edit : edit book moves in this position + // + BookEdit(pos); + return(TRUE); + } +#endif + + else if (!STRNCMPI(argv[1], "HACKHACK", 8)) + { + if (argc == 2) + { + Trace("Usage: book hackhack \n"); + return; + } + _FindTerminalPositions(argv[2], 4); + } + + else if (!STRNCMPI(argv[1], "OPENINGS", 8)) + { + // + // book openings : read book opening names file + // + if (argc == 2) + { + Trace("Usage: book openings \n"); + return; + } + + if (FALSE == SystemDoesFileExist(argv[2])) + { + Trace("Error (file doesn't exist): %s\n", argv[2]); + return; + } + +// Trace("%u opening lines named.\n", LearnOpeningNames(argv[2])); + } + + else if (!STRNCMPI(argv[1], "IMPORT", 6)) + { + // + // book import : create new book file from PGN -or- + // apply editing / learning to a book file + // + if (argc == 2) + { + Trace("Usage: book import \n"); + return; + } + + if (FALSE == SystemDoesFileExist(argv[2])) + { + Trace("Error (file doesn't exist): %s\n", argv[2]); + return; + } + + pDot = strrchr(argv[2], '.'); + if (NULL == pDot) + { + Trace("Error (unknown filetype): %s\n", argv[2]); + return; + } + + if (!STRNCMPI(pDot, ".pgn", 4)) + { + if (TRUE == SystemDoesFileExist(g_Options.szBookName)) + { + Trace("The opening book %s already exists, " + "importing new lines\n", g_Options.szBookName); + _LearnPgnOpenings(argv[2], 0); + } + else + { + Trace("The opening book %s does not exists, " + "creating new book\n", g_Options.szBookName); + _LearnPgnOpenings(argv[2], 1); + } + } +#if 0 + else if (!STRNCMPI(pDot, ".edt", 4)) + { + if (FALSE == ImportEditing(argv[2])) + { + Trace("An error occurred while importing .edt file.\n"); + } + } +#endif + else + { + Trace("Error (unknown filetype): %s\n", argv[2]); + } + } +} diff --git a/src/build.sh b/src/build.sh new file mode 100755 index 0000000..3d391a1 --- /dev/null +++ b/src/build.sh @@ -0,0 +1,11 @@ +#!/bin/sh +touch main.c +opts='GENETIC=1 PERF_COUNTERS=1 MP=1 ' +if expr $OSTYPE = "darwin"; then + opts=${opts}' OSX=1 CC=gcc' + make -j5 $opts $* +else + opts=${opts}' CC=gcc' + gmake -j5 $opts $* +fi +strip ./typhoon diff --git a/src/changes/._chess.h b/src/changes/._chess.h new file mode 100755 index 0000000..a5aba7a Binary files /dev/null and b/src/changes/._chess.h differ diff --git a/src/changes/._main.c b/src/changes/._main.c new file mode 100755 index 0000000..2bb5ca6 Binary files /dev/null and b/src/changes/._main.c differ diff --git a/src/changes/._root.c b/src/changes/._root.c new file mode 100755 index 0000000..45a96d0 Binary files /dev/null and b/src/changes/._root.c differ diff --git a/src/changes/._util.c b/src/changes/._util.c new file mode 100755 index 0000000..2fd756a Binary files /dev/null and b/src/changes/._util.c differ diff --git a/src/changes/._vars.c b/src/changes/._vars.c new file mode 100644 index 0000000..e8c7104 Binary files /dev/null and b/src/changes/._vars.c differ diff --git a/src/changes/chess.h b/src/changes/chess.h new file mode 100755 index 0000000..e86911a --- /dev/null +++ b/src/changes/chess.h @@ -0,0 +1,2982 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + chess.h + +Abstract: + +Author: + + Scott Gasch (scott.gasch@gmail.com) 7 Apr 2004 + +Revision History: + + $Id: chess.h 350 2008-06-28 03:12:34Z scott $ + +**/ + +#ifndef CHESS_ +#define CHESS_ + +#include "compiler.h" + +// +// Datatype wrappers +// +#define MIN_CHAR (0x80) +#define MAX_CHAR (0x7f) +typedef char CHAR; + +#define MIN_BYTE (0x00) +#define MAX_BYTE (0xff) +typedef unsigned char BYTE; + +#define MIN_UCHAR (0x00) +#define MAX_UCHAR (0xff) +typedef unsigned char UCHAR; +#define CAN_FIT_IN_UCHAR(x) ((x) <= MAX_UCHAR) + +#define MIN_SHORT (0x8000) +#define MAX_SHORT (0x7fff) +typedef signed short SHORT; + +#define MIN_USHORT (0x0000) +#define MAX_USHORT (0xffff) +typedef unsigned short USHORT; +#define CAN_FIT_IN_USHORT(x) ((x) <= MAX_USHORT) + +#define MIN_WORD (0x0000) +#define MAX_WORD (0xffff) +typedef unsigned short WORD; + +#define MIN_INT (0x80000000) +#define MAX_INT (0x7fffffff) +typedef signed int INT; + +#define MIN_DWORD (0x00000000) +#define MAX_DWORD (0xffffffff) +typedef unsigned int DWORD; + +#define MIN_UINT (0x00000000) +#define MAX_UINT (0xffffffff) +typedef unsigned int UINT; + +#define MIN_ULONG (0x00000000) +#define MAX_ULONG (0xffffffff) +typedef unsigned int ULONG; + +#define MIN_INT64 (0x8000000000000000) +#define MAX_INT64 (0x7fffffffffffffff) +typedef signed COMPILER_LONGLONG INT64; + +#define MIN_UINT64 (0x0000000000000000) +#define MAX_UINT64 (0xffffffffffffffff) +typedef unsigned COMPILER_LONGLONG UINT64; + +#define MIN_BITBOARD (0x0000000000000000) +#define MAX_BITBOARD (0xffffffffffffffff) +typedef UINT64 BITBOARD; + +#define MIN_BITV MIN_UINT +#define MAX_BITV MAX_UINT +typedef unsigned int BITV; + +#define MIN_FLAG MIN_UINT +#define MAX_FLAG MAX_UINT +typedef unsigned int FLAG; +#define IS_VALID_FLAG(x) (((x) == TRUE) || ((x) == FALSE)) + +typedef unsigned int COOR; +typedef unsigned int PIECE; +typedef signed int SCORE; + +#define BIT1 (0x1) +#define BIT2 (0x2) +#define BIT3 (0x4) +#define BIT4 (0x8) +#define BIT5 (0x10) +#define BIT6 (0x20) +#define BIT7 (0x40) +#define BIT8 (0x80) +#define BIT9 (0x100) +#define BIT10 (0x200) +#define BIT11 (0x400) +#define BIT12 (0x800) +#define BIT13 (0x1000) +#define BIT14 (0x2000) +#define BIT15 (0x4000) +#define BIT16 (0x8000) +#define BIT17 (0x10000) +#define BIT18 (0x20000) +#define BIT19 (0x40000) +#define BIT20 (0x80000) +#define BIT21 (0x100000) +#define BIT22 (0x200000) +#define BIT23 (0x400000) +#define BIT24 (0x800000) +#define BIT25 (0x1000000) +#define BIT26 (0x2000000) +#define BIT27 (0x4000000) +#define BIT28 (0x8000000) +#define BIT29 (0x10000000) +#define BIT30 (0x20000000) +#define BIT31 (0x40000000) +#define BIT32 (0x80000000) + +typedef struct _DLIST_ENTRY +{ + struct _DLIST_ENTRY *pFlink; + struct _DLIST_ENTRY *pBlink; +} DLIST_ENTRY; + +// +// Constants +// +#define YES (1) +#define NO (0) +#ifndef TRUE +#define TRUE (YES) +#endif +#ifndef FALSE +#define FALSE (NO) +#endif + +// +// Calculate the length of an array (i.e. number of elements) +// +#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +#define COMMAND(x) \ + void (x)(CHAR *szInput, ULONG argc, CHAR *argv[], POSITION *pos) +#define MB (1024 * 1024) + +// +// Calculate the address of the base of the structure given its type, and an +// address of a field within the structure. +// +#ifndef OFFSET_OF +#define OFFSET_OF(field, type) \ + (ULONG)(&((type *)0)->field) +#endif +#ifndef CONTAINING_STRUCT +#define CONTAINING_STRUCT(address, type, field) \ + ((type *)((BYTE *)(address) - (BYTE *)(OFFSET_OF(field, type)))) +#endif + +#define WHITE (1) +#define BLACK (0) +#define BAD_COLOR (2) +#define IS_VALID_COLOR(x) (((x) == WHITE) || ((x) == BLACK)) +#define FOREACH_COLOR(x) for((x) = BLACK; (x) < BAD_COLOR; (x)++) +#define RANDOM_COLOR (rand() & 1) +#define FLIP(color) ((color) ^ 1) +#define COLOR_NAME(color) (((color) == WHITE) ? "white" : "black") + +#define MAX_MOVES_PER_PLY (218) +#define MAX_PLY_PER_SEARCH (64) +#define MAX_MOVES_PER_GAME (1024) +#define SMALL_STRING_LEN_CHAR (256) +#define MEDIUM_STRING_LEN_CHAR (8192) +#define BIG_STRING_LEN_CHAR (16384) + +#define QUARTER_PLY 16 +#define HALF_PLY 32 +#define THREE_QUARTERS_PLY 48 +#define ONE_PLY 64 +#define TWO_PLY 128 +#define THREE_PLY 192 +#define FOUR_PLY 256 +#define MAX_DEPTH_PER_SEARCH (MAX_PLY_PER_SEARCH * ONE_PLY) + +#define IS_VALID_DEPTH(x) (((x) >= 0) && \ + ((x) <= MAX_DEPTH_PER_SEARCH) && \ + (((x) & 0xfffff00f) == 0)) + +#define INFINITY (MAX_SHORT) +#define INVALID_SCORE (INFINITY + 1) +#define IS_VALID_SCORE(x) (((x) >= -INFINITY) && \ + ((x) <= +INFINITY)) +#define NMATE (+INFINITY - 200) +#define MATED_SCORE(ply) (-INFINITY + (ply)) + +#define IS_A_POWER_OF_2(x) (((x) & (x - 1)) == 0) +// +// Program version number +// +#define VERSION "1.00" +#define REVISION "$Id: chess.h 350 2008-06-28 03:12:34Z scott $\n" + +// +// Function decorators +// +#define IN +#define OUT +#define INOUT +#define UNUSED +#define NOTHING + +// ---------------------------------------------------------------------- +// +// PIECE: +// +// a piece (4 bits) = type (3 bits) + color (1 bit) +// +// 3 1 0 +// . . . . +// | | | +// type C +// +#define KING (6) // 110X +#define QUEEN (5) // 101X +#define ROOK (4) // 100X +#define BISHOP (3) // 011X +#define KNIGHT (2) // 010X +#define PAWN (1) // 001X +#define EMPTY (0) // 000X + +// (WHATEVER << 1) +#define BLACK_PAWN (2) // 0010 +#define BLACK_KNIGHT (4) // 0100 +#define BLACK_BISHOP (6) // 0110 +#define BLACK_ROOK (8) // 1000 +#define BLACK_QUEEN (10) // 1010 +#define BLACK_KING (12) // 1100 + +// (WHATEVER << 1) | WHITE +#define WHITE_PAWN (3) // 0011 +#define WHITE_KNIGHT (5) // 0101 +#define WHITE_BISHOP (7) // 0111 +#define WHITE_ROOK (9) // 1001 +#define WHITE_QUEEN (11) // 1011 +#define WHITE_KING (13) // 1101 + +#define PIECE_TYPE(p) ((p) >> 1) +#define PIECE_COLOR(p) ((p) & WHITE) +#define RANDOM_PIECE (rand() % 12) + 2; +#define IS_PAWN(p) (((p) & 0xE) == BLACK_PAWN) +#define IS_KNIGHT(p) (((p) & 0xE) == BLACK_KNIGHT) +#define IS_BISHOP(p) (((p) & 0xE) == BLACK_BISHOP) +#define IS_ROOK(p) (((p) & 0xE) == BLACK_ROOK) +#define IS_QUEEN(p) (((p) & 0xE) == BLACK_QUEEN) +#define IS_KING(p) (((p) & 0xE) == BLACK_KING) +#define IS_KNIGHT_OR_KING(p) (((p) & 0x6) == 0x4) +#define IS_VALID_PIECE(p) ((PIECE_TYPE((p)) >= PAWN) && \ + (PIECE_TYPE((p)) <= KING)) +#define IS_WHITE_PIECE(p) ((p) & WHITE) +#define IS_BLACK_PIECE(p) (!IS_WHITE(p)) +#define OPPOSITE_COLORS(p, q) (((p) ^ (q)) & WHITE) +#define SAME_COLOR(p,q) (!OPPOSITE_COLORS(p, q)) +#define GET_COLOR(p) ((p) & WHITE) + +// ---------------------------------------------------------------------- +// +// a coordinate (8 bits) = rank + file (0x88) +// +// 7 4 3 0 +// . . . . . . . . +// | | | +// rank file +// | | +// | +--- 0-7 = file A thru file H +// | +// +------------ 0-7 = rank 1 thru rank 8 +// +// given a coordinate, C, if C & 0x88 then it is illegal (off board) +// +// +// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 +// +---------------------------------------+ +// 8 | 00 |:01:| 02 |:03:| 04 |:05:| 06 |:07:| 0x00 +// 7 |:10:| 11 |:12:| 13 |:14:| 15 |:16:| 17 | 0x10 +// 6 | 20 |:21:| 22 |:23:| 24 |:25:| 26 |:27:| 0x20 +// 5 |:30:| 31 |:32:| 33 |:34:| 35 |:36:| 37 | 0x30 +// 4 | 40 |:41:| 42 |:43:| 44 |:45:| 46 |:47:| 0x40 +// 3 |:50:| 51 |:52:| 53 |:54:| 55 |:56:| 57 | 0x50 +// 2 | 60 |:61:| 62 |:63:| 64 |:65:| 66 |:67:| 0x60 +// 1 |:70:| 71 |:72:| 73 |:74:| 75 |:76:| 77 | 0x70 +// +---------------------------------------+ +// A B C D E F G H +// +#define A (0) +#define B (1) +#define C (2) +#define D (3) +#define E (4) +#define F (5) +#define G (6) +#define H (7) + +#define A8 (0x00) +#define B8 (0x01) +#define C8 (0x02) +#define D8 (0x03) +#define E8 (0x04) +#define F8 (0x05) +#define G8 (0x06) +#define H8 (0x07) + +#define A7 (0x10) +#define B7 (0x11) +#define C7 (0x12) +#define D7 (0x13) +#define E7 (0x14) +#define F7 (0x15) +#define G7 (0x16) +#define H7 (0x17) + +#define A6 (0x20) +#define B6 (0x21) +#define C6 (0x22) +#define D6 (0x23) +#define E6 (0x24) +#define F6 (0x25) +#define G6 (0x26) +#define H6 (0x27) + +#define A5 (0x30) +#define B5 (0x31) +#define C5 (0x32) +#define D5 (0x33) +#define E5 (0x34) +#define F5 (0x35) +#define G5 (0x36) +#define H5 (0x37) + +#define A4 (0x40) +#define B4 (0x41) +#define C4 (0x42) +#define D4 (0x43) +#define E4 (0x44) +#define F4 (0x45) +#define G4 (0x46) +#define H4 (0x47) + +#define A3 (0x50) +#define B3 (0x51) +#define C3 (0x52) +#define D3 (0x53) +#define E3 (0x54) +#define F3 (0x55) +#define G3 (0x56) +#define H3 (0x57) + +#define A2 (0x60) +#define B2 (0x61) +#define C2 (0x62) +#define D2 (0x63) +#define E2 (0x64) +#define F2 (0x65) +#define G2 (0x66) +#define H2 (0x67) + +#define A1 (0x70) +#define B1 (0x71) +#define C1 (0x72) +#define D1 (0x73) +#define E1 (0x74) +#define F1 (0x75) +#define G1 (0x76) +#define H1 (0x77) + +// TODO: if use this anywhere that matters, consider double loop +// and unrolling the inside loop to prevent the multiple +// continue for invalid squares +#define FOREACH_SQUARE(x) for((x) = (A8); (x) <= (H1); (x)++) + +#define IS_ON_BOARD(c) (!((c) & 0x88)) +#define RANDOM_COOR (rand() & 0x77) +#define FILE_RANK_TO_COOR(f, r) (((8 - (r)) << 4) | (f)) +#define RANK(c) (8 - ((c) >> 4)) +#define RANK1(c) (((c) & 0xF0) == 0x70) +#define RANK2(c) (((c) & 0xF0) == 0x60) +#define RANK3(c) (((c) & 0xF0) == 0x50) +#define RANK4(c) (((c) & 0xF0) == 0x40) +#define RANK5(c) (((c) & 0xF0) == 0x30) +#define RANK6(c) (((c) & 0xF0) == 0x20) +#define RANK7(c) (((c) & 0xF0) == 0x10) +#define RANK8(c) (((c) & 0xF0) == 0x00) +#define FILE(c) ((c) & 0x0F) +#define FILEA(c) (((c) & 0x0F) == 0x00) +#define FILEB(c) (((c) & 0x0F) == 0x01) +#define FILEC(c) (((c) & 0x0F) == 0x02) +#define FILED(c) (((c) & 0x0F) == 0x03) +#define FILEE(c) (((c) & 0x0F) == 0x04) +#define FILEF(c) (((c) & 0x0F) == 0x05) +#define FILEG(c) (((c) & 0x0F) == 0x06) +#define FILEH(c) (((c) & 0x0F) == 0x07) +#define IS_WHITE_SQUARE_FR(f, r) (((f) + (r) - 1) & 1) +#define IS_WHITE_SQUARE_COOR(c) (IS_WHITE_SQUARE_FR(FILE(c), RANK(c))) +#define VALID_EP_SQUARE(c) (((c) == ILLEGAL_COOR) || ((c) == 0) || \ + (RANK3(c)) || \ + (RANK6(c))) + +// ---------------------------------------------------------------------- +// +// a move (4 bytes) = from/to, moved, captured, promoted and special +// +// 31 24 23 16 15 12 11 8 7 4 3 0 +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +// | from | to | moved | capt | prom | flags | +// | | | | | +// | | | | | +// | | | | | +// | | +-------+-------+-- type and +// | | color of +// | | piece moved +// | | captured and +// | | promote targ +// +---------------+-- board location where +// move begins and ends +// +// +// Special flag asserted on special move types: +// +// if (special) +// { +// if (moved == PAWN) +// { +// if (promotion) +// { +// move is a promote (w/ or w/o capture) +// } +// else if (capture) +// { +// move is an en passant catpure +// } +// else +// { +// move is a double jump +// } +// } +// else if (moved == KING) +// { +// move is a castle (long or short) +// } +// else +// { +// invalid use of special flag +// } +// } +// +typedef union _MOVE +{ + ULONG uMove; + struct + { + UCHAR cFrom : 8; + UCHAR cTo : 8; + UCHAR pMoved : 4; + UCHAR pCaptured : 4; + UCHAR pPromoted : 4; + UCHAR bvFlags : 4; + }; +} MOVE; + +#define IS_SAME_MOVE(a, b) \ + (((a).uMove & 0x0FFFFFFF) == (((b).uMove & 0x0FFFFFFF))) + +#define MAKE_MOVE(from,to,piece,cap,prom,flags) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20) | \ + ((ULONG)(prom) << 24) | \ + ((ULONG)(flags) << 28)) + +#define MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(from,to,piece,cap) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20)) + +// +// Move flag values: +// +#define MOVE_FLAG_SPECIAL (1) // en pass, prom, castle, double +#define IS_SPECIAL_MOVE(mv) \ + ((mv).uMove & 0x10000000) + +#define IS_CASTLE(mv) \ + (IS_SPECIAL_MOVE(mv) && IS_KING((mv).pMoved)) + +#ifdef DEBUG +#define IS_PROMOTION(mv) \ + (IS_SPECIAL_MOVE(mv) && ((mv).pPromoted)) +#else +#define IS_PROMOTION(mv) \ + ((mv).pPromoted) +#endif + +#define IS_CAPTURE_OR_PROMOTION(mv) \ + ((mv).uMove & 0x0FF00000) + +#define IS_ENPASSANT(mv) \ + (IS_SPECIAL_MOVE(mv) && (mv.pCaptured) && !IS_PROMOTION(mv)) + +#define IS_DOUBLE_JUMP(mv) \ + (IS_SPECIAL_MOVE(mv) && !IS_CAPTURE_OR_PROMOTION(mv)) + +#define MOVE_FLAG_KILLERMATE (2) // killer mate +#define IS_KILLERMATE_MOVE(mv) ((mv).uMove & 0x20000000) + +#define MOVE_FLAG_ESCAPING_CHECK (4) // escaping check +#define IS_ESCAPING_CHECK(mv) ((mv).uMove & 0x40000000) + +#define MOVE_FLAG_CHECKING (8) // checking move +#define IS_CHECKING_MOVE(mv) ((mv).uMove & 0x80000000) + +// ---------------------------------------------------------------------- +// +// Move list +// +#define MAX_MOVE_LIST (MAX_MOVES_PER_GAME + MAX_PLY_PER_SEARCH) + +// ---------------------------------------------------------------------- + +#pragma pack(1) +typedef union _ATTACK_BITV +{ + ULONG uWholeThing; + struct + { + union + { + UCHAR uSmall; + struct + { + UCHAR uNumAttacks : 3; // 0..2 + UCHAR uKing : 1; // 4..7 + UCHAR uQueen : 1; + UCHAR uRook : 1; + UCHAR uMinor : 1; + UCHAR uPawn : 1; + } small; + }; + + // -------------------- + union + { + USHORT uBig; + struct + { + USHORT uKing : 1; // 8..23 + USHORT uQueens : 4; + USHORT uRooks : 4; + USHORT uMinors : 4; + USHORT uPawns : 2; + USHORT uUnusedFlag1 : 1; + } big; + }; + + // ------------------- + union + { + UCHAR uXray; + struct + { + UCHAR uNumXrays : 3; + UCHAR uUnusedFlag2 : 1; + UCHAR uQueen : 1; // 24..28 + UCHAR uRook : 1; + UCHAR uBishop : 1; + UCHAR uUnusedFlag3 : 1; + } xray; + }; + }; +} +ATTACK_BITV; + +#define UNSAFE_FOR_MINOR(x) ((ULONG)((x).uWholeThing) & 0x00000080UL) +#define UNSAFE_FOR_ROOK(x) ((ULONG)((x).uWholeThing) & 0x000000C0UL) +#define UNSAFE_FOR_QUEEN(x) ((ULONG)((x).uWholeThing) & 0x000000E0UL) + +#define PAWN_BIT 0x00000080UL +#define MINOR_BIT 0x00000040UL +#define MINOR_XRAY_BIT 0x40000000UL +#define ROOK_BIT 0x00000020UL +#define ROOK_XRAY_BIT 0x20000000UL +#define QUEEN_BIT 0x00000010UL +#define QUEEN_XRAY_BIT 0x10000000UL + +#define INVALID_PIECE_INDEX (17) +#define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX) + +typedef union _SQUARE +{ + struct + { + PIECE pPiece; + ULONG uIndex; + }; + ATTACK_BITV bvAttacks[2]; +} +SQUARE; +#pragma pack() + +// +// POSITION +// +typedef struct _POSITION +{ + SQUARE rgSquare[128]; // where the pieces are, + // also, the attack table + UINT64 u64NonPawnSig; // hash signature + UINT64 u64PawnSig; // pawn hash signature + ULONG uToMove; // whose turn? + ULONG uFifty; // 50 moves w/o progress = draw + FLAG fCastled[2]; // record when sides have castled + BITV bvCastleInfo; // who can castle how? + COOR cEpSquare; // en-passant capture square + + COOR cPawns[2][8]; // location of pawns on the board + ULONG uPawnMaterial[2]; // pawn material of each side + ULONG uPawnCount[2]; // number of pawns for each side + + COOR cNonPawns[2][16]; // location of pieces on the board + ULONG uNonPawnMaterial[2]; // piece material of each side + ULONG uNonPawnCount[2][8]; // number of non-pawns / type + // 0 and 1 are the sum, + // 2..6 are per PIECE_TYPE + + ULONG uWhiteSqBishopCount[2]; // num bishops on white squares + SCORE iMaterialBalance[2]; // material balance + + // temporary storage space for use in eval + COOR cTrapped[2]; + ULONG uArmyScaler[2]; + ULONG uClosedScaler; + SCORE iScore[2]; + SCORE iReducedMaterialDownScaler[2]; + SCORE iTempScore; + ULONG uMinMobility[2]; + COOR cPiece; + ULONG uMinorsAtHome[2]; + BITBOARD bb; + ULONG uPiecesPointingAtKing[2]; +} +POSITION; + +// +// Castling permission bitvector flags. +// +#define CASTLE_WHITE_SHORT (1) +#define CASTLE_WHITE_LONG (2) +#define WHITE_CAN_CASTLE \ + (CASTLE_WHITE_SHORT | CASTLE_WHITE_LONG) +#define CASTLE_BLACK_SHORT (4) +#define CASTLE_BLACK_LONG (8) +#define BLACK_CAN_CASTLE \ + (CASTLE_BLACK_SHORT | CASTLE_BLACK_LONG) +#define CASTLE_NONE_POSSIBLE (0) +#define CASTLE_ALL_POSSIBLE \ + (WHITE_CAN_CASTLE | BLACK_CAN_CASTLE) + +// ---------------------------------------------------------------------- +// +// Move stack +// +#define MAX_MOVE_STACK (MAX_PLY_PER_SEARCH * \ + MAX_MOVES_PER_PLY) + +// +// Main part of the move stack, triads of moves, their values and flags +// that denote where the values came from +// +#define MVF_MOVE_SEARCHED (1) +#define MVF_EXTEND_MOVE (2) +#define MVF_REDUCE_MOVE (4) +#define MVF_PRUNE_SUBTREE (8) + +typedef struct _MOVE_STACK_MOVE_VALUE_FLAGS +{ + SCORE iValue; + MOVE mv; + BITV bvFlags; +} +MOVE_STACK_MOVE_VALUE_FLAGS; + +typedef struct _KEY_POINTER +{ + int iPointer; + ULONG uKey; +} +KEY_POINTER; + +typedef union _GENERATOR_FLAGS +{ + struct { + UCHAR uMoveCount; + UCHAR uKingMoveCount; + UCHAR uCheckingPieces; + UCHAR uUnused; + }; + ULONG uAllGenFlags; +} +GENERATOR_FLAGS; + +// +// A move stack +// +typedef struct _MOVE_STACK +{ +#ifdef DEBUG + POSITION board[MAX_PLY_PER_SEARCH]; +#endif + // + // Unblocked squares map, used for check detection + // + ULONG uUnblockedKeyValue[MAX_PLY_PER_SEARCH]; + KEY_POINTER sUnblocked[MAX_PLY_PER_SEARCH][128]; + + // + // The main move list, a long series of moves, their values and some + // flag bits to tell search what the values are based upon. + // + MOVE_STACK_MOVE_VALUE_FLAGS mvf[MAX_MOVE_STACK]; + + // + // uBegin[ply] and uEnd[ply] specify the start and end of moves gen- + // erated for a position at ply distance from the root. + // + ULONG uPly; + ULONG uBegin[MAX_PLY_PER_SEARCH]; + ULONG uEnd[MAX_PLY_PER_SEARCH]; + MOVE mvHash[MAX_PLY_PER_SEARCH]; + GENERATOR_FLAGS sGenFlags[MAX_PLY_PER_SEARCH]; +} +MOVE_STACK; + +#define GENERATE_NO_MOVES \ + ctx->sMoveStack.uEnd[ctx->uPly] = \ + ctx->sMoveStack.uBegin[ctx->uPly] + 1; \ + ctx->sMoveStack.uBegin[ctx->uPly + 1] = \ + ctx->sMoveStack.uEnd[ctx->uPly] + +#define GENERATE_ALL_MOVES (1) +#define GENERATE_ESCAPES (2) +#define GENERATE_CAPTURES_PROMS_CHECKS (3) +#define GENERATE_CAPTURES_PROMS (4) +#define GENERATE_DONT_SCORE (5) +#ifdef TEST +#define GENERATE_ALL_MOVES_CHECK_OK (6) +#endif + +#define MOVE_COUNT(ctx, x) \ + (((ctx)->sMoveStack.uEnd[(x)]) - (ctx)->sMoveStack.uBegin[(x)]) +#define ONE_LEGAL_MOVE(ctx, x) \ + (MOVE_COUNT(ctx, x) == 1) +#define NUM_KING_MOVES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uKingMoveCount) +#define NUM_CHECKING_PIECES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces) + + +// ---------------------------------------------------------------------- +// +// Accumulators +// +typedef struct _COUNTERS +{ + struct + { + UINT64 u64Probes; + UINT64 u64OverallHits; + UINT64 u64UsefulHits; + UINT64 u64UpperBoundHits; + UINT64 u64LowerBoundHits; + UINT64 u64ExactScoreHits; + } + hash; + + struct + { + UINT64 u64Probes; + UINT64 u64Hits; + } + pawnhash; + + struct + { + UINT64 u64TotalNodeCount; + UINT64 u64QNodeCount; + UINT64 u64LeafCount; + UINT64 u64TerminalPositionCount; + UINT64 u64BetaCutoffs; + UINT64 u64BetaCutoffsOnFirstMove; + UINT64 u64NullMoves; + UINT64 u64NullMoveSuccess; +#ifdef TEST_NULL + UINT64 u64QuickNullSuccess; + UINT64 u64QuickNullDeferredSuccess; + UINT64 u64QuickNullFailures; + UINT64 u64AvoidNullSuccess; + UINT64 u64AvoidNullFailures; +#endif + UINT64 u64EvalHashHits; + UINT64 u64LazyEvals; + UINT64 u64FullEvals; + UINT64 u64CyclesInEval; + } + tree; + + struct + { + ULONG uNumSplits; + ULONG uNumSplitsTerminated; + } + parallel; + + struct + { + ULONG uPawnPush; + ULONG uCheck; + ULONG uMateThreat; + ULONG uRecapture; + ULONG uOneLegalMove; + ULONG uNoLegalKingMoves; + ULONG uMultiCheck; + ULONG uSingularMove; + ULONG uZugzwang; + ULONG uSingularReplyToCheck; + ULONG uEndgame; + ULONG uBotvinnikMarkoff; + ULONG uQExtend; + } + extension; + + struct + { + ULONG uProbes; + ULONG uHits; + } + egtb; +} +COUNTERS; + +typedef struct _CUMULATIVE_SEARCH_FLAGS +{ + // search + ULONG uNumChecks[2]; // not used + FLAG fInSuspiciousBranch; // not used + FLAG fInReducedDepthBranch; // not used + FLAG fAvoidNullmove; // restore + FLAG fVerifyNullmove; // restore + + // qsearch + ULONG uQsearchDepth; // restore + ULONG uQsearchNodes; // incremental + ULONG uQsearchCheckDepth; // restore + FLAG fCouldStandPat[2]; // restore +} +CUMULATIVE_SEARCH_FLAGS; + +// ---------------------------------------------------------------------- +// +// Searcher thread record +// +typedef struct _SPLIT_INFO +{ + // locks / counters + volatile ULONG uLock; // lock for this split node + volatile ULONG uNumThreadsHelping; // num threads in this node + volatile FLAG fTerminate; // signal helpers to terminate + + // moves in the split node + ULONG uRemainingMoves; // num moves remaining to do + ULONG uOnDeckMove; // next move to do + ULONG uNumMoves; + ULONG uAlreadyDone; + MOVE_STACK_MOVE_VALUE_FLAGS + mvf[MAX_MOVES_PER_PLY]; // the moves to search + + // input to the split node + POSITION sRootPosition; // the root position + MOVE mvPathToHere[MAX_PLY_PER_SEARCH]; // path from root to split + MOVE mvLast; // last move before split + ULONG uDepth; // remaining depth at split + INT iPositionExtend; // positional extension + SCORE iAlpha; // original alpha at split + SCORE iBeta; // beta at split + ULONG uSplitPositional; // pos->uPositional at split + CUMULATIVE_SEARCH_FLAGS sSearchFlags; // flags at split time + + // output from the split node + MOVE mvBest; // the best move + SCORE iBestScore; // it's score + COUNTERS sCounters; // updated counters + MOVE PV[MAX_PLY_PER_SEARCH]; + +#ifdef DEBUG + ULONG uSplitPly; + POSITION sSplitPosition; +#endif +} +SPLIT_INFO; + +typedef struct _PLY_INFO +{ +#ifdef DEBUG + POSITION sPosition; + SCORE iAlpha; + SCORE iBeta; +#endif + SCORE iEval; + INT iExtensionAmount; + FLAG fInCheck; + FLAG fInQsearch; + MOVE mv; + MOVE mvBest; + MOVE PV[MAX_PLY_PER_SEARCH]; + + SCORE iKingScore[2]; + ULONG uMinMobility[2]; + UINT64 u64NonPawnSig; + UINT64 u64PawnSig; + UINT64 u64Sig; + ULONG uFifty; + FLAG fCastled[2]; + ULONG uTotalNonPawns; + BITV bvCastleInfo; + COOR cEpSquare; +} +PLY_INFO; + +#define EVAL_HASH +#ifdef EVAL_HASH +#define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread) +typedef struct _EVAL_HASH_ENTRY +{ + UINT64 u64Key; + SCORE iEval; + ULONG uPositional; + COOR cTrapped[2]; + +} EVAL_HASH_ENTRY; +#endif + +#define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread) +typedef struct _PAWN_HASH_ENTRY +{ + UINT64 u64Key; + BITBOARD bbPawnLocations[2]; + BITBOARD bbPasserLocations[2]; + BITBOARD bbStationaryPawns[2]; + SHORT iScore[2]; + UCHAR uCountPerFile[2][10]; + UCHAR uNumRammedPawns; + UCHAR uNumUnmovedPawns[2]; +} +PAWN_HASH_ENTRY; + +#define NUM_SPLIT_PTRS_IN_CONTEXT (8) + +typedef struct _SEARCHER_THREAD_CONTEXT +{ + ULONG uPly; // its distance from root + ULONG uPositional; // positional component of score + POSITION sPosition; // the board + MOVE_STACK sMoveStack; // the move stack + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; + MOVE mvKiller[MAX_PLY_PER_SEARCH][2]; + MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2]; + MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH]; + COUNTERS sCounters; + ULONG uThreadNumber; + SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT]; + MOVE mvRootMove; + SCORE iRootScore; + ULONG uRootDepth; + PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE]; +#ifdef EVAL_HASH + EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE]; +#endif + CHAR szLastPV[SMALL_STRING_LEN_CHAR]; +} +SEARCHER_THREAD_CONTEXT; + +// +// When I added the pawn hash table and eval hash tables to searcher +// thread contexts they became too heavy to just allocate on the fly +// for things like checking the legality of SAN moves or seeing if an +// opening book line leads to a draw. This +// LIGHTWEIGHT_SEARCHER_CONTEXT structure can be cast into a full +// SEARCHER_THREAD_CONTEXT and passed safely into the Generate, +// MakeMove and UnMakeMove functions because they presently only +// need: +// +// 1. uPly +// 2. sPosition +// 3. sPlyInfo +// 4. sMoveStack +// +typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT +{ + ULONG uPly; + ULONG uPositional; + POSITION sPosition; + MOVE_STACK sMoveStack; + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; +} +LIGHTWEIGHT_SEARCHER_CONTEXT; + +// ---------------------------------------------------------------------- +// +// Global game options +// +typedef struct _GAME_OPTIONS +{ + ULONG uMyClock; + ULONG uOpponentsClock; + FLAG fGameIsRated; + FLAG fOpponentIsComputer; + ULONG uSecPerMove; + ULONG uMaxDepth; + UINT64 u64MaxNodeCount; + FLAG fShouldPonder; + FLAG fPondering; + FLAG fThinking; + FLAG fSuccessfulPonder; + MOVE mvPonder; + FLAG fShouldPost; + FLAG fForceDrawWorthZero; + ULONG uMyIncrement; + ULONG uMovesPerTimePeriod; + CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR]; + FLAG fShouldAnnounceOpening; + SCORE iLastEvalScore; + UINT64 u64NodesSearched; + CHAR szLogfile[SMALL_STRING_LEN_CHAR]; + CHAR szEGTBPath[SMALL_STRING_LEN_CHAR]; + CHAR szBookName[SMALL_STRING_LEN_CHAR]; + ULONG uNumProcessors; + ULONG uNumHashTableEntries; + FLAG fNoInputThread; + FLAG fVerbosePosting; + FLAG fRunningUnderXboard; + FLAG fStatusLine; + FLAG fFastScript; + FLAG fShouldResign; + + enum + { + CLOCK_NORMAL = 0, + CLOCK_FIXED, + CLOCK_INCREMENT, + CLOCK_NONE + } + eClock; + + enum + { + GAME_UNKNOWN = 0, + GAME_BULLET, + GAME_BLITZ, + GAME_STANDARD + } + eGameType; + + enum + { + I_PLAY_WHITE = 0, + I_PLAY_BLACK, + FORCE_MODE, + EDIT_MODE, + ANALYZE_MODE + } + ePlayMode; +} +GAME_OPTIONS; +extern GAME_OPTIONS g_Options; + +// ---------------------------------------------------------------------- +// +// Move timer +// + +#define TIMER_SEARCHING_FIRST_MOVE (0x1) +#define TIMER_SEARCHING_IMPORTANT_MOVE (0x2) +#define TIMER_RESOLVING_ROOT_FL (0x4) +#define TIMER_RESOLVING_ROOT_FH (0x8) +#define TIMER_JUST_OUT_OF_BOOK (0x10) +#define TIMER_CURRENT_OBVIOUS (0x20) +#define TIMER_CURRENT_WONT_UNBLOCK (0x40) +#define TIMER_ROOT_POSITION_CRITICAL (0x80) +#define TIMER_MOVE_IMMEDIATELY (0x100) +#define TIMER_MANY_ROOT_FLS (0x200) +#define TIMER_STOPPING (0x400) +#define TIMER_SPLIT_FAILED (0x800) + +typedef struct _MOVE_TIMER +{ + double dStartTime; + double dEndTime; + double dSoftTimeLimit; + double dHardTimeLimit; + ULONG uNodeCheckMask; + volatile BITV bvFlags; +} +MOVE_TIMER; + +// ---------------------------------------------------------------------- +// +// Special move tag literals +// +#define ILLEGALMOVE ((ULONG)0x1DDD8888) + +// +// useful macros +// +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine); + +#define ASSERT(x) if (x) \ + { ; } \ + else \ + { _assert(__FILE__, __LINE__); } +#define VERIFY(x) ASSERT(x) +#else +#define ASSERT(x) ; +#define VERIFY(x) x; +#endif // DEBUG + +#ifdef PERF_COUNTERS +#define INC(x) ((x) += 1) +#else +#define INC(x) +#endif + +#define BREAKPOINT SystemDebugBreakpoint() + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#ifdef _X86_ +// +// Note: MAXU, MINU and ABS_DIFF require arguments with the high order +// bit CLEAR to work right. +// +// These are branchless constructs. MAXU and MINU are equivalent to +// MIN and MAX (with the above restriction on inputs) +// +// MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x). These +// macros have no restiction on argument type. +// +// ABS_DIFF is equivalent to abs(x - y). Again, x and y must have +// their high-order bits CLEAR for this to work. +// +// Note: gcc generates code with cmovs so no need for MAXU/MINU on +// that compiler. +// +#define MINU(x, y) \ + (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y)) +#define MAXU(x, y) \ + (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x)) +#define MIN0(x) \ + ((x) & (((int)(x)) >> 31)) +#define MAX0(x) \ + ((x) & ~(((int)(x)) >> 31)) + + +#define ABS_DIFF(a, b) \ + (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1)) + +#endif // _X86_ + +#ifndef MINU +#define MINU(x, y) (MIN((x), (y))) +#endif + +#ifndef MAXU +#define MAXU(x, y) (MAX((x), (y))) +#endif + +#ifndef MIN0 +#define MIN0(x) (MIN((x), 0)) +#endif + +#ifndef MAX0 +#define MAX0(x) (MAX((x), 0)) +#endif + +#ifndef ABS_DIFF +#define ABS_DIFF(a, b) (abs((a) - (b))) +#endif + +#define FILE_DISTANCE(a, b) (ABS_DIFF(FILE((a)), FILE((b)))) +#define RANK_DISTANCE(a, b) (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4) +#define REAL_DISTANCE(a, b) (MAXU(FILE_DISTANCE((a), (b)), \ + RANK_DISTANCE((a), (b)))) +#ifdef DEBUG +#define DISTANCE(a, b) DistanceBetweenSquares((a), (b)) +#else +#define DISTANCE(a, b) g_pDistance[(a) - (b)] +#endif // DEBUG + +#define IS_EMPTY( square ) (!(square)) +#define IS_OCCUPIED( square ) ((square)) + +#define IS_DEAD( listindex ) ((listindex) > 119) +#define IS_ALIVE( listindex ) ((listindex) <= 119) +#define ILLEGAL_COOR (0x88) +#define EDGE_DISTANCE(c) (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \ + MIN(abs(FILE(c) - 7), FILE(c)))) +#define NOT_ON_EDGE(c) ((((c) & 0xF0) != 0x00) && \ + (((c) & 0xF0) != 0x70) && \ + (((c) & 0x0F) != 0x00) && \ + (((c) & 0x0F) != 0x07)) +#define ON_EDGE(c) (RANK8(c) || \ + RANK1(c) || \ + FILEA(c) || \ + FILEH(c)) +#define CORNER_DISTANCE(c) (MAX(MIN((ULONG)abs(RANK(c) - 7), RANK(c)),\ + MIN((ULONG)abs(FILE(c) - 7), FILE(c)))) +#define IN_CORNER(c) (((c) == A8) || \ + ((c) == A1) || \ + ((c) == H8) || \ + ((c) == H1)) +#define WHITE_CORNER_DISTANCE(c) (MIN(DISTANCE((c), A8), \ + DISTANCE((c), H1))) +#define BLACK_CORNER_DISTANCE(c) (MIN(DISTANCE((c), H8), \ + DISTANCE((c), A1))) +#define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \ + | (7 - ((c) & 0x0F)) +#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a[0]))) +#define MAKE_PSQT(a, b, c, d) (((a) << 24) | ((b) << 16) | \ + ((c) << 8) | (d)) +#define TO64(x) ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3) +#define COOR_TO_BIT_NUMBER(c) (((((c) & 0x70) >> 1) | ((c) & 0x7))) +#define SLOWCOOR_TO_BB(c) (1ULL << COOR_TO_BIT_NUMBER(c)) +#define COOR_TO_BB(c) (BBSQUARE[COOR_TO_BIT_NUMBER(c)]) +#define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7)) +#define BIT_NUMBER_TO_COOR(b) ((((b) & 0xF8) << 1) | ((b) & 7)) + +#define BBRANK88 \ + SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \ + SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \ + SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8) + +#define BBRANK77 \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7) + +#define BBRANK66 \ + SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6) + +#define BBRANK55 \ + SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \ + SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \ + SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5) + +#define BBRANK44 \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4) + +#define BBRANK33 \ + SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3) + +#define BBRANK22 \ + SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \ + SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \ + SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2) + +#define BBRANK11 \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1) + +#define BBFILEA \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8) + +#define BBFILEB \ + SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \ + SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \ + SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8) + +#define BBFILEC \ + SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8) + +#define BBFILED \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8) + +#define BBFILEE \ + SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \ + SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \ + SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8) + +#define BBFILEF \ + SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8) + +#define BBFILEG \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8) + +#define BBFILEH \ + SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \ + SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \ + SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8) + +#define BBRANK72 \ + BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK62 \ + BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK52 \ + BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK42 \ + BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK32 \ + BBRANK33 | BBRANK22 + +#define BBRANK27 \ + BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK37 \ + BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK47 \ + BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK57 \ + BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK67 \ + BBRANK66 | BBRANK77 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// util.c +// +COMMAND(LearnPsqtFromPgn); + +COMMAND(GeneratePositionAndBestMoveSuite); + +CHAR * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx); + +CHAR * +ReadNextGameFromPgnFile(FILE *pf); + +COOR +DistanceBetweenSquares(COOR a, COOR b); + +void CDECL +Trace(CHAR *szMessage, ...); + +void CDECL +Log(CHAR *szMessage, ...); + +void CDECL +Bug(CHAR *szMessage, ...); + +char * +FindChunk(char *sz, ULONG uTargetChunk); + +FLAG +BufferIsZeroed(BYTE *p, ULONG u); + +char * +ColorToString(ULONG u); + +char * +CoorToString(COOR c); + +char * +ScoreToString(SCORE iScore); + +char * +TimeToString(double d); + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock); + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock); + +void +ReleaseSpinLock(volatile ULONG *pSpinLock); + +BYTE +Checksum(BYTE *p, ULONG uSize); + +FLAG +BackupFile(CHAR *szFile); + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv); + +#define CANNOT_INITIALIZE_SPLIT (1) +#define INCONSISTENT_POSITION (2) +#define UNEXPECTED_SYSTEM_CALL_FAILURE (3) +#define SHOULD_NOT_GET_HERE (4) +#define GOT_ILLEGAL_MOVE_WHILE_PONDERING (5) +#define CANNOT_OFFICIALLY_MAKE_MOVE (6) +#define DETECTED_INCORRECT_INITIALIZATION (7) +#define INCONSISTENT_STATE (8) +#define FATAL_ACCESS_DENIED (9) +#define TESTCASE_FAILURE (10) +#define INITIALIZATION_FAILURE (11) + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *a1, + void *a2, + void *a3, + char *file, ULONG line); + + +// +// main.c +// +#define LOGFILE_NAME "typhoon.log" +extern FILE *g_pfLogfile; + +void +Banner(void); + +FLAG +PreGameReset(FLAG fResetBoard); + +// +// system dependent exports (see win32.c or fbsd.c) +// +typedef ULONG (THREAD_ENTRYPOINT)(ULONG); + +#ifdef DEBUG +ULONG +GetHeapMemoryUsage(void); +#endif + +void +SystemDebugBreakpoint(void); + +CHAR * +SystemStrDup(CHAR *p); + +double +SystemTimeStamp(void); + +FLAG +SystemDoesFileExist(CHAR *szFilename); + +void +SystemDeferExecution(ULONG uMs); + +void +SystemFreeMemory(void *pMem); + +void * +SystemAllocateMemory(ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemDependentInitialization(void); + +UINT64 FASTCALL +SystemReadTimeStampCounter(void); + +// +// This routine _must_ implement a full memory fence -- it is used in +// util.c to implement spinlocks. +// +FLAG +SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle); + +FLAG +SystemWaitForThreadToExit(ULONG uThreadHandle); + +FLAG +SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode); + +FLAG +SystemDeleteThread(ULONG uThreadHandle); + +CHAR * +SystemGetDateString(void); + +CHAR * +SystemGetTimeString(void); + +FLAG +SystemCopyFile(CHAR *szSource, CHAR *szDest); + +FLAG +SystemDeleteFile(CHAR *szFile); + +ULONG +SystemCreateLock(void); + +FLAG +SystemDeleteLock(ULONG u); + +FLAG +SystemBlockingWaitForLock(ULONG u); + +FLAG +SystemReleaseLock(ULONG u); + +ULONG +SystemCreateSemaphore(ULONG u); + +FLAG +SystemDeleteSemaphore(ULONG u); + +void +SystemReleaseSemaphoreResource(ULONG u); + +void +SystemObtainSemaphoreResource(ULONG u); + + +// +// fen.c +// +#define STARTING_POSITION_IN_FEN \ + "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + +FLAG +LooksLikeFen(char *szFen); + +char * +PositionToFen(POSITION *p); + +FLAG +FenToPosition(POSITION *p, char *szFen); + +// +// testfen.c +// +#ifdef TEST +void +TestFenCode(void); +#endif + +// +// piece.c +// +// INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN; +#define VALUE_PAWN 100 +#define INVERT_PAWN 900 +#define VALUE_KNIGHT 300 +#define INVERT_KNIGHT 300 +#define VALUE_BISHOP 300 +#define INVERT_BISHOP 300 +#define VALUE_ROOK 500 +#define INVERT_ROOK 180 +#define VALUE_QUEEN 975 +#define INVERT_QUEEN 100 +#define VALUE_KING (INFINITY) +#define INVERT_KING 1 + +#define VALUE_FULL_ARMY (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_QUEEN + VALUE_KING +#define VALUE_MAX_ARMY (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_KING + +typedef struct _PIECE_DATA +{ + ULONG uValue; + ULONG uValueOver100; + ULONG uInvertedValue; + CHAR *szName; +} PIECE_DATA; + +extern PIECE_DATA g_PieceData[8]; + +#define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100) +extern ULONG +PieceValueOver100(PIECE p); + +#define PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uValue) +extern ULONG +PieceValue(PIECE p); + +#define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue) +extern ULONG +PieceInvertedValue(PIECE p); + +CHAR * +PieceAbbrev(PIECE p); + +// +// board.c +// +FLAG +VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError); + +FLAG +PositionsAreEquivalent(POSITION *p1, POSITION *p2); + +CHAR * +DrawTextBoardFromPosition(POSITION *pos); + +void +DumpPosition(POSITION *pos); + +CHAR * +CastleInfoString(BITV bv); + +void +SetRootToInitialPosition(void); + +// +// move.c +// +void +SlidePiece(POSITION *pos, COOR cFrom, COOR cTo); + +PIECE +LiftPiece(POSITION *pos, COOR cSquare); + +void +PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece); + +FLAG +MakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +void +UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +FLAG +MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser); + +void +DumpMove(ULONG u); + +// +// movesup.c +// +#define MOVE_TO_INDEX(mv) (((mv).uMove & 0xFFFF) + \ + (0x10000 * GET_COLOR(mv.pMoved))) + +COOR +FasterExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheckEp(POSITION *pos, + COOR cTest, + COOR cIgnore, + COOR cBlock, + COOR cKing); + +FLAG +IsAttacked(COOR cTest, POSITION *pos, ULONG uSide); + +FLAG +InCheck(POSITION *pos, ULONG uSide); + +FLAG +SanityCheckMove(POSITION *pos, MOVE mv); + +FLAG +LooksLikeFile(CHAR c); + +FLAG +LooksLikeRank(CHAR c); + +FLAG +LooksLikeCoor(CHAR *szData); + +CHAR * +StripMove(CHAR *szMove); + +ULONG +LooksLikeMove(CHAR *szData); + +void FASTCALL +SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +#define NOT_MOVE 0 +#define MOVE_ICS 1 +#define MOVE_SAN 2 + +COMMAND(PerftCommand); + + +// +// testmove.c +// +#ifdef TEST +void +TestLiftPlaceSlidePiece(void); + +void +TestExposesCheck(void); + +void +TestIsAttacked(void); + +void +TestMakeUnmakeMove(void); +#endif + +// +// generate.c +// +#define SORT_THESE_FIRST (0x40000000) +#define FIRST_KILLER (0x20000000) +#define SECOND_KILLER (0x10000000) +#define THIRD_KILLER (0x08000000) +#define FOURTH_KILLER (0x04000000) +#define GOOD_MOVE (0x02000000) +#define STRIP_OFF_FLAGS (0x00FFFFFF) + +extern const int g_iQKDeltas[9]; +extern const int g_iNDeltas[9]; +extern const int g_iBDeltas[5]; +extern const int g_iRDeltas[5]; + +void +GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mvOrderFirst, + ULONG uType); + +FLAG +WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv); + +// +// testgenerate.c +// +#ifdef TEST + +void +PlyTest(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fRootPositionInCheck); + +void +TestMoveGenerator(void); + +void +TestLegalMoveGenerator(void); + +#endif + +// +// sig.c +// +extern UINT64 g_u64SigSeeds[128][7][2]; +extern UINT64 g_u64PawnSigSeeds[128][2]; +extern UINT64 g_u64CastleSigSeeds[16]; +extern UINT64 g_u64EpSigSeeds[9]; + +void +InitializeSigSystem(void); + +UINT64 +ComputePawnSig(POSITION *pos); + +UINT64 +ComputeSig(POSITION *pos); + +// +// mersenne.c +// +void +seedMT(unsigned int seed); + +unsigned int +reloadMT(void); + +unsigned int +randomMT(void); + +// +// data.c +// +typedef struct _VECTOR_DELTA +{ + UCHAR iVector[2]; + signed char iDelta; + signed char iNegDelta; +} +VECTOR_DELTA; + +extern ULONG g_uDistance[256]; +extern ULONG *g_pDistance; +extern VECTOR_DELTA g_VectorDelta[256]; +extern VECTOR_DELTA *g_pVectorDelta; +extern CHAR g_SwapTable[14][32][32]; +extern SCORE _PSQT[14][128]; +extern ULONG g_uSearchSortLimits[]; +extern MOVE NULLMOVE; +extern MOVE HASHMOVE; +extern MOVE RECOGNMOVE; +extern MOVE DRAWMOVE; +extern MOVE MATEMOVE; +extern FLAG g_fIsWhiteSquare[128]; +extern BITBOARD BBFILE[8]; +extern BITBOARD BBRANK[9]; +extern BITBOARD BBWHITESQ; +extern BITBOARD BBBLACKSQ; +extern BITBOARD BBLEFTSIDE; +extern BITBOARD BBRIGHTSIDE; +extern BITBOARD BBSQUARE[64]; +extern BITBOARD BBROOK_PAWNS; +extern BITBOARD BBPRECEEDING_RANKS[8][2]; +extern BITBOARD BBADJACENT_FILES[8]; +extern BITBOARD BBADJACENT_RANKS[9]; + +void +InitializeWhiteSquaresTable(void); + +void +InitializeVectorDeltaTable(void); + +void +InitializeSwapTable(void); + +void +InitializeDistanceTable(void); + +void +InitializeSearchDepthArray(void); + +ULONG +GetSearchSortLimit(ULONG); + +#ifdef DEBUG +#define SEARCH_SORT_LIMIT(x) (GetSearchSortLimit((x))) +#else +#define SEARCH_SORT_LIMIT(x) (g_uSearchSortLimits[(x)]) +#endif + +#ifdef DEBUG +ULONG CheckVectorWithIndex(int i, ULONG uColor); +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + CheckVectorWithIndex(i, color) + +int DirectionBetweenSquaresWithIndex(int i); +#define CHECK_DELTA_WITH_INDEX(i) \ + DirectionBetweenSquaresWithIndex(i) + +int DirectionBetweenSquaresFromTo(COOR, COOR); +#define DIRECTION_BETWEEN_SQUARES(from, to) \ + DirectionBetweenSquaresFromTo(from, to) + +int NegativeDirectionBetweenSquaresWithIndex(int i); +#define NEG_DELTA_WITH_INDEX(i) \ + NegativeDirectionBetweenSquaresWithIndex(i) + +FLAG IsSquareWhite(COOR c); +#define IS_SQUARE_WHITE(c) \ + IsSquareWhite(c) + +#else +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + (g_pVectorDelta[(i)].iVector[(color)]) + +#define CHECK_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iDelta) + +#define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \ + CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo)) + +#define NEG_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iNegDelta) + +#define IS_SQUARE_WHITE(c) \ + (g_fIsWhiteSquare[(c)]) +#endif + +// +// san.c +// +MOVE +ParseMoveSan(CHAR *szInput, + POSITION *pos); + +CHAR * +MoveToSan(MOVE mv, POSITION *pos); + +// +// testsan.c +// +void +TestSan(void); + +// +// list.c +// +void +InitializeListHead(IN DLIST_ENTRY *pListHead); + +FLAG +IsListEmpty(IN DLIST_ENTRY *pListHead); + +FLAG +RemoveEntryList(IN DLIST_ENTRY *pEntry); + +DLIST_ENTRY * +RemoveHeadList(IN DLIST_ENTRY *pListHead); + +DLIST_ENTRY * +RemoveTailList(IN DLIST_ENTRY *pListHead); + +void +InsertTailList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +void +InsertHeadList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +// +// command.c +// +void +ParseUserInput(FLAG fSearching); + +FLAG +InitializeCommandSystem(void); + +void +CleanupCommandSystem(void); + +// +// input.c +// +void +InitInputSystemInBatchMode(void); + +ULONG +InitInputSystemWithDedicatedThread(void); + +void +PushNewInput(CHAR *buf); + +CHAR * +PeekNextInput(void); + +CHAR * +ReadNextInput(void); + +CHAR * +BlockingReadInput(void); + +ULONG +NumberOfPendingInputEvents(void); + +volatile extern FLAG g_fExitProgram; + +// +// ics.c +// +MOVE +ParseMoveIcs(CHAR *szInput, POSITION *pos); + +CHAR * +MoveToIcs(MOVE mv); + +// +// testics.c +// +void +TestIcs(void); + +// +// gamelist.c +// +typedef enum _ERESULT +{ + RESULT_BLACK_WON = -1, + RESULT_DRAW = 0, + RESULT_WHITE_WON = 1, + RESULT_IN_PROGRESS, + RESULT_ABANDONED, + RESULT_UNKNOWN +} ERESULT; + +typedef struct _GAME_RESULT +{ + ERESULT eResult; + CHAR szDescription[256]; +} GAME_RESULT; + +typedef struct _GAME_PLAYER +{ + CHAR *szName; + CHAR *szDescription; + FLAG fIsComputer; + ULONG uRating; +} +GAME_PLAYER; + +typedef struct _GAME_HEADER +{ + CHAR *szGameDescription; + CHAR *szLocation; + GAME_PLAYER sPlayer[2]; + FLAG fGameIsRated; + UINT64 u64OpeningSig; + ERESULT eResult; + CHAR *szResultComment; + CHAR *szInitialFen; +} +GAME_HEADER; + +typedef struct _GAME_MOVE +{ + DLIST_ENTRY links; + ULONG uNumber; + MOVE mv; + CHAR *szComment; + CHAR *szDecoration; + CHAR *szMoveInSan; + CHAR *szMoveInIcs; + CHAR *szUndoPositionFen; + SCORE iMoveScore; + UINT64 u64PositionSigAfterMove; + UINT64 u64PositionSigBeforeMove; + volatile FLAG fInUse; +} +GAME_MOVE; + +typedef struct _GAME_DATA +{ + GAME_HEADER sHeader; + DLIST_ENTRY sMoveList; +} +GAME_DATA; + +extern GAME_DATA g_GameData; + +POSITION * +GetRootPosition(void); + +FLAG +SetRootPosition(CHAR *szFen); + +void +ResetGameList(void); + +ULONG +GetMoveNumber(ULONG uColor); + +void +SetGameResultAndDescription(ERESULT r, CHAR *sz); + +INT +GetGameResult(void); + +void +SetMyName(void); + +void +SetOpponentsName(CHAR *sz); + +void +SetMyRating(ULONG u); + +void +SetOpponentsRating(ULONG u); + +void +DumpGameList(void); + +void +TellGamelistThatIPlayColor(ULONG u); + +void +DumpPgn(void); + +FLAG +LoadPgn(CHAR *szPgn); + +ULONG +CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig); + +FLAG +DoesSigAppearInOfficialGameList(UINT64 u64Sig); + +FLAG +OfficiallyTakebackMove(void); + +FLAG +OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast); + +GAME_MOVE * +GetNthOfficialMoveRecord(ULONG n); + +void +MakeStatusLine(void); + +FLAG +IsLegalDrawByRepetition(void); + +// +// script.c +// +COMMAND(ScriptCommand); + +COMMAND(SolutionCommand); + +COMMAND(AvoidCommand); + +COMMAND(IdCommand); + +void +PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *); + +FLAG +CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth); + +FLAG +WeAreRunningASuite(void); + + +// +// vars.c +// +COMMAND(SetCommand); + +// +// root.c +// +extern ULONG g_uSoftExtendLimit; +extern ULONG g_uHardExtendLimit; +extern volatile MOVE_TIMER g_MoveTimer; +extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; + +#ifdef PERF_COUNTERS +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) \ + ctx->sCounters.tree.u64BetaCutoffs++; \ + if (x) \ + { \ + ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\ + } +#else +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) +#endif + +#define GAME_NOT_OVER 0 +#define GAME_WHITE_WON 1 +#define GAME_BLACK_WON 2 +#define GAME_DRAW_STALEMATE 3 +#define GAME_DRAW_REPETITION 4 +#define GAME_ONE_LEGAL_MOVE 5 +#define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6 + +GAME_RESULT +Think(POSITION *pos); + +GAME_RESULT +Ponder(POSITION *pos); + +GAME_RESULT +Iterate(SEARCHER_THREAD_CONTEXT *ctx); + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor); + +void +SetMoveTimerToThinkForever(void); + +void +ClearRootNodecountHash(void); + +// +// draw.c +// +FLAG +IsDraw(SEARCHER_THREAD_CONTEXT *ctx); + + +// +// search.c +// +#define QPLIES_OF_NON_CAPTURE_CHECKS (1) +#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100) +#define DO_IID +#define IID_R_FACTOR (TWO_PLY + HALF_PLY) + +#ifndef MP +#define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING) +#else +#define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \ + (ThreadUnderTerminatingSplit(ctx))) +#endif + +SCORE FASTCALL +QSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta); + +SCORE FASTCALL +Search(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth); + + +// +// searchsup.c +// +SCORE +ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv, + IN ULONG uMoveNum); + +FLAG +ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *); + +FLAG +WeShouldDoHistoryPruning(IN SCORE iRoughEval, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN ULONG uLegalMoves, + IN MOVE mv, + IN ULONG uMoveNum, + IN INT iExtend); + +FLAG +WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SCORE iRoughEval, + IN ULONG uNullDepth); + +FLAG +TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN OUT FLAG *pfThreat, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uNullDepth, + IN OUT INT *piOrigExtend, + OUT SCORE *piNullScore); + +void +UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv); + +FLAG +CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx); + +void +ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uGenFlags, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN SCORE iAlpha, + IN OUT INT *piExtend, + IN OUT INT *piOrigExtend); + +void +ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN ULONG uDepth, + IN OUT INT *piExtend); + +SCORE +RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uDepth, + IN SCORE iAlpha, + IN SCORE iBeta); + +FLAG +MateDistancePruningCutoff(IN ULONG uPly, + IN FLAG fInCheck, + IN OUT SCORE *piBestScore, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta); + +FLAG +CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta, + IN OUT SCORE *piScore); + +ULONG +SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx, + IN INT uDepth); + +#define VERIFY_BEFORE (1) +#define VERIFY_AFTER (2) + +FLAG +SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uCurrent, + IN ULONG uType); + + +// +// testsearch.c +// +FLAG +TestSearch(void); + +// +// see.c +// +#define SEE_HEAPS + +SCORE +SEE(POSITION *pos, + MOVE mv); + +typedef struct _SEE_THREESOME +{ + PIECE pPiece; + COOR cLoc; + ULONG uVal; +} SEE_THREESOME; + +typedef struct _SEE_LIST +{ + ULONG uCount; + SEE_THREESOME data[16]; +} +SEE_LIST; + +SCORE +ControlsSquareMinusPiece(ULONG uSide, + POSITION *pos, + COOR c, + COOR cIgnore); + +// +// testsee.c +// +SCORE +DebugSEE(POSITION *pos, + MOVE mv); + +void +TestGetAttacks(void); + +// +// hash.c +// +#define NUM_HASH_ENTRIES_PER_LINE 4 +#define HASH_FLAG_EXACT 0x1 +#define HASH_FLAG_LOWER 0x2 +#define HASH_FLAG_UPPER 0x4 +#define HASH_FLAG_VALID_BOUNDS 0x7 +#define HASH_FLAG_THREAT 0x8 +#define HASH_FLAG_DIRTY 0xF0 + +typedef struct _HASH_ENTRY +{ + MOVE mv; // 0 1 2 3 + UCHAR uDepth; // 4 + UCHAR bvFlags; // 5 ==> d d d d | thr up low exact + signed short iValue; // 6 7 + UINT64 u64Sig; // 8 9 A B C D E F == 16 bytes +} HASH_ENTRY; + +FLAG +InitializeHashSystem(void); + +void +CleanupHashSystem(void); + +void +ClearHashTable(void); + +void +DirtyHashTable(void); + +void +StoreLowerBound(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); +void +StoreExactScore(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat, + ULONG uPly); + +void +StoreUpperBound(//MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); + +HASH_ENTRY * +HashLookup(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + ULONG uNextDepth, + SCORE iAlpha, + SCORE iBeta, + FLAG *pfThreat, + FLAG *pfAvoidNull, + MOVE *pHashMove, + SCORE *piScore); + +COOR +CheckHashForDangerSquare(POSITION *pos); + +MOVE +GetPonderMove(POSITION *pos); + +extern ULONG g_uHashTableSizeEntries; +extern ULONG g_uHashTableSizeBytes; +extern HASH_ENTRY *g_pHashTable; + +// +// testhash.c +// +void +AnalyzeFullHashTable(void); + +// +// positionhash.c +// +// IDEA: store "mate threat" flag in here? +// IDEA: store "king safety" numbers in here? +// +typedef struct _POSITION_HASH_ENTRY { + UINT64 u64Sig; + UCHAR cEnprise[2]; + UCHAR uEnpriseCount[2]; + UCHAR cTrapped[2]; +} POSITION_HASH_ENTRY; + +void +InitializePositionHashSystem(void); + +void +CleanupPositionHashSystem(void); + +void +StoreEnprisePiece(POSITION *pos, COOR cSquare); + +void +StoreTrappedPiece(POSITION *pos, COOR cSquare); + +COOR +GetEnprisePiece(POSITION *pos, ULONG uSide); + +ULONG +GetEnpriseCount(POSITION *pos, ULONG uSide); + +COOR +GetTrappedPiece(POSITION *pos, ULONG uSide); + +FLAG +SideCanStandPat(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide); + +// +// pawnhash.c +// +#define COOR_TO_BIT(x) ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3) + +void +ClearPawnHashStats(void); + +void +ReportPawnHashStats(void); + +PAWN_HASH_ENTRY * +PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx); + +// +// eval.c +// +#define LAZY_EVAL +#define LAZE_EVAL_BASE_SCORE 10 +extern const int g_iAhead[2]; +extern const int g_iBehind[2]; + +ULONG +DNABufferSizeBytes(); + +char * +ExportEvalDNA(); + +FLAG +WriteEvalDNA(char *szFilename); + +FLAG +ImportEvalDNA(char *p); + +FLAG +ReadEvalDNA(char *szFilename); + + + +SCORE +Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE); + +FLAG +EvalPasserRaces(POSITION *, + PAWN_HASH_ENTRY *); + +ULONG +CountKingSafetyDefects(POSITION *pos, + ULONG uSide); + +// +// testeval.c +// +#ifdef EVAL_DUMP +void +TestEval(void); + +void +EvalTraceReport(void); + +void +EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage); + +SCORE +EvalSigmaForPiece(POSITION *pos, COOR c); + +void +EvalTraceClear(void); + +void +TestEvalWithSymmetry(void); + +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); \ + EvalTrace((COL), (PIE), (COO), (ADJ), (MESS)); +#else +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); +#endif + +// +// bitboard.c +// +void +InitializeBitboards(void); + +ULONG CDECL +SlowCountBits(BITBOARD bb); + +ULONG CDECL +DeBruijnFirstBit(BITBOARD bb); + +ULONG CDECL +SlowFirstBit(BITBOARD bb); + +ULONG CDECL +SlowLastBit(BITBOARD bb); + +#ifdef CROUTINES +#define CountBits SlowCountBits +#define FirstBit SlowFirstBit +#define LastBit SlowLastBit +#endif + +COOR +CoorFromBitBoardRank8ToRank1(BITBOARD *pbb); + +COOR +CoorFromBitBoardRank1ToRank8(BITBOARD *pbb); + +// +// x86.asm +// +ULONG CDECL +CountBits(BITBOARD bb); + +ULONG CDECL +FirstBit(BITBOARD bb); + +ULONG CDECL +LastBit(BITBOARD bb); + +ULONG CDECL +LockCompareExchange(volatile void *pDest, + ULONG uExch, + ULONG uComp); + +ULONG CDECL +LockIncrement(volatile void *pDest); + +ULONG CDECL +LockDecrement(volatile void *pDest); + +FLAG CDECL +CanUseParallelOpcodes(); + +ULONG CDECL +ParallelCompareUlong(ULONG uComparand, void *pComparators); + +ULONG CDECL +ParallelCompareVector(void *pComparand, void *pComparators); + +void CDECL +GetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); + +void CDECL +SlowGetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); +#ifdef CROUTINES +#define GetAttacks SlowGetAttacks +#endif + +#ifdef _X86_ +// +// Note: this is most of the stuff that x86.asm assumes about the +// internal data structures. If any of this fails then either the +// assembly language code needs to be updated or you need to use the C +// version of the routine in see.c instead. +// +#define ASSERT_ASM_ASSUMPTIONS \ + ASSERT(VALUE_PAWN == 100); \ + ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \ + ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \ + ASSERT(sizeof(SEE_THREESOME) == 12); \ + ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \ + ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \ + ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \ + ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \ + ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \ + ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \ + ASSERT(sizeof(SQUARE) == 8); \ + ASSERT(sizeof(VECTOR_DELTA) == 4); \ + ASSERT(sizeof(g_VectorDelta) == 256 * 4); \ + ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \ + ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \ + ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \ + ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \ + ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0); +#else +#define ASSERT_ASM_ASSUMPTIONS +#endif + +// +// testbitboard.c +// +void +TestBitboards(void); + +// +// dynamic.c +// +extern ULONG g_HistoryCounters[14][128]; + +ULONG +GetMoveFailHighPercentage(MOVE mv); + +void +UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uRemainingDepth, + MOVE mvBest, + SCORE iScore, + ULONG uCurrent); + +void +NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore); + +FLAG +InitializeDynamicMoveOrdering(void); + +void +CleanupDynamicMoveOrdering(void); + +void +ClearDynamicMoveOrdering(void); + +void +MaintainDynamicMoveOrdering(void); + +void +IncrementMoveHistoryCounter(MOVE mv, ULONG u); + +void +DecrementMoveHistoryCounter(MOVE mv, ULONG u); + +// +// split.c +// +extern volatile ULONG g_uNumHelpersAvailable; +extern ULONG g_uNumHelperThreads; + +FLAG +InitializeParallelSearch(void); + +FLAG +CleanupParallelSearch(void); + +void +ClearHelperThreadIdleness(void); + +void +DumpHelperIdlenessReport(void); + +SCORE +StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN SCORE iBeta, + IN OUT SCORE *piBestScore, + IN OUT MOVE *pmvBest, + IN ULONG uMoveNum, + IN INT iPositionExtend, + IN ULONG uDepth); + +void +InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx); + +// +// book.c +// + +#define BOOK_PROBE_MISS_LIMIT (7) +#define FLAG_DISABLED (1) +#define FLAG_ALWAYSPLAY (2) +#define FLAG_DELETED (4) + +#define BOOKMOVE_SELECT_MOVE (1) +#define BOOKMOVE_DUMP (2) + +#pragma pack(4) +typedef struct _BOOK_ENTRY +{ + UINT64 u64Sig; // 8 bytes + UINT64 u64NextSig; // 8 bytes + MOVE mvNext; // 4 bytes + ULONG uWins; // 4 bytes + ULONG uDraws; // 4 bytes + ULONG uLosses; // 4 bytes + BITV bvFlags; // 4 bytes +} +BOOK_ENTRY; +#pragma pack() + +typedef struct _OPENING_NAME_MAPPING +{ + UINT64 u64Sig; + CHAR *szString; +} +OPENING_NAME_MAPPING; + +#define BOOK_EDITING_RECORD "bkedit.edt" +#define OPENING_LEARNING_FILENAME "bklearn.bin" + +typedef struct _OPENING_LEARNING_ENTRY +{ + UINT64 u64Sig; + ULONG uWhiteWins; + ULONG uDraws; + ULONG uBlackWins; +} +OPENING_LEARNING_ENTRY; + +FLAG +InitializeOpeningBook(void); + +void +ResetOpeningBook(void); + +void +CleanupOpeningBook(void); + +MOVE +BookMove(POSITION *pos, + BITV bvFlags); + +COMMAND(BookCommand); + +extern ULONG g_uBookProbeFailures; +extern FLAG g_fTournamentMode; +extern CHAR *g_szBookName; + +// +// bench.c +// +COMMAND(BenchCommand); + +// +// testdraw.c +// +void +TestDraw(void); + +// +// probe.c +// +FLAG +ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score); + +void +InitializeEGTB(void); + +void +CleanupEGTB(void); + +// +// dumptree.c +// +#ifdef DUMP_TREE + +void +InitializeTreeDump(void); + +void +CleanupTreeDump(void); + +void +DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fIsQNode, + SCORE iAlpha, + SCORE iBeta); + +void +DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fQNode, + SCORE iBestScore, + MOVE mvBestMove); + +void CDECL +DTTrace(ULONG uPly, CHAR *szMessage, ...); + +#define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__) + +#else + +#define DTTRACE(...) + +#define DTEnterNode(...) + +#define DTLeaveNode(...) + +#define InitializeTreeDump(...) + +#define CleanupTreeDump(...) + +#endif + +// +// testsup.c +// +FLAG +IsBoardLegal(POSITION *pos); + +void +GenerateRandomLegalPosition(POSITION *pos); + +void +GenerateRandomLegalSymetricPosition(POSITION *pos); + +// +// recogn.c +// +#define UNRECOGNIZED (0) +#define RECOGN_EXACT (1) +#define RECOGN_UPPER (2) +#define RECOGN_LOWER (3) +#define RECOGN_EGTB (4) + +void +InitializeInteriorNodeRecognizers(void); + +ULONG +RecognLookup(SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore, + FLAG fProbeEGTB); + +#ifdef EVAL_HASH +void +ClearEvalHashStats(void); + +void +ReportEvalHashStats(void); + +SCORE +ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx); + +SCORE +GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash); + +void +StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore); +#endif // EVAL_HASH + +#endif // CHESS diff --git a/src/changes/main.c b/src/changes/main.c new file mode 100755 index 0000000..b5e4ffe --- /dev/null +++ b/src/changes/main.c @@ -0,0 +1,736 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + main.c + +Abstract: + + Program entry point and setup code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: main.c 351 2008-06-28 04:21:53Z scott $ + +**/ + +#include "chess.h" + +FILE *g_pfLogfile = NULL; +GAME_OPTIONS g_Options; +CHAR g_szInitialCommand[SMALL_STRING_LEN_CHAR]; +ULONG g_uInputThreadHandle = (ULONG)-1; + +void +Banner(void) +/** + +Routine description: + + Describe the compile/build options and program version. + +Parameters: + + void + +Return value: + + void + +**/ +{ + char *p; + + Trace("Typhoon %s (built on %s %s):\n", VERSION, __DATE__, __TIME__); + Trace(" Copyright (C) 2000-2007, Scott Gasch (scott.gasch@gmail.com)\n"); + Trace(" " REVISION); + Trace(" " COMPILER_STRING); + Trace(" Make profile used: %s\n", PROFILE); +#ifdef MP + Trace(" Multiprocessor enabled; %u searcher thread%s\n", + g_Options.uNumProcessors, (g_Options.uNumProcessors > 1) ? "s" : ""); +#else + Trace(" Single processor version\n"); +#endif +#ifdef DEBUG + Trace(" DEBUG build\n"); +#endif +#ifdef TEST + Trace(" Testcode compiled in\n"); +#endif +#ifdef EVAL_DUMP + Trace(" Evaluation terms\n"); +#endif +#ifdef EVAL_TIME + Trace(" Evaluation timing\n"); +#endif +#ifdef PERF_COUNTERS + Trace(" Performance counters\n"); +#ifdef TEST_NULL + Trace(" Testing nullmove prediction algorithms\n"); +#endif +#endif +#ifdef DUMP_TREE + Trace(" Search tree dumpfile generation enabled\n"); +#endif + Trace(" Hash sizes: %u Mb (main), %u Mb / thread (pawn), %u Mb / thread (eval)\n", + (g_uHashTableSizeEntries * sizeof(HASH_ENTRY)) / MB, + PAWN_HASH_TABLE_SIZE * sizeof(PAWN_HASH_ENTRY) / MB, + EVAL_HASH_TABLE_SIZE * sizeof(EVAL_HASH_ENTRY) / MB); + Trace(" QCheckPlies: %u\n", QPLIES_OF_NON_CAPTURE_CHECKS); + Trace(" FutilityBase: %u\n", FUTILITY_BASE_MARGIN); + p = ExportEvalDNA(); + Trace(" Logging Eval DNA.\n"); + Log(p); + free(p); +#ifdef DO_IID + Trace(" IID R-factor: %u ply\n", IID_R_FACTOR / ONE_PLY); +#endif +} + + +void +EndLogging(void) +/** + +Routine description: + + Close the main logfile. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (NULL != g_pfLogfile) + { + fflush(g_pfLogfile); + fflush(stdout); + fclose(g_pfLogfile); + g_pfLogfile = NULL; + } +} + + +FLAG +BeginLogging(void) +/** + +Routine description: + + Open the main logfile. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (NULL != g_pfLogfile) + { + EndLogging(); + } + ASSERT(g_pfLogfile == NULL); + ASSERT(strlen(g_Options.szLogfile)); + + // + // If the logfile we want to write already exists, back it up. + // + if (TRUE == SystemDoesFileExist(g_Options.szLogfile)) + { + VERIFY(BackupFile(g_Options.szLogfile)); + } + ASSERT(FALSE == SystemDoesFileExist(g_Options.szLogfile)); + + g_pfLogfile = fopen(g_Options.szLogfile, "wb+"); + if (NULL == g_pfLogfile) + { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Can't open logfile", + (void *)&(g_Options.szLogfile), + (void *)"write", + NULL, + __FILE__, __LINE__); + } + return(TRUE); +} + + +FLAG +PreGameReset(FLAG fResetBoard) +/** + +Routine description: + + Reset internal state between games. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (TRUE == fResetBoard) + { + SetRootToInitialPosition(); + } + SetMyName(); + ClearDynamicMoveOrdering(); + ClearHashTable(); + ResetOpeningBook(); + return(TRUE); +} + + +static ULONG +_ParseHashOption(char *p, + ULONG uEntrySize) +{ + ULONG u, v; + CHAR c; + + if ((!STRCMPI(p, "none")) || (!STRCMPI(p, "no"))) return(0); + if (2 == sscanf(p, "%u%1c", &u, &c)) + { + v = u; + switch(c) + { + case 'K': + case 'k': + u *= 1024; + break; + case 'M': + case 'm': + u *= 1024 * 1024; + break; + case 'G': + case 'g': + u *= 1024 * 1024 * 1024; + break; + default: + Trace("Error (unrecognized size): \"%s\"\n", p); + break; + } + if (u < v) + { + Trace("Error (size too large): \"%s\"\n", p); + u = v; + } + u /= uEntrySize; + } + else + { + u = (ULONG)atoi(p); + } + + while(!IS_A_POWER_OF_2(u)) + { + u &= (u - 1); + } + return(u); +} + + + +void +InitializeOptions(int argc, char *argv[]) +/** + +Routine description: + + Set global options to their initial state. This code also is + responsible for parsing the commandline in order to override the + default state of global options. + +Parameters: + + int argc, + char *argv[] + +Return value: + + void + +**/ +{ + int i; + + // + // Defaults + // + memset(&g_Options, 0, sizeof(g_Options)); + g_szInitialCommand[0] = '\0'; + g_Options.uMyClock = g_Options.uOpponentsClock = 600; + g_Options.fGameIsRated = FALSE; + g_Options.fOpponentIsComputer = FALSE; + g_Options.uSecPerMove = 0; + g_Options.uMaxDepth = MAX_PLY_PER_SEARCH - 1; + g_Options.fShouldPonder = TRUE; + g_Options.fPondering = g_Options.fThinking = FALSE; + g_Options.mvPonder.uMove = 0; + g_Options.fShouldPost = TRUE; + g_Options.fForceDrawWorthZero = FALSE; + g_Options.uMyIncrement = 0; + g_Options.uMovesPerTimePeriod = 0; + g_Options.szAnalyzeProgressReport[0] = '\0'; + g_Options.fShouldAnnounceOpening = TRUE; + g_Options.eClock = CLOCK_NONE; + g_Options.eGameType = GAME_UNKNOWN; + g_Options.ePlayMode = FORCE_MODE; + g_Options.fNoInputThread = FALSE; + g_Options.fVerbosePosting = TRUE; + strcpy(g_Options.szEGTBPath, "/egtb/three;/etc/four;/egtb/five"); + strcpy(g_Options.szLogfile, "typhoon.log"); + strcpy(g_Options.szBookName, "book.bin"); + g_Options.uNumHashTableEntries = 0x10000; + g_Options.uNumProcessors = 1; + g_Options.fStatusLine = TRUE; + g_Options.fShouldResign = FALSE; + g_Options.u64MaxNodeCount = 0ULL; + + i = 1; + while(i < argc) + { +#ifdef MP + if ((!STRCMPI(argv[i], "--cpus")) && (argc > i)) + { + g_Options.uNumProcessors = (ULONG)atoi(argv[i+1]); + if ((g_Options.uNumProcessors == 0) || + (g_Options.uNumProcessors > 64)) + { + g_Options.uNumProcessors = 2; + } + i++; + } + else +#endif + if ((!STRCMPI(argv[i], "--command")) && (argc > i)) + { + strncpy(g_szInitialCommand, + argv[i+1], + SMALL_STRING_LEN_CHAR - 2); + strcat(g_szInitialCommand, "\r\n"); + i++; + } + else if ((!STRCMPI(argv[i], "--hash")) && (argc > i)) + { + g_Options.uNumHashTableEntries = + _ParseHashOption(argv[i+1], + sizeof(HASH_ENTRY)); + i++; + } + else if ((!STRCMPI(argv[i], "--egtbpath")) && (argc > i)) + { + g_Options.szEGTBPath[0] = '\0'; + strncpy(g_Options.szEGTBPath, argv[i+1], SMALL_STRING_LEN_CHAR); + i++; + } + else if (!STRCMPI(argv[i], "--batch")) + { + g_Options.fNoInputThread = TRUE; + } + else if ((!STRCMPI(argv[i], "--dnafile")) && (argc > i)) + { + if (!ReadEvalDNA(argv[i+1])) + { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Bad DNA file", + (void *)&(argv[i+1]), + (void *)"read", + NULL, + __FILE__, __LINE__); + } + i++; + } + else if ((!STRCMPI(argv[i], "--logfile")) && (argc > i)) + { + strncpy(g_Options.szLogfile, argv[i+1], + SMALL_STRING_LEN_CHAR); + i++; + } + else if (!STRCMPI(argv[i], "--help")) { + Trace("Usage: %s [--batch] [--command arg] [--logfile arg] [--egtbpath arg]\n" + " [--dnafile arg] [--cpus arg] [--hash arg]\n\n" + " --batch : operate the engine without an input thread\n" + " --command : specify initial command(s) (requires arg)\n" + " --cpus : indicate the number of cpus to use (requires arg, MP build)\n" + " --hash : indicate desired hash size (requires arg)\n" + " --egtbpath : supplies the egtb path to engine (requires arg)\n" + " --logfile : indicate desired output logfile name (requires arg)\n" + " --dnafile : indicate desired eval profile input (requres arg)\n\n" + "Example: %s --hash 256m --cpus 2\n" + " %s --logfile test.out --batch --command \"test\" --dnafile test.in\n", argv[0], argv[0], argv[0]); + exit(-1); + } + else + { + Trace("Error (unknown argument): \"%s\"; try --help\n", argv[i]); + } + + // + // TODO: parse other commandline options and override above + // + + i++; + } +} + + +void +CleanupOptions(void) +/** + +Routine description: + + Cleanup options... + +Parameters: + + void + +Return value: + + void + +**/ +{ + NOTHING; +} + + +FLAG +MainProgramInitialization(int argc, char *argv[]) +/** + +Routine description: + + Perform main program initialization. This includes stuff like: + precomputing some data structures, resetting the global options, + parsing the commandline to override said options, and calling out + to other modules to tell them to initialize themselves. + +Parameters: + + int argc, + char *argv[] + +Return value: + + FLAG + +**/ +{ + srand((unsigned int)time(0)); + InitializeOptions(argc, argv); + InitializeTreeDump(); + InitializeEGTB(); + InitializeSigSystem(); + InitializeInteriorNodeRecognizers(); + InitializeSearchDepthArray(); + InitializeWhiteSquaresTable(); + InitializeVectorDeltaTable(); + InitializeSwapTable(); + InitializeDistanceTable(); + InitializeOpeningBook(); + InitializeDynamicMoveOrdering(); + InitializeHashSystem(); + InitializePositionHashSystem(); +#ifdef MP + InitializeParallelSearch(); +#endif + VERIFY(PreGameReset(TRUE)); + return(BeginLogging()); +} + + +FLAG +MainProgramCleanup(void) +/** + +Routine description: + + Perform main program cleanup. Tear down the stuff we set up in + MainProgramInitialization. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + CleanupOpeningBook(); + CleanupEGTB(); + CleanupDynamicMoveOrdering(); +#ifdef MP + CleanupParallelSearch(); +#endif + CleanupPositionHashSystem(); + CleanupHashSystem(); + CleanupTreeDump(); + CleanupOptions(); + EndLogging(); + return(TRUE); +} + + +#ifdef TEST +FLAG +RunStartupProgramTest(void) +/** + +Routine description: + + If we built this version with -DTEST then this code is the start + of the self-test that runs at program startup time. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + ULONG u, x, y; + +#ifdef _X86_ + Trace("Testing CPP macros...\n"); + for (u = 0; u < 1000000; u++) + { + x = rand() * rand(); + y = rand() * rand(); + x = x & ~(0x80000000); + y = y & ~(0x80000000); + + if (MAX(x, y) != MAXU(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "max maxu", NULL, NULL, __FILE__, __LINE__); + } + + if (MAXU(x, y) != MAXU(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "maxu assoc", NULL, NULL, __FILE__, __LINE__); + } + + if (MIN(x, y) != MINU(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "min minu", NULL, NULL, __FILE__, __LINE__); + } + + if (MINU(x, y) != MINU(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "minu assoc", NULL, NULL, __FILE__, __LINE__); + } + + if (abs(x - y) != ABS_DIFF(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "abs_diff", NULL, NULL, __FILE__, __LINE__); + } + + if (ABS_DIFF(x, y) != ABS_DIFF(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "abs_diff assoc", NULL, NULL, __FILE__, __LINE__); + } + } +#endif + + TestDraw(); +#ifdef EVAL_DUMP + TestEval(); +#endif + TestBitboards(); + TestSan(); + TestIcs(); + TestGetAttacks(); + TestMoveGenerator(); + TestLegalMoveGenerator(); + TestFenCode(); + TestLiftPlaceSlidePiece(); + TestExposesCheck(); + TestIsAttacked(); + TestMakeUnmakeMove(); + TestSearch(); + + return(TRUE); +} +#endif // TEST + + + +void DeclareTerminalStates(GAME_RESULT result) { + switch(result.eResult) { + case RESULT_IN_PROGRESS: + return; + case RESULT_BLACK_WON: + Trace("0-1 {%s}\n", result.szDescription); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_WHITE_WON: + Trace("1-0 {%s}\n", result.szDescription); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_DRAW: + Trace("1/2-1/2 {%s}\n", result.szDescription); + Trace("tellics draw\n"); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_ABANDONED: + case RESULT_UNKNOWN: + ASSERT(FALSE); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + } +} + + +// Main work loop +void MainProgramLoop() { + POSITION pos; + GAME_RESULT result; + FLAG fThink; + FLAG fPonder; + + while(!g_fExitProgram) { + + // Prepare to search or ponder + memcpy(&pos, GetRootPosition(), sizeof(POSITION)); + fThink = fPonder = FALSE; + result.eResult = RESULT_IN_PROGRESS; + result.szDescription[0] = '\0'; + + // What should we do? + switch(g_Options.ePlayMode) { + case I_PLAY_WHITE: + fThink = (pos.uToMove == WHITE); + fPonder = (pos.uToMove == BLACK); + break; + case I_PLAY_BLACK: + fThink = (pos.uToMove == BLACK); + fPonder = (pos.uToMove == WHITE); + break; + case FORCE_MODE: + default: + MakeStatusLine(); + ParseUserInput(FALSE); + continue; + } + + if (fThink) { + result = Think(&pos); + if ((NumberOfPendingInputEvents() != 0) && + (FALSE == g_fExitProgram)) + { + MakeStatusLine(); + ParseUserInput(FALSE); + } + } else if (fPonder) { + if (g_Options.fShouldPonder) { + result = Ponder(&pos); + } + if (FALSE == g_fExitProgram) + { + MakeStatusLine(); + ParseUserInput(FALSE); + } + } + DeclareTerminalStates(result); + } +} + + +int CDECL +main(int argc, char *argv[]) +/** + +Routine description: + + Chess engine entry point and main loop. + +Parameters: + + int argc, + char *argv[] + +Return value: + + int CDECL + +**/ +{ + // Initial setup work... + Trace("Setting up, please wait...\n"); + if (FALSE == SystemDependentInitialization()) + { + Trace("main: Operating system dependent init code failed, " + "aborting.\n"); + exit(-1); + } + if (FALSE == MainProgramInitialization(argc, argv)) + { + Trace("main: Main program init code failed, aborting.\n"); + exit(-1); + } + Banner(); +#ifdef TEST + (void)RunStartupProgramTest(); +#endif + if (TRUE == g_Options.fNoInputThread) + { + InitInputSystemInBatchMode(); + } + else + { + g_uInputThreadHandle = InitInputSystemWithDedicatedThread(); + } + + // Enter the main work loop code... + MainProgramLoop(); + + // If we get here g_fExitProgram is set -- clean up. + Trace("MAIN THREAD: thread terminating.\n"); + if (FALSE == MainProgramCleanup()) + { + Trace("main: Main program cleanup code failed, aborting.\n"); + exit(-1); + } + exit(0); +} diff --git a/src/changes/root.c b/src/changes/root.c new file mode 100755 index 0000000..d38f8c0 --- /dev/null +++ b/src/changes/root.c @@ -0,0 +1,1462 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + root.c + +Abstract: + + Routines dealing with the root of the search tree. Specifically + move ordering at the root node, searching, search support, pondering, + pondering support, and the main iterative deepening loop. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 21 May 2004 + +Revision History: + + $Id: root.c 351 2008-06-28 04:21:53Z scott $ + +**/ + +#include "chess.h" + +volatile MOVE_TIMER g_MoveTimer; +ULONG g_uIterateDepth; +ULONG g_uSoftExtendLimit; +ULONG g_uHardExtendLimit; +ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; +FLAG g_fCanSplit[MAX_PLY_PER_SEARCH]; +extern FILE *g_pfLogfile; +SCORE g_iRootScore[2] = {0, 0}; +SCORE g_iScore; + + +static void +_SetMoveTimerForPonder(void) +/** + +Routine description: + + Set the move timer before a ponder operation. A time limit of -1 + means search forever... so the only way out of the ponder is for + new user input to interrupt it. + +Parameters: + + void + +Return value: + + static void + +**/ +{ + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.dSoftTimeLimit = -1; + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.uNodeCheckMask = 0x200 - 1; + g_MoveTimer.bvFlags = 0; +} + + +void +SetMoveTimerToThinkForever(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + void + +**/ +{ + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.dSoftTimeLimit = -1; + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.uNodeCheckMask = 0x1000000 - 1; + g_MoveTimer.bvFlags = 0; +} + + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor) +/** + +Routine description: + + Set the move timer for a search operation. + +Parameters: + + FLAG fSwitchOver : if TRUE then this search is a converted ponder + (i.e. they made the ponder move and now we are searching). + +Return value: + + void + +**/ +{ + ULONG uMovesDone = GetMoveNumber(uColor); + double dClock = (double)g_Options.uMyClock; + double dSec = 0; + ULONG uMargin = 0; + ULONG uMovesToDo; + + // + // If switching over from a ponder search leave the start time and + // move flags alone (i.e. N seconds in the past already). + // + if (FALSE == fSwitchOver) + { + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.bvFlags = 0; + } + + // + // Check the clock more often in search if there is little time + // left on the clock -- we can't afford an oversearch when the + // bullet game is down to the wire. + // +#ifdef DEBUG + g_MoveTimer.uNodeCheckMask = 0x800 - 1; +#else + if (WeAreRunningASuite()) + { + g_MoveTimer.uNodeCheckMask = 0x20000 - 1; + } + else if (g_Options.u64MaxNodeCount) + { + g_MoveTimer.uNodeCheckMask = 0x1000 - 1; + } + else + { + if (dClock < 10.0) + { + g_MoveTimer.uNodeCheckMask = 0x400 - 1; + } + else + { + g_MoveTimer.uNodeCheckMask = 0x8000 - 1; + } + } +#endif + + switch (g_Options.eClock) + { + // + // Fixed time per move. Think for g_uMyIncrement seconds exactly and + // no hard time limit. + // + case CLOCK_FIXED: + dSec = (double)g_Options.uMyIncrement; + uMargin = 0; + break; + + // + // N moves per time control or entire game in time control. + // + case CLOCK_NORMAL: + if (g_Options.uMovesPerTimePeriod != 0) + { + // + // N moves per time control. + // + ASSERT(g_Options.uMovesPerTimePeriod < 256); + uMovesToDo = + (g_Options.uMovesPerTimePeriod - + ((uMovesDone - 1) % g_Options.uMovesPerTimePeriod)); +#ifdef DEBUG + Trace("SetMoveTimer: %u moves left to do this in %s sec.\n", + uMovesToDo, TimeToString(dClock)); +#endif + ASSERT(uMovesToDo <= g_Options.uMovesPerTimePeriod); + dSec = (dClock / (double)uMovesToDo); + dSec *= 0.95; + uMargin = (ULONG)(dSec * 2.2); + if (uMovesToDo <= 5) + { + dSec *= 0.75; + uMargin /= 2; + } + break; + } + else + { + // + // Fixed time finish entire game. + // +#ifdef DEBUG + Trace("SetMoveTimer: finish the game in %s sec.\n", + TimeToString(dClock)); +#endif + dSec = dClock / 60; + uMargin = (ULONG)(dSec * 2.2); + } + break; + + // + // We get back a certain number of seconds with each move made. + // + case CLOCK_INCREMENT: + dSec = g_Options.uMyIncrement; + dSec += (dClock / 50); + uMargin = (int)(dSec * 2.2); + +#ifdef DEBUG + Trace("SetMoveTimer: finish the game in %s sec (+%u per move).\n", + TimeToString(dClock), g_Options.uMyIncrement); +#endif + + // + // If we are running out of time, think for less than the + // increment. + // + if (dClock < 20.0) + { + dSec -= g_Options.uMyIncrement; + uMargin = 0; + } + ASSERT(dSec > 0); + break; + + case CLOCK_NONE: +#ifdef DEBUG + Trace("SetMoveTimer: no time limit, think until interrupted.\n"); +#endif + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.dSoftTimeLimit = -1; + goto post; + + default: + ASSERT(FALSE); + break; + } + if ((dSec + uMargin) >= (dClock * 7 / 8)) uMargin = 0; + g_MoveTimer.dSoftTimeLimit = g_MoveTimer.dStartTime + dSec; + g_MoveTimer.dHardTimeLimit = g_MoveTimer.dStartTime + dSec + uMargin; + + post: + if (TRUE == g_Options.fShouldPost) + { + if (g_MoveTimer.dSoftTimeLimit > 0) + { + Trace("SetMoveTimer: Soft time limit %s seconds.\n", + TimeToString(g_MoveTimer.dSoftTimeLimit - + g_MoveTimer.dStartTime)); + ASSERT(g_MoveTimer.dHardTimeLimit > 0); + Trace("SetMoveTimer: Hard time limit %s seconds.\n", + TimeToString(g_MoveTimer.dHardTimeLimit - + g_MoveTimer.dStartTime)); + if (TRUE == fSwitchOver) + { + Trace("SetMoveTimer: Already searched %s seconds.\n", + TimeToString(SystemTimeStamp() - + g_MoveTimer.dStartTime)); + } + } +#ifdef DEBUG + Trace("SetMoveTimer: Checking input and timer every %u nodes.\n", + g_MoveTimer.uNodeCheckMask); +#endif + } +} + + +void +ReInitializeSearcherContext(POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Reinitializes a SEARCHER_THREAD_CONTEXT structure. + +Parameters: + + POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + if (NULL != pos) + { + memmove(&(ctx->sPosition), pos, sizeof(POSITION)); + } + ctx->uPly = 0; + ctx->uPositional = 133; + memset(&(ctx->sCounters), 0, sizeof(COUNTERS)); +} + + +void +InitializeSearcherContext(POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Initialize a SEARCHER_THREAD_CONTEXT structure. + +Parameters: + + POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG u; + + memset(ctx, 0, sizeof(SEARCHER_THREAD_CONTEXT)); + ReInitializeSearcherContext(pos, ctx); + ctx->sMoveStack.uUnblockedKeyValue[0] = 1; + for (u = 1; + u < MAX_PLY_PER_SEARCH; + u++) + { + ctx->sMoveStack.uUnblockedKeyValue[u] = + ctx->sMoveStack.uUnblockedKeyValue[u-1] + 0x28F5C28; + } +} + + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx) +/** + +Routine description: + + Initialize a LIGHTWEIGHT_SEARCHER_CONTEXT structure. + +Parameters: + + POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG u; + + memset(ctx, 0, sizeof(LIGHTWEIGHT_SEARCHER_CONTEXT)); + if (NULL != pos) + { + memmove(&(ctx->sPosition), pos, sizeof(POSITION)); + } + ctx->uPly = 0; + ctx->uPositional = 133; + ctx->sMoveStack.uUnblockedKeyValue[0] = 1; + for (u = 1; + u < MAX_PLY_PER_SEARCH; + u++) + { + ctx->sMoveStack.uUnblockedKeyValue[u] = + ctx->sMoveStack.uUnblockedKeyValue[u-1] + 0x28F5C28; + } +} + + +void +PostMoveSearchReport(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Dump a report to stdout after every move. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + +Return value: + + void + +**/ +{ + double d; + char buf[256]; +#ifdef PERF_COUNTERS + double n; +#endif + d = (double)g_MoveTimer.dEndTime - (double)g_MoveTimer.dStartTime + 0.01; + ASSERT(d); + Trace("---------------------------------------------\n" + "Searched for %5.1f seconds, saw %" + COMPILER_LONGLONG_UNSIGNED_FORMAT + " nodes (%" + COMPILER_LONGLONG_UNSIGNED_FORMAT + " qnodes) (%6.0f nps).\n", + d, ctx->sCounters.tree.u64TotalNodeCount, + ctx->sCounters.tree.u64QNodeCount, + ((double)ctx->sCounters.tree.u64TotalNodeCount / d)); + if (g_Options.fThinking) + { + snprintf(buf, ARRAY_LENGTH(buf), "d%u, %s, %3.1fs, %6.0fknps, PV=%s", + ctx->uRootDepth / ONE_PLY, + ScoreToString(ctx->iRootScore), + d, + ((double)ctx->sCounters.tree.u64TotalNodeCount / d / 1000), + ctx->szLastPV); + Trace("tellothers %s\n", buf); + } +#ifdef MP +#ifdef PERF_COUNTERS + if (ctx->sCounters.parallel.uNumSplits > 0) + { + n = (double)ctx->sCounters.parallel.uNumSplits; + Trace("Split %u times total ", + ctx->sCounters.parallel.uNumSplits); + Trace("(~%7.2fx/sec).\n", (n / d)); + d = n + 1; + ASSERT(d); + n = (double)ctx->sCounters.parallel.uNumSplitsTerminated; + Trace(" ...%u (%5.2f percent) terminated early.\n", + ctx->sCounters.parallel.uNumSplitsTerminated, ((n/d) * 100.0)); + DumpHelperIdlenessReport(); + } +#endif +#endif + +#ifdef TEST + AnalyzeFullHashTable(); +#endif +#ifdef PERF_COUNTERS + d = (double)(ctx->sCounters.hash.u64Probes) + 1; + ASSERT(d); + Trace("Hashing percentages: (%5.3f total, %5.3f useful)\n", + ((double)(ctx->sCounters.hash.u64OverallHits) / d) * 100.0, + ((double)(ctx->sCounters.hash.u64UsefulHits) / d) * 100.0); + d = (double)(ctx->sCounters.pawnhash.u64Probes) + 1; + ASSERT(d); + n = (double)(ctx->sCounters.pawnhash.u64Hits); + Trace("Pawn hash hitrate: %5.3f percent.\n", (n/d) * 100.0); + n = (double)(ctx->sCounters.tree.u64NullMoveSuccess); + d = (double)(ctx->sCounters.tree.u64NullMoves) + 1; + ASSERT(d); + Trace("Null move cutoff rate: %5.3f percent.\n", + ((n / d) * 100.0)); +#ifdef TEST_ENDGAME + n = (double)(ctx->sCounters.tree.u64EndgamePruningSuccess); + d = n + (double)(ctx->sCounters.tree.u64EndgamePruningFailures); + if (d != 0.0) + { + Trace("Endgame pruning heuristic success rate was %5.3f percent.\n" + "Endgame pruning heuristic was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64EndgamePruningSuccess, + (ctx->sCounters.tree.u64EndgamePruningSuccess + + ctx->sCounters.tree.u64EndgamePruningFailures)); + } + else + { + Trace("Never used endgame pruning heuristic.\n"); + } +#endif +#ifdef TEST_NULL + n = (double)(ctx->sCounters.tree.u64AvoidNullSuccess); + d = n + (double)(ctx->sCounters.tree.u64AvoidNullFailures); + if (d != 0.0) + { + Trace("Avoid null move heuristic rate was %5.3f percent.\n" + "Avoid null move heuristic was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64AvoidNullSuccess, + (ctx->sCounters.tree.u64AvoidNullSuccess + + ctx->sCounters.tree.u64AvoidNullFailures)); + } + else + { + Trace("Never used the avoid null move heuristic.\n"); + } + n = (double)(ctx->sCounters.tree.u64QuickNullSuccess); + n += (double)(ctx->sCounters.tree.u64QuickNullDeferredSuccess); + d = n + (double)(ctx->sCounters.tree.u64QuickNullFailures); + if (d != 0.0) + { + Trace("Quick null move heuristic rate was %5.3f percent.\n" + "Quick null move heuristic rate was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " (" + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ") / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64QuickNullSuccess, + ctx->sCounters.tree.u64QuickNullDeferredSuccess, + (ctx->sCounters.tree.u64QuickNullSuccess + + ctx->sCounters.tree.u64QuickNullDeferredSuccess + + ctx->sCounters.tree.u64QuickNullFailures)); + } + else + { + Trace("Never used the quick null move heuristic.\n"); + } +#endif + n = (double)ctx->sCounters.tree.u64BetaCutoffsOnFirstMove; + d = (double)ctx->sCounters.tree.u64BetaCutoffs + 1; + Trace("First move beta cutoff rate was %5.3f percent.\n", + ((n / d) * 100.0)); +#ifdef LAZY_EVAL + d = (double)ctx->sCounters.tree.u64LazyEvals; + d += (double)ctx->sCounters.tree.u64FullEvals; + d += (double)ctx->sCounters.tree.u64EvalHashHits; + d += 1; + ASSERT(d); + Trace("Eval percentages: (%5.2f hash, %5.2f lazy, %5.2f full)\n", + ((double)ctx->sCounters.tree.u64EvalHashHits / d) * 100.0, + ((double)ctx->sCounters.tree.u64LazyEvals / d) * 100.0, + ((double)ctx->sCounters.tree.u64FullEvals / d) * 100.0); +#endif + Trace("Extensions: (%u +, %u q+, %u 1mv, %u !kmvs, %u mult+, %u pawn\n" + " %u threat, %u zug, %u sing, %u endg, %u bm, %u recap)\n", + ctx->sCounters.extension.uCheck, + ctx->sCounters.extension.uQExtend, + ctx->sCounters.extension.uOneLegalMove, + ctx->sCounters.extension.uNoLegalKingMoves, + ctx->sCounters.extension.uMultiCheck, + ctx->sCounters.extension.uPawnPush, + ctx->sCounters.extension.uMateThreat, + ctx->sCounters.extension.uZugzwang, + ctx->sCounters.extension.uSingularReplyToCheck, + ctx->sCounters.extension.uEndgame, + ctx->sCounters.extension.uBotvinnikMarkoff, + ctx->sCounters.extension.uRecapture); +#ifdef EVAL_TIME + n = (double)ctx->sCounters.tree.u64CyclesInEval; + Trace("Avg. cpu cycles in eval: %8.1f.\n", (n / d)); +#endif +#endif + fflush(g_pfLogfile); +} + + +SCORE +RootSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth) +/** + +Routine description: + + Search at the root of the whole tree. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth, + +Return value: + + SCORE + +**/ +{ + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + SCORE iBestScore = -INFINITY; + SCORE iInitialAlpha = iAlpha; + MOVE mv; + ULONG x, y; + SCORE iScore; + ULONG uNextDepth; + UINT64 u64StartingNodeCount; + ULONG uNumLegalMoves; + +#ifdef DEBUG + POSITION *pos = &ctx->sPosition; + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT((ctx->uPly == 0) || (ctx->uPly == 1)); // 1 is for under a ponder + memcpy(&pi->sPosition, pos, sizeof(POSITION)); +#endif + + ctx->sCounters.tree.u64TotalNodeCount++; + pi->PV[ctx->uPly] = NULLMOVE; + pi->mvBest = NULLMOVE; + g_MoveTimer.bvFlags |= TIMER_SEARCHING_FIRST_MOVE; +#ifdef DEBUG + Trace("---- depth=%u, a=%d, b=%d ----\n", uDepth / ONE_PLY, iAlpha, iBeta); +#endif + + uNumLegalMoves = 0; + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectMoveAtRoot(ctx, x); + if (ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED) break; + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; + mv = ctx->sMoveStack.mvf[x].mv; + mv.bvFlags |= WouldGiveCheck(ctx, mv); + + if (MakeMove(ctx, mv)) + { + uNumLegalMoves++; + u64StartingNodeCount = ctx->sCounters.tree.u64TotalNodeCount; + + // + // TODO: Fancy recap shit here? + // + + uNextDepth = uDepth - ONE_PLY; + if (IS_CHECKING_MOVE(mv)) + { + uNextDepth += HALF_PLY; + ctx->sPlyInfo[ctx->uPly].iExtensionAmount = HALF_PLY; + } + + ctx->sSearchFlags.fVerifyNullmove = TRUE; + ctx->sSearchFlags.uQsearchDepth = 0; + if (uNumLegalMoves == 1) + { + // + // Move 1, full a..b window + // + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + else + { + // + // Moves 2..N, minimal window search + // + ASSERT(x > 0); + ASSERT(uNumLegalMoves > 1); + iScore = -Search(ctx, -iAlpha - 1, -iAlpha, uNextDepth); + if ((iAlpha < iScore) && (iScore < iBeta)) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + } + ctx->sSearchFlags.fVerifyNullmove = FALSE; + UnmakeMove(ctx, mv); + if (WE_SHOULD_STOP_SEARCHING) + { + iBestScore = INVALID_SCORE; + goto end; + } +#ifdef DEBUG + Trace("%2u. %-8s => node=%" COMPILER_LONGLONG_UNSIGNED_FORMAT + ", predict=%d, actual=%d, ", + x + 1, + MoveToSan(mv, &ctx->sPosition), + u64StartingNodeCount, + ctx->sMoveStack.mvf[x].iValue, + iScore); + ASSERT(PositionsAreEquivalent(&pi->sPosition, &ctx->sPosition)); +#endif + // + // Keep track of how many moves are under each one we + // search and use this as the basis for root move ordering + // next iteration. + // + u64StartingNodeCount = (ctx->sCounters.tree.u64TotalNodeCount - + u64StartingNodeCount); + u64StartingNodeCount >>= 9; + u64StartingNodeCount &= (MAX_INT / 4); + ctx->sMoveStack.mvf[x].iValue = + (SCORE)(u64StartingNodeCount + iScore); +#ifdef DEBUG + Trace("next_predict: %d\n", ctx->sMoveStack.mvf[x].iValue); + ASSERT(iBestScore <= iAlpha); + ASSERT(iAlpha < iBeta); +#endif + if (iScore > iBestScore) + { + iBestScore = iScore; + pi->mvBest = mv; + if (iScore > iAlpha) + { + // + // We have a best move so far. As of now it is + // the one we'll be playing. Also make sure to + // search it first at the next depth. + // +#ifdef DEBUG + Trace("Best so far... root score=%d.\n", iScore); +#endif + ctx->mvRootMove = mv; + ctx->iRootScore = iScore; + ctx->uRootDepth = uDepth; + ctx->sMoveStack.mvf[x].iValue = MAX_INT; + + // + // If there was a previous PV move then knock its + // score down so that it will be considered second + // on the next depth. + // + for (y = ctx->sMoveStack.uBegin[ctx->uPly]; + y < x; + y++) + { + if (ctx->sMoveStack.mvf[y].iValue == MAX_INT) + { + ctx->sMoveStack.mvf[y].iValue /= 2; + } + } + + UpdatePV(ctx, mv); + if (iScore >= iBeta) + { + // + // Root fail high... + // + UpdateDynamicMoveOrdering(ctx, + uDepth, + mv, + iScore, + x + 1); + UtilPrintPV(ctx, iAlpha, iBeta, iScore, mv); + KEEP_TRACK_OF_FIRST_MOVE_FHs(iBestScore == -INFINITY); + ctx->sMoveStack.mvf[x].bvFlags &= ~MVF_MOVE_SEARCHED; + goto end; + } + else + { + // + // Root PV change... + // + UtilPrintPV(ctx, iAlpha, iBeta, iScore, mv); + iAlpha = iScore; + } + } + } + g_MoveTimer.bvFlags &= ~TIMER_SEARCHING_FIRST_MOVE; + } + } + + if (iAlpha == iInitialAlpha) + { + // + // Root fail low... + // + ASSERT(iBestScore <= iAlpha); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + UtilPrintPV(ctx, iAlpha, iBeta, iBestScore, mv); + } + + end: + return(iBestScore); +} + + + +static GAME_RESULT +_DetectPreMoveTerminalStates(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fInCheck, + MOVE *pmv) { + ULONG u; + MOVE mv; + MOVE mvLegal; + ULONG uNumLegal = 0; + GAME_RESULT ret; + + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + pmv->uMove = 0; + + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) { + mv = ctx->sMoveStack.mvf[u].mv; + if (MakeMove(ctx, mv)) { + mvLegal = mv; + uNumLegal += 1; + UnmakeMove(ctx, mv); + if (uNumLegal > 1) { + return ret; + } + } + } + + if (uNumLegal == 1) { + *pmv = mvLegal; + } + if (uNumLegal == 0) { + if (TRUE == fInCheck) { + if (ctx->sPosition.uToMove == WHITE) { + ret.eResult = RESULT_BLACK_WON; + strcpy(ret.szDescription, "black checkmated white"); + return ret; + } + ret.eResult = RESULT_WHITE_WON; + strcpy(ret.szDescription, "white checkmated black"); + return ret; + } + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "stalemate"); + } + return ret; +} + + + +static GAME_RESULT +_DetectPostMoveTerminalStates(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + This function is called by Iterate and MakeTheMove to declare + wins/losses/draws. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG + +**/ +{ + GAME_RESULT ret; + FLAG fInCheck = InCheck(&ctx->sPosition, ctx->sPosition.uToMove); + + // Did we just make the 50th+ move without progress? + if (ctx->sPosition.uFifty >= 100) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "fifty moves without progress"); + return ret; + } + + // Did we just repeat a position for the 3rd time? + if (IsLegalDrawByRepetition()) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "third repetition of position"); + return ret; + } + + // Did we just checkmate or stalemate our opponent? The conditions + // here are the same as PreMove... so call that code. + GenerateMoves(ctx, NULLMOVE, (fInCheck ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + MOVE mvUnused; + return _DetectPreMoveTerminalStates(ctx, + fInCheck, + &mvUnused); +} + + +static void +_IterateSetSearchGlobals(ULONG uDepth) +{ + ULONG u, v; + ULONG uDontSplitLessThan; + + // + // Set some globals that will be used throughout this search. + // + g_uIterateDepth = uDepth; + ASSERT(g_uIterateDepth > 0); + ASSERT(g_uIterateDepth < MAX_PLY_PER_SEARCH); + + // + // For use in scaling back extensions that are very far from + // the root. + // + // Iterate g_Soft g_Hard + // | | | | | | | | | + // 0 1 2 2.5 3 3.5 4 (x Iterate) + // |-------------------|----|----|---------|----... + // |full full full full|-1/4|-1/2|-3/4 -3/4|none... + // + g_uSoftExtendLimit = g_uIterateDepth * 2; + g_uHardExtendLimit = g_uIterateDepth * 4; + for (u = 0; u < MAX_PLY_PER_SEARCH; u++) + { + if (u < g_uSoftExtendLimit) + { + g_uExtensionReduction[u] = 0; + } + else if (u < (g_uSoftExtendLimit + g_uIterateDepth / 2)) + { + g_uExtensionReduction[u] = QUARTER_PLY; + } + else if (u < (g_uSoftExtendLimit + g_uIterateDepth)) + { + g_uExtensionReduction[u] = HALF_PLY; + } + else if (u < g_uHardExtendLimit) + { + g_uExtensionReduction[u] = THREE_QUARTERS_PLY; + } + else + { + g_uExtensionReduction[u] = 5 * ONE_PLY; + } + } + + // + // Determine how much depth we need below a point in the tree in + // order to split the search (which is based on iteration depth). + // + uDontSplitLessThan = (ULONG)((double)(uDepth) * 0.30); + for (v = 0; v < MAX_PLY_PER_SEARCH; v++) + { + g_fCanSplit[v] = ((v + 1) >= uDontSplitLessThan); + } + g_fCanSplit[0] = FALSE; +} + + +#define SKIP_GRADUAL_OPENING 600 +#define INITIAL_HALF_WINDOW 75 +#define FIRST_FAIL_STEP 150 +#define SECOND_FAIL_STEP 375 + +void +_IterateWidenWindow(ULONG uColor, + SCORE iScore, + SCORE *piBound, + ULONG *puState, + int iDir) +{ + SCORE iRoughScore = g_iRootScore[uColor]; + static SCORE _Steps[] = + { + FIRST_FAIL_STEP, + SECOND_FAIL_STEP, + INFINITY + }; + +// Trace("State = %u.\n", *puState); +// Trace("Bound from %d to ", *piBound); + if ((abs(iRoughScore - iScore) > SKIP_GRADUAL_OPENING) || + (*puState == 2)) + { + *piBound = iDir * INFINITY; + *puState = 2; + } + else + { + ASSERT(*puState < 2); + *piBound = iScore; + *piBound += iDir * _Steps[*puState]; + *puState += 1; + } +// Trace("%d.\n", *piBound); +// Trace("State = %u\n", *puState); +} + + +GAME_RESULT Iterate(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Main iterative deepening loop for both thinking and pondering. + Call RootSearch with progressively deeper depths while there is + remaining time, we haven't found a forced mate, and there's no + user interruption. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG : is the game over? + +**/ +{ + ULONG uNumRootFailLows = 0; + ULONG uDepth; + ULONG uFailState = 0; + ULONG uColor; + ULONG u; + SCORE iAlpha = -INFINITY; + SCORE iBeta = +INFINITY; + SCORE iScore; + FLAG fInCheck = InCheck(&(ctx->sPosition), ctx->sPosition.uToMove); + MOVE mv; + GAME_RESULT ret; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); + VerifyPositionConsistency(&board, FALSE); +#endif + + uColor = ctx->sPosition.uToMove; + g_iRootScore[uColor] = GetRoughEvalScore(ctx, iAlpha, iBeta, TRUE); + g_iRootScore[FLIP(uColor)] = -g_iRootScore[uColor]; + + // + // Generate moves here so that RootSearch doesn't have to. + // + ASSERT((ctx->uPly == 0) || (ctx->uPly == 1)); // 1 is under a ponder + ctx->sPlyInfo[ctx->uPly].fInCheck = fInCheck; + GenerateMoves(ctx, NULLMOVE, (fInCheck ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + ASSERT(ctx->sMoveStack.uBegin[0] == 0); + + // + // See if we are sitting at a checkmate or stalemate position; no + // sense searching if so. + // + ret = _DetectPreMoveTerminalStates(ctx, + fInCheck, + &mv); + if (ret.eResult != RESULT_IN_PROGRESS) { + goto end; + } + + // One legal move available? + if (mv.uMove != 0) { + ctx->mvRootMove = mv; + ctx->iRootScore = 0; + ctx->uRootDepth = 0; + ctx->sPlyInfo[0].PV[0] = mv; + ctx->sPlyInfo[0].PV[1] = NULLMOVE; + strcpy(ctx->szLastPV, "only"); + if (!g_Options.fPondering) { + Trace("ONLY MOVE --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + g_MoveTimer.bvFlags |= TIMER_CURRENT_OBVIOUS; + } else { + Trace("ONLY PONDER --> move immediately if prediction correct.\n"); + g_MoveTimer.bvFlags |= TIMER_MOVE_IMMEDIATELY; + g_MoveTimer.bvFlags |= TIMER_CURRENT_OBVIOUS; + } + goto end; + } + + for (uDepth = 1; + uDepth <= g_Options.uMaxDepth; + uDepth++) + { + // + // Re-rank the moves based on nodecounts and mark all moves as + // not yet searched at this depth. + // + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) + { + ctx->sMoveStack.mvf[u].bvFlags &= ~MVF_MOVE_SEARCHED; + } + + // + // Make sure a..b window makes sense and set some other per-depth + // globals used by the search. + // + _IterateSetSearchGlobals(uDepth); + + // + // Try to get a PV for this depth before we're out of time... + // + do + { + if (iBeta > INFINITY) iBeta = +INFINITY; + if (iAlpha < -INFINITY) iAlpha = -INFINITY; + if (iAlpha >= iBeta) iAlpha = iBeta - 1; + iScore = RootSearch(ctx, + iAlpha, + iBeta, + uDepth * ONE_PLY + HALF_PLY); + if (g_MoveTimer.bvFlags & TIMER_STOPPING) break; + mv = ctx->mvRootMove; + + // + // Got a PV, we're done with this depth. + // + if ((iAlpha < iScore) && (iScore < iBeta)) + { + ASSERT(iScore == ctx->iRootScore); + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + iAlpha = iScore - INITIAL_HALF_WINDOW; + iBeta = iScore + INITIAL_HALF_WINDOW; + g_iRootScore[uColor] = iScore; + g_iRootScore[FLIP(uColor)] = -iScore; + g_MoveTimer.bvFlags &= ~TIMER_RESOLVING_ROOT_FH; + g_MoveTimer.bvFlags &= ~TIMER_RESOLVING_ROOT_FL; + uFailState = 0; + (void)CheckTestSuiteMove(mv, iScore, uDepth); + break; + } + + // + // Root fail low? We'll have to research with a wider + // window. + // + else if (iScore <= iAlpha) + { + ASSERT(ctx->mvRootMove.uMove); + g_MoveTimer.bvFlags |= TIMER_RESOLVING_ROOT_FL; + uNumRootFailLows++; + if (uNumRootFailLows > 3) + { + g_MoveTimer.bvFlags |= TIMER_MANY_ROOT_FLS; + } + _IterateWidenWindow(uColor, iScore, &iAlpha, &uFailState, -1); + + // + // Consider all moves again with wider window... + // + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) + { + ctx->sMoveStack.mvf[u].bvFlags &= ~MVF_MOVE_SEARCHED; + } + } + + // + // Must be a root fail high. + // + else + { + ASSERT(iScore >= iBeta); + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + g_MoveTimer.bvFlags |= TIMER_RESOLVING_ROOT_FH; + _IterateWidenWindow(uColor, iScore, &iBeta, &uFailState, +1); + } + } + while(1); // repeat until we run out of time or fall inside a..b + + // + // We are here because either: + // + // 1. we completed a search depth, + // or 2. we ran out of time, + // or 3. there is one legal move and we want to make it immediately, + // or 4. there was user input and we unrolled the search. + // + + // + // TODO: Scale back history between iterative depths? + // + + // + // Mate-in-n when we have searched n? Stop searching. + // + if (IS_VALID_SCORE(iScore) && + (ULONG)abs(iScore) >= (INFINITY - uDepth)) + { + Trace("FORCED MATE --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + + // + // Have we reached user's maxdepth option? Stop searching. + // + if (uDepth >= g_Options.uMaxDepth) + { + Trace("DEPTH LIMIT --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + + // + // Did the move timer expire? Stop searching. + // + if (g_MoveTimer.bvFlags & TIMER_STOPPING) break; + } + g_Options.u64NodesSearched = ctx->sCounters.tree.u64TotalNodeCount; + g_MoveTimer.dEndTime = SystemTimeStamp(); + + // + // Here we are at the end of a search. If we were: + // + // ...Searching then: ...Pondering then: + // + // 1. we ran out of time 1. they made a different move than + // the predicted move and we aborted + // 2. we ran out of depth + // 2. we ran out of depth + // 3. we found a mate-in-n + // 3. we found a mate-in-n + // TODO: node count limit? + // (4. if they made the predicted move + // then we converted to a search) + // + ASSERT(ctx->mvRootMove.uMove); + ASSERT(SanityCheckMove(&board, ctx->mvRootMove)); + if (g_MoveTimer.bvFlags & TIMER_RESOLVING_ROOT_FL) + { + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly] = ctx->mvRootMove; + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly+1] = NULLMOVE; + } + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + end: + return ret; +} + +void +MakeTheMove(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Make the move that search selected in the official game list. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG + +**/ +{ + MOVE mv = ctx->mvRootMove; + ASSERT(mv.uMove); + + if (TRUE == g_Options.fThinking) + { + // + // TODO: keep track of how many moves in a row we are at or + // below a draw score and use this to respond to draw offers. + // + + // + // Was this a search that converted from a ponder? + // + if (TRUE == g_Options.fSuccessfulPonder) + { + if (FALSE == OfficiallyMakeMove(g_Options.mvPonder, 0, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)g_Options.mvPonder.uMove, + NULL, + NULL, + __FILE__, + __LINE__); + } + g_Options.fSuccessfulPonder = FALSE; + } + + // + // Tell the server about our move and actually play it on the + // root board. + // + Trace("move %s\n", MoveToSan(mv, &ctx->sPosition)); + if (FALSE == OfficiallyMakeMove(mv, g_iScore, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)mv.uMove, + NULL, + NULL, + __FILE__, + __LINE__); + } + if (g_Options.fVerbosePosting) + { + PostMoveSearchReport(ctx); + PostMoveTestSuiteReport(ctx); + } + } + g_Options.fPondering = g_Options.fThinking = FALSE; +} + + +GAME_RESULT +Ponder(POSITION *pos) +/** + +Routine description: + + Prepare to ponder. + +Parameters: + + POSITION *pos + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + GAME_RESULT ret; + + InitializeSearcherContext(pos, &ctx); + g_Options.fPondering = TRUE; + g_Options.fThinking = FALSE; + g_Options.fSuccessfulPonder = FALSE; + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + + // + // When do we not want to ponder + // + if ((g_Options.ePlayMode == FORCE_MODE) || (g_Options.uMyClock < 10)) + { + g_Options.fPondering = FALSE; + return ret; + } + + // + // What should we ponder? + // + g_Options.mvPonder = GetPonderMove(pos); + if (g_Options.mvPonder.uMove == 0) + { + g_Options.fPondering = FALSE; + return ret; + } + ASSERT(SanityCheckMove(pos, g_Options.mvPonder)); + + // + // Prepare to ponder by doing some maintenance on the dynamic move + // ordering scheme counters, changing the dirty tag in the hash + // code, and clearing the root nodes-per-move hash. + // + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + // + // Make the move ponder move. + // + if (FALSE == MakeMove(&ctx, g_Options.mvPonder)) + { + ASSERT(FALSE); + g_Options.fPondering = FALSE; + return ret; + } + + // + // TODO: probe the book + // + + _SetMoveTimerForPonder(); + + // + // TODO: Any preEval? + // + + // + // TODO: Set draw value + // + + MakeStatusLine(); +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + ASSERT(ctx.uPly == 1); + ret = Iterate(&ctx); + ASSERT(ctx.uPly == 1); + if (ret.eResult == RESULT_IN_PROGRESS) { + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } else { + return ret; + } +} + + +GAME_RESULT Think(POSITION *pos) +/** + +Routine description: + + Prepare to think. + +Parameters: + + POSITION *pos + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + MOVE mvBook; + CHAR *p; + + InitializeSearcherContext(pos, &ctx); + g_MoveTimer.bvFlags = 0; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + g_Options.fSuccessfulPonder = FALSE; + + // + // Prepare to think by doing some maintenance on the dynamic move + // ordering scheme counters, changing the dirty tag in the hash + // code, and clearing the root nodes-per-move hash. + // + if (NULL != (p = PositionToFen(&(ctx.sPosition)))) + { + Trace("The root position is: %s\n", p); + SystemFreeMemory(p); + } + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + // + // Check the opening book, maybe it has a move for us. + // + if ((g_uBookProbeFailures < 3) && (!WeAreRunningASuite())) + { + mvBook = BookMove(pos, BOOKMOVE_SELECT_MOVE); + if (mvBook.uMove == 0) + { + g_uBookProbeFailures++; + } + else + { + g_uBookProbeFailures = 0; + ASSERT(SanityCheckMove(pos, mvBook)); + ctx.mvRootMove = mvBook; + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } + } + + // + // TODO: Any preEval? + // + + // + // Set time limit for move + // + SetMoveTimerForSearch(FALSE, pos->uToMove); + + // + // TODO: Set draw value + // +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + GAME_RESULT ret = Iterate(&ctx); + if (ret.eResult == RESULT_IN_PROGRESS) { + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } else { + return ret; + } +} diff --git a/src/changes/util.c b/src/changes/util.c new file mode 100755 index 0000000..90431e2 --- /dev/null +++ b/src/changes/util.c @@ -0,0 +1,1254 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + util.c + +Abstract: + + General purpose utility code to support the engine. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: util.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uIterateDepth; +extern ULONG g_uFullWidthDepth; + +#define STATE_UNKNOWN (0) +#define STATE_HEADER (1) +#define STATE_MOVELIST (2) + +CHAR * +ReadNextGameFromPgnFile(FILE *pf) +/** + +Routine description: + + Reads the next game in a PGN file and returns a pointer to it. + +Parameters: + + FILE *pf : open file pointer + +Return value: + + CHAR * : NULL on error, else caller must free via SystemFreeMemory. + +**/ +{ + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + CHAR *p; + long lStartOfGame = -1; + long lEndOfGame = -1; + long lBefore; + ULONG uBytes; + ULONG uState = STATE_UNKNOWN; + + while(1) + { + lBefore = ftell(pf); + if (fgets(buf, ARRAY_LENGTH(buf), pf) <= 0) + { + //Trace("fgets failed, errno=%u.\n", errno); + break; + } + + // + // Skip leading whitespace on this line... + // + p = buf; + while(*p && isspace(*p)) p++; + + if (*p == '\0') + { + // + // We just read a blank line + // + switch(uState) + { + case STATE_UNKNOWN: + break; + + case STATE_HEADER: + uState = STATE_MOVELIST; + break; + + case STATE_MOVELIST: + lEndOfGame = lBefore; + uBytes = lEndOfGame - lStartOfGame; + if (uBytes <= 0) + { + return(NULL); + } + + p = SystemAllocateMemory(uBytes + 1); + ASSERT(p); + fseek(pf, lStartOfGame, SEEK_SET); + if (1 != fread(p, uBytes, 1, pf)) + { + SystemFreeMemory(p); + return(NULL); + } + p[uBytes] = '\0'; + return(p); + } + } + else + { + // + // We saw a non-blank line + // + switch(uState) + { + case STATE_HEADER: + case STATE_MOVELIST: + break; + + case STATE_UNKNOWN: + if (*p == '[') + { + uState = STATE_HEADER; + lStartOfGame = lBefore; + } + break; + } + } + } + return(NULL); +} + + +COMMAND(LearnPsqtFromPgn) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + +Return value: + + FLAG + +**/ +{ + CHAR *szFilename; + ULONG uPSQT[12][128]; + CHAR *pPGN; + FILE *pf = NULL; + DLIST_ENTRY *p; + GAME_MOVE *q; + ULONG x, y, z; + double d; + struct stat s; +#ifdef DEBUG + ULONG uHeap; +#endif + + if (argc < 2) + { + Trace("Error (missing filename)\n"); + return; + } + szFilename = argv[1]; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPsqtFromPgn: file \"%s\" doesn't exist.\n", + szFilename); + return; + } + + if (0 != stat(szFilename, &s)) + { + Trace("Stat failed.\n"); + return; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPsqtFromPgn: error reading file \"%s\".\n", + szFilename); + return; + } + + memset(uPSQT, 0, sizeof(uPSQT)); +#ifdef DEBUG + ResetGameList(); + uHeap = GetHeapMemoryUsage(); +#endif + while((pPGN = ReadNextGameFromPgnFile(pf)) != NULL) + { + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("(%5.2f%% done)\r", d); + + if (TRUE == LoadPgn(pPGN)) + { + p = g_GameData.sMoveList.pFlink; + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if ((q->uNumber > 10) && + (q->uNumber < 50) && + (!q->mv.pCaptured)) + { + uPSQT[q->mv.pMoved - 2][q->mv.cTo] += 1; + } + p = p->pFlink; + } + } + SystemFreeMemory(pPGN); +#ifdef DEBUG + ResetGameList(); + ASSERT(uHeap == GetHeapMemoryUsage()); +#endif + } + fclose(pf); + + z = 0; + for (x = 0; x < 12; x++) + { + for (y = 0; y < 128; y++) + { + if (uPSQT[x][y] > z) + { + z = uPSQT[x][y]; + } + } + } + + Trace("ULONG g_PSQT[12][128] = {\n"); + for (x = 0; x < 12; x++) + { + Trace("// Piece 0x%x (%s)\n", x + 2, PieceAbbrev((PIECE)(x + 2))); + Trace("{\n"); + + for (y = 0; y < 128; y++) + { + if (y % 16 == 0) Trace("\n"); + d = (double)uPSQT[x][y]; + d /= (double)z; + d *= (double)1000.0; + Trace("%4u,", (ULONG)d); + } + Trace("},\n"); + } + Trace("};\n"); +} + + +COMMAND(GeneratePositionAndBestMoveSuite) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + +Return value: + + FLAG + +**/ +{ + CHAR *szFilename; + CHAR *pPGN; + FILE *pf = NULL; + DLIST_ENTRY *p; + GAME_MOVE *q; + SEARCHER_THREAD_CONTEXT *ctx = NULL; + FLAG fPost = g_Options.fShouldPost; + struct stat s; + double d; + POSITION board; + + if (argc < 2) + { + Trace("Error (missing filename)\n"); + goto end; + } + szFilename = argv[1]; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPsqtFromPgn: file \"%s\" doesn't exist.\n", + szFilename); + goto end; + } + + if (0 != stat(szFilename, &s)) + { + Trace("Stat failed.\n"); + goto end; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPsqtFromPgn: error reading file \"%s\".\n", + szFilename); + goto end; + } + + ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT)); + if (NULL == ctx) + { + Trace("Out of memory.\n"); + goto end; + } + + g_Options.fShouldPost = FALSE; + while((pPGN = ReadNextGameFromPgnFile(pf)) != NULL) + { + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("(%5.2f%% done)\r", d); + + if (TRUE == LoadPgn(pPGN)) + { + p = g_GameData.sMoveList.pFlink; + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if ((q->uNumber > 20) && (q->uNumber < 60)) + { + if (FenToPosition(&board, q->szUndoPositionFen)) + { + InitializeSearcherContext(&board, ctx); + g_MoveTimer.bvFlags = 0; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + g_Options.fSuccessfulPonder = FALSE; + + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + g_MoveTimer.uNodeCheckMask = 0x1000 - 1; + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.bvFlags = 0; + g_MoveTimer.dSoftTimeLimit = + g_MoveTimer.dStartTime + 3.0; + g_MoveTimer.dHardTimeLimit = + g_MoveTimer.dStartTime + 3.0; + g_Options.uMaxDepth = MAX_DEPTH_PER_SEARCH - 1; + + // + // TODO: Set draw value + // +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + GAME_RESULT result = Iterate(ctx); + if (result.eResult == RESULT_IN_PROGRESS) { + ASSERT(SanityCheckMove(&board, + ctx->sPlyInfo[0].PV[0])); + Trace("setboard %s\n", q->szUndoPositionFen); + Trace("gmmove %s\n", q->szMoveInSan); + Trace("solution %s\n", + MoveToSan(ctx->sPlyInfo[0].PV[0], &board)); + } + } + } + p = p->pFlink; + } + } + SystemFreeMemory(pPGN); + } + + end: + if (NULL != pf) + { + fclose(pf); + } + + if (NULL != ctx) + { + SystemFreeMemory(ctx); + } + + g_Options.fShouldPost = fPost; +} + + +char * +FindChunk(char *sz, ULONG uTargetChunk) +/** + +Routine description: + + A support routine used by FenToPosition. Used to parse apart a + string and return the Nth chunk of text (delimited by whitespace) + +Parameters: + + char *sz, + ULONG uTargetChunk + +Return value: + + char * + +**/ +{ + char *p = sz; + ULONG u = 0; + + if (0 == uTargetChunk) return(p); + + do + { + // + // Skip whitespace between chunks + // + while(isspace(*p) && *p) p++; + if (!*p) return(NULL); + + u++; + if (u == uTargetChunk) return(p); + + // + // Skip chunks + // + while(!isspace(*p) && &p) p++; + if (!*p) return(NULL); + } + while(1); + +#ifdef DEBUG + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +#endif + return(NULL); +} + + + +CHAR * +ScoreToString(SCORE iScore) +/** + +Routine description: + + Format a chess score as a string that looks like: + + +0.100 + -4.951 + +MATE20 + -MATE4 + +0.000 + + etc... + + Note: NOT thread safe. + +Parameters: + + SCORE iScore + +Return value: + + CHAR * + +**/ +{ + static char szBuf[10]; + ULONG uDist; + + if (abs(iScore) < +NMATE) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), + "%c%u.%02u", + (iScore < 0) ? '-' : '+', + abs(iScore / 100), + abs(iScore % 100)); + return(szBuf); + } + + if (iScore > 0) + { + uDist = +INFINITY - iScore; + uDist /= 2; + if (uDist) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "+MATE%u", uDist); + } + else + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "+MATE"); + } + } + else + { + uDist = +INFINITY + iScore; + uDist /= 2; + if (uDist) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "-MATE%u", uDist); + } + else + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "-MATE"); + } + } + return(szBuf); +} + + + +CHAR * +CoorToString(COOR c) +/** + +Routine description: + + Take a chessboard coordinate and convert it into a string. Note: + NOT thread safe. + +Parameters: + + COOR c + +Return value: + + CHAR * + +**/ +{ + static char buf[3]; + + if (IS_ON_BOARD(c)) + { + buf[0] = 'a' + FILE(c); + buf[1] = '0' + RANK(c); + buf[2] = '\0'; + } + else + { + buf[0] = '-'; + buf[1] = '\0'; + } + return(buf); +} + + +CHAR * +ColorToString(ULONG u) +/** + +Routine description: + + Convert a color into a string ("WHITE" or "BLACK"). Callers + should not mess with the contents of the buffer returned! + +Parameters: + + ULONG u + +Return value: + + char + +**/ +{ + static CHAR *szColor[2] = + { + "BLACK", + "WHITE" + }; + ASSERT(IS_VALID_COLOR(u)); + return(szColor[u]); +} + + +CHAR * +TimeToString(double d) +/** + +Routine description: + + Convert a time value into a string. e.g. + + 00:00:01.021 // seconds with ms + 00:15:21.998 // minutes+seconds + 01:59:23.232 // hours+minutes+sec + 27:08:11:103 // we don't do days + + Note: NOT thread safe. The caller should not mess with the + buffer returned. + +Parameters: + + double d + +Return value: + + CHAR * + +**/ +{ + ULONG uTotalSecs = (ULONG)d; + double dFract = d - (double)uTotalSecs; + ULONG uHours; + ULONG uMinutes; + ULONG uFract; + static char buf[13]; + + dFract *= 1000; + uFract = (int)dFract; + uHours = uTotalSecs / 60 / 60; + uTotalSecs -= uHours * 60 * 60; + uMinutes = uTotalSecs / 60; + uTotalSecs -= uMinutes * 60; + ASSERT(uTotalSecs < 60); + + if (uHours != 0) + { + snprintf(buf, ARRAY_LENGTH(buf), + "%2u:%02u:%02u.%03u", + uHours, uMinutes, uTotalSecs, uFract); + } + else + { + snprintf(buf, ARRAY_LENGTH(buf), + "%02u:%02u.%03u", + uMinutes, uTotalSecs, uFract); + } + return(buf); +} + + +FLAG +BufferIsZeroed(BYTE *p, ULONG u) +/** + +Routine description: + + Verify that a buffer is zeroed out. + +Parameters: + + BYTE *p : buffer start + ULONG u : buffer length + +Return value: + + FLAG + +**/ +{ + while(u) + { + if (*p != (BYTE)0) + { + return(FALSE); + } + p++; + u--; + } + return(TRUE); +} + + +void CDECL +Trace(CHAR *szMessage, ...) +/** + +Routine description: + + Trace a logging message on stdout and to the logfile + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send to logfile + // + if (NULL != g_pfLogfile) + { + fprintf(g_pfLogfile, buf); + } + + // + // Send to stdout + // + fprintf(stdout, buf); + fflush(stdout); +} + + +void CDECL +Log(CHAR *szMessage, ...) +/** + +Routine description: + + Trace a logging message to the logfile only + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send to logfile + // + if (NULL != g_pfLogfile) + { + fprintf(g_pfLogfile, buf); + } +} + + +void CDECL +Bug(CHAR *szMessage, ...) +/** + +Routine description: + + Trace an error message to stderr and the logfile + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send it to logfile + // + if (NULL != g_pfLogfile) + { + fprintf(g_pfLogfile, buf); + fflush(g_pfLogfile); + } + + // + // Send it to stderr + // + fprintf(stderr, buf); + fflush(stderr); +} + + +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine) +/** + +Routine description: + + An assertion handler + +Parameters: + + CHAR *szFile, + UINT uLine + +Return value: + + void + +**/ +{ + Bug("Assertion failure in %s, line %u.\n", szFile, uLine); + BREAKPOINT; +} +#endif + + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock) +/** + +Routine description: + + Atomically acquire a lock or spin trying. + +Parameters: + + ULONG *pSpinlock : a pointer to the lock + +Return value: + + ULONG : the number of times we had to spin + +**/ +{ + ULONG uLoops = 0; + while(0 != LockCompareExchange(pSpinlock, 1, 0)) + { + uLoops++; + } + ASSERT(*pSpinlock == 1); + return(uLoops); +} + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock) +{ + return(0 != LockCompareExchange(pSpinlock, 1, 0)); +} + +void +ReleaseSpinLock(volatile ULONG *pSpinlock) +/** + +Routine description: + + Release a lock so someone else can acquire it. + +Parameters: + + ULONG *pSpinlock : a pointer to the lock + +Return value: + + void + +**/ +{ + ULONG u; + ASSERT(*pSpinlock == 1); + u = LockCompareExchange(pSpinlock, 0, 1); + ASSERT(u == 1); +} + + +FLAG +BackupFile(CHAR *szFile) +/** + +Routine description: + + Backup a file to file.000. If file.000 already exists, back it up + to file.001 etc... + + Note: this function is recursive and can require quite a lot of + stack space. Also it is full of race conditions and should not be + used when some other code may be accessing the filesystem at the + same time. + +Parameters: + + CHAR *szFile : the file to backup + +Return value: + + FLAG + +**/ +{ + ULONG u; + CHAR buf[SMALL_STRING_LEN_CHAR]; + CHAR *p; + + if (TRUE == SystemDoesFileExist(szFile)) + { + if ((strlen(szFile) > 3) && + (isdigit(szFile[0])) && + (isdigit(szFile[1])) && + (isdigit(szFile[2]))) + { + u = (szFile[0] - '0') * 100; + u += (szFile[1] - '0') * 10; + u += szFile[2] - '0' + 1; + p = &(szFile[3]); + } + else + { + u = 0; + p = szFile; + } + snprintf(buf, ARRAY_LENGTH(buf), "%03u%s", u, p); + if (TRUE == SystemDoesFileExist(buf)) + { + BackupFile(buf); + } + return(SystemCopyFile(szFile, buf) && SystemDeleteFile(szFile)); + } + return(FALSE); +} + + +BYTE +Checksum(BYTE *p, ULONG uSize) +/** + +Routine description: + + Compute the checksum of a buffer. + +Parameters: + + BYTE *p, + ULONG uSize + +Return value: + + BYTE + +**/ +{ + BYTE b = 0; + while(uSize) + { + b ^= *p; + p++; + uSize--; + } + return(b); +} + +void +FinishPVTailFromHash(SEARCHER_THREAD_CONTEXT *ctx, + CHAR *buf, + ULONG uLenRemain) +{ + MOVE PV[MAX_PLY_PER_SEARCH]; + MOVE mv; + ULONG uPly = ctx->uPly; + ULONG uLen; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + + if (NULL == g_pHashTable) return; + do + { + mv = GetPonderMove(&ctx->sPosition); + if (mv.uMove == 0) break; + PV[ctx->uPly] = mv; + + uLen = (ULONG)strlen(MoveToSan(mv, &ctx->sPosition)) + 1; + ASSERT(uLen <= 11); + if (uLenRemain <= uLen) break; + strcat(buf, MoveToSan(PV[ctx->uPly], &ctx->sPosition)); + strcat(buf, " "); + uLenRemain -= uLen; + + if (FALSE == MakeMove(ctx, mv)) break; + } + while(1); + + // + // Unmake the moves + // + while(ctx->uPly > uPly) + { + UnmakeMove(ctx, PV[ctx->uPly - 1]); + } + ASSERT(ctx->uPly == uPly); + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); +} + + + +char * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Return a string buffer representing the principle variation. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + CHAR * + +**/ +{ + static CHAR buf[SMALL_STRING_LEN_CHAR]; + ULONG u = ctx->uPly; + ULONG v = u; + MOVE mv; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + + buf[0] = '\0'; + while((mv.uMove = ctx->sPlyInfo[v].PV[u].uMove) != 0) + { + if (mv.uMove == HASHMOVE.uMove) + { + strncat(buf, " ", ARRAY_LENGTH(buf) - strlen(buf) - 1); + FinishPVTailFromHash(ctx, buf, ARRAY_LENGTH(buf) - strlen(buf)); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else if (mv.uMove == RECOGNMOVE.uMove) + { + strncat(buf, "", ARRAY_LENGTH(buf) - strlen(buf) - 1); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else if (mv.uMove == DRAWMOVE.uMove) + { + strncat(buf, "<=>", ARRAY_LENGTH(buf) - strlen(buf) - 1); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else + { + strncat(buf, MoveToSan(mv, &ctx->sPosition), + ARRAY_LENGTH(buf) - strlen(buf)); + strncat(buf, " ", ARRAY_LENGTH(buf) - strlen(buf) - 1); + } + + if (FALSE == MakeMove(ctx, mv)) break; + u++; + + if (strlen(buf) > (SMALL_STRING_LEN_CHAR - 10)) break; + } + + // + // Unmake the moves + // + u--; + while(ctx->uPly > v) + { + UnmakeMove(ctx, ctx->sPlyInfo[v].PV[u]); + u--; + } + ASSERT(ctx->uPly == v); + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); + return(buf); +} + + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *arg1, void *arg2, void *arg3, + char *szFile, ULONG uLine) +{ + Bug("Typhoon PANIC 0x%x (%p, %p, %p, %p)\n" + "Location: %s at line %u\n\n", + uPanicCode, pos, arg1, arg2, arg3, szFile, uLine); + Banner(); + Bug("----------------------------------------------------------------\n"); + switch(uPanicCode) { + case CANNOT_INITIALIZE_SPLIT: + case GOT_ILLEGAL_MOVE_WHILE_PONDERING: + case CANNOT_OFFICIALLY_MAKE_MOVE: + DumpPosition(pos); + DumpMove((ULONG)arg1); + break; + case INITIALIZATION_FAILURE: + Bug("%s\n", (char *)arg1); + break; + default: + break; + } + fflush(stdout); + fflush(g_pfLogfile); + BREAKPOINT; + exit(-1); +} + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv) +/** + +Routine description: + + Print a PV out to stdout and the log. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv + +Return value: + + void + +**/ +{ + double dNow = SystemTimeStamp(); + + ASSERT(ctx->uThreadNumber == 0); + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(IS_VALID_SCORE(iScore)); + + dNow -= g_MoveTimer.dStartTime; + + // + // Set the last PV in the context if we have a root PV or a root + // fail high. + // + if ((iAlpha < iScore) && (iScore < iBeta)) + { + strncpy(ctx->szLastPV, WalkPV(ctx), SMALL_STRING_LEN_CHAR); + } + else if (iScore > iBeta) + { + strncpy(ctx->szLastPV, MoveToSan(mv, &(ctx->sPosition)), + SMALL_STRING_LEN_CHAR); + } + + if ((TRUE == g_Options.fThinking) && (TRUE == g_Options.fShouldPost)) + { + // + // Maybe output the PV. Note: xboard gets confused by PV + // lines that don't match its requirements exactly; if we are + // running under xboard, match its expected format. Otherwise + // be more helpful / verbose. + // + if ((dNow > 0.35) || ((dNow > 0.15) && (g_Options.fVerbosePosting))) + { + if (TRUE == g_Options.fRunningUnderXboard) + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + else if (iScore <= iAlpha) + { + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" FL --\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount); + } + else + { + ASSERT(iScore >= iBeta); + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s ++\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + } + else // !running under xboard + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + Trace("%2u %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + else if (iScore <= iAlpha) + { + Trace("%2u- %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" FL --\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount); + } + else + { + ASSERT(iScore >= iBeta); + Trace("%2u+ %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s ++\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + } + } + } +} diff --git a/src/changes/vars.c b/src/changes/vars.c new file mode 100644 index 0000000..1db4c72 --- /dev/null +++ b/src/changes/vars.c @@ -0,0 +1,483 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + vars.c + +Abstract: + + This is code that implements variables in the engine. Some of + these variables are read only but others can be set by the engine + user to affect certain aspects of engine operation. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 18 May 2004 + +Revision History: + + $Id: vars.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uNumInputEvents; + +typedef void(PUSERVARFUN)(void); + +// +// Here's how we expose engine variables to the user. +// +typedef struct _USER_VARIABLE +{ + char *szName; // variable name + char *szType; // variable type: + // * - char *, strdup/free + // H - hash size + // B - boolean + // U - unsigned + // I - int + // M - move + // D - double + // S - string buffer + void *pValue; // pointer to value + PUSERVARFUN *pFunction; // funct to call when it changes +} USER_VARIABLE; + +extern ULONG g_uBookProbeFailures; + +USER_VARIABLE g_UserVarList[] = +{ + { "AnnounceOpening", + "B", + (void *)&(g_Options.fShouldAnnounceOpening), + NULL }, + { "BatchMode", + "b", + (void *)&(g_Options.fNoInputThread), + NULL }, + { "BlackPlayer", + "*", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].szName), + NULL }, + { "BlackRating", + "U", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].uRating), + NULL }, + { "BlackDescription", + "*", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].szDescription), + NULL }, + { "BlackIsComputer", + "B", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].fIsComputer), + NULL }, + { "BookFileName", + "S", + (void *)&(g_Options.szBookName), + NULL }, + { "BookProbeFailures", + "u", + (void *)&(g_uBookProbeFailures), + NULL }, + { "ComputerTimeRemainingSec", + "U", + (void *)&(g_Options.uOpponentsClock), + NULL }, //&DoVerifyClocks }, + { "EGTBPath", + "S", + (void *)&(g_Options.szEGTBPath), + InitializeEGTB }, + { "FastScript", + "B", + (void *)&(g_Options.fFastScript), + NULL }, + { "GameDescription", + "*", + (void *)&(g_GameData.sHeader.szGameDescription), + NULL }, + { "GameLocation", + "*", + (void *)&(g_GameData.sHeader.szLocation), + NULL }, + { "GameIsRated", + "B", + (void *)&(g_GameData.sHeader.fGameIsRated), + NULL }, + { "GameResultComment", + "*", + (void *)&(g_GameData.sHeader.szResultComment), + NULL }, + { "LastEval", + "I", + (void *)&(g_Options.iLastEvalScore), + NULL }, + { "LogfileName", + "S", + (void *)&(g_Options.szLogfile), + NULL }, + { "MoveToPonder", + "m", + (void *)&(g_Options.mvPonder), + NULL }, + { "MovesPerTimePeriod", + "U", + (void *)&(g_Options.uMovesPerTimePeriod), + NULL }, + { "OpponentTimeRemainingSec", + "U", + (void *)&(g_Options.uMyClock), + NULL }, //&DoVerifyClocks }, + { "PendingInputEvents", + "u", + (void *)&(g_uNumInputEvents), + NULL }, + { "PonderingNow", + "b", + (void *)&(g_Options.fPondering), + NULL }, + { "PostLines", + "B", + (void *)&(g_Options.fShouldPost), + NULL }, + { "Resign", + "B", + (void *)&(g_Options.fShouldResign), + NULL }, + { "SearchDepthLimit", + "U", + (void *)&(g_Options.uMaxDepth), + NULL }, //&DoVerifySearchDepth }, + { "SearchTimeLimit", + "U", + (void *)&(g_Options.uMyIncrement), + NULL }, //&DoVerifySearchTime }, + { "SearchStartedTime", + "d", + (void *)&(g_MoveTimer.dStartTime), + NULL }, + { "SearchSoftTimeLimit", + "d", + (void *)&(g_MoveTimer.dSoftTimeLimit), + NULL }, + { "SearchHardTimeLimit", + "d", + (void *)&(g_MoveTimer.dHardTimeLimit), + NULL }, + { "SearchNodesBetweenTimeCheck", + "u", + (void *)&(g_MoveTimer.uNodeCheckMask), + NULL }, + { "StatusLine", + "B", + (void *)&(g_Options.fStatusLine), + NULL }, + { "ThinkOnOpponentsTime", + "B", + (void *)&(g_Options.fShouldPonder), + NULL }, + { "ThinkingNow", + "b", + (void *)&(g_Options.fThinking), + NULL }, + { "TournamentMode", + "B", + (void *)&(g_fTournamentMode), + NULL }, + { "VerbosePosting", + "B", + (void *)&(g_Options.fVerbosePosting), + NULL }, + { "WhitePlayer", + "*", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].szName), + NULL }, + { "WhiteRating", + "U", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].uRating), + NULL }, + { "WhiteDescription", + "*", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].szDescription), + NULL }, + { "WhiteIsComputer", + "B", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].fIsComputer), + NULL }, + { "Xboard", + "B", + (void *)&(g_Options.fRunningUnderXboard), + NULL } +}; + + + + +COMMAND(SetCommand) +/** + +Routine description: + + This function implements the 'set' engine command. + + Usage: + + set [variable name [value]] + + With no arguments, set dumps a list of all variables and their + current values. + + With one argument, set displays the specified variable's value. + + With two arguments, set changes the value of the specified + variable to the given value. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x, y; + FLAG fFound; + + if (argc == 1) + { + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + switch(toupper(g_UserVarList[x].szType[0])) + { + case 'H': + case 'U': + Trace("%-28s => %u\n", + g_UserVarList[x].szName, + *((unsigned int *)g_UserVarList[x].pValue)); + break; + case 'I': + Trace("%-28s => %d\n", + g_UserVarList[x].szName, + *((int *)g_UserVarList[x].pValue)); + break; + case 'S': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (char *)g_UserVarList[x].pValue); + break; + case 'M': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + MoveToIcs(*((MOVE *)g_UserVarList[x].pValue))); + break; + case 'B': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (*((FLAG *)g_UserVarList[x].pValue) == TRUE) ? + "TRUE" : "FALSE"); + break; + case 'D': + Trace("%-28s => %f\n", + g_UserVarList[x].szName, + *((double *)g_UserVarList[x].pValue)); + break; + case '*': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + *((char **)g_UserVarList[x].pValue)); + break; + default: + Trace("%-28s => ???\n", + g_UserVarList[x].szName); + // ASSERT(FALSE); + break; + } + } + return; + } + else if (argc == 2) + { + fFound = FALSE; + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + if (!STRNCMPI(argv[1], + g_UserVarList[x].szName, + strlen(argv[1]))) + { + fFound = TRUE; + switch(toupper(g_UserVarList[x].szType[0])) + { + case 'H': + case 'U': + Trace("%-28s => %u\n", + g_UserVarList[x].szName, + *((unsigned int *)g_UserVarList[x].pValue)); + break; + case 'I': + Trace("%-28s => %d\n", + g_UserVarList[x].szName, + *((int *)g_UserVarList[x].pValue)); + break; + case 'S': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (char *)g_UserVarList[x].pValue); + break; + case 'M': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + MoveToIcs(*((MOVE *)g_UserVarList[x].pValue))); + break; + case 'B': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (*((FLAG *)g_UserVarList[x].pValue) == TRUE) ? + "TRUE" : "FALSE"); + break; + case 'D': + Trace("%-28s => %f\n", + g_UserVarList[x].szName, + *((double *)g_UserVarList[x].pValue)); + break; + case '*': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + *((char **)g_UserVarList[x].pValue)); + break; + default: + Trace("%-28s => ???\n", + g_UserVarList[x].szName); + // ASSERT(FALSE); + break; + } + } + } + + if (FALSE == fFound) + { + Trace("Error (invalid variable): %s\n", argv[1]); + } + return; + } + else + { + ASSERT(argc > 2); + + fFound = FALSE; + + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + if (!STRNCMPI(argv[1], + g_UserVarList[x].szName, + strlen(argv[1]))) + { + fFound = TRUE; + + if (islower(g_UserVarList[x].szType[0])) + { + Trace("Error (variable is read only): %s\n", + argv[1]); + } + + switch(g_UserVarList[x].szType[0]) + { + case 'H': + y = atoi(argv[2]); + if ((y < 0) || (y & (y - 1))) + { + Trace("Error (invalid size): %d\n", y); + } + else + { + *((int *)g_UserVarList[x].pValue) = y; + } + break; + + case '*': + if (NULL != *((char **)g_UserVarList[x].pValue)) + { + SystemFreeMemory( *((char **)g_UserVarList[x].pValue ) ); + } + *((char **)g_UserVarList[x].pValue) = STRDUP(argv[2]); + if (NULL == *((char **)g_UserVarList[x].pValue)) + { + Trace("Error (out of memory)\n"); + return; + } + break; + + case 'S': + strncpy(((char *)g_UserVarList[x].pValue), + argv[2], + 127); + break; + + case 'U': + y = atoi(argv[2]); + if (y < 0) + { + Trace("Error (invalid value): %d\n", y); + return; + } + *((unsigned *)g_UserVarList[x].pValue) = y; + break; + + case 'I': + y = atoi(argv[2]); + *((int *)g_UserVarList[x].pValue) = y; + break; + + case 'B': + if (toupper(*(argv[2])) == 'T') + { + *((FLAG *)g_UserVarList[x].pValue) = TRUE; + } + else if (toupper(*(argv[2])) == 'F') + { + *((FLAG *)g_UserVarList[x].pValue) = FALSE; + } + else + { + Trace("Error (invalid value, must be TRUE or " + "FALSE): %s\n", argv[2]); + } + break; + + default: + ASSERT(FALSE); + break; + } + + if (NULL != g_UserVarList[x].pFunction) + { + (void)(g_UserVarList[x].pFunction)(); + } + } + } + + if (FALSE == fFound) + { + Trace("Error (invalid variable): %s\n", argv[1]); + } + } +} + +// +// TODO: unset? +// diff --git a/src/chess.h b/src/chess.h new file mode 100755 index 0000000..c815701 --- /dev/null +++ b/src/chess.h @@ -0,0 +1,2981 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + chess.h + +Abstract: + +Author: + + Scott Gasch (scott.gasch@gmail.com) 7 Apr 2004 + +Revision History: + + $Id: chess.h 354 2008-06-30 05:10:08Z scott $ + +**/ + +#ifndef CHESS_ +#define CHESS_ + +#include "compiler.h" + +// +// Datatype wrappers +// +#define MIN_CHAR (0x80) +#define MAX_CHAR (0x7f) +typedef char CHAR; + +#define MIN_BYTE (0x00) +#define MAX_BYTE (0xff) +typedef unsigned char BYTE; + +#define MIN_UCHAR (0x00) +#define MAX_UCHAR (0xff) +typedef unsigned char UCHAR; +#define CAN_FIT_IN_UCHAR(x) ((x) <= MAX_UCHAR) + +#define MIN_SHORT (0x8000) +#define MAX_SHORT (0x7fff) +typedef signed short SHORT; + +#define MIN_USHORT (0x0000) +#define MAX_USHORT (0xffff) +typedef unsigned short USHORT; +#define CAN_FIT_IN_USHORT(x) ((x) <= MAX_USHORT) + +#define MIN_WORD (0x0000) +#define MAX_WORD (0xffff) +typedef unsigned short WORD; + +#define MIN_INT (0x80000000) +#define MAX_INT (0x7fffffff) +typedef signed int INT; + +#define MIN_DWORD (0x00000000) +#define MAX_DWORD (0xffffffff) +typedef unsigned int DWORD; + +#define MIN_UINT (0x00000000) +#define MAX_UINT (0xffffffff) +typedef unsigned int UINT; + +#define MIN_ULONG (0x00000000) +#define MAX_ULONG (0xffffffff) +typedef unsigned int ULONG; + +#define MIN_INT64 (0x8000000000000000) +#define MAX_INT64 (0x7fffffffffffffff) +typedef signed COMPILER_LONGLONG INT64; + +#define MIN_UINT64 (0x0000000000000000) +#define MAX_UINT64 (0xffffffffffffffff) +typedef unsigned COMPILER_LONGLONG UINT64; + +#define MIN_BITBOARD (0x0000000000000000) +#define MAX_BITBOARD (0xffffffffffffffff) +typedef UINT64 BITBOARD; + +#define MIN_BITV MIN_UINT +#define MAX_BITV MAX_UINT +typedef unsigned int BITV; + +#define MIN_FLAG MIN_UINT +#define MAX_FLAG MAX_UINT +typedef unsigned int FLAG; +#define IS_VALID_FLAG(x) (((x) == TRUE) || ((x) == FALSE)) + +typedef unsigned int COOR; +typedef unsigned int PIECE; +typedef signed int SCORE; + +#define BIT1 (0x1) +#define BIT2 (0x2) +#define BIT3 (0x4) +#define BIT4 (0x8) +#define BIT5 (0x10) +#define BIT6 (0x20) +#define BIT7 (0x40) +#define BIT8 (0x80) +#define BIT9 (0x100) +#define BIT10 (0x200) +#define BIT11 (0x400) +#define BIT12 (0x800) +#define BIT13 (0x1000) +#define BIT14 (0x2000) +#define BIT15 (0x4000) +#define BIT16 (0x8000) +#define BIT17 (0x10000) +#define BIT18 (0x20000) +#define BIT19 (0x40000) +#define BIT20 (0x80000) +#define BIT21 (0x100000) +#define BIT22 (0x200000) +#define BIT23 (0x400000) +#define BIT24 (0x800000) +#define BIT25 (0x1000000) +#define BIT26 (0x2000000) +#define BIT27 (0x4000000) +#define BIT28 (0x8000000) +#define BIT29 (0x10000000) +#define BIT30 (0x20000000) +#define BIT31 (0x40000000) +#define BIT32 (0x80000000) + +typedef struct _DLIST_ENTRY +{ + struct _DLIST_ENTRY *pFlink; + struct _DLIST_ENTRY *pBlink; +} DLIST_ENTRY; + +// +// Constants +// +#define YES (1) +#define NO (0) +#ifndef TRUE +#define TRUE (YES) +#endif +#ifndef FALSE +#define FALSE (NO) +#endif + +// +// Calculate the length of an array (i.e. number of elements) +// +#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +#define COMMAND(x) \ + void (x)(CHAR *szInput, ULONG argc, CHAR *argv[], POSITION *pos) +#define MB (1024 * 1024) + +// +// Calculate the address of the base of the structure given its type, and an +// address of a field within the structure. +// +#ifndef OFFSET_OF +#define OFFSET_OF(field, type) \ + (ULONG)(&((type *)0)->field) +#endif +#ifndef CONTAINING_STRUCT +#define CONTAINING_STRUCT(address, type, field) \ + ((type *)((BYTE *)(address) - (BYTE *)(OFFSET_OF(field, type)))) +#endif + +#define WHITE (1) +#define BLACK (0) +#define BAD_COLOR (2) +#define IS_VALID_COLOR(x) (((x) == WHITE) || ((x) == BLACK)) +#define FOREACH_COLOR(x) for((x) = BLACK; (x) < BAD_COLOR; (x)++) +#define RANDOM_COLOR (rand() & 1) +#define FLIP(color) ((color) ^ 1) +#define COLOR_NAME(color) (((color) == WHITE) ? "white" : "black") + +#define MAX_MOVES_PER_PLY (218) +#define MAX_PLY_PER_SEARCH (64) +#define MAX_MOVES_PER_GAME (1024) +#define SMALL_STRING_LEN_CHAR (256) +#define MEDIUM_STRING_LEN_CHAR (8192) +#define BIG_STRING_LEN_CHAR (16384) + +#define QUARTER_PLY 16 +#define HALF_PLY 32 +#define THREE_QUARTERS_PLY 48 +#define ONE_PLY 64 +#define TWO_PLY 128 +#define THREE_PLY 192 +#define FOUR_PLY 256 +#define MAX_DEPTH_PER_SEARCH (MAX_PLY_PER_SEARCH * ONE_PLY) + +#define IS_VALID_DEPTH(x) (((x) >= 0) && \ + ((x) <= MAX_DEPTH_PER_SEARCH) && \ + (((x) & 0xfffff00f) == 0)) + +#define INFINITY (MAX_SHORT) +#define INVALID_SCORE (INFINITY + 1) +#define IS_VALID_SCORE(x) (((x) >= -INFINITY) && \ + ((x) <= +INFINITY)) +#define NMATE (+INFINITY - 200) +#define MATED_SCORE(ply) (-INFINITY + (ply)) + +#define IS_A_POWER_OF_2(x) (((x) & (x - 1)) == 0) +// +// Program version number +// +#define VERSION "1.00" +#define REVISION "$Id: chess.h 354 2008-06-30 05:10:08Z scott $\n" + +// +// Function decorators +// +#define IN +#define OUT +#define INOUT +#define UNUSED +#define NOTHING + +// ---------------------------------------------------------------------- +// +// PIECE: +// +// a piece (4 bits) = type (3 bits) + color (1 bit) +// +// 3 1 0 +// . . . . +// | | | +// type C +// +#define KING (6) // 110X +#define QUEEN (5) // 101X +#define ROOK (4) // 100X +#define BISHOP (3) // 011X +#define KNIGHT (2) // 010X +#define PAWN (1) // 001X +#define EMPTY (0) // 000X + +// (WHATEVER << 1) +#define BLACK_PAWN (2) // 0010 +#define BLACK_KNIGHT (4) // 0100 +#define BLACK_BISHOP (6) // 0110 +#define BLACK_ROOK (8) // 1000 +#define BLACK_QUEEN (10) // 1010 +#define BLACK_KING (12) // 1100 + +// (WHATEVER << 1) | WHITE +#define WHITE_PAWN (3) // 0011 +#define WHITE_KNIGHT (5) // 0101 +#define WHITE_BISHOP (7) // 0111 +#define WHITE_ROOK (9) // 1001 +#define WHITE_QUEEN (11) // 1011 +#define WHITE_KING (13) // 1101 + +#define PIECE_TYPE(p) ((p) >> 1) +#define PIECE_COLOR(p) ((p) & WHITE) +#define RANDOM_PIECE (rand() % 12) + 2; +#define IS_PAWN(p) (((p) & 0xE) == BLACK_PAWN) +#define IS_KNIGHT(p) (((p) & 0xE) == BLACK_KNIGHT) +#define IS_BISHOP(p) (((p) & 0xE) == BLACK_BISHOP) +#define IS_ROOK(p) (((p) & 0xE) == BLACK_ROOK) +#define IS_QUEEN(p) (((p) & 0xE) == BLACK_QUEEN) +#define IS_KING(p) (((p) & 0xE) == BLACK_KING) +#define IS_KNIGHT_OR_KING(p) (((p) & 0x6) == 0x4) +#define IS_VALID_PIECE(p) ((PIECE_TYPE((p)) >= PAWN) && \ + (PIECE_TYPE((p)) <= KING)) +#define IS_WHITE_PIECE(p) ((p) & WHITE) +#define IS_BLACK_PIECE(p) (!IS_WHITE(p)) +#define OPPOSITE_COLORS(p, q) (((p) ^ (q)) & WHITE) +#define SAME_COLOR(p,q) (!OPPOSITE_COLORS(p, q)) +#define GET_COLOR(p) ((p) & WHITE) + +// ---------------------------------------------------------------------- +// +// a coordinate (8 bits) = rank + file (0x88) +// +// 7 4 3 0 +// . . . . . . . . +// | | | +// rank file +// | | +// | +--- 0-7 = file A thru file H +// | +// +------------ 0-7 = rank 1 thru rank 8 +// +// given a coordinate, C, if C & 0x88 then it is illegal (off board) +// +// +// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 +// +---------------------------------------+ +// 8 | 00 |:01:| 02 |:03:| 04 |:05:| 06 |:07:| 0x00 +// 7 |:10:| 11 |:12:| 13 |:14:| 15 |:16:| 17 | 0x10 +// 6 | 20 |:21:| 22 |:23:| 24 |:25:| 26 |:27:| 0x20 +// 5 |:30:| 31 |:32:| 33 |:34:| 35 |:36:| 37 | 0x30 +// 4 | 40 |:41:| 42 |:43:| 44 |:45:| 46 |:47:| 0x40 +// 3 |:50:| 51 |:52:| 53 |:54:| 55 |:56:| 57 | 0x50 +// 2 | 60 |:61:| 62 |:63:| 64 |:65:| 66 |:67:| 0x60 +// 1 |:70:| 71 |:72:| 73 |:74:| 75 |:76:| 77 | 0x70 +// +---------------------------------------+ +// A B C D E F G H +// +#define A (0) +#define B (1) +#define C (2) +#define D (3) +#define E (4) +#define F (5) +#define G (6) +#define H (7) + +#define A8 (0x00) +#define B8 (0x01) +#define C8 (0x02) +#define D8 (0x03) +#define E8 (0x04) +#define F8 (0x05) +#define G8 (0x06) +#define H8 (0x07) + +#define A7 (0x10) +#define B7 (0x11) +#define C7 (0x12) +#define D7 (0x13) +#define E7 (0x14) +#define F7 (0x15) +#define G7 (0x16) +#define H7 (0x17) + +#define A6 (0x20) +#define B6 (0x21) +#define C6 (0x22) +#define D6 (0x23) +#define E6 (0x24) +#define F6 (0x25) +#define G6 (0x26) +#define H6 (0x27) + +#define A5 (0x30) +#define B5 (0x31) +#define C5 (0x32) +#define D5 (0x33) +#define E5 (0x34) +#define F5 (0x35) +#define G5 (0x36) +#define H5 (0x37) + +#define A4 (0x40) +#define B4 (0x41) +#define C4 (0x42) +#define D4 (0x43) +#define E4 (0x44) +#define F4 (0x45) +#define G4 (0x46) +#define H4 (0x47) + +#define A3 (0x50) +#define B3 (0x51) +#define C3 (0x52) +#define D3 (0x53) +#define E3 (0x54) +#define F3 (0x55) +#define G3 (0x56) +#define H3 (0x57) + +#define A2 (0x60) +#define B2 (0x61) +#define C2 (0x62) +#define D2 (0x63) +#define E2 (0x64) +#define F2 (0x65) +#define G2 (0x66) +#define H2 (0x67) + +#define A1 (0x70) +#define B1 (0x71) +#define C1 (0x72) +#define D1 (0x73) +#define E1 (0x74) +#define F1 (0x75) +#define G1 (0x76) +#define H1 (0x77) + +// TODO: if use this anywhere that matters, consider double loop +// and unrolling the inside loop to prevent the multiple +// continue for invalid squares +#define FOREACH_SQUARE(x) for((x) = (A8); (x) <= (H1); (x)++) + +#define IS_ON_BOARD(c) (!((c) & 0x88)) +#define RANDOM_COOR (rand() & 0x77) +#define FILE_RANK_TO_COOR(f, r) (((8 - (r)) << 4) | (f)) +#define RANK(c) (8 - ((c) >> 4)) +#define RANK1(c) (((c) & 0xF0) == 0x70) +#define RANK2(c) (((c) & 0xF0) == 0x60) +#define RANK3(c) (((c) & 0xF0) == 0x50) +#define RANK4(c) (((c) & 0xF0) == 0x40) +#define RANK5(c) (((c) & 0xF0) == 0x30) +#define RANK6(c) (((c) & 0xF0) == 0x20) +#define RANK7(c) (((c) & 0xF0) == 0x10) +#define RANK8(c) (((c) & 0xF0) == 0x00) +#define FILE(c) ((c) & 0x0F) +#define FILEA(c) (((c) & 0x0F) == 0x00) +#define FILEB(c) (((c) & 0x0F) == 0x01) +#define FILEC(c) (((c) & 0x0F) == 0x02) +#define FILED(c) (((c) & 0x0F) == 0x03) +#define FILEE(c) (((c) & 0x0F) == 0x04) +#define FILEF(c) (((c) & 0x0F) == 0x05) +#define FILEG(c) (((c) & 0x0F) == 0x06) +#define FILEH(c) (((c) & 0x0F) == 0x07) +#define IS_WHITE_SQUARE_FR(f, r) (((f) + (r) - 1) & 1) +#define IS_WHITE_SQUARE_COOR(c) (IS_WHITE_SQUARE_FR(FILE(c), RANK(c))) +#define VALID_EP_SQUARE(c) (((c) == ILLEGAL_COOR) || ((c) == 0) || \ + (RANK3(c)) || \ + (RANK6(c))) + +// ---------------------------------------------------------------------- +// +// a move (4 bytes) = from/to, moved, captured, promoted and special +// +// 31 24 23 16 15 12 11 8 7 4 3 0 +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +// | from | to | moved | capt | prom | flags | +// | | | | | +// | | | | | +// | | | | | +// | | +-------+-------+-- type and +// | | color of +// | | piece moved +// | | captured and +// | | promote targ +// +---------------+-- board location where +// move begins and ends +// +// +// Special flag asserted on special move types: +// +// if (special) +// { +// if (moved == PAWN) +// { +// if (promotion) +// { +// move is a promote (w/ or w/o capture) +// } +// else if (capture) +// { +// move is an en passant catpure +// } +// else +// { +// move is a double jump +// } +// } +// else if (moved == KING) +// { +// move is a castle (long or short) +// } +// else +// { +// invalid use of special flag +// } +// } +// +typedef union _MOVE +{ + ULONG uMove; + struct + { + UCHAR cFrom : 8; + UCHAR cTo : 8; + UCHAR pMoved : 4; + UCHAR pCaptured : 4; + UCHAR pPromoted : 4; + UCHAR bvFlags : 4; + }; +} MOVE; + +#define IS_SAME_MOVE(a, b) \ + (((a).uMove & 0x0FFFFFFF) == (((b).uMove & 0x0FFFFFFF))) + +#define MAKE_MOVE(from,to,piece,cap,prom,flags) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20) | \ + ((ULONG)(prom) << 24) | \ + ((ULONG)(flags) << 28)) + +#define MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(from,to,piece,cap) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20)) + +// +// Move flag values: +// +#define MOVE_FLAG_SPECIAL (1) // en pass, prom, castle, double +#define IS_SPECIAL_MOVE(mv) \ + ((mv).uMove & 0x10000000) + +#define IS_CASTLE(mv) \ + (IS_SPECIAL_MOVE(mv) && IS_KING((mv).pMoved)) + +#ifdef DEBUG +#define IS_PROMOTION(mv) \ + (IS_SPECIAL_MOVE(mv) && ((mv).pPromoted)) +#else +#define IS_PROMOTION(mv) \ + ((mv).pPromoted) +#endif + +#define IS_CAPTURE_OR_PROMOTION(mv) \ + ((mv).uMove & 0x0FF00000) + +#define IS_ENPASSANT(mv) \ + (IS_SPECIAL_MOVE(mv) && (mv.pCaptured) && !IS_PROMOTION(mv)) + +#define IS_DOUBLE_JUMP(mv) \ + (IS_SPECIAL_MOVE(mv) && !IS_CAPTURE_OR_PROMOTION(mv)) + +#define MOVE_FLAG_KILLERMATE (2) // killer mate +#define IS_KILLERMATE_MOVE(mv) ((mv).uMove & 0x20000000) + +#define MOVE_FLAG_ESCAPING_CHECK (4) // escaping check +#define IS_ESCAPING_CHECK(mv) ((mv).uMove & 0x40000000) + +#define MOVE_FLAG_CHECKING (8) // checking move +#define IS_CHECKING_MOVE(mv) ((mv).uMove & 0x80000000) + +// ---------------------------------------------------------------------- +// +// Move list +// +#define MAX_MOVE_LIST (MAX_MOVES_PER_GAME + MAX_PLY_PER_SEARCH) + +// ---------------------------------------------------------------------- + +#pragma pack(1) +typedef union _ATTACK_BITV +{ + ULONG uWholeThing; + struct + { + union + { + UCHAR uSmall; + struct + { + UCHAR uNumAttacks : 3; // 0..2 + UCHAR uKing : 1; // 4..7 + UCHAR uQueen : 1; + UCHAR uRook : 1; + UCHAR uMinor : 1; + UCHAR uPawn : 1; + } small; + }; + + // -------------------- + union + { + USHORT uBig; + struct + { + USHORT uKing : 1; // 8..23 + USHORT uQueens : 4; + USHORT uRooks : 4; + USHORT uMinors : 4; + USHORT uPawns : 2; + USHORT uUnusedFlag1 : 1; + } big; + }; + + // ------------------- + union + { + UCHAR uXray; + struct + { + UCHAR uNumXrays : 3; + UCHAR uUnusedFlag2 : 1; + UCHAR uQueen : 1; // 24..28 + UCHAR uRook : 1; + UCHAR uBishop : 1; + UCHAR uUnusedFlag3 : 1; + } xray; + }; + }; +} +ATTACK_BITV; + +#define UNSAFE_FOR_MINOR(x) ((ULONG)((x).uWholeThing) & 0x00000080UL) +#define UNSAFE_FOR_ROOK(x) ((ULONG)((x).uWholeThing) & 0x000000C0UL) +#define UNSAFE_FOR_QUEEN(x) ((ULONG)((x).uWholeThing) & 0x000000E0UL) + +#define PAWN_BIT 0x00000080UL +#define MINOR_BIT 0x00000040UL +#define MINOR_XRAY_BIT 0x40000000UL +#define ROOK_BIT 0x00000020UL +#define ROOK_XRAY_BIT 0x20000000UL +#define QUEEN_BIT 0x00000010UL +#define QUEEN_XRAY_BIT 0x10000000UL + +#define INVALID_PIECE_INDEX (17) +#define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX) + +typedef union _SQUARE +{ + struct + { + PIECE pPiece; + ULONG uIndex; + }; + ATTACK_BITV bvAttacks[2]; +} +SQUARE; +#pragma pack() + +// +// POSITION +// +typedef struct _POSITION +{ + SQUARE rgSquare[128]; // where the pieces are, + // also, the attack table + UINT64 u64NonPawnSig; // hash signature + UINT64 u64PawnSig; // pawn hash signature + ULONG uToMove; // whose turn? + ULONG uFifty; // 50 moves w/o progress = draw + FLAG fCastled[2]; // record when sides have castled + BITV bvCastleInfo; // who can castle how? + COOR cEpSquare; // en-passant capture square + + COOR cPawns[2][8]; // location of pawns on the board + ULONG uPawnMaterial[2]; // pawn material of each side + ULONG uPawnCount[2]; // number of pawns for each side + + COOR cNonPawns[2][16]; // location of pieces on the board + ULONG uNonPawnMaterial[2]; // piece material of each side + ULONG uNonPawnCount[2][8]; // number of non-pawns / type + // 0 and 1 are the sum, + // 2..6 are per PIECE_TYPE + + ULONG uWhiteSqBishopCount[2]; // num bishops on white squares + SCORE iMaterialBalance[2]; // material balance + + // temporary storage space for use in eval + COOR cTrapped[2]; + ULONG uArmyScaler[2]; + ULONG uClosedScaler; + SCORE iScore[2]; + SCORE iReducedMaterialDownScaler[2]; + SCORE iTempScore; + ULONG uMinMobility[2]; + COOR cPiece; + ULONG uMinorsAtHome[2]; + BITBOARD bb; + ULONG uPiecesPointingAtKing[2]; +} +POSITION; + +// +// Castling permission bitvector flags. +// +#define CASTLE_WHITE_SHORT (1) +#define CASTLE_WHITE_LONG (2) +#define WHITE_CAN_CASTLE \ + (CASTLE_WHITE_SHORT | CASTLE_WHITE_LONG) +#define CASTLE_BLACK_SHORT (4) +#define CASTLE_BLACK_LONG (8) +#define BLACK_CAN_CASTLE \ + (CASTLE_BLACK_SHORT | CASTLE_BLACK_LONG) +#define CASTLE_NONE_POSSIBLE (0) +#define CASTLE_ALL_POSSIBLE \ + (WHITE_CAN_CASTLE | BLACK_CAN_CASTLE) + +// ---------------------------------------------------------------------- +// +// Move stack +// +#define MAX_MOVE_STACK (MAX_PLY_PER_SEARCH * \ + MAX_MOVES_PER_PLY) + +// +// Main part of the move stack, triads of moves, their values and flags +// that denote where the values came from +// +#define MVF_MOVE_SEARCHED (1) +#define MVF_EXTEND_MOVE (2) +#define MVF_REDUCE_MOVE (4) +#define MVF_PRUNE_SUBTREE (8) + +typedef struct _MOVE_STACK_MOVE_VALUE_FLAGS +{ + SCORE iValue; + MOVE mv; + BITV bvFlags; +} +MOVE_STACK_MOVE_VALUE_FLAGS; + +typedef struct _KEY_POINTER +{ + int iPointer; + ULONG uKey; +} +KEY_POINTER; + +typedef union _GENERATOR_FLAGS +{ + struct { + UCHAR uMoveCount; + UCHAR uKingMoveCount; + UCHAR uCheckingPieces; + UCHAR uUnused; + }; + ULONG uAllGenFlags; +} +GENERATOR_FLAGS; + +// +// A move stack +// +typedef struct _MOVE_STACK +{ +#ifdef DEBUG + POSITION board[MAX_PLY_PER_SEARCH]; +#endif + // + // Unblocked squares map, used for check detection + // + ULONG uUnblockedKeyValue[MAX_PLY_PER_SEARCH]; + KEY_POINTER sUnblocked[MAX_PLY_PER_SEARCH][128]; + + // + // The main move list, a long series of moves, their values and some + // flag bits to tell search what the values are based upon. + // + MOVE_STACK_MOVE_VALUE_FLAGS mvf[MAX_MOVE_STACK]; + + // + // uBegin[ply] and uEnd[ply] specify the start and end of moves gen- + // erated for a position at ply distance from the root. + // + ULONG uPly; + ULONG uBegin[MAX_PLY_PER_SEARCH]; + ULONG uEnd[MAX_PLY_PER_SEARCH]; + MOVE mvHash[MAX_PLY_PER_SEARCH]; + GENERATOR_FLAGS sGenFlags[MAX_PLY_PER_SEARCH]; +} +MOVE_STACK; + +#define GENERATE_NO_MOVES \ + ctx->sMoveStack.uEnd[ctx->uPly] = \ + ctx->sMoveStack.uBegin[ctx->uPly] + 1; \ + ctx->sMoveStack.uBegin[ctx->uPly + 1] = \ + ctx->sMoveStack.uEnd[ctx->uPly] + +#define GENERATE_ALL_MOVES (1) +#define GENERATE_ESCAPES (2) +#define GENERATE_CAPTURES_PROMS_CHECKS (3) +#define GENERATE_CAPTURES_PROMS (4) +#define GENERATE_DONT_SCORE (5) +#ifdef TEST +#define GENERATE_ALL_MOVES_CHECK_OK (6) +#endif + +#define MOVE_COUNT(ctx, x) \ + (((ctx)->sMoveStack.uEnd[(x)]) - (ctx)->sMoveStack.uBegin[(x)]) +#define ONE_LEGAL_MOVE(ctx, x) \ + (MOVE_COUNT(ctx, x) == 1) +#define NUM_KING_MOVES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uKingMoveCount) +#define NUM_CHECKING_PIECES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces) + + +// ---------------------------------------------------------------------- +// +// Accumulators +// +typedef struct _COUNTERS +{ + struct + { + UINT64 u64Probes; + UINT64 u64OverallHits; + UINT64 u64UsefulHits; + UINT64 u64UpperBoundHits; + UINT64 u64LowerBoundHits; + UINT64 u64ExactScoreHits; + } + hash; + + struct + { + UINT64 u64Probes; + UINT64 u64Hits; + } + pawnhash; + + struct + { + UINT64 u64TotalNodeCount; + UINT64 u64QNodeCount; + UINT64 u64LeafCount; + UINT64 u64TerminalPositionCount; + UINT64 u64BetaCutoffs; + UINT64 u64BetaCutoffsOnFirstMove; + UINT64 u64NullMoves; + UINT64 u64NullMoveSuccess; +#ifdef TEST_NULL + UINT64 u64QuickNullSuccess; + UINT64 u64QuickNullDeferredSuccess; + UINT64 u64QuickNullFailures; + UINT64 u64AvoidNullSuccess; + UINT64 u64AvoidNullFailures; +#endif + UINT64 u64EvalHashHits; + UINT64 u64LazyEvals; + UINT64 u64FullEvals; + UINT64 u64CyclesInEval; + } + tree; + + struct + { + ULONG uNumSplits; + ULONG uNumSplitsTerminated; + } + parallel; + + struct + { + ULONG uPawnPush; + ULONG uCheck; + ULONG uMateThreat; + ULONG uRecapture; + ULONG uOneLegalMove; + ULONG uNoLegalKingMoves; + ULONG uMultiCheck; + ULONG uSingularMove; + ULONG uZugzwang; + ULONG uSingularReplyToCheck; + ULONG uEndgame; + ULONG uBotvinnikMarkoff; + ULONG uQExtend; + } + extension; + + struct + { + ULONG uProbes; + ULONG uHits; + } + egtb; +} +COUNTERS; + +typedef struct _CUMULATIVE_SEARCH_FLAGS +{ + // search + ULONG uNumChecks[2]; // not used + FLAG fInSuspiciousBranch; // not used + FLAG fInReducedDepthBranch; // not used + FLAG fAvoidNullmove; // restore + FLAG fVerifyNullmove; // restore + + // qsearch + ULONG uQsearchDepth; // restore + ULONG uQsearchNodes; // incremental + ULONG uQsearchCheckDepth; // restore + FLAG fCouldStandPat[2]; // restore +} +CUMULATIVE_SEARCH_FLAGS; + +// ---------------------------------------------------------------------- +// +// Searcher thread record +// +typedef struct _SPLIT_INFO +{ + // locks / counters + volatile ULONG uLock; // lock for this split node + volatile ULONG uNumThreadsHelping; // num threads in this node + volatile FLAG fTerminate; // signal helpers to terminate + + // moves in the split node + ULONG uRemainingMoves; // num moves remaining to do + ULONG uOnDeckMove; // next move to do + ULONG uNumMoves; + ULONG uAlreadyDone; + MOVE_STACK_MOVE_VALUE_FLAGS + mvf[MAX_MOVES_PER_PLY]; // the moves to search + + // input to the split node + POSITION sRootPosition; // the root position + MOVE mvPathToHere[MAX_PLY_PER_SEARCH]; // path from root to split + MOVE mvLast; // last move before split + ULONG uDepth; // remaining depth at split + INT iPositionExtend; // positional extension + SCORE iAlpha; // original alpha at split + SCORE iBeta; // beta at split + ULONG uSplitPositional; // pos->uPositional at split + CUMULATIVE_SEARCH_FLAGS sSearchFlags; // flags at split time + + // output from the split node + MOVE mvBest; // the best move + SCORE iBestScore; // it's score + COUNTERS sCounters; // updated counters + MOVE PV[MAX_PLY_PER_SEARCH]; + +#ifdef DEBUG + ULONG uSplitPly; + POSITION sSplitPosition; +#endif +} +SPLIT_INFO; + +typedef struct _PLY_INFO +{ +#ifdef DEBUG + POSITION sPosition; + SCORE iAlpha; + SCORE iBeta; +#endif + SCORE iEval; + INT iExtensionAmount; + FLAG fInCheck; + FLAG fInQsearch; + MOVE mv; + MOVE mvBest; + MOVE PV[MAX_PLY_PER_SEARCH]; + + SCORE iKingScore[2]; + ULONG uMinMobility[2]; + UINT64 u64NonPawnSig; + UINT64 u64PawnSig; + UINT64 u64Sig; + ULONG uFifty; + FLAG fCastled[2]; + ULONG uTotalNonPawns; + BITV bvCastleInfo; + COOR cEpSquare; +} +PLY_INFO; + +#define EVAL_HASH +#ifdef EVAL_HASH +#define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread) +typedef struct _EVAL_HASH_ENTRY +{ + UINT64 u64Key; + SCORE iEval; + ULONG uPositional; + COOR cTrapped[2]; + +} EVAL_HASH_ENTRY; +#endif + +#define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread) +typedef struct _PAWN_HASH_ENTRY +{ + UINT64 u64Key; + BITBOARD bbPawnLocations[2]; + BITBOARD bbPasserLocations[2]; + BITBOARD bbStationaryPawns[2]; + SHORT iScore[2]; + UCHAR uCountPerFile[2][10]; + UCHAR uNumRammedPawns; + UCHAR uNumUnmovedPawns[2]; +} +PAWN_HASH_ENTRY; + +#define NUM_SPLIT_PTRS_IN_CONTEXT (8) + +typedef struct _SEARCHER_THREAD_CONTEXT +{ + ULONG uPly; // its distance from root + ULONG uPositional; // positional component of score + POSITION sPosition; // the board + MOVE_STACK sMoveStack; // the move stack + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; + MOVE mvKiller[MAX_PLY_PER_SEARCH][2]; + MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2]; + MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH]; + COUNTERS sCounters; + ULONG uThreadNumber; + SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT]; + MOVE mvRootMove; + SCORE iRootScore; + ULONG uRootDepth; + PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE]; +#ifdef EVAL_HASH + EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE]; +#endif + CHAR szLastPV[SMALL_STRING_LEN_CHAR]; +} +SEARCHER_THREAD_CONTEXT; + +// +// When I added the pawn hash table and eval hash tables to searcher +// thread contexts they became too heavy to just allocate on the fly +// for things like checking the legality of SAN moves or seeing if an +// opening book line leads to a draw. This +// LIGHTWEIGHT_SEARCHER_CONTEXT structure can be cast into a full +// SEARCHER_THREAD_CONTEXT and passed safely into the Generate, +// MakeMove and UnMakeMove functions because they presently only +// need: +// +// 1. uPly +// 2. sPosition +// 3. sPlyInfo +// 4. sMoveStack +// +typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT +{ + ULONG uPly; + ULONG uPositional; + POSITION sPosition; + MOVE_STACK sMoveStack; + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; +} +LIGHTWEIGHT_SEARCHER_CONTEXT; + +// ---------------------------------------------------------------------- +// +// Global game options +// +typedef struct _GAME_OPTIONS +{ + ULONG uMyClock; + ULONG uOpponentsClock; + FLAG fGameIsRated; + FLAG fOpponentIsComputer; + ULONG uSecPerMove; + ULONG uMaxDepth; + UINT64 u64MaxNodeCount; + FLAG fShouldPonder; + FLAG fPondering; + FLAG fThinking; + FLAG fSuccessfulPonder; + MOVE mvPonder; + FLAG fShouldPost; + FLAG fForceDrawWorthZero; + ULONG uMyIncrement; + ULONG uMovesPerTimePeriod; + CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR]; + FLAG fShouldAnnounceOpening; + SCORE iLastEvalScore; + UINT64 u64NodesSearched; + CHAR szLogfile[SMALL_STRING_LEN_CHAR]; + CHAR szEGTBPath[SMALL_STRING_LEN_CHAR]; + CHAR szBookName[SMALL_STRING_LEN_CHAR]; + ULONG uNumProcessors; + ULONG uNumHashTableEntries; + FLAG fNoInputThread; + FLAG fVerbosePosting; + FLAG fRunningUnderXboard; + FLAG fStatusLine; + FLAG fFastScript; + INT iResignThreshold; + + enum + { + CLOCK_NORMAL = 0, + CLOCK_FIXED, + CLOCK_INCREMENT, + CLOCK_NONE + } + eClock; + + enum + { + GAME_UNKNOWN = 0, + GAME_BULLET, + GAME_BLITZ, + GAME_STANDARD + } + eGameType; + + enum + { + I_PLAY_WHITE = 0, + I_PLAY_BLACK, + FORCE_MODE, + EDIT_MODE, + ANALYZE_MODE + } + ePlayMode; +} +GAME_OPTIONS; +extern GAME_OPTIONS g_Options; + +// ---------------------------------------------------------------------- +// +// Move timer +// + +#define TIMER_SEARCHING_FIRST_MOVE (0x1) +#define TIMER_SEARCHING_IMPORTANT_MOVE (0x2) +#define TIMER_RESOLVING_ROOT_FL (0x4) +#define TIMER_RESOLVING_ROOT_FH (0x8) +#define TIMER_JUST_OUT_OF_BOOK (0x10) +#define TIMER_CURRENT_OBVIOUS (0x20) +#define TIMER_CURRENT_WONT_UNBLOCK (0x40) +#define TIMER_ROOT_POSITION_CRITICAL (0x80) +#define TIMER_MOVE_IMMEDIATELY (0x100) +#define TIMER_MANY_ROOT_FLS (0x200) +#define TIMER_STOPPING (0x400) +#define TIMER_SPLIT_FAILED (0x800) + +typedef struct _MOVE_TIMER +{ + double dStartTime; + double dEndTime; + double dSoftTimeLimit; + double dHardTimeLimit; + ULONG uNodeCheckMask; + volatile BITV bvFlags; +} +MOVE_TIMER; + +// ---------------------------------------------------------------------- +// +// Special move tag literals +// +#define ILLEGALMOVE ((ULONG)0x1DDD8888) + +// +// useful macros +// +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine); + +#define ASSERT(x) if (x) \ + { ; } \ + else \ + { _assert(__FILE__, __LINE__); } +#define VERIFY(x) ASSERT(x) +#else +#define ASSERT(x) ; +#define VERIFY(x) x; +#endif // DEBUG + +#ifdef PERF_COUNTERS +#define INC(x) ((x) += 1) +#else +#define INC(x) +#endif + +#define BREAKPOINT SystemDebugBreakpoint() + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#ifdef _X86_ +// +// Note: MAXU, MINU and ABS_DIFF require arguments with the high order +// bit CLEAR to work right. +// +// These are branchless constructs. MAXU and MINU are equivalent to +// MIN and MAX (with the above restriction on inputs) +// +// MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x). These +// macros have no restiction on argument type. +// +// ABS_DIFF is equivalent to abs(x - y). Again, x and y must have +// their high-order bits CLEAR for this to work. +// +// Note: gcc generates code with cmovs so no need for MAXU/MINU on +// that compiler. +// +#define MINU(x, y) \ + (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y)) +#define MAXU(x, y) \ + (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x)) +#define MIN0(x) \ + ((x) & (((int)(x)) >> 31)) +#define MAX0(x) \ + ((x) & ~(((int)(x)) >> 31)) + + +#define ABS_DIFF(a, b) \ + (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1)) + +#endif // _X86_ + +#ifndef MINU +#define MINU(x, y) (MIN((x), (y))) +#endif + +#ifndef MAXU +#define MAXU(x, y) (MAX((x), (y))) +#endif + +#ifndef MIN0 +#define MIN0(x) (MIN((x), 0)) +#endif + +#ifndef MAX0 +#define MAX0(x) (MAX((x), 0)) +#endif + +#ifndef ABS_DIFF +#define ABS_DIFF(a, b) (abs((a) - (b))) +#endif + +#define FILE_DISTANCE(a, b) (ABS_DIFF(FILE((a)), FILE((b)))) +#define RANK_DISTANCE(a, b) (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4) +#define REAL_DISTANCE(a, b) (MAXU(FILE_DISTANCE((a), (b)), \ + RANK_DISTANCE((a), (b)))) +#ifdef DEBUG +#define DISTANCE(a, b) DistanceBetweenSquares((a), (b)) +#else +#define DISTANCE(a, b) g_pDistance[(a) - (b)] +#endif // DEBUG + +#define IS_EMPTY( square ) (!(square)) +#define IS_OCCUPIED( square ) ((square)) + +#define IS_DEAD( listindex ) ((listindex) > 119) +#define IS_ALIVE( listindex ) ((listindex) <= 119) +#define ILLEGAL_COOR (0x88) +#define EDGE_DISTANCE(c) (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \ + MIN(abs(FILE(c) - 7), FILE(c)))) +#define NOT_ON_EDGE(c) ((((c) & 0xF0) != 0x00) && \ + (((c) & 0xF0) != 0x70) && \ + (((c) & 0x0F) != 0x00) && \ + (((c) & 0x0F) != 0x07)) +#define ON_EDGE(c) (RANK8(c) || \ + RANK1(c) || \ + FILEA(c) || \ + FILEH(c)) +#define CORNER_DISTANCE(c) (MAX(MIN((ULONG)abs(RANK(c) - 7), RANK(c)),\ + MIN((ULONG)abs(FILE(c) - 7), FILE(c)))) +#define IN_CORNER(c) (((c) == A8) || \ + ((c) == A1) || \ + ((c) == H8) || \ + ((c) == H1)) +#define WHITE_CORNER_DISTANCE(c) (MIN(DISTANCE((c), A8), \ + DISTANCE((c), H1))) +#define BLACK_CORNER_DISTANCE(c) (MIN(DISTANCE((c), H8), \ + DISTANCE((c), A1))) +#define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \ + | (7 - ((c) & 0x0F)) +#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a[0]))) +#define MAKE_PSQT(a, b, c, d) (((a) << 24) | ((b) << 16) | \ + ((c) << 8) | (d)) +#define TO64(x) ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3) +#define COOR_TO_BIT_NUMBER(c) (((((c) & 0x70) >> 1) | ((c) & 0x7))) +#define SLOWCOOR_TO_BB(c) (1ULL << COOR_TO_BIT_NUMBER(c)) +#define COOR_TO_BB(c) (BBSQUARE[COOR_TO_BIT_NUMBER(c)]) +#define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7)) +#define BIT_NUMBER_TO_COOR(b) ((((b) & 0xF8) << 1) | ((b) & 7)) + +#define BBRANK88 \ + SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \ + SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \ + SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8) + +#define BBRANK77 \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7) + +#define BBRANK66 \ + SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6) + +#define BBRANK55 \ + SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \ + SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \ + SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5) + +#define BBRANK44 \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4) + +#define BBRANK33 \ + SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3) + +#define BBRANK22 \ + SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \ + SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \ + SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2) + +#define BBRANK11 \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1) + +#define BBFILEA \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8) + +#define BBFILEB \ + SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \ + SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \ + SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8) + +#define BBFILEC \ + SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8) + +#define BBFILED \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8) + +#define BBFILEE \ + SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \ + SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \ + SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8) + +#define BBFILEF \ + SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8) + +#define BBFILEG \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8) + +#define BBFILEH \ + SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \ + SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \ + SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8) + +#define BBRANK72 \ + BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK62 \ + BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK52 \ + BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK42 \ + BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK32 \ + BBRANK33 | BBRANK22 + +#define BBRANK27 \ + BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK37 \ + BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK47 \ + BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK57 \ + BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK67 \ + BBRANK66 | BBRANK77 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// util.c +// +COMMAND(LearnPsqtFromPgn); + +COMMAND(GeneratePositionAndBestMoveSuite); + +CHAR * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx); + +CHAR * +ReadNextGameFromPgnFile(FILE *pf); + +COOR +DistanceBetweenSquares(COOR a, COOR b); + +void CDECL +Trace(CHAR *szMessage, ...); + +void CDECL +Log(CHAR *szMessage, ...); + +void CDECL +Bug(CHAR *szMessage, ...); + +char * +FindChunk(char *sz, ULONG uTargetChunk); + +FLAG +BufferIsZeroed(BYTE *p, ULONG u); + +char * +ColorToString(ULONG u); + +char * +CoorToString(COOR c); + +char * +ScoreToString(SCORE iScore); + +char * +TimeToString(double d); + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock); + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock); + +void +ReleaseSpinLock(volatile ULONG *pSpinLock); + +BYTE +Checksum(BYTE *p, ULONG uSize); + +FLAG +BackupFile(CHAR *szFile); + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv); + +#define CANNOT_INITIALIZE_SPLIT (1) +#define INCONSISTENT_POSITION (2) +#define UNEXPECTED_SYSTEM_CALL_FAILURE (3) +#define SHOULD_NOT_GET_HERE (4) +#define GOT_ILLEGAL_MOVE_WHILE_PONDERING (5) +#define CANNOT_OFFICIALLY_MAKE_MOVE (6) +#define DETECTED_INCORRECT_INITIALIZATION (7) +#define INCONSISTENT_STATE (8) +#define FATAL_ACCESS_DENIED (9) +#define TESTCASE_FAILURE (10) +#define INITIALIZATION_FAILURE (11) + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *a1, + void *a2, + void *a3, + char *file, ULONG line); + + +// +// main.c +// +#define LOGFILE_NAME "typhoon.log" +extern FILE *g_pfLogfile; + +void +Banner(void); + +FLAG +PreGameReset(FLAG fResetBoard); + +// +// system dependent exports (see win32.c or fbsd.c) +// +typedef ULONG (THREAD_ENTRYPOINT)(ULONG); + +#ifdef DEBUG +ULONG +GetHeapMemoryUsage(void); +#endif + +void +SystemDebugBreakpoint(void); + +CHAR * +SystemStrDup(CHAR *p); + +double +SystemTimeStamp(void); + +FLAG +SystemDoesFileExist(CHAR *szFilename); + +void +SystemDeferExecution(ULONG uMs); + +void +SystemFreeMemory(void *pMem); + +void * +SystemAllocateMemory(ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemDependentInitialization(void); + +UINT64 FASTCALL +SystemReadTimeStampCounter(void); + +// +// This routine _must_ implement a full memory fence -- it is used in +// util.c to implement spinlocks. +// +FLAG +SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle); + +FLAG +SystemWaitForThreadToExit(ULONG uThreadHandle); + +FLAG +SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode); + +FLAG +SystemDeleteThread(ULONG uThreadHandle); + +CHAR * +SystemGetDateString(void); + +CHAR * +SystemGetTimeString(void); + +FLAG +SystemCopyFile(CHAR *szSource, CHAR *szDest); + +FLAG +SystemDeleteFile(CHAR *szFile); + +ULONG +SystemCreateLock(void); + +FLAG +SystemDeleteLock(ULONG u); + +FLAG +SystemBlockingWaitForLock(ULONG u); + +FLAG +SystemReleaseLock(ULONG u); + +ULONG +SystemCreateSemaphore(ULONG u); + +FLAG +SystemDeleteSemaphore(ULONG u); + +void +SystemReleaseSemaphoreResource(ULONG u); + +void +SystemObtainSemaphoreResource(ULONG u); + + +// +// fen.c +// +#define STARTING_POSITION_IN_FEN \ + "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + +FLAG +LooksLikeFen(char *szFen); + +char * +PositionToFen(POSITION *p); + +FLAG +FenToPosition(POSITION *p, char *szFen); + +// +// testfen.c +// +#ifdef TEST +void +TestFenCode(void); +#endif + +// +// piece.c +// +// INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN; +#define VALUE_PAWN 100 +#define INVERT_PAWN 900 +#define VALUE_KNIGHT 300 +#define INVERT_KNIGHT 300 +#define VALUE_BISHOP 300 +#define INVERT_BISHOP 300 +#define VALUE_ROOK 500 +#define INVERT_ROOK 180 +#define VALUE_QUEEN 975 +#define INVERT_QUEEN 100 +#define VALUE_KING (INFINITY) +#define INVERT_KING 1 + +#define VALUE_FULL_ARMY (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_QUEEN + VALUE_KING +#define VALUE_MAX_ARMY (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_KING + +typedef struct _PIECE_DATA +{ + ULONG uValue; + ULONG uValueOver100; + ULONG uInvertedValue; + CHAR *szName; +} PIECE_DATA; + +extern PIECE_DATA g_PieceData[8]; + +#define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100) +extern ULONG +PieceValueOver100(PIECE p); + +#define PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uValue) +extern ULONG +PieceValue(PIECE p); + +#define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue) +extern ULONG +PieceInvertedValue(PIECE p); + +CHAR * +PieceAbbrev(PIECE p); + +// +// board.c +// +FLAG +VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError); + +FLAG +PositionsAreEquivalent(POSITION *p1, POSITION *p2); + +CHAR * +DrawTextBoardFromPosition(POSITION *pos); + +void +DumpPosition(POSITION *pos); + +CHAR * +CastleInfoString(BITV bv); + +void +SetRootToInitialPosition(void); + +// +// move.c +// +void +SlidePiece(POSITION *pos, COOR cFrom, COOR cTo); + +PIECE +LiftPiece(POSITION *pos, COOR cSquare); + +void +PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece); + +FLAG +MakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +void +UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +FLAG +MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser); + +void +DumpMove(ULONG u); + +// +// movesup.c +// +#define MOVE_TO_INDEX(mv) (((mv).uMove & 0xFFFF) + \ + (0x10000 * GET_COLOR(mv.pMoved))) + +COOR +FasterExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheckEp(POSITION *pos, + COOR cTest, + COOR cIgnore, + COOR cBlock, + COOR cKing); + +FLAG +IsAttacked(COOR cTest, POSITION *pos, ULONG uSide); + +FLAG +InCheck(POSITION *pos, ULONG uSide); + +FLAG +SanityCheckMove(POSITION *pos, MOVE mv); + +FLAG +LooksLikeFile(CHAR c); + +FLAG +LooksLikeRank(CHAR c); + +FLAG +LooksLikeCoor(CHAR *szData); + +CHAR * +StripMove(CHAR *szMove); + +ULONG +LooksLikeMove(CHAR *szData); + +void FASTCALL +SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +#define NOT_MOVE 0 +#define MOVE_ICS 1 +#define MOVE_SAN 2 + +COMMAND(PerftCommand); + + +// +// testmove.c +// +#ifdef TEST +void +TestLiftPlaceSlidePiece(void); + +void +TestExposesCheck(void); + +void +TestIsAttacked(void); + +void +TestMakeUnmakeMove(void); +#endif + +// +// generate.c +// +#define SORT_THESE_FIRST (0x40000000) +#define FIRST_KILLER (0x20000000) +#define SECOND_KILLER (0x10000000) +#define THIRD_KILLER (0x08000000) +#define FOURTH_KILLER (0x04000000) +#define GOOD_MOVE (0x02000000) +#define STRIP_OFF_FLAGS (0x00FFFFFF) + +extern const int g_iQKDeltas[9]; +extern const int g_iNDeltas[9]; +extern const int g_iBDeltas[5]; +extern const int g_iRDeltas[5]; + +void +GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mvOrderFirst, + ULONG uType); + +FLAG +WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv); + +// +// testgenerate.c +// +#ifdef TEST + +void +PlyTest(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fRootPositionInCheck); + +void +TestMoveGenerator(void); + +void +TestLegalMoveGenerator(void); + +#endif + +// +// sig.c +// +extern UINT64 g_u64SigSeeds[128][7][2]; +extern UINT64 g_u64PawnSigSeeds[128][2]; +extern UINT64 g_u64CastleSigSeeds[16]; +extern UINT64 g_u64EpSigSeeds[9]; + +void +InitializeSigSystem(void); + +UINT64 +ComputePawnSig(POSITION *pos); + +UINT64 +ComputeSig(POSITION *pos); + +// +// mersenne.c +// +void +seedMT(unsigned int seed); + +unsigned int +reloadMT(void); + +unsigned int +randomMT(void); + +// +// data.c +// +typedef struct _VECTOR_DELTA +{ + UCHAR iVector[2]; + signed char iDelta; + signed char iNegDelta; +} +VECTOR_DELTA; + +extern ULONG g_uDistance[256]; +extern ULONG *g_pDistance; +extern VECTOR_DELTA g_VectorDelta[256]; +extern VECTOR_DELTA *g_pVectorDelta; +extern CHAR g_SwapTable[14][32][32]; +extern SCORE _PSQT[14][128]; +extern ULONG g_uSearchSortLimits[]; +extern MOVE NULLMOVE; +extern MOVE HASHMOVE; +extern MOVE RECOGNMOVE; +extern MOVE DRAWMOVE; +extern MOVE MATEMOVE; +extern FLAG g_fIsWhiteSquare[128]; +extern BITBOARD BBFILE[8]; +extern BITBOARD BBRANK[9]; +extern BITBOARD BBWHITESQ; +extern BITBOARD BBBLACKSQ; +extern BITBOARD BBLEFTSIDE; +extern BITBOARD BBRIGHTSIDE; +extern BITBOARD BBSQUARE[64]; +extern BITBOARD BBROOK_PAWNS; +extern BITBOARD BBPRECEEDING_RANKS[8][2]; +extern BITBOARD BBADJACENT_FILES[8]; +extern BITBOARD BBADJACENT_RANKS[9]; + +void +InitializeWhiteSquaresTable(void); + +void +InitializeVectorDeltaTable(void); + +void +InitializeSwapTable(void); + +void +InitializeDistanceTable(void); + +void +InitializeSearchDepthArray(void); + +ULONG +GetSearchSortLimit(ULONG); + +#ifdef DEBUG +#define SEARCH_SORT_LIMIT(x) (GetSearchSortLimit((x))) +#else +#define SEARCH_SORT_LIMIT(x) (g_uSearchSortLimits[(x)]) +#endif + +#ifdef DEBUG +ULONG CheckVectorWithIndex(int i, ULONG uColor); +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + CheckVectorWithIndex(i, color) + +int DirectionBetweenSquaresWithIndex(int i); +#define CHECK_DELTA_WITH_INDEX(i) \ + DirectionBetweenSquaresWithIndex(i) + +int DirectionBetweenSquaresFromTo(COOR, COOR); +#define DIRECTION_BETWEEN_SQUARES(from, to) \ + DirectionBetweenSquaresFromTo(from, to) + +int NegativeDirectionBetweenSquaresWithIndex(int i); +#define NEG_DELTA_WITH_INDEX(i) \ + NegativeDirectionBetweenSquaresWithIndex(i) + +FLAG IsSquareWhite(COOR c); +#define IS_SQUARE_WHITE(c) \ + IsSquareWhite(c) + +#else +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + (g_pVectorDelta[(i)].iVector[(color)]) + +#define CHECK_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iDelta) + +#define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \ + CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo)) + +#define NEG_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iNegDelta) + +#define IS_SQUARE_WHITE(c) \ + (g_fIsWhiteSquare[(c)]) +#endif + +// +// san.c +// +MOVE +ParseMoveSan(CHAR *szInput, + POSITION *pos); + +CHAR * +MoveToSan(MOVE mv, POSITION *pos); + +// +// testsan.c +// +void +TestSan(void); + +// +// list.c +// +void +InitializeListHead(IN DLIST_ENTRY *pListHead); + +FLAG +IsListEmpty(IN DLIST_ENTRY *pListHead); + +FLAG +RemoveEntryList(IN DLIST_ENTRY *pEntry); + +DLIST_ENTRY * +RemoveHeadList(IN DLIST_ENTRY *pListHead); + +DLIST_ENTRY * +RemoveTailList(IN DLIST_ENTRY *pListHead); + +void +InsertTailList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +void +InsertHeadList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +// +// command.c +// +void +ParseUserInput(FLAG fSearching); + +FLAG +InitializeCommandSystem(void); + +void +CleanupCommandSystem(void); + +// +// input.c +// +void +InitInputSystemInBatchMode(void); + +ULONG +InitInputSystemWithDedicatedThread(void); + +void +PushNewInput(CHAR *buf); + +CHAR * +PeekNextInput(void); + +CHAR * +ReadNextInput(void); + +CHAR * +BlockingReadInput(void); + +ULONG +NumberOfPendingInputEvents(void); + +volatile extern FLAG g_fExitProgram; + +// +// ics.c +// +MOVE +ParseMoveIcs(CHAR *szInput, POSITION *pos); + +CHAR * +MoveToIcs(MOVE mv); + +// +// testics.c +// +void +TestIcs(void); + +// +// gamelist.c +// +typedef enum _ERESULT +{ + RESULT_BLACK_WON = -1, + RESULT_DRAW = 0, + RESULT_WHITE_WON = 1, + RESULT_IN_PROGRESS, + RESULT_ABANDONED, + RESULT_UNKNOWN +} ERESULT; + +typedef struct _GAME_RESULT +{ + ERESULT eResult; + CHAR szDescription[256]; +} GAME_RESULT; + +typedef struct _GAME_PLAYER +{ + CHAR *szName; + CHAR *szDescription; + FLAG fIsComputer; + ULONG uRating; +} +GAME_PLAYER; + +typedef struct _GAME_HEADER +{ + CHAR *szGameDescription; + CHAR *szLocation; + GAME_PLAYER sPlayer[2]; + FLAG fGameIsRated; + UINT64 u64OpeningSig; + GAME_RESULT result; + CHAR *szInitialFen; +} +GAME_HEADER; + +typedef struct _GAME_MOVE +{ + DLIST_ENTRY links; + ULONG uNumber; + MOVE mv; + CHAR *szComment; + CHAR *szDecoration; + CHAR *szMoveInSan; + CHAR *szMoveInIcs; + CHAR *szUndoPositionFen; + SCORE iMoveScore; + UINT64 u64PositionSigAfterMove; + UINT64 u64PositionSigBeforeMove; + volatile FLAG fInUse; +} +GAME_MOVE; + +typedef struct _GAME_DATA +{ + GAME_HEADER sHeader; + DLIST_ENTRY sMoveList; +} +GAME_DATA; + +extern GAME_DATA g_GameData; + +POSITION * +GetRootPosition(void); + +FLAG +SetRootPosition(CHAR *szFen); + +void +ResetGameList(void); + +ULONG +GetMoveNumber(ULONG uColor); + +void +SetGameResultAndDescription(GAME_RESULT result); + +GAME_RESULT +GetGameResult(void); + +void +SetMyName(void); + +void +SetOpponentsName(CHAR *sz); + +void +SetMyRating(ULONG u); + +void +SetOpponentsRating(ULONG u); + +void +DumpGameList(void); + +void +TellGamelistThatIPlayColor(ULONG u); + +void +DumpPgn(void); + +FLAG +LoadPgn(CHAR *szPgn); + +ULONG +CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig); + +FLAG +DoesSigAppearInOfficialGameList(UINT64 u64Sig); + +FLAG +OfficiallyTakebackMove(void); + +FLAG +OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast); + +GAME_MOVE * +GetNthOfficialMoveRecord(ULONG n); + +void +MakeStatusLine(void); + +FLAG +IsLegalDrawByRepetition(void); + +// +// script.c +// +COMMAND(ScriptCommand); + +COMMAND(SolutionCommand); + +COMMAND(AvoidCommand); + +COMMAND(IdCommand); + +void +PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *); + +FLAG +CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth); + +FLAG +WeAreRunningASuite(void); + + +// +// vars.c +// +COMMAND(SetCommand); + +// +// root.c +// +extern ULONG g_uSoftExtendLimit; +extern ULONG g_uHardExtendLimit; +extern volatile MOVE_TIMER g_MoveTimer; +extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; + +#ifdef PERF_COUNTERS +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) \ + ctx->sCounters.tree.u64BetaCutoffs++; \ + if (x) \ + { \ + ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\ + } +#else +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) +#endif + +#define GAME_NOT_OVER 0 +#define GAME_WHITE_WON 1 +#define GAME_BLACK_WON 2 +#define GAME_DRAW_STALEMATE 3 +#define GAME_DRAW_REPETITION 4 +#define GAME_ONE_LEGAL_MOVE 5 +#define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6 + +GAME_RESULT +Think(POSITION *pos); + +GAME_RESULT +Ponder(POSITION *pos); + +GAME_RESULT +Iterate(SEARCHER_THREAD_CONTEXT *ctx); + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor); + +void +SetMoveTimerToThinkForever(void); + +void +ClearRootNodecountHash(void); + +// +// draw.c +// +FLAG +IsDraw(SEARCHER_THREAD_CONTEXT *ctx); + + +// +// search.c +// +#define QPLIES_OF_NON_CAPTURE_CHECKS (1) +#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100) +#define DO_IID +#define IID_R_FACTOR (TWO_PLY + HALF_PLY) + +#ifndef MP +#define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING) +#else +#define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \ + (ThreadUnderTerminatingSplit(ctx))) +#endif + +SCORE FASTCALL +QSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta); + +SCORE FASTCALL +Search(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth); + + +// +// searchsup.c +// +SCORE +ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv, + IN ULONG uMoveNum); + +FLAG +ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *); + +FLAG +WeShouldDoHistoryPruning(IN SCORE iRoughEval, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN ULONG uLegalMoves, + IN MOVE mv, + IN ULONG uMoveNum, + IN INT iExtend); + +FLAG +WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SCORE iRoughEval, + IN ULONG uNullDepth); + +FLAG +TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN OUT FLAG *pfThreat, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uNullDepth, + IN OUT INT *piOrigExtend, + OUT SCORE *piNullScore); + +void +UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv); + +FLAG +CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx); + +void +ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uGenFlags, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN SCORE iAlpha, + IN OUT INT *piExtend, + IN OUT INT *piOrigExtend); + +void +ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN ULONG uDepth, + IN OUT INT *piExtend); + +SCORE +RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uDepth, + IN SCORE iAlpha, + IN SCORE iBeta); + +FLAG +MateDistancePruningCutoff(IN ULONG uPly, + IN FLAG fInCheck, + IN OUT SCORE *piBestScore, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta); + +FLAG +CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta, + IN OUT SCORE *piScore); + +ULONG +SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx, + IN INT uDepth); + +#define VERIFY_BEFORE (1) +#define VERIFY_AFTER (2) + +FLAG +SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uCurrent, + IN ULONG uType); + + +// +// testsearch.c +// +FLAG +TestSearch(void); + +// +// see.c +// +#define SEE_HEAPS + +SCORE +SEE(POSITION *pos, + MOVE mv); + +typedef struct _SEE_THREESOME +{ + PIECE pPiece; + COOR cLoc; + ULONG uVal; +} SEE_THREESOME; + +typedef struct _SEE_LIST +{ + ULONG uCount; + SEE_THREESOME data[16]; +} +SEE_LIST; + +SCORE +ControlsSquareMinusPiece(ULONG uSide, + POSITION *pos, + COOR c, + COOR cIgnore); + +// +// testsee.c +// +SCORE +DebugSEE(POSITION *pos, + MOVE mv); + +void +TestGetAttacks(void); + +// +// hash.c +// +#define NUM_HASH_ENTRIES_PER_LINE 4 +#define HASH_FLAG_EXACT 0x1 +#define HASH_FLAG_LOWER 0x2 +#define HASH_FLAG_UPPER 0x4 +#define HASH_FLAG_VALID_BOUNDS 0x7 +#define HASH_FLAG_THREAT 0x8 +#define HASH_FLAG_DIRTY 0xF0 + +typedef struct _HASH_ENTRY +{ + MOVE mv; // 0 1 2 3 + UCHAR uDepth; // 4 + UCHAR bvFlags; // 5 ==> d d d d | thr up low exact + signed short iValue; // 6 7 + UINT64 u64Sig; // 8 9 A B C D E F == 16 bytes +} HASH_ENTRY; + +FLAG +InitializeHashSystem(void); + +void +CleanupHashSystem(void); + +void +ClearHashTable(void); + +void +DirtyHashTable(void); + +void +StoreLowerBound(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); +void +StoreExactScore(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat, + ULONG uPly); + +void +StoreUpperBound(//MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); + +HASH_ENTRY * +HashLookup(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + ULONG uNextDepth, + SCORE iAlpha, + SCORE iBeta, + FLAG *pfThreat, + FLAG *pfAvoidNull, + MOVE *pHashMove, + SCORE *piScore); + +COOR +CheckHashForDangerSquare(POSITION *pos); + +MOVE +GetPonderMove(POSITION *pos); + +extern ULONG g_uHashTableSizeEntries; +extern ULONG g_uHashTableSizeBytes; +extern HASH_ENTRY *g_pHashTable; + +// +// testhash.c +// +void +AnalyzeFullHashTable(void); + +// +// positionhash.c +// +// IDEA: store "mate threat" flag in here? +// IDEA: store "king safety" numbers in here? +// +typedef struct _POSITION_HASH_ENTRY { + UINT64 u64Sig; + UCHAR cEnprise[2]; + UCHAR uEnpriseCount[2]; + UCHAR cTrapped[2]; +} POSITION_HASH_ENTRY; + +void +InitializePositionHashSystem(void); + +void +CleanupPositionHashSystem(void); + +void +StoreEnprisePiece(POSITION *pos, COOR cSquare); + +void +StoreTrappedPiece(POSITION *pos, COOR cSquare); + +COOR +GetEnprisePiece(POSITION *pos, ULONG uSide); + +ULONG +GetEnpriseCount(POSITION *pos, ULONG uSide); + +COOR +GetTrappedPiece(POSITION *pos, ULONG uSide); + +FLAG +SideCanStandPat(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide); + +// +// pawnhash.c +// +#define COOR_TO_BIT(x) ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3) + +void +ClearPawnHashStats(void); + +void +ReportPawnHashStats(void); + +PAWN_HASH_ENTRY * +PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx); + +// +// eval.c +// +#define LAZY_EVAL +#define LAZE_EVAL_BASE_SCORE 10 +extern const int g_iAhead[2]; +extern const int g_iBehind[2]; + +ULONG +DNABufferSizeBytes(); + +char * +ExportEvalDNA(); + +FLAG +WriteEvalDNA(char *szFilename); + +FLAG +ImportEvalDNA(char *p); + +FLAG +ReadEvalDNA(char *szFilename); + + + +SCORE +Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE); + +FLAG +EvalPasserRaces(POSITION *, + PAWN_HASH_ENTRY *); + +ULONG +CountKingSafetyDefects(POSITION *pos, + ULONG uSide); + +// +// testeval.c +// +#ifdef EVAL_DUMP +void +TestEval(void); + +void +EvalTraceReport(void); + +void +EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage); + +SCORE +EvalSigmaForPiece(POSITION *pos, COOR c); + +void +EvalTraceClear(void); + +void +TestEvalWithSymmetry(void); + +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); \ + EvalTrace((COL), (PIE), (COO), (ADJ), (MESS)); +#else +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); +#endif + +// +// bitboard.c +// +void +InitializeBitboards(void); + +ULONG CDECL +SlowCountBits(BITBOARD bb); + +ULONG CDECL +DeBruijnFirstBit(BITBOARD bb); + +ULONG CDECL +SlowFirstBit(BITBOARD bb); + +ULONG CDECL +SlowLastBit(BITBOARD bb); + +#ifdef CROUTINES +#define CountBits SlowCountBits +#define FirstBit SlowFirstBit +#define LastBit SlowLastBit +#endif + +COOR +CoorFromBitBoardRank8ToRank1(BITBOARD *pbb); + +COOR +CoorFromBitBoardRank1ToRank8(BITBOARD *pbb); + +// +// x86.asm +// +ULONG CDECL +CountBits(BITBOARD bb); + +ULONG CDECL +FirstBit(BITBOARD bb); + +ULONG CDECL +LastBit(BITBOARD bb); + +ULONG CDECL +LockCompareExchange(volatile void *pDest, + ULONG uExch, + ULONG uComp); + +ULONG CDECL +LockIncrement(volatile void *pDest); + +ULONG CDECL +LockDecrement(volatile void *pDest); + +FLAG CDECL +CanUseParallelOpcodes(); + +ULONG CDECL +ParallelCompareUlong(ULONG uComparand, void *pComparators); + +ULONG CDECL +ParallelCompareVector(void *pComparand, void *pComparators); + +void CDECL +GetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); + +void CDECL +SlowGetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); +#ifdef CROUTINES +#define GetAttacks SlowGetAttacks +#endif + +#ifdef _X86_ +// +// Note: this is most of the stuff that x86.asm assumes about the +// internal data structures. If any of this fails then either the +// assembly language code needs to be updated or you need to use the C +// version of the routine in see.c instead. +// +#define ASSERT_ASM_ASSUMPTIONS \ + ASSERT(VALUE_PAWN == 100); \ + ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \ + ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \ + ASSERT(sizeof(SEE_THREESOME) == 12); \ + ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \ + ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \ + ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \ + ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \ + ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \ + ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \ + ASSERT(sizeof(SQUARE) == 8); \ + ASSERT(sizeof(VECTOR_DELTA) == 4); \ + ASSERT(sizeof(g_VectorDelta) == 256 * 4); \ + ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \ + ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \ + ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \ + ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \ + ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0); +#else +#define ASSERT_ASM_ASSUMPTIONS +#endif + +// +// testbitboard.c +// +void +TestBitboards(void); + +// +// dynamic.c +// +extern ULONG g_HistoryCounters[14][128]; + +ULONG +GetMoveFailHighPercentage(MOVE mv); + +void +UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uRemainingDepth, + MOVE mvBest, + SCORE iScore, + ULONG uCurrent); + +void +NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore); + +FLAG +InitializeDynamicMoveOrdering(void); + +void +CleanupDynamicMoveOrdering(void); + +void +ClearDynamicMoveOrdering(void); + +void +MaintainDynamicMoveOrdering(void); + +void +IncrementMoveHistoryCounter(MOVE mv, ULONG u); + +void +DecrementMoveHistoryCounter(MOVE mv, ULONG u); + +// +// split.c +// +extern volatile ULONG g_uNumHelpersAvailable; +extern ULONG g_uNumHelperThreads; + +FLAG +InitializeParallelSearch(void); + +FLAG +CleanupParallelSearch(void); + +void +ClearHelperThreadIdleness(void); + +void +DumpHelperIdlenessReport(void); + +SCORE +StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN SCORE iBeta, + IN OUT SCORE *piBestScore, + IN OUT MOVE *pmvBest, + IN ULONG uMoveNum, + IN INT iPositionExtend, + IN ULONG uDepth); + +void +InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx); + +// +// book.c +// + +#define BOOK_PROBE_MISS_LIMIT (7) +#define FLAG_DISABLED (1) +#define FLAG_ALWAYSPLAY (2) +#define FLAG_DELETED (4) + +#define BOOKMOVE_SELECT_MOVE (1) +#define BOOKMOVE_DUMP (2) + +#pragma pack(4) +typedef struct _BOOK_ENTRY +{ + UINT64 u64Sig; // 8 bytes + UINT64 u64NextSig; // 8 bytes + MOVE mvNext; // 4 bytes + ULONG uWins; // 4 bytes + ULONG uDraws; // 4 bytes + ULONG uLosses; // 4 bytes + BITV bvFlags; // 4 bytes +} +BOOK_ENTRY; +#pragma pack() + +typedef struct _OPENING_NAME_MAPPING +{ + UINT64 u64Sig; + CHAR *szString; +} +OPENING_NAME_MAPPING; + +#define BOOK_EDITING_RECORD "bkedit.edt" +#define OPENING_LEARNING_FILENAME "bklearn.bin" + +typedef struct _OPENING_LEARNING_ENTRY +{ + UINT64 u64Sig; + ULONG uWhiteWins; + ULONG uDraws; + ULONG uBlackWins; +} +OPENING_LEARNING_ENTRY; + +FLAG +InitializeOpeningBook(void); + +void +ResetOpeningBook(void); + +void +CleanupOpeningBook(void); + +MOVE +BookMove(POSITION *pos, + BITV bvFlags); + +COMMAND(BookCommand); + +extern ULONG g_uBookProbeFailures; +extern FLAG g_fTournamentMode; +extern CHAR *g_szBookName; + +// +// bench.c +// +COMMAND(BenchCommand); + +// +// testdraw.c +// +void +TestDraw(void); + +// +// probe.c +// +FLAG +ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score); + +void +InitializeEGTB(void); + +void +CleanupEGTB(void); + +// +// dumptree.c +// +#ifdef DUMP_TREE + +void +InitializeTreeDump(void); + +void +CleanupTreeDump(void); + +void +DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fIsQNode, + SCORE iAlpha, + SCORE iBeta); + +void +DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fQNode, + SCORE iBestScore, + MOVE mvBestMove); + +void CDECL +DTTrace(ULONG uPly, CHAR *szMessage, ...); + +#define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__) + +#else + +#define DTTRACE(...) + +#define DTEnterNode(...) + +#define DTLeaveNode(...) + +#define InitializeTreeDump(...) + +#define CleanupTreeDump(...) + +#endif + +// +// testsup.c +// +FLAG +IsBoardLegal(POSITION *pos); + +void +GenerateRandomLegalPosition(POSITION *pos); + +void +GenerateRandomLegalSymetricPosition(POSITION *pos); + +// +// recogn.c +// +#define UNRECOGNIZED (0) +#define RECOGN_EXACT (1) +#define RECOGN_UPPER (2) +#define RECOGN_LOWER (3) +#define RECOGN_EGTB (4) + +void +InitializeInteriorNodeRecognizers(void); + +ULONG +RecognLookup(SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore, + FLAG fProbeEGTB); + +#ifdef EVAL_HASH +void +ClearEvalHashStats(void); + +void +ReportEvalHashStats(void); + +SCORE +ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx); + +SCORE +GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash); + +void +StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore); +#endif // EVAL_HASH + +#endif // CHESS diff --git a/src/chess.hbak b/src/chess.hbak new file mode 100755 index 0000000..e64569a --- /dev/null +++ b/src/chess.hbak @@ -0,0 +1,2988 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + chess.h + +Abstract: + +Author: + + Scott Gasch (scott@wannabe.guru.org) 7 Apr 2004 + +Revision History: + + $Id: chess.h 344 2007-11-30 06:49:50Z scott $ + +**/ + +#ifndef CHESS_ +#define CHESS_ + +#include "compiler.h" + +// +// Datatype wrappers +// +#define MIN_CHAR (0x80) +#define MAX_CHAR (0x7f) +typedef char CHAR; + +#define MIN_BYTE (0x00) +#define MAX_BYTE (0xff) +typedef unsigned char BYTE; + +#define MIN_UCHAR (0x00) +#define MAX_UCHAR (0xff) +typedef unsigned char UCHAR; +#define CAN_FIT_IN_UCHAR(x) ((x) <= MAX_UCHAR) + +#define MIN_SHORT (0x8000) +#define MAX_SHORT (0x7fff) +typedef signed short SHORT; + +#define MIN_USHORT (0x0000) +#define MAX_USHORT (0xffff) +typedef unsigned short USHORT; +#define CAN_FIT_IN_USHORT(x) ((x) <= MAX_USHORT) + +#define MIN_WORD (0x0000) +#define MAX_WORD (0xffff) +typedef unsigned short WORD; + +#define MIN_INT (0x80000000) +#define MAX_INT (0x7fffffff) +typedef signed int INT; + +#define MIN_DWORD (0x00000000) +#define MAX_DWORD (0xffffffff) +typedef unsigned int DWORD; + +#define MIN_UINT (0x00000000) +#define MAX_UINT (0xffffffff) +typedef unsigned int UINT; + +#define MIN_ULONG (0x00000000) +#define MAX_ULONG (0xffffffff) +typedef unsigned int ULONG; + +#define MIN_INT64 (0x8000000000000000) +#define MAX_INT64 (0x7fffffffffffffff) +typedef signed COMPILER_LONGLONG INT64; + +#define MIN_UINT64 (0x0000000000000000) +#define MAX_UINT64 (0xffffffffffffffff) +typedef unsigned COMPILER_LONGLONG UINT64; + +#define MIN_BITBOARD (0x0000000000000000) +#define MAX_BITBOARD (0xffffffffffffffff) +typedef UINT64 BITBOARD; + +#define MIN_BITV MIN_UINT +#define MAX_BITV MAX_UINT +typedef unsigned int BITV; + +#define MIN_FLAG MIN_UINT +#define MAX_FLAG MAX_UINT +typedef unsigned int FLAG; +#define IS_VALID_FLAG(x) (((x) == TRUE) || ((x) == FALSE)) + +typedef unsigned int COOR; +typedef unsigned int PIECE; +typedef signed int SCORE; + +#define BIT1 (0x1) +#define BIT2 (0x2) +#define BIT3 (0x4) +#define BIT4 (0x8) +#define BIT5 (0x10) +#define BIT6 (0x20) +#define BIT7 (0x40) +#define BIT8 (0x80) +#define BIT9 (0x100) +#define BIT10 (0x200) +#define BIT11 (0x400) +#define BIT12 (0x800) +#define BIT13 (0x1000) +#define BIT14 (0x2000) +#define BIT15 (0x4000) +#define BIT16 (0x8000) +#define BIT17 (0x10000) +#define BIT18 (0x20000) +#define BIT19 (0x40000) +#define BIT20 (0x80000) +#define BIT21 (0x100000) +#define BIT22 (0x200000) +#define BIT23 (0x400000) +#define BIT24 (0x800000) +#define BIT25 (0x1000000) +#define BIT26 (0x2000000) +#define BIT27 (0x4000000) +#define BIT28 (0x8000000) +#define BIT29 (0x10000000) +#define BIT30 (0x20000000) +#define BIT31 (0x40000000) +#define BIT32 (0x80000000) + +typedef struct _DLIST_ENTRY +{ + struct _DLIST_ENTRY *pFlink; + struct _DLIST_ENTRY *pBlink; +} DLIST_ENTRY; + +// +// Constants +// +#define YES (1) +#define NO (0) +#ifndef TRUE +#define TRUE (YES) +#endif +#ifndef FALSE +#define FALSE (NO) +#endif + +// +// Calculate the length of an array (i.e. number of elements) +// +#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +#define COMMAND(x) \ + void (x)(CHAR *szInput, ULONG argc, CHAR *argv[], POSITION *pos) +#define MB (1024 * 1024) + +// +// Calculate the address of the base of the structure given its type, and an +// address of a field within the structure. +// +#ifndef OFFSET_OF +#define OFFSET_OF(field, type) \ + (ULONG)(&((type *)0)->field) +#endif +#ifndef CONTAINING_STRUCT +#define CONTAINING_STRUCT(address, type, field) \ + ((type *)((BYTE *)(address) - (BYTE *)(OFFSET_OF(field, type)))) +#endif + +#define WHITE (1) +#define BLACK (0) +#define BAD_COLOR (2) +#define IS_VALID_COLOR(x) (((x) == WHITE) || ((x) == BLACK)) +#define FOREACH_COLOR(x) for((x) = BLACK; (x) < BAD_COLOR; (x)++) +#define RANDOM_COLOR (rand() & 1) +#define FLIP(color) ((color) ^ 1) +#define COLOR_NAME(color) (((color) == WHITE) ? "white" : "black") + +#define MAX_MOVES_PER_PLY (218) +#define MAX_PLY_PER_SEARCH (64) +#define MAX_MOVES_PER_GAME (1024) +#define SMALL_STRING_LEN_CHAR (256) +#define MEDIUM_STRING_LEN_CHAR (8192) +#define BIG_STRING_LEN_CHAR (16384) + +#define QUARTER_PLY 16 +#define HALF_PLY 32 +#define THREE_QUARTERS_PLY 48 +#define ONE_PLY 64 +#define TWO_PLY 128 +#define THREE_PLY 192 +#define FOUR_PLY 256 +#define MAX_DEPTH_PER_SEARCH (MAX_PLY_PER_SEARCH * ONE_PLY) + +#define IS_VALID_DEPTH(x) (((x) >= 0) && \ + ((x) <= MAX_DEPTH_PER_SEARCH) && \ + (((x) & 0xfffff00f) == 0)) + +#define INFINITY (MAX_SHORT) +#define INVALID_SCORE (INFINITY + 1) +#define IS_VALID_SCORE(x) (((x) >= -INFINITY) && \ + ((x) <= +INFINITY)) +#define NMATE (+INFINITY - 200) +#define MATED_SCORE(ply) (-INFINITY + (ply)) + +#define IS_A_POWER_OF_2(x) (((x) & (x - 1)) == 0) +// +// Program version number +// +#define VERSION "1.00" +#define REVISION "$Id: chess.h 344 2007-11-30 06:49:50Z scott $\n" + +// +// Function decorators +// +#define IN +#define OUT +#define INOUT +#define UNUSED +#define NOTHING + +// ---------------------------------------------------------------------- +// +// PIECE: +// +// a piece (4 bits) = type (3 bits) + color (1 bit) +// +// 3 1 0 +// . . . . +// | | | +// type C +// +#define KING (6) // 110X +#define QUEEN (5) // 101X +#define ROOK (4) // 100X +#define BISHOP (3) // 011X +#define KNIGHT (2) // 010X +#define PAWN (1) // 001X +#define EMPTY (0) // 000X + +// (WHATEVER << 1) +#define BLACK_PAWN (2) // 0010 +#define BLACK_KNIGHT (4) // 0100 +#define BLACK_BISHOP (6) // 0110 +#define BLACK_ROOK (8) // 1000 +#define BLACK_QUEEN (10) // 1010 +#define BLACK_KING (12) // 1100 + +// (WHATEVER << 1) | WHITE +#define WHITE_PAWN (3) // 0011 +#define WHITE_KNIGHT (5) // 0101 +#define WHITE_BISHOP (7) // 0111 +#define WHITE_ROOK (9) // 1001 +#define WHITE_QUEEN (11) // 1011 +#define WHITE_KING (13) // 1101 + +#define PIECE_TYPE(p) ((p) >> 1) +#define PIECE_COLOR(p) ((p) & WHITE) +#define RANDOM_PIECE (rand() % 12) + 2; +#define IS_PAWN(p) (((p) & 0xE) == BLACK_PAWN) +#define IS_KNIGHT(p) (((p) & 0xE) == BLACK_KNIGHT) +#define IS_BISHOP(p) (((p) & 0xE) == BLACK_BISHOP) +#define IS_ROOK(p) (((p) & 0xE) == BLACK_ROOK) +#define IS_QUEEN(p) (((p) & 0xE) == BLACK_QUEEN) +#define IS_KING(p) (((p) & 0xE) == BLACK_KING) +#define IS_KNIGHT_OR_KING(p) (((p) & 0x6) == 0x4) +#define IS_VALID_PIECE(p) ((PIECE_TYPE((p)) >= PAWN) && \ + (PIECE_TYPE((p)) <= KING)) +#define IS_WHITE_PIECE(p) ((p) & WHITE) +#define IS_BLACK_PIECE(p) (!IS_WHITE(p)) +#define OPPOSITE_COLORS(p, q) (((p) ^ (q)) & WHITE) +#define SAME_COLOR(p,q) (!OPPOSITE_COLORS(p, q)) +#define GET_COLOR(p) ((p) & WHITE) + +// ---------------------------------------------------------------------- +// +// a coordinate (8 bits) = rank + file (0x88) +// +// 7 4 3 0 +// . . . . . . . . +// | | | +// rank file +// | | +// | +--- 0-7 = file A thru file H +// | +// +------------ 0-7 = rank 1 thru rank 8 +// +// given a coordinate, C, if C & 0x88 then it is illegal (off board) +// +// +// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 +// +---------------------------------------+ +// 8 | 00 |:01:| 02 |:03:| 04 |:05:| 06 |:07:| 0x00 +// 7 |:10:| 11 |:12:| 13 |:14:| 15 |:16:| 17 | 0x10 +// 6 | 20 |:21:| 22 |:23:| 24 |:25:| 26 |:27:| 0x20 +// 5 |:30:| 31 |:32:| 33 |:34:| 35 |:36:| 37 | 0x30 +// 4 | 40 |:41:| 42 |:43:| 44 |:45:| 46 |:47:| 0x40 +// 3 |:50:| 51 |:52:| 53 |:54:| 55 |:56:| 57 | 0x50 +// 2 | 60 |:61:| 62 |:63:| 64 |:65:| 66 |:67:| 0x60 +// 1 |:70:| 71 |:72:| 73 |:74:| 75 |:76:| 77 | 0x70 +// +---------------------------------------+ +// A B C D E F G H +// +#define A (0) +#define B (1) +#define C (2) +#define D (3) +#define E (4) +#define F (5) +#define G (6) +#define H (7) + +#define A8 (0x00) +#define B8 (0x01) +#define C8 (0x02) +#define D8 (0x03) +#define E8 (0x04) +#define F8 (0x05) +#define G8 (0x06) +#define H8 (0x07) + +#define A7 (0x10) +#define B7 (0x11) +#define C7 (0x12) +#define D7 (0x13) +#define E7 (0x14) +#define F7 (0x15) +#define G7 (0x16) +#define H7 (0x17) + +#define A6 (0x20) +#define B6 (0x21) +#define C6 (0x22) +#define D6 (0x23) +#define E6 (0x24) +#define F6 (0x25) +#define G6 (0x26) +#define H6 (0x27) + +#define A5 (0x30) +#define B5 (0x31) +#define C5 (0x32) +#define D5 (0x33) +#define E5 (0x34) +#define F5 (0x35) +#define G5 (0x36) +#define H5 (0x37) + +#define A4 (0x40) +#define B4 (0x41) +#define C4 (0x42) +#define D4 (0x43) +#define E4 (0x44) +#define F4 (0x45) +#define G4 (0x46) +#define H4 (0x47) + +#define A3 (0x50) +#define B3 (0x51) +#define C3 (0x52) +#define D3 (0x53) +#define E3 (0x54) +#define F3 (0x55) +#define G3 (0x56) +#define H3 (0x57) + +#define A2 (0x60) +#define B2 (0x61) +#define C2 (0x62) +#define D2 (0x63) +#define E2 (0x64) +#define F2 (0x65) +#define G2 (0x66) +#define H2 (0x67) + +#define A1 (0x70) +#define B1 (0x71) +#define C1 (0x72) +#define D1 (0x73) +#define E1 (0x74) +#define F1 (0x75) +#define G1 (0x76) +#define H1 (0x77) + +// TODO: if use this anywhere that matters, consider double loop +// and unrolling the inside loop to prevent the multiple +// continue for invalid squares +#define FOREACH_SQUARE(x) for((x) = (A8); (x) <= (H1); (x)++) + +#define IS_ON_BOARD(c) (!((c) & 0x88)) +#define RANDOM_COOR (rand() & 0x77) +#define FILE_RANK_TO_COOR(f, r) (((8 - (r)) << 4) | (f)) +#define RANK(c) (8 - ((c) >> 4)) +#define RANK1(c) (((c) & 0xF0) == 0x70) +#define RANK2(c) (((c) & 0xF0) == 0x60) +#define RANK3(c) (((c) & 0xF0) == 0x50) +#define RANK4(c) (((c) & 0xF0) == 0x40) +#define RANK5(c) (((c) & 0xF0) == 0x30) +#define RANK6(c) (((c) & 0xF0) == 0x20) +#define RANK7(c) (((c) & 0xF0) == 0x10) +#define RANK8(c) (((c) & 0xF0) == 0x00) +#define FILE(c) ((c) & 0x0F) +#define FILEA(c) (((c) & 0x0F) == 0x00) +#define FILEB(c) (((c) & 0x0F) == 0x01) +#define FILEC(c) (((c) & 0x0F) == 0x02) +#define FILED(c) (((c) & 0x0F) == 0x03) +#define FILEE(c) (((c) & 0x0F) == 0x04) +#define FILEF(c) (((c) & 0x0F) == 0x05) +#define FILEG(c) (((c) & 0x0F) == 0x06) +#define FILEH(c) (((c) & 0x0F) == 0x07) +#define IS_WHITE_SQUARE_FR(f, r) (((f) + (r) - 1) & 1) +#define IS_WHITE_SQUARE_COOR(c) (IS_WHITE_SQUARE_FR(FILE(c), RANK(c))) +#define VALID_EP_SQUARE(c) (((c) == ILLEGAL_COOR) || ((c) == 0) || \ + (RANK3(c)) || \ + (RANK6(c))) + +// ---------------------------------------------------------------------- +// +// a move (4 bytes) = from/to, moved, captured, promoted and special +// +// 31 24 23 16 15 12 11 8 7 4 3 0 +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +// | from | to | moved | capt | prom | flags | +// | | | | | +// | | | | | +// | | | | | +// | | +-------+-------+-- type and +// | | color of +// | | piece moved +// | | captured and +// | | promote targ +// +---------------+-- board location where +// move begins and ends +// +// +// Special flag asserted on special move types: +// +// if (special) +// { +// if (moved == PAWN) +// { +// if (promotion) +// { +// move is a promote (w/ or w/o capture) +// } +// else if (capture) +// { +// move is an en passant catpure +// } +// else +// { +// move is a double jump +// } +// } +// else if (moved == KING) +// { +// move is a castle (long or short) +// } +// else +// { +// invalid use of special flag +// } +// } +// +typedef union _MOVE +{ + ULONG uMove; + struct + { + UCHAR cFrom : 8; + UCHAR cTo : 8; + UCHAR pMoved : 4; + UCHAR pCaptured : 4; + UCHAR pPromoted : 4; + UCHAR bvFlags : 4; + }; +} MOVE; + +#define IS_SAME_MOVE(a, b) \ + (((a).uMove & 0x0FFFFFFF) == (((b).uMove & 0x0FFFFFFF))) + +#define MAKE_MOVE(from,to,piece,cap,prom,flags) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20) | \ + ((ULONG)(prom) << 24) | \ + ((ULONG)(flags) << 28)) + +#define MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(from,to,piece,cap) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20)) + +// +// Move flag values: +// +#define MOVE_FLAG_SPECIAL (1) // en pass, prom, castle, double +#define IS_SPECIAL_MOVE(mv) \ + ((mv).uMove & 0x10000000) + +#define IS_CASTLE(mv) \ + (IS_SPECIAL_MOVE(mv) && IS_KING((mv).pMoved)) + +#ifdef DEBUG +#define IS_PROMOTION(mv) \ + (IS_SPECIAL_MOVE(mv) && ((mv).pPromoted)) +#else +#define IS_PROMOTION(mv) \ + ((mv).pPromoted) +#endif + +#define IS_CAPTURE_OR_PROMOTION(mv) \ + ((mv).uMove & 0x0FF00000) + +#define IS_ENPASSANT(mv) \ + (IS_SPECIAL_MOVE(mv) && (mv.pCaptured) && !IS_PROMOTION(mv)) + +#define IS_DOUBLE_JUMP(mv) \ + (IS_SPECIAL_MOVE(mv) && !IS_CAPTURE_OR_PROMOTION(mv)) + +#define MOVE_FLAG_KILLERMATE (2) // killer mate +#define IS_KILLERMATE_MOVE(mv) ((mv).uMove & 0x20000000) + +#define MOVE_FLAG_ESCAPING_CHECK (4) // escaping check +#define IS_ESCAPING_CHECK(mv) ((mv).uMove & 0x40000000) + +#define MOVE_FLAG_CHECKING (8) // checking move +#define IS_CHECKING_MOVE(mv) ((mv).uMove & 0x80000000) + +// ---------------------------------------------------------------------- +// +// Move list +// +#define MAX_MOVE_LIST (MAX_MOVES_PER_GAME + MAX_PLY_PER_SEARCH) + +// ---------------------------------------------------------------------- + +#pragma pack(1) +typedef union _ATTACK_BITV +{ + ULONG uWholeThing; + struct + { + union + { + UCHAR uSmall; + struct + { + UCHAR uNumAttacks : 3; // 0..2 + UCHAR uKing : 1; // 4..7 + UCHAR uQueen : 1; + UCHAR uRook : 1; + UCHAR uMinor : 1; + UCHAR uPawn : 1; + } small; + }; + + // -------------------- + union + { + USHORT uBig; + struct + { + USHORT uKing : 1; // 8..23 + USHORT uQueens : 4; + USHORT uRooks : 4; + USHORT uMinors : 4; + USHORT uPawns : 2; + USHORT uUnusedFlag1 : 1; + } big; + }; + + // ------------------- + union + { + UCHAR uXray; + struct + { + UCHAR uNumXrays : 3; + UCHAR uUnusedFlag2 : 1; + UCHAR uQueen : 1; // 24..28 + UCHAR uRook : 1; + UCHAR uBishop : 1; + UCHAR uUnusedFlag3 : 1; + } xray; + }; + }; +} +ATTACK_BITV; + +#define UNSAFE_FOR_MINOR(x) ((ULONG)((x).uWholeThing) & 0x00000080UL) +#define UNSAFE_FOR_ROOK(x) ((ULONG)((x).uWholeThing) & 0x000000C0UL) +#define UNSAFE_FOR_QUEEN(x) ((ULONG)((x).uWholeThing) & 0x000000E0UL) + +#define PAWN_BIT 0x00000080UL +#define MINOR_BIT 0x00000040UL +#define MINOR_XRAY_BIT 0x40000000UL +#define ROOK_BIT 0x00000020UL +#define ROOK_XRAY_BIT 0x20000000UL +#define QUEEN_BIT 0x00000010UL +#define QUEEN_XRAY_BIT 0x10000000UL + +#define INVALID_PIECE_INDEX (17) +#define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX) + +typedef union _SQUARE +{ + struct + { + PIECE pPiece; + ULONG uIndex; + }; + ATTACK_BITV bvAttacks[2]; +} +SQUARE; +#pragma pack() + +// +// POSITION +// +typedef struct _POSITION +{ + SQUARE rgSquare[128]; // where the pieces are, + // also, the attack table + UINT64 u64NonPawnSig; // hash signature + UINT64 u64PawnSig; // pawn hash signature + ULONG uToMove; // whose turn? + ULONG uFifty; // 50 moves w/o progress = draw + FLAG fCastled[2]; // record when sides have castled + BITV bvCastleInfo; // who can castle how? + COOR cEpSquare; // en-passant capture square + + COOR cPawns[2][8]; // location of pawns on the board + ULONG uPawnMaterial[2]; // pawn material of each side + ULONG uPawnCount[2]; // number of pawns for each side + + COOR cNonPawns[2][16]; // location of pieces on the board + ULONG uNonPawnMaterial[2]; // piece material of each side + ULONG uNonPawnCount[2][8]; // number of non-pawns / type + // 0 and 1 are the sum, + // 2..6 are per PIECE_TYPE + + ULONG uWhiteSqBishopCount[2]; // num bishops on white squares + SCORE iMaterialBalance[2]; // material balance + + // temporary storage space for use in eval + COOR cTrapped[2]; + ULONG uArmyScaler[2]; + ULONG uClosedScaler; + SCORE iScore[2]; + SCORE iReducedMaterialDownScaler[2]; + SCORE iTempScore; + ULONG uMinMobility[2]; + COOR cPiece; + ULONG uMinorsAtHome[2]; + BITBOARD bb; + ULONG uPiecesPointingAtKing[2]; +} +POSITION; + +// +// Castling permission bitvector flags. +// +#define CASTLE_WHITE_SHORT (1) +#define CASTLE_WHITE_LONG (2) +#define WHITE_CAN_CASTLE \ + (CASTLE_WHITE_SHORT | CASTLE_WHITE_LONG) +#define CASTLE_BLACK_SHORT (4) +#define CASTLE_BLACK_LONG (8) +#define BLACK_CAN_CASTLE \ + (CASTLE_BLACK_SHORT | CASTLE_BLACK_LONG) +#define CASTLE_NONE_POSSIBLE (0) +#define CASTLE_ALL_POSSIBLE \ + (WHITE_CAN_CASTLE | BLACK_CAN_CASTLE) + +// ---------------------------------------------------------------------- +// +// Move stack +// +#define MAX_MOVE_STACK (MAX_PLY_PER_SEARCH * \ + MAX_MOVES_PER_PLY) + +// +// Main part of the move stack, triads of moves, their values and flags +// that denote where the values came from +// +#define MVF_MOVE_SEARCHED (1) +#define MVF_EXTEND_MOVE (2) +#define MVF_REDUCE_MOVE (4) +#define MVF_PRUNE_SUBTREE (8) + +typedef struct _MOVE_STACK_MOVE_VALUE_FLAGS +{ + SCORE iValue; + MOVE mv; + BITV bvFlags; +} +MOVE_STACK_MOVE_VALUE_FLAGS; + +typedef struct _KEY_POINTER +{ + int iPointer; + ULONG uKey; +} +KEY_POINTER; + +typedef union _GENERATOR_FLAGS +{ + struct { + UCHAR uMoveCount; + UCHAR uKingMoveCount; + UCHAR uCheckingPieces; + UCHAR uUnused; + }; + ULONG uAllGenFlags; +} +GENERATOR_FLAGS; + +// +// A move stack +// +typedef struct _MOVE_STACK +{ +#ifdef DEBUG + POSITION board[MAX_PLY_PER_SEARCH]; +#endif + // + // Unblocked squares map, used for check detection + // + ULONG uUnblockedKeyValue[MAX_PLY_PER_SEARCH]; + KEY_POINTER sUnblocked[MAX_PLY_PER_SEARCH][128]; + + // + // The main move list, a long series of moves, their values and some + // flag bits to tell search what the values are based upon. + // + MOVE_STACK_MOVE_VALUE_FLAGS mvf[MAX_MOVE_STACK]; + + // + // uBegin[ply] and uEnd[ply] specify the start and end of moves gen- + // erated for a position at ply distance from the root. + // + ULONG uPly; + ULONG uBegin[MAX_PLY_PER_SEARCH]; + ULONG uEnd[MAX_PLY_PER_SEARCH]; + MOVE mvHash[MAX_PLY_PER_SEARCH]; + GENERATOR_FLAGS sGenFlags[MAX_PLY_PER_SEARCH]; +} +MOVE_STACK; + +#define GENERATE_NO_MOVES \ + ctx->sMoveStack.uEnd[ctx->uPly] = \ + ctx->sMoveStack.uBegin[ctx->uPly] + 1; \ + ctx->sMoveStack.uBegin[ctx->uPly + 1] = \ + ctx->sMoveStack.uEnd[ctx->uPly] + +#define GENERATE_ALL_MOVES (1) +#define GENERATE_ESCAPES (2) +#define GENERATE_CAPTURES_PROMS_CHECKS (3) +#define GENERATE_CAPTURES_PROMS (4) +#define GENERATE_DONT_SCORE (5) +#ifdef TEST +#define GENERATE_ALL_MOVES_CHECK_OK (6) +#endif + +#define MOVE_COUNT(ctx, x) \ + (((ctx)->sMoveStack.uEnd[(x)]) - (ctx)->sMoveStack.uBegin[(x)]) +#define ONE_LEGAL_MOVE(ctx, x) \ + (MOVE_COUNT(ctx, x) == 1) +#define NUM_KING_MOVES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uKingMoveCount) +#define NUM_CHECKING_PIECES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces) + + +// ---------------------------------------------------------------------- +// +// Accumulators +// +typedef struct _COUNTERS +{ + struct + { + UINT64 u64Probes; + UINT64 u64OverallHits; + UINT64 u64UsefulHits; + UINT64 u64UpperBoundHits; + UINT64 u64LowerBoundHits; + UINT64 u64ExactScoreHits; + } + hash; + + struct + { + UINT64 u64Probes; + UINT64 u64Hits; + } + pawnhash; + + struct + { + UINT64 u64TotalNodeCount; + UINT64 u64QNodeCount; + UINT64 u64LeafCount; + UINT64 u64TerminalPositionCount; + UINT64 u64BetaCutoffs; + UINT64 u64BetaCutoffsOnFirstMove; + UINT64 u64NullMoves; + UINT64 u64NullMoveSuccess; +#ifdef TEST_NULL + UINT64 u64QuickNullSuccess; + UINT64 u64QuickNullDeferredSuccess; + UINT64 u64QuickNullFailures; + UINT64 u64AvoidNullSuccess; + UINT64 u64AvoidNullFailures; +#endif + UINT64 u64EvalHashHits; + UINT64 u64LazyEvals; + UINT64 u64FullEvals; + UINT64 u64CyclesInEval; + } + tree; + + struct + { + ULONG uNumSplits; + ULONG uNumSplitsTerminated; + } + parallel; + + struct + { + ULONG uPawnPush; + ULONG uCheck; + ULONG uMateThreat; + ULONG uRecapture; + ULONG uOneLegalMove; + ULONG uNoLegalKingMoves; + ULONG uMultiCheck; + ULONG uSingularMove; + ULONG uZugzwang; + ULONG uSingularReplyToCheck; + ULONG uEndgame; + ULONG uBotvinnikMarkoff; + ULONG uQExtend; + } + extension; + + struct + { + ULONG uProbes; + ULONG uHits; + } + egtb; +} +COUNTERS; + +typedef struct _CUMULATIVE_SEARCH_FLAGS +{ + // search + ULONG uNumChecks[2]; // not used + FLAG fInSuspiciousBranch; // not used + FLAG fInReducedDepthBranch; // not used + FLAG fAvoidNullmove; // restore + FLAG fVerifyNullmove; // restore + + // qsearch + ULONG uQsearchDepth; // restore + ULONG uQsearchNodes; // incremental + ULONG uQsearchCheckDepth; // restore + FLAG fCouldStandPat[2]; // restore +} +CUMULATIVE_SEARCH_FLAGS; + +// ---------------------------------------------------------------------- +// +// Searcher thread record +// +typedef struct _SPLIT_INFO +{ + // locks / counters + volatile ULONG uLock; // lock for this split node + volatile ULONG uNumThreadsHelping; // num threads in this node + volatile FLAG fTerminate; // signal helpers to terminate + + // moves in the split node + ULONG uRemainingMoves; // num moves remaining to do + ULONG uOnDeckMove; // next move to do + ULONG uNumMoves; + ULONG uAlreadyDone; + MOVE_STACK_MOVE_VALUE_FLAGS + mvf[MAX_MOVES_PER_PLY]; // the moves to search + + // input to the split node + POSITION sRootPosition; // the root position + MOVE mvPathToHere[MAX_PLY_PER_SEARCH]; // path from root to split + MOVE mvLast; // last move before split + ULONG uDepth; // remaining depth at split + INT iPositionExtend; // positional extension + SCORE iAlpha; // original alpha at split + SCORE iBeta; // beta at split + ULONG uSplitPositional; // pos->uPositional at split + CUMULATIVE_SEARCH_FLAGS sSearchFlags; // flags at split time + + // output from the split node + MOVE mvBest; // the best move + SCORE iBestScore; // it's score + COUNTERS sCounters; // updated counters + MOVE PV[MAX_PLY_PER_SEARCH]; + +#ifdef DEBUG + ULONG uSplitPly; + POSITION sSplitPosition; +#endif +} +SPLIT_INFO; + +typedef struct _PLY_INFO +{ +#ifdef DEBUG + POSITION sPosition; + SCORE iAlpha; + SCORE iBeta; +#endif + SCORE iEval; + INT iExtensionAmount; + FLAG fInCheck; + FLAG fInQsearch; + MOVE mv; + MOVE mvBest; + MOVE PV[MAX_PLY_PER_SEARCH]; + + SCORE iKingScore[2]; + ULONG uMinMobility[2]; + UINT64 u64NonPawnSig; + UINT64 u64PawnSig; + UINT64 u64Sig; + ULONG uFifty; + FLAG fCastled[2]; + ULONG uTotalNonPawns; + BITV bvCastleInfo; + COOR cEpSquare; +} +PLY_INFO; + +#define EVAL_HASH +#ifdef EVAL_HASH +#define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread) +typedef struct _EVAL_HASH_ENTRY +{ + UINT64 u64Key; + SCORE iEval; + ULONG uPositional; + COOR cTrapped[2]; + +} EVAL_HASH_ENTRY; +#endif + +#define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread) +typedef struct _PAWN_HASH_ENTRY +{ + UINT64 u64Key; + BITBOARD bbPawnLocations[2]; + BITBOARD bbPasserLocations[2]; + BITBOARD bbStationaryPawns[2]; + SHORT iScore[2]; + UCHAR uCountPerFile[2][10]; + UCHAR uNumRammedPawns; + UCHAR uNumUnmovedPawns[2]; +} +PAWN_HASH_ENTRY; + +#define NUM_SPLIT_PTRS_IN_CONTEXT (8) + +typedef struct _SEARCHER_THREAD_CONTEXT +{ + ULONG uPly; // its distance from root + ULONG uPositional; // positional component of score + POSITION sPosition; // the board + MOVE_STACK sMoveStack; // the move stack + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; + MOVE mvKiller[MAX_PLY_PER_SEARCH][2]; + MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2]; + MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH]; + COUNTERS sCounters; + ULONG uThreadNumber; + SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT]; + MOVE mvRootMove; + SCORE iRootScore; + ULONG uRootDepth; + PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE]; +#ifdef EVAL_HASH + EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE]; +#endif + CHAR szLastPV[SMALL_STRING_LEN_CHAR]; +} +SEARCHER_THREAD_CONTEXT; + +// +// When I added the pawn hash table and eval hash tables to searcher +// thread contexts they became too heavy to just allocate on the fly +// for things like checking the legality of SAN moves or seeing if an +// opening book line leads to a draw. This +// LIGHTWEIGHT_SEARCHER_CONTEXT structure can be cast into a full +// SEARCHER_THREAD_CONTEXT and passed safely into the Generate, +// MakeMove and UnMakeMove functions because they presently only +// need: +// +// 1. uPly +// 2. sPosition +// 3. sPlyInfo +// 4. sMoveStack +// +typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT +{ + ULONG uPly; + ULONG uPositional; + POSITION sPosition; + MOVE_STACK sMoveStack; + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; +} +LIGHTWEIGHT_SEARCHER_CONTEXT; + +// ---------------------------------------------------------------------- +// +// Global game options +// +typedef struct _GAME_OPTIONS +{ + ULONG uMyClock; + ULONG uOpponentsClock; + FLAG fGameIsRated; + FLAG fOpponentIsComputer; + ULONG uSecPerMove; + ULONG uMaxDepth; + FLAG fShouldPonder; + FLAG fPondering; + FLAG fThinking; + FLAG fSuccessfulPonder; + MOVE mvPonder; + FLAG fShouldPost; + FLAG fForceDrawWorthZero; + ULONG uMyIncrement; + ULONG uMovesPerTimePeriod; + CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR]; + FLAG fShouldAnnounceOpening; + SCORE iLastEvalScore; + UINT64 u64NodesSearched; + CHAR szLogfile[SMALL_STRING_LEN_CHAR]; + CHAR szEGTBPath[SMALL_STRING_LEN_CHAR]; + CHAR szBookName[SMALL_STRING_LEN_CHAR]; + ULONG uNumProcessors; + ULONG uNumHashTableEntries; + FLAG fNoInputThread; + FLAG fVerbosePosting; + FLAG fRunningUnderXboard; + FLAG fStatusLine; + FLAG fFastScript; + + enum + { + CLOCK_NORMAL = 0, + CLOCK_FIXED, + CLOCK_INCREMENT, + CLOCK_NONE + } + eClock; + + enum + { + GAME_UNKNOWN = 0, + GAME_BULLET, + GAME_BLITZ, + GAME_STANDARD + } + eGameType; + + enum + { + I_PLAY_WHITE = 0, + I_PLAY_BLACK, + FORCE_MODE, + EDIT_MODE, + ANALYZE_MODE + } + ePlayMode; +} +GAME_OPTIONS; +extern GAME_OPTIONS g_Options; + +// ---------------------------------------------------------------------- +// +// Move timer +// + +#define TIMER_SEARCHING_FIRST_MOVE (0x1) +#define TIMER_SEARCHING_IMPORTANT_MOVE (0x2) +#define TIMER_RESOLVING_ROOT_FL (0x4) +#define TIMER_RESOLVING_ROOT_FH (0x8) +#define TIMER_JUST_OUT_OF_BOOK (0x10) +#define TIMER_CURRENT_OBVIOUS (0x20) +#define TIMER_CURRENT_WONT_UNBLOCK (0x40) +#define TIMER_ROOT_POSITION_CRITICAL (0x80) +#define TIMER_MOVE_IMMEDIATELY (0x100) +#define TIMER_MANY_ROOT_FLS (0x200) +#define TIMER_STOPPING (0x400) +#define TIMER_SPLIT_FAILED (0x800) + +typedef struct _MOVE_TIMER +{ + double dStartTime; + double dEndTime; + double dSoftTimeLimit; + double dHardTimeLimit; + ULONG uNodeCheckMask; + volatile BITV bvFlags; +} +MOVE_TIMER; + +// ---------------------------------------------------------------------- +// +// Special move tag literals +// +#define ILLEGALMOVE ((ULONG)0x1DDD8888) + +// +// useful macros +// +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine); + +#define ASSERT(x) if (x) \ + { ; } \ + else \ + { _assert(__FILE__, __LINE__); } +#define VERIFY(x) ASSERT(x) +#else +#define ASSERT(x) ; +#define VERIFY(x) x; +#endif // DEBUG + +#ifdef PERF_COUNTERS +#define INC(x) ((x) += 1) +#else +#define INC(x) +#endif + +#define BREAKPOINT SystemDebugBreakpoint() + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#ifdef _X86_ +// +// Note: MAXU, MINU and ABS_DIFF require arguments with the high order +// bit CLEAR to work right. +// +// These are branchless constructs. MAXU and MINU are equivalent to +// MIN and MAX (with the above restriction on inputs) +// +// MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x). These +// macros have no restiction on argument type. +// +// ABS_DIFF is equivalent to abs(x - y). Again, x and y must have +// their high-order bits CLEAR for this to work. +// +// Note: gcc generates code with cmovs so no need for MAXU/MINU on +// that compiler. +// +//#ifndef __GNUC__ +#define MINU(x, y) \ + (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y)) +#define MAXU(x, y) \ + (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x)) +//#endif +#ifndef DEBUG + +#define MIN0(x) \ + ((x) & (((int)(x)) >> 31)) + +#define MAX0(x) \ + ((x) & ~(((int)(x)) >> 31)) + +#else // !DEBUG +extern INLINE int MIN0(int x) +{ + int y = MIN(x, 0); + int z = ((x) & (((int)(x)) >> 31)); + ASSERT(y == z); + return(z); +} + +extern INLINE int MAX0(int x) +{ + int y = MAX(x, 0); + int z = ((x) & ~(((int)(x)) >> 31)); + ASSERT(y == z); + return(z); +} +#endif // DEBUG + +#define ABS_DIFF(a, b) \ + (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1)) + +#endif // _X86_ + +#ifndef MINU +#define MINU(x, y) (MIN((x), (y))) +#endif + +#ifndef MAXU +#define MAXU(x, y) (MAX((x), (y))) +#endif + +#ifndef MIN0 +#define MIN0(x) (MIN((x), 0)) +#endif + +#ifndef MAX0 +#define MAX0(x) (MAX((x), 0)) +#endif + +#ifndef ABS_DIFF +#define ABS_DIFF(a, b) (abs((a) - (b))) +#endif + +#define FILE_DISTANCE(a, b) (ABS_DIFF(FILE((a)), FILE((b)))) +#define RANK_DISTANCE(a, b) (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4) +#define REAL_DISTANCE(a, b) (MAXU(FILE_DISTANCE((a), (b)), \ + RANK_DISTANCE((a), (b)))) +#ifdef DEBUG +#define DISTANCE(a, b) DistanceBetweenSquares((a), (b)) +#else +#define DISTANCE(a, b) g_pDistance[(a) - (b)] +#endif // DEBUG + +#define IS_EMPTY( square ) (!(square)) +#define IS_OCCUPIED( square ) ((square)) + +#define IS_DEAD( listindex ) ((listindex) > 119) +#define IS_ALIVE( listindex ) ((listindex) <= 119) +#define ILLEGAL_COOR (0x88) +#define EDGE_DISTANCE(c) (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \ + MIN(abs(FILE(c) - 7), FILE(c)))) +#define NOT_ON_EDGE(c) ((((c) & 0xF0) != 0x00) && \ + (((c) & 0xF0) != 0x70) && \ + (((c) & 0x0F) != 0x00) && \ + (((c) & 0x0F) != 0x07)) +#define ON_EDGE(c) (RANK8(c) || \ + RANK1(c) || \ + FILEA(c) || \ + FILEH(c)) +#define CORNER_DISTANCE(c) (MAX(MIN((ULONG)abs(RANK(c) - 7), RANK(c)),\ + MIN((ULONG)abs(FILE(c) - 7), FILE(c)))) +#define IN_CORNER(c) (((c) == A8) || \ + ((c) == A1) || \ + ((c) == H8) || \ + ((c) == H1)) +#define WHITE_CORNER_DISTANCE(c) (MIN(DISTANCE((c), A8), \ + DISTANCE((c), H1))) +#define BLACK_CORNER_DISTANCE(c) (MIN(DISTANCE((c), H8), \ + DISTANCE((c), A1))) +#define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \ + | (7 - ((c) & 0x0F)) +#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a[0]))) +#define MAKE_PSQT(a, b, c, d) (((a) << 24) | ((b) << 16) | \ + ((c) << 8) | (d)) +#define TO64(x) ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3) +#define COOR_TO_BIT_NUMBER(c) (((((c) & 0x70) >> 1) | ((c) & 0x7))) +#define SLOWCOOR_TO_BB(c) (1ULL << COOR_TO_BIT_NUMBER(c)) +#define COOR_TO_BB(c) (BBSQUARE[COOR_TO_BIT_NUMBER(c)]) +#define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7)) +#define BIT_NUMBER_TO_COOR(b) ((((b) & 0xF8) << 1) | ((b) & 7)) + +#define BBRANK88 \ + SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \ + SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \ + SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8) + +#define BBRANK77 \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7) + +#define BBRANK66 \ + SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6) + +#define BBRANK55 \ + SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \ + SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \ + SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5) + +#define BBRANK44 \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4) + +#define BBRANK33 \ + SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3) + +#define BBRANK22 \ + SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \ + SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \ + SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2) + +#define BBRANK11 \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1) + +#define BBFILEA \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8) + +#define BBFILEB \ + SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \ + SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \ + SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8) + +#define BBFILEC \ + SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8) + +#define BBFILED \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8) + +#define BBFILEE \ + SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \ + SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \ + SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8) + +#define BBFILEF \ + SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8) + +#define BBFILEG \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8) + +#define BBFILEH \ + SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \ + SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \ + SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8) + +#define BBRANK72 \ + BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK62 \ + BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK52 \ + BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK42 \ + BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK32 \ + BBRANK33 | BBRANK22 + +#define BBRANK27 \ + BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK37 \ + BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK47 \ + BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK57 \ + BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK67 \ + BBRANK66 | BBRANK77 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// util.c +// +COMMAND(LearnPsqtFromPgn); + +COMMAND(GeneratePositionAndBestMoveSuite); + +CHAR * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx); + +CHAR * +ReadNextGameFromPgnFile(FILE *pf); + +COOR +DistanceBetweenSquares(COOR a, COOR b); + +void CDECL +Trace(CHAR *szMessage, ...); + +void CDECL +Log(CHAR *szMessage, ...); + +void CDECL +Bug(CHAR *szMessage, ...); + +char * +FindChunk(char *sz, ULONG uTargetChunk); + +FLAG +BufferIsZeroed(BYTE *p, ULONG u); + +char * +ColorToString(ULONG u); + +char * +CoorToString(COOR c); + +char * +ScoreToString(SCORE iScore); + +char * +TimeToString(double d); + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock); + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock); + +void +ReleaseSpinLock(volatile ULONG *pSpinLock); + +BYTE +Checksum(BYTE *p, ULONG uSize); + +FLAG +BackupFile(CHAR *szFile); + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv); + +#define CANNOT_INITIALIZE_SPLIT (1) +#define INCONSISTENT_POSITION (2) +#define UNEXPECTED_SYSTEM_CALL_FAILURE (3) +#define SHOULD_NOT_GET_HERE (4) +#define GOT_ILLEGAL_MOVE_WHILE_PONDERING (5) +#define CANNOT_OFFICIALLY_MAKE_MOVE (6) +#define DETECTED_INCORRECT_INITIALIZATION (7) +#define INCONSISTENT_STATE (8) +#define FATAL_ACCESS_DENIED (9) +#define TESTCASE_FAILURE (10) +#define INITIALIZATION_FAILURE (11) + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *a1, + void *a2, + void *a3, + char *file, ULONG line); + + +// +// main.c +// +#define LOGFILE_NAME "typhoon.log" +extern FILE *g_pfLogfile; + +void +Banner(void); + +FLAG +PreGameReset(FLAG fResetBoard); + +// +// system dependent exports (see win32.c or fbsd.c) +// +typedef ULONG (THREAD_ENTRYPOINT)(ULONG); + +#ifdef DEBUG +ULONG +GetHeapMemoryUsage(void); +#endif + +void +SystemDebugBreakpoint(void); + +CHAR * +SystemStrDup(CHAR *p); + +double +SystemTimeStamp(void); + +FLAG +SystemDoesFileExist(CHAR *szFilename); + +void +SystemDeferExecution(ULONG uMs); + +void +SystemFreeMemory(void *pMem); + +void * +SystemAllocateMemory(ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemDependentInitialization(void); + +UINT64 FASTCALL +SystemReadTimeStampCounter(void); + +// +// This routine _must_ implement a full memory fence -- it is used in +// util.c to implement spinlocks. +// +FLAG +SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle); + +FLAG +SystemWaitForThreadToExit(ULONG uThreadHandle); + +FLAG +SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode); + +FLAG +SystemDeleteThread(ULONG uThreadHandle); + +CHAR * +SystemGetDateString(void); + +CHAR * +SystemGetTimeString(void); + +FLAG +SystemCopyFile(CHAR *szSource, CHAR *szDest); + +FLAG +SystemDeleteFile(CHAR *szFile); + +ULONG +SystemCreateLock(void); + +FLAG +SystemDeleteLock(ULONG u); + +FLAG +SystemBlockingWaitForLock(ULONG u); + +FLAG +SystemReleaseLock(ULONG u); + +ULONG +SystemCreateSemaphore(ULONG u); + +FLAG +SystemDeleteSemaphore(ULONG u); + +void +SystemReleaseSemaphoreResource(ULONG u); + +void +SystemObtainSemaphoreResource(ULONG u); + + +// +// fen.c +// +#define STARTING_POSITION_IN_FEN \ + "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + +FLAG +LooksLikeFen(char *szFen); + +char * +PositionToFen(POSITION *p); + +FLAG +FenToPosition(POSITION *p, char *szFen); + +// +// testfen.c +// +#ifdef TEST +void +TestFenCode(void); +#endif + +// +// piece.c +// +// INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN; +#define VALUE_PAWN 100 +#define INVERT_PAWN 900 +#define VALUE_KNIGHT 300 +#define INVERT_KNIGHT 300 +#define VALUE_BISHOP 300 +#define INVERT_BISHOP 300 +#define VALUE_ROOK 500 +#define INVERT_ROOK 180 +#define VALUE_QUEEN 975 +#define INVERT_QUEEN 100 +#define VALUE_KING (INFINITY) +#define INVERT_KING 1 + +#define VALUE_FULL_ARMY (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_QUEEN + VALUE_KING +#define VALUE_MAX_ARMY (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_KING + +typedef struct _PIECE_DATA +{ + ULONG uValue; + ULONG uValueOver100; + ULONG uInvertedValue; + CHAR *szName; +} PIECE_DATA; + +extern PIECE_DATA g_PieceData[8]; + +#define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100) +extern ULONG +PieceValueOver100(PIECE p); + +#define PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uValue) +extern ULONG +PieceValue(PIECE p); + +#define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue) +extern ULONG +PieceInvertedValue(PIECE p); + +CHAR * +PieceAbbrev(PIECE p); + +// +// board.c +// +FLAG +VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError); + +FLAG +PositionsAreEquivalent(POSITION *p1, POSITION *p2); + +CHAR * +DrawTextBoardFromPosition(POSITION *pos); + +void +DumpPosition(POSITION *pos); + +CHAR * +CastleInfoString(BITV bv); + +void +SetRootToInitialPosition(void); + +// +// move.c +// +void +SlidePiece(POSITION *pos, COOR cFrom, COOR cTo); + +PIECE +LiftPiece(POSITION *pos, COOR cSquare); + +void +PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece); + +FLAG +MakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +void +UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +FLAG +MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser); + +void +DumpMove(ULONG u); + +// +// movesup.c +// +#define MOVE_TO_INDEX(mv) (((mv).uMove & 0xFFFF) + \ + (0x10000 * GET_COLOR(mv.pMoved))) + +COOR +FasterExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheckEp(POSITION *pos, + COOR cTest, + COOR cIgnore, + COOR cBlock, + COOR cKing); + +FLAG +IsAttacked(COOR cTest, POSITION *pos, ULONG uSide); + +FLAG +InCheck(POSITION *pos, ULONG uSide); + +FLAG +SanityCheckMove(POSITION *pos, MOVE mv); + +FLAG +LooksLikeFile(CHAR c); + +FLAG +LooksLikeRank(CHAR c); + +FLAG +LooksLikeCoor(CHAR *szData); + +CHAR * +StripMove(CHAR *szMove); + +ULONG +LooksLikeMove(CHAR *szData); + +void FASTCALL +SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +#define NOT_MOVE 0 +#define MOVE_ICS 1 +#define MOVE_SAN 2 + +COMMAND(PerftCommand); + + +// +// testmove.c +// +#ifdef TEST +void +TestLiftPlaceSlidePiece(void); + +void +TestExposesCheck(void); + +void +TestIsAttacked(void); + +void +TestMakeUnmakeMove(void); +#endif + +// +// generate.c +// +#define SORT_THESE_FIRST (0x40000000) +#define FIRST_KILLER (0x20000000) +#define SECOND_KILLER (0x10000000) +#define THIRD_KILLER (0x08000000) +#define FOURTH_KILLER (0x04000000) +#define GOOD_MOVE (0x02000000) +#define STRIP_OFF_FLAGS (0x00FFFFFF) + +extern const int g_iQKDeltas[9]; +extern const int g_iNDeltas[9]; +extern const int g_iBDeltas[5]; +extern const int g_iRDeltas[5]; + +void +GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mvOrderFirst, + ULONG uType); + +FLAG +WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv); + +// +// testgenerate.c +// +#ifdef TEST + +void +PlyTest(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fRootPositionInCheck); + +void +TestMoveGenerator(void); + +void +TestLegalMoveGenerator(void); + +#endif + +// +// sig.c +// +extern UINT64 g_u64SigSeeds[128][7][2]; +extern UINT64 g_u64PawnSigSeeds[128][2]; +extern UINT64 g_u64CastleSigSeeds[16]; +extern UINT64 g_u64EpSigSeeds[9]; + +void +InitializeSigSystem(void); + +UINT64 +ComputePawnSig(POSITION *pos); + +UINT64 +ComputeSig(POSITION *pos); + +// +// mersenne.c +// +void +seedMT(unsigned int seed); + +unsigned int +reloadMT(void); + +unsigned int +randomMT(void); + +// +// data.c +// +typedef struct _VECTOR_DELTA +{ + UCHAR iVector[2]; + signed char iDelta; + signed char iNegDelta; +} +VECTOR_DELTA; + +extern ULONG g_uDistance[256]; +extern ULONG *g_pDistance; +extern VECTOR_DELTA g_VectorDelta[256]; +extern VECTOR_DELTA *g_pVectorDelta; +extern CHAR g_SwapTable[14][32][32]; +extern SCORE _PSQT[14][128]; +extern ULONG g_uSearchSortLimits[]; +extern MOVE NULLMOVE; +extern MOVE HASHMOVE; +extern MOVE RECOGNMOVE; +extern MOVE DRAWMOVE; +extern MOVE MATEMOVE; +extern FLAG g_fIsWhiteSquare[128]; +extern BITBOARD BBFILE[8]; +extern BITBOARD BBRANK[9]; +extern BITBOARD BBWHITESQ; +extern BITBOARD BBBLACKSQ; +extern BITBOARD BBLEFTSIDE; +extern BITBOARD BBRIGHTSIDE; +extern BITBOARD BBSQUARE[64]; +extern BITBOARD BBROOK_PAWNS; +extern BITBOARD BBPRECEEDING_RANKS[8][2]; +extern BITBOARD BBADJACENT_FILES[8]; +extern BITBOARD BBADJACENT_RANKS[9]; + +void +InitializeWhiteSquaresTable(void); + +void +InitializeVectorDeltaTable(void); + +void +InitializeSwapTable(void); + +void +InitializeDistanceTable(void); + +void +InitializeSearchDepthArray(void); + +ULONG +GetSearchSortLimit(ULONG); + +#ifdef DEBUG +#define SEARCH_SORT_LIMIT(x) (GetSearchSortLimit((x))) +#else +#define SEARCH_SORT_LIMIT(x) (g_uSearchSortLimits[(x)]) +#endif + +#ifdef DEBUG +ULONG CheckVectorWithIndex(int i, ULONG uColor); +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + CheckVectorWithIndex(i, color) + +int DirectionBetweenSquaresWithIndex(int i); +#define CHECK_DELTA_WITH_INDEX(i) \ + DirectionBetweenSquaresWithIndex(i) + +int DirectionBetweenSquaresFromTo(COOR, COOR); +#define DIRECTION_BETWEEN_SQUARES(from, to) \ + DirectionBetweenSquaresFromTo(from, to) + +int NegativeDirectionBetweenSquaresWithIndex(int i); +#define NEG_DELTA_WITH_INDEX(i) \ + NegativeDirectionBetweenSquaresWithIndex(i) + +FLAG IsSquareWhite(COOR c); +#define IS_SQUARE_WHITE(c) \ + IsSquareWhite(c) + +#else +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + (g_pVectorDelta[(i)].iVector[(color)]) + +#define CHECK_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iDelta) + +#define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \ + CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo)) + +#define NEG_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iNegDelta) + +#define IS_SQUARE_WHITE(c) \ + (g_fIsWhiteSquare[(c)]) +#endif + +// +// san.c +// +MOVE +ParseMoveSan(CHAR *szInput, + POSITION *pos); + +CHAR * +MoveToSan(MOVE mv, POSITION *pos); + +// +// testsan.c +// +void +TestSan(void); + +// +// list.c +// +void +InitializeListHead(IN DLIST_ENTRY *pListHead); + +FLAG +IsListEmpty(IN DLIST_ENTRY *pListHead); + +FLAG +RemoveEntryList(IN DLIST_ENTRY *pEntry); + +DLIST_ENTRY * +RemoveHeadList(IN DLIST_ENTRY *pListHead); + +DLIST_ENTRY * +RemoveTailList(IN DLIST_ENTRY *pListHead); + +void +InsertTailList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +void +InsertHeadList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +// +// command.c +// +void +ParseUserInput(FLAG fSearching); + +FLAG +InitializeCommandSystem(void); + +void +CleanupCommandSystem(void); + +// +// input.c +// +void +InitInputSystemInBatchMode(void); + +ULONG +InitInputSystemWithDedicatedThread(void); + +void +PushNewInput(CHAR *buf); + +CHAR * +PeekNextInput(void); + +CHAR * +ReadNextInput(void); + +CHAR * +BlockingReadInput(void); + +ULONG +NumberOfPendingInputEvents(void); + +volatile extern FLAG g_fExitProgram; + +// +// ics.c +// +MOVE +ParseMoveIcs(CHAR *szInput, POSITION *pos); + +CHAR * +MoveToIcs(MOVE mv); + +// +// testics.c +// +void +TestIcs(void); + +// +// gamelist.c +// +typedef enum _ERESULT +{ + RESULT_BLACK_WON = -1, + RESULT_DRAW = 0, + RESULT_WHITE_WON = 1, + RESULT_IN_PROGRESS, + RESULT_ABANDONED, + RESULT_UNKNOWN +} +ERESULT; + +typedef struct _GAME_PLAYER +{ + CHAR *szName; + CHAR *szDescription; + FLAG fIsComputer; + ULONG uRating; +} +GAME_PLAYER; + +typedef struct _GAME_HEADER +{ + CHAR *szGameDescription; + CHAR *szLocation; + GAME_PLAYER sPlayer[2]; + FLAG fGameIsRated; + UINT64 u64OpeningSig; + ERESULT eResult; + CHAR *szResultComment; + CHAR *szInitialFen; +} +GAME_HEADER; + +typedef struct _GAME_MOVE +{ + DLIST_ENTRY links; + ULONG uNumber; + MOVE mv; + CHAR *szComment; + CHAR *szDecoration; + CHAR *szMoveInSan; + CHAR *szMoveInIcs; + CHAR *szUndoPositionFen; + SCORE iMoveScore; + UINT64 u64PositionSigAfterMove; + UINT64 u64PositionSigBeforeMove; + volatile FLAG fInUse; +} +GAME_MOVE; + +typedef struct _GAME_DATA +{ + GAME_HEADER sHeader; + DLIST_ENTRY sMoveList; +} +GAME_DATA; + +extern GAME_DATA g_GameData; + +POSITION * +GetRootPosition(void); + +FLAG +SetRootPosition(CHAR *szFen); + +void +ResetGameList(void); + +ULONG +GetMoveNumber(ULONG uColor); + +void +SetGameResultAndDescription(ERESULT r, CHAR *sz); + +INT +GetGameResult(void); + +void +SetMyName(void); + +void +SetOpponentsName(CHAR *sz); + +void +SetMyRating(ULONG u); + +void +SetOpponentsRating(ULONG u); + +void +DumpGameList(void); + +void +TellGamelistThatIPlayColor(ULONG u); + +void +DumpPgn(void); + +FLAG +LoadPgn(CHAR *szPgn); + +ULONG +CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig); + +FLAG +DoesSigAppearInOfficialGameList(UINT64 u64Sig); + +FLAG +OfficiallyTakebackMove(void); + +FLAG +OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast); + +GAME_MOVE * +GetNthOfficialMoveRecord(ULONG n); + +void +MakeStatusLine(void); + +FLAG +IsLegalDrawByRepetition(void); + +// +// script.c +// +COMMAND(ScriptCommand); + +COMMAND(SolutionCommand); + +COMMAND(AvoidCommand); + +COMMAND(IdCommand); + +void +PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *); + +FLAG +CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth); + +FLAG +WeAreRunningASuite(void); + + +// +// vars.c +// +COMMAND(SetCommand); + +// +// root.c +// +extern ULONG g_uSoftExtendLimit; +extern ULONG g_uHardExtendLimit; +extern volatile MOVE_TIMER g_MoveTimer; +extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; + +#ifdef PERF_COUNTERS +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) \ + ctx->sCounters.tree.u64BetaCutoffs++; \ + if (x) \ + { \ + ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\ + } +#else +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) +#endif + +#define GAME_NOT_OVER 0 +#define GAME_WHITE_WON 1 +#define GAME_BLACK_WON 2 +#define GAME_DRAW_STALEMATE 3 +#define GAME_DRAW_REPETITION 4 +#define GAME_ONE_LEGAL_MOVE 5 +#define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6 + +FLAG +Think(POSITION *pos); + +FLAG +Ponder(POSITION *pos); + +FLAG +Iterate(SEARCHER_THREAD_CONTEXT *ctx); + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor); + +void +SetMoveTimerToThinkForever(void); + +void +ClearRootNodecountHash(void); + +// +// draw.c +// +FLAG +IsDraw(SEARCHER_THREAD_CONTEXT *ctx); + + +// +// search.c +// +#define QPLIES_OF_NON_CAPTURE_CHECKS (1) +#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100) +#define DO_IID +#define IID_R_FACTOR (TWO_PLY + HALF_PLY) + +#ifndef MP +#define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING) +#else +#define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \ + (ThreadUnderTerminatingSplit(ctx))) +#endif + +SCORE FASTCALL +QSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta); + +SCORE FASTCALL +Search(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth); + + +// +// searchsup.c +// +SCORE +ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv, + IN ULONG uMoveNum); + +FLAG +ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *); + +FLAG +WeShouldDoHistoryPruning(IN SCORE iRoughEval, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN ULONG uLegalMoves, + IN MOVE mv, + IN ULONG uMoveNum, + IN INT iExtend); + +FLAG +WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SCORE iRoughEval, + IN ULONG uNullDepth); + +FLAG +TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN OUT FLAG *pfThreat, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uNullDepth, + IN OUT INT *piOrigExtend, + OUT SCORE *piNullScore); + +void +UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv); + +FLAG +CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx); + +void +ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uGenFlags, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN SCORE iAlpha, + IN OUT INT *piExtend, + IN OUT INT *piOrigExtend); + +void +ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN ULONG uDepth, + IN OUT INT *piExtend); + +SCORE +RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uDepth, + IN SCORE iAlpha, + IN SCORE iBeta); + +FLAG +MateDistancePruningCutoff(IN ULONG uPly, + IN FLAG fInCheck, + IN OUT SCORE *piBestScore, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta); + +FLAG +CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta, + IN OUT SCORE *piScore); + +ULONG +SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx, + IN INT uDepth); + +#define VERIFY_BEFORE (1) +#define VERIFY_AFTER (2) + +FLAG +SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uCurrent, + IN ULONG uType); + + +// +// testsearch.c +// +FLAG +TestSearch(void); + +// +// see.c +// +#define SEE_HEAPS + +SCORE +SEE(POSITION *pos, + MOVE mv); + +typedef struct _SEE_THREESOME +{ + PIECE pPiece; + COOR cLoc; + ULONG uVal; +} SEE_THREESOME; + +typedef struct _SEE_LIST +{ + ULONG uCount; + SEE_THREESOME data[16]; +} +SEE_LIST; + +SCORE +ControlsSquareMinusPiece(ULONG uSide, + POSITION *pos, + COOR c, + COOR cIgnore); + +// +// testsee.c +// +SCORE +DebugSEE(POSITION *pos, + MOVE mv); + +void +TestGetAttacks(void); + +// +// hash.c +// +#define NUM_HASH_ENTRIES_PER_LINE 4 +#define HASH_FLAG_EXACT 0x1 +#define HASH_FLAG_LOWER 0x2 +#define HASH_FLAG_UPPER 0x4 +#define HASH_FLAG_VALID_BOUNDS 0x7 +#define HASH_FLAG_THREAT 0x8 +#define HASH_FLAG_DIRTY 0xF0 + +typedef struct _HASH_ENTRY +{ + MOVE mv; // 0 1 2 3 + UCHAR uDepth; // 4 + UCHAR bvFlags; // 5 ==> d d d d | thr up low exact + signed short iValue; // 6 7 + UINT64 u64Sig; // 8 9 A B C D E F == 16 bytes +} HASH_ENTRY; + +FLAG +InitializeHashSystem(void); + +void +CleanupHashSystem(void); + +void +ClearHashTable(void); + +void +DirtyHashTable(void); + +void +StoreLowerBound(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); +void +StoreExactScore(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat, + ULONG uPly); + +void +StoreUpperBound(//MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); + +HASH_ENTRY * +HashLookup(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + ULONG uNextDepth, + SCORE iAlpha, + SCORE iBeta, + FLAG *pfThreat, + FLAG *pfAvoidNull, + MOVE *pHashMove, + SCORE *piScore); + +COOR +CheckHashForDangerSquare(POSITION *pos); + +MOVE +GetPonderMove(POSITION *pos); + +extern ULONG g_uHashTableSizeEntries; +extern ULONG g_uHashTableSizeBytes; +extern HASH_ENTRY *g_pHashTable; + +// +// testhash.c +// +void +AnalyzeFullHashTable(void); + +// +// positionhash.c +// +// IDEA: store "mate threat" flag in here? +// IDEA: store "king safety" numbers in here? +// +typedef struct _POSITION_HASH_ENTRY { + UINT64 u64Sig; + UCHAR cEnprise[2]; + UCHAR uEnpriseCount[2]; + UCHAR cTrapped[2]; +} POSITION_HASH_ENTRY; + +void +InitializePositionHashSystem(void); + +void +CleanupPositionHashSystem(void); + +void +StoreEnprisePiece(POSITION *pos, COOR cSquare); + +void +StoreTrappedPiece(POSITION *pos, COOR cSquare); + +COOR +GetEnprisePiece(POSITION *pos, ULONG uSide); + +ULONG +GetEnpriseCount(POSITION *pos, ULONG uSide); + +COOR +GetTrappedPiece(POSITION *pos, ULONG uSide); + +FLAG +SideCanStandPat(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide); + +// +// pawnhash.c +// +#define COOR_TO_BIT(x) ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3) + +void +ClearPawnHashStats(void); + +void +ReportPawnHashStats(void); + +PAWN_HASH_ENTRY * +PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx); + +// +// eval.c +// +#define LAZY_EVAL +#define LAZE_EVAL_BASE_SCORE 10 +extern const int g_iAhead[2]; +extern const int g_iBehind[2]; + +ULONG +DNABufferSizeBytes(); + +char * +ExportEvalDNA(); + +FLAG +WriteEvalDNA(char *szFilename); + +FLAG +ImportEvalDNA(char *p); + +FLAG +ReadEvalDNA(char *szFilename); + + + +SCORE +Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE); + +FLAG +EvalPasserRaces(POSITION *, + PAWN_HASH_ENTRY *); + +ULONG +CountKingSafetyDefects(POSITION *pos, + ULONG uSide); + +// +// testeval.c +// +#ifdef EVAL_DUMP +void +TestEval(void); + +void +EvalTraceReport(void); + +void +EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage); + +SCORE +EvalSigmaForPiece(POSITION *pos, COOR c); + +void +EvalTraceClear(void); + +void +TestEvalWithSymmetry(void); + +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); \ + EvalTrace((COL), (PIE), (COO), (ADJ), (MESS)); +#else +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); +#endif + +// +// bitboard.c +// +void +InitializeBitboards(void); + +ULONG CDECL +SlowCountBits(BITBOARD bb); + +ULONG CDECL +DeBruijnFirstBit(BITBOARD bb); + +ULONG CDECL +SlowFirstBit(BITBOARD bb); + +ULONG CDECL +SlowLastBit(BITBOARD bb); + +COOR +CoorFromBitBoardRank8ToRank1(BITBOARD *pbb); + +COOR +CoorFromBitBoardRank1ToRank8(BITBOARD *pbb); + +// +// x86.asm +// +ULONG CDECL +CountBits(BITBOARD bb); + +ULONG CDECL +FirstBit(BITBOARD bb); + +ULONG CDECL +LastBit(BITBOARD bb); + +ULONG CDECL +LockCompareExchange(volatile void *pDest, + ULONG uExch, + ULONG uComp); + +ULONG CDECL +LockIncrement(volatile void *pDest); + +ULONG CDECL +LockDecrement(volatile void *pDest); + +FLAG CDECL +CanUseParallelOpcodes(); + +ULONG CDECL +ParallelCompareUlong(ULONG uComparand, void *pComparators); + +ULONG CDECL +ParallelCompareVector(void *pComparand, void *pComparators); + +void CDECL +GetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); + +void CDECL +SlowGetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); + +#ifdef _X86_ +// +// Note: this is most of the stuff that x86.asm assumes about the +// internal data structures. If any of this fails then either the +// assembly language code needs to be updated or you need to use the C +// version of the routine in see.c instead. +// +#define ASSERT_ASM_ASSUMPTIONS \ + ASSERT(VALUE_PAWN == 100); \ + ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \ + ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \ + ASSERT(sizeof(SEE_THREESOME) == 12); \ + ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \ + ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \ + ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \ + ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \ + ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \ + ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \ + ASSERT(sizeof(SQUARE) == 8); \ + ASSERT(sizeof(VECTOR_DELTA) == 4); \ + ASSERT(sizeof(g_VectorDelta) == 256 * 4); \ + ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \ + ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \ + ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \ + ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \ + ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0); +#else +#define ASSERT_ASM_ASSUMPTIONS +#endif + +// +// testbitboard.c +// +void +TestBitboards(void); + +// +// dynamic.c +// +extern ULONG g_HistoryCounters[14][128]; + +ULONG +GetMoveFailHighPercentage(MOVE mv); + +void +UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uRemainingDepth, + MOVE mvBest, + SCORE iScore, + ULONG uCurrent); + +void +NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore); + +FLAG +InitializeDynamicMoveOrdering(void); + +void +CleanupDynamicMoveOrdering(void); + +void +ClearDynamicMoveOrdering(void); + +void +MaintainDynamicMoveOrdering(void); + +void +IncrementMoveHistoryCounter(MOVE mv, ULONG u); + +void +DecrementMoveHistoryCounter(MOVE mv, ULONG u); + +// +// split.c +// +extern volatile ULONG g_uNumHelpersAvailable; +extern ULONG g_uNumHelperThreads; + +FLAG +InitializeParallelSearch(void); + +FLAG +CleanupParallelSearch(void); + +void +ClearHelperThreadIdleness(void); + +void +DumpHelperIdlenessReport(void); + +SCORE +StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN SCORE iBeta, + IN OUT SCORE *piBestScore, + IN OUT MOVE *pmvBest, + IN ULONG uMoveNum, + IN INT iPositionExtend, + IN ULONG uDepth); + +void +InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx); + +// +// book.c +// + +#define BOOK_PROBE_MISS_LIMIT (7) +#define FLAG_DISABLED (1) +#define FLAG_ALWAYSPLAY (2) +#define FLAG_DELETED (4) + +#define BOOKMOVE_SELECT_MOVE (1) +#define BOOKMOVE_DUMP (2) + +#pragma pack(4) +typedef struct _BOOK_ENTRY +{ + UINT64 u64Sig; // 8 bytes + UINT64 u64NextSig; // 8 bytes + MOVE mvNext; // 4 bytes + ULONG uWins; // 4 bytes + ULONG uDraws; // 4 bytes + ULONG uLosses; // 4 bytes + BITV bvFlags; // 4 bytes +} +BOOK_ENTRY; +#pragma pack() + +typedef struct _OPENING_NAME_MAPPING +{ + UINT64 u64Sig; + CHAR *szString; +} +OPENING_NAME_MAPPING; + +#define BOOK_EDITING_RECORD "bkedit.edt" +#define OPENING_LEARNING_FILENAME "bklearn.bin" + +typedef struct _OPENING_LEARNING_ENTRY +{ + UINT64 u64Sig; + ULONG uWhiteWins; + ULONG uDraws; + ULONG uBlackWins; +} +OPENING_LEARNING_ENTRY; + +FLAG +InitializeOpeningBook(void); + +void +ResetOpeningBook(void); + +void +CleanupOpeningBook(void); + +MOVE +BookMove(POSITION *pos, + BITV bvFlags); + +COMMAND(BookCommand); + +extern ULONG g_uBookProbeFailures; +extern FLAG g_fTournamentMode; +extern CHAR *g_szBookName; + +// +// bench.c +// +COMMAND(BenchCommand); + +// +// testdraw.c +// +void +TestDraw(void); + +// +// probe.c +// +FLAG +ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score); + +void +InitializeEGTB(void); + +void +CleanupEGTB(void); + +// +// dumptree.c +// +#ifdef DUMP_TREE + +void +InitializeTreeDump(void); + +void +CleanupTreeDump(void); + +void +DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fIsQNode, + SCORE iAlpha, + SCORE iBeta); + +void +DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fQNode, + SCORE iBestScore, + MOVE mvBestMove); + +void CDECL +DTTrace(ULONG uPly, CHAR *szMessage, ...); + +#define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__) + +#else + +#define DTTRACE(...) + +#define DTEnterNode(...) + +#define DTLeaveNode(...) + +#define InitializeTreeDump(...) + +#define CleanupTreeDump(...) + +#endif + +// +// testsup.c +// +FLAG +IsBoardLegal(POSITION *pos); + +void +GenerateRandomLegalPosition(POSITION *pos); + +void +GenerateRandomLegalSymetricPosition(POSITION *pos); + +// +// recogn.c +// +#define UNRECOGNIZED (0) +#define RECOGN_EXACT (1) +#define RECOGN_UPPER (2) +#define RECOGN_LOWER (3) +#define RECOGN_EGTB (4) + +void +InitializeInteriorNodeRecognizers(void); + +ULONG +RecognLookup(SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore, + FLAG fProbeEGTB); + +#ifdef EVAL_HASH +void +ClearEvalHashStats(void); + +void +ReportEvalHashStats(void); + +SCORE +ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx); + +SCORE +GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash); + +void +StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore); +#endif // EVAL_HASH + +#endif // CHESS diff --git a/src/command.c b/src/command.c new file mode 100755 index 0000000..d528994 --- /dev/null +++ b/src/command.c @@ -0,0 +1,2655 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + command.c + +Abstract: + + Process commands received by the input thread. Note: the COMMAND + macro is defined in chess.h and used heavily in this module to + build function declarations. It hides four parameters: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Author: + + Scott Gasch (scott.gasch@gmail.com) 13 May 2004 + +Revision History: + + $Id: command.c 354 2008-06-30 05:10:08Z scott $ + +**/ + +#include "chess.h" + +#define MAX_ARGS 32 +int g_eModeBeforeAnalyze = -1; + +typedef void (COMMAND_PARSER_FUNCTION)(CHAR *szInput, + ULONG argc, + CHAR *argv[], + POSITION *pos); +typedef struct _COMMAND_PARSER_ENTRY +{ + CHAR *szOpcode; + COMMAND_PARSER_FUNCTION *pFunction; + FLAG fHandleOnTheFly; + FLAG fInvisible; + FLAG fWinBoard; + CHAR *szSimpleHelp; +} +COMMAND_PARSER_ENTRY; + + +COMMAND(AnalyzeCommand) +/** + +Routine description: + + This function implements the 'analyze' engine command. + + Usage: + + analyze + + This command takes no arguments and causes the engine to enter + analyze mode. See also: exit + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (g_Options.ePlayMode != ANALYZE_MODE) + { + g_eModeBeforeAnalyze = g_Options.ePlayMode; + g_Options.ePlayMode = ANALYZE_MODE; + } +} + +COMMAND(AnalyzeProgressCommand) +/** + +Routine description: + + This function implements the 'analyzeprogressreport' engine + command. + + Usage: + + analyzeprogressreport + + This command takes no arguments and causes the engine to dump + the current analysis. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (g_Options.ePlayMode == ANALYZE_MODE) + { + Trace("%s\n", g_Options.szAnalyzeProgressReport); + } +} + +COMMAND(BlackCommand) +/** + +Routine description: + + This function implements the 'black' engine command. + + Usage: + + black + + This command takes no arguments and causes the engine to play + white and set black to move. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + TellGamelistThatIPlayColor(WHITE); + g_Options.ePlayMode = I_PLAY_WHITE; + pos->uToMove = BLACK; + pos->u64NonPawnSig = ComputeSig(pos); +} + + +COMMAND(BoardCommand) +/** + +Routine description: + + This function implements the 'board' engine command. + + Usage: + + board + + This command takes no arguments and displays the current board + position on stdout and in the log. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + DumpPosition(pos); +} + +COMMAND(ComputerCommand) +/** + +Routine description: + + This function implements the 'computer' engine command. + + Usage: + + computer + + This command takes no argument and informs the engine that it + is playing against another computer. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fOpponentIsComputer = TRUE; + Trace("tellics +alias whisper kib\n"); +} + +COMMAND(DrawCommand) +{ + //if (g_iNumDrawScoresInARow > 4) + //{ + // ToXboard("tellopponent I accept your draw offer.\n"); + // ToXboard("tellics draw\n"); + //} + //else + //{ + //Trace("tellopponent Sorry I do not accept your draw offer at " + // "this time.\n"); + //Trace("tellics decline draw\n"); + //} +} + + +// +// TODO: timestamp command +// + +void +DumpSizes(void) +/** + +Routine description: + + Dump the sizes of some internal data structures on stdout. + +Parameters: + + void + +Return value: + + void + +**/ +{ + Trace("sizeof(PAWN_HASH_ENTRY). . . . . . . . . %u bytes\n" + "sizeof(HASH_ENTRY) . . . . . . . . . . . %u bytes\n" + "sizeof(MOVE) . . . . . . . . . . . . . . %u bytes\n" + "sizeof(ATTACK_BITV). . . . . . . . . . . %u bytes\n" + "sizeof(SQUARE) . . . . . . . . . . . . . %u bytes\n" + "sizeof(POSITION) . . . . . . . . . . . . %u bytes\n" + "sizeof(MOVE_STACK) . . . . . . . . . . . %u bytes\n" + "sizeof(PLY_INFO) . . . . . . . . . . . . %u bytes\n" + "sizeof(COUNTERS) . . . . . . . . . . . . %u bytes\n" + "sizeof(SEARCHER_THREAD_CONTEXT). . . . . %u bytes\n" + "sizeof(GAME_OPTIONS) . . . . . . . . . . %u bytes\n" + "sizeof(MOVE_TIMER) . . . . . . . . . . . %u bytes\n" + "sizeof(PIECE_DATA) . . . . . . . . . . . %u bytes\n" + "sizeof(VECTOR_DELTA) . . . . . . . . . . %u bytes\n" + "sizeof(GAME_PLAYER). . . . . . . . . . . %u bytes\n" + "sizeof(GAME_HEADER). . . . . . . . . . . %u bytes\n" + "sizeof(GAME_MOVE). . . . . . . . . . . . %u bytes\n" + "sizeof(GAME_DATA). . . . . . . . . . . . %u bytes\n" + "sizeof(SEE_LIST) . . . . . . . . . . . . %u bytes\n" + "sizeof(BOOK_ENTRY) . . . . . . . . . . . %u bytes\n" + "-------------------------------------------------\n" + "Current main hash table size . . . . . . %u bytes (~%u Mb)\n", + sizeof(PAWN_HASH_ENTRY), sizeof(HASH_ENTRY), sizeof(MOVE), + sizeof(ATTACK_BITV), sizeof(SQUARE), sizeof(POSITION), + sizeof(MOVE_STACK), sizeof(PLY_INFO), sizeof(COUNTERS), + sizeof(SEARCHER_THREAD_CONTEXT), sizeof(GAME_OPTIONS), + sizeof(MOVE_TIMER), sizeof(PIECE_DATA), sizeof(VECTOR_DELTA), + sizeof(GAME_PLAYER), sizeof(GAME_HEADER), sizeof(GAME_MOVE), + sizeof(GAME_DATA), sizeof(SEE_LIST), sizeof(BOOK_ENTRY), + (g_uHashTableSizeEntries * sizeof(HASH_ENTRY)), + ((g_uHashTableSizeEntries * sizeof(HASH_ENTRY)) / MB)); + ASSERT_ASM_ASSUMPTIONS; +} + + +COMMAND(DumpCommand) +/** + +Routine description: + + This function implements the 'dump' engine command. + + Usage: + + dump board + dump moves + dump pgn + dump sizes + dump eval [optional coor] + dump evaldna + + This command is used to dump internal information to the + stdout. + + When used with the 'board' argument, a dump of the internal + representation of the current board position is produced. + + When used with the 'moves' argument, a list of the moves played + thus far in the current game is produced in list format. + + When used with the 'pgn' argument, a list of the moves played + thus far in the current game is produced in PGN format. + + When used with the 'sizes' argument, a dump of internal data + structure sizes is produced. + + When used with the 'eval' argument and no optional coordinate + a dump of all eval terms from the last time the eval function + was invoked is produced. If the optional coordinate is + provided then the eval terms DIRECTLY affected by the piece at + the supplied coordinate is produced. Note: to use dump eval + the engine must have been built with -DEVAL_DUMP. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ +#ifdef EVAL_DUMP + COOR c; +#endif + + if (argc < 2) + { + Trace("Error (missing argument)\n"); + return; + } + if (!STRCMPI(argv[1], "board")) + { + DumpPosition(pos); + } + else if (!STRCMPI(argv[1], "moves")) + { + DumpGameList(); + } + else if (!STRCMPI(argv[1], "pgn")) + { + DumpPgn(); + } + else if (!STRCMPI(argv[1], "sizes")) + { + DumpSizes(); + } + else if (!STRCMPI(argv[1], "evaldna")) + { + char *p = ExportEvalDNA(); + Trace("EvalDNA: %s\n", p); + free(p); + } +#ifdef EVAL_DUMP + else if (!STRCMPI(argv[1], "eval")) + { + if (argc < 3) + { + EvalTraceReport(); + } + else + { + if (!STRCMPI(argv[2], "terms")) + { + EvalTraceReport(); + } else { + if (LooksLikeCoor(argv[2])) + { + c = FILE_RANK_TO_COOR((tolower(argv[2][0]) - 'a'), + (tolower(argv[2][1]) - '0')); + (void)EvalSigmaForPiece(pos, c); + } else { + (void)EvalSigmaForPiece(pos, ILLEGAL_COOR); + } + } + } + } +#endif +} + +COMMAND(EasyCommand) +/** + +Routine description: + + This function implements the 'easy' engine command. + + Usage: + + easy + + This command takes no arguments and causes the engine not to + think on the opponent's time (i.e. not to ponder) + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fShouldPonder = FALSE; +} + +COMMAND(EditCommand) +/** + +Routine description: + + This function implements the 'edit' engine command. + + Usage: + + This command is deprecated and should not be used. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("Error (obsolete command): %s\n", argv[0]); + Trace("\nPlease upgrade your version of xboard at " + "http://www.timmann.org/\n"); +} + +COMMAND(EvalCommand) +/** + +Routine description: + + This function implements the 'eval' engine command. + + Usage: + + eval + + This command takes no arguments and causes the engine to print + out a static evaluation of the current board position. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + SEARCHER_THREAD_CONTEXT *ctx; + SCORE i; + + ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT)); + if (NULL != ctx) + { + InitializeSearcherContext(pos, ctx); + i = Eval(ctx, -INFINITY, +INFINITY); + Trace("Static eval: %s\n", ScoreToString(i)); + SystemFreeMemory(ctx); + } else { + Trace("Out of memory.\n"); + } +} + + +COMMAND(EvalDnaCommand) +/** + +Routine description: + + This function implements the 'evaldna' engine command. + + Usage: + + evaldna write + evaldna read + evaldna dump + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + char *p; + if (argc < 2) + { + Trace("Usage: evaldna \n" + " evaldna dump\n"); + return; + } + if (!STRCMPI(argv[1], "write")) + { + if (argc < 3) { + Trace("Error (missing argument)\n"); + return; + } + if (!WriteEvalDNA(argv[2])) + { + Trace("Error writing dna file.\n"); + } else { + Trace("DNA file written.\n"); + } + } + else if (!STRCMPI(argv[1], "read") || + !STRCMPI(argv[1], "load")) + { + if (argc < 3) { + Trace("Error (missing argument)\n"); + return; + } + if (!ReadEvalDNA(argv[2])) + { + Trace("Error reading dna file.\n"); + } else { + Trace("Loaded dna file \"%s\"\n", argv[2]); + p = ExportEvalDNA(); + Log("(New) dna: %s\n", p); + free(p); + } + } + else if (!STRCMPI(argv[1], "dump")) + { + p = ExportEvalDNA(); + Trace("EvalDNA: %s\n", p); + free(p); + } +} + + +COMMAND(ExitCommand) +/** + +Routine description: + + This function implements the 'exit' engine command. + + Usage: + + exit + + This command takes no arguments and causes the engine to leave + analyze mode. The engine reverts to the mode it was in prior + to entering analyze mode. See also: analyze + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (g_Options.ePlayMode == ANALYZE_MODE) + { + ASSERT(g_eModeBeforeAnalyze != ANALYZE_MODE); + g_Options.ePlayMode = g_eModeBeforeAnalyze; + } +} + +COMMAND(ForceCommand) +/** + +Routine description: + + This function implements the 'force' engine command. + + Usage: + + force + + This command takes no arguments and causes the engine to enter + 'force mode'. In this mode it will play neither side. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + TellGamelistThatIPlayColor(BLACK); + g_Options.ePlayMode = FORCE_MODE; +} + +COMMAND(GenerateCommand) +/** + +Routine description: + + This function is not directly callable. See 'test generate' + instead. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + SEARCHER_THREAD_CONTEXT *ctx; + MOVE mv; + ULONG u, uLegal = 0; + + ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT)); + if (NULL != ctx) + { + memcpy(&(ctx->sPosition), pos, sizeof(POSITION)); + mv.uMove = 0; + GenerateMoves(ctx, mv, (InCheck(pos, pos->uToMove) ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + ASSERT(ctx->uPly == 0); + for (u = ctx->sMoveStack.uBegin[0]; + u < ctx->sMoveStack.uEnd[0]; + u++) + { + mv = ctx->sMoveStack.mvf[u].mv; + if (MakeMove(ctx, mv)) + { + ASSERT(!InCheck(&(ctx->sPosition), GET_COLOR(mv.pMoved))); + uLegal++; + UnmakeMove(ctx, mv); + Trace("%2u. %s (%d)\t", + uLegal, + MoveToSan(mv, &(ctx->sPosition)), + ctx->sMoveStack.mvf[u].iValue); + if (uLegal % 3 == 0) + { + Trace("\n"); + } + } + } + Trace("\n%u legal move(s).\n", uLegal); + SystemFreeMemory(ctx); + } +} + +COMMAND(PlayOtherCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (pos->uToMove == WHITE) + { + TellGamelistThatIPlayColor(BLACK); + g_Options.ePlayMode = I_PLAY_BLACK; + } else { + ASSERT(pos->uToMove == BLACK); + TellGamelistThatIPlayColor(WHITE); + g_Options.ePlayMode = I_PLAY_WHITE; + } +} + + +COMMAND(GoCommand) +/** + +Routine description: + + This function implements the 'go' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (pos->uToMove == WHITE) + { + TellGamelistThatIPlayColor(WHITE); + g_Options.ePlayMode = I_PLAY_WHITE; + } else { + ASSERT(pos->uToMove == BLACK); + TellGamelistThatIPlayColor(BLACK); + g_Options.ePlayMode = I_PLAY_BLACK; + } +} + +COMMAND(HardCommand) +{ + g_Options.fShouldPonder = TRUE; +} + +COMMAND(HelpCommand); + +COMMAND(HintCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("Error (not implemented): %s\n", argv[0]); +} + +CHAR *OnlyDigits(CHAR *sz) +{ + static CHAR out[SMALL_STRING_LEN_CHAR]; + CHAR *p = out; + ULONG uCount = 0; + + while((*sz) && (uCount < SMALL_STRING_LEN_CHAR)) + { + if (isdigit(*sz)) + { + uCount++; + *p++ = *sz++; + } + } + *p++ = '\0'; + return(out); +} + +COMMAND(LevelCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x; + + if (argc < 4) + { + Trace("Error (syntax): %s\n", argv[0]); + } else { + g_Options.uMovesPerTimePeriod = atoi(OnlyDigits(argv[1])); + g_Options.uMyClock = atoi(OnlyDigits(argv[2])); + g_Options.uMyIncrement = atoi(OnlyDigits(argv[3])); + + g_Options.eClock = CLOCK_NORMAL; + if (g_Options.uMyIncrement) + { + g_Options.eClock = CLOCK_INCREMENT; + } + + x = (g_Options.uMyClock + ((g_Options.uMyIncrement * 2) / 3)); + g_Options.uMyClock *= 60; + + Trace("etime = %u (clock %u and inc %u)\n", x, + g_Options.uMyClock, g_Options.uMyIncrement); + if (x <= 6) + { + Trace("bullet game\n"); + g_Options.eGameType = GAME_BULLET; + } + else if (x < 15) + { + Trace("blitz game\n"); + g_Options.eGameType = GAME_BLITZ; + } else { + Trace("standard game\n"); + g_Options.eGameType = GAME_STANDARD; + } + } +} + +COMMAND(MoveNowCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("MOVE NOW COMMAND --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; +} + +COMMAND(MovesCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + DumpGameList(); +} + +COMMAND(XboardCommand); +COMMAND(NameCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (argc < 2) + { + XboardCommand(szInput, argc, argv, pos); + } else { + SetOpponentsName(argv[1]); + } +} + +COMMAND(NewCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("tellics -alias whisp*\n"); + PreGameReset(TRUE); + TellGamelistThatIPlayColor(BLACK); + g_Options.ePlayMode = I_PLAY_BLACK; + g_Options.uMaxDepth = MAX_PLY_PER_SEARCH - 1; +} + +COMMAND(NoPostCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fShouldPost = FALSE; +} + +COMMAND(OtimCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x; + + if (argc < 2) + { + Trace("My opponent's clock stands at %u sec remaining.\n", + g_Options.uOpponentsClock); + + switch (g_Options.eClock) + { + case CLOCK_FIXED: + Trace("The move timer is fixed, %u sec / move.\n", + g_Options.uMyIncrement); + break; + case CLOCK_NORMAL: + if (g_Options.uMovesPerTimePeriod != 0) + { + Trace("The move timer is normal, %u moves / time " + "period.\n", + g_Options.uMovesPerTimePeriod); + } else { + Trace("The move timer is normal, finish entire " + "game in allotted time.\n"); + } + break; + case CLOCK_INCREMENT: + Trace("The move timer is increment, additional %u sec " + "/ move.\n", + g_Options.uMyIncrement); + break; + case CLOCK_NONE: + default: + Trace("The clock and move timer are disabled.\n"); + break; + } + } else { + x = atoi(argv[1]); + if (x >= 0) + { + g_Options.uOpponentsClock = x / 100; // convert to seconds + } else { + Trace("Error (invalid time): %d\n", x); + } + } +} + +COMMAND(PingCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (argc > 1) + { + Trace("pong %s\n", argv[1]); + } +} + +COMMAND(PostCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fShouldPost = TRUE; +} + +COMMAND(ProtoverCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("feature sigint=0 sigterm=0 myname=\"typhoon %s\" ping=1 " + "setboard=1 playother=1 colors=0 time=1 analyze=1 pause=1 " + "reuse=1 done=1\n", VERSION); +} + +COMMAND(QuitCommand) +/** + +Routine description: + + This function implements the 'quit' engine command. + + Usage: quit + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ +#ifdef MP + ULONG u = 0; +#endif + + // + // Stop searching; if we are on an MP box wait until all helper + // threads return to the idle state and exit. + // + g_MoveTimer.bvFlags |= TIMER_STOPPING; +#ifdef MP + u = 0; + do + { + SystemDeferExecution(100); + if (++u == 5) break; + } + while(g_uNumHelpersAvailable != g_uNumHelperThreads); +#endif + + // + // We should be the last thread in the process now. + // +} + +COMMAND(RatedCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fGameIsRated = TRUE; +} + +COMMAND(RatingCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x; + + if (argc < 3) + { + Trace("Error (bad usage): %s\n", argv[0]); + } else { + x = atoi(argv[1]); + if (x >= 0) + { + SetMyRating(x); + } + x = atoi(argv[2]); + if (x >= 0) + { + SetOpponentsRating(x); + } + } +} + +COMMAND(RandomCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("%u\n", rand()); +} + +COMMAND(RemoveCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (TRUE == OfficiallyTakebackMove()) + { + if (TRUE == OfficiallyTakebackMove()) + { + return; + } + } + Trace("Error (unable to takeback move)\n"); +} + +COMMAND(ResultCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + GAME_RESULT result; + result.eResult = RESULT_UNKNOWN; + result.szDescription[0] = '\0'; + + if (argc < 2) + { + Trace("Argc was %u\n", argc); + Trace("Usage: result [optional comment]\n"); + } else { + if (!STRNCMPI("1-0", argv[1], 3)) + { + result.eResult = RESULT_WHITE_WON; + } + else if (!STRNCMPI("0-1", argv[1], 3)) + { + result.eResult = RESULT_BLACK_WON; + } + else if ((!STRNCMPI("1/2", argv[1], 3)) || + (!STRNCMPI("=", argv[1], 1))) + { + result.eResult = RESULT_DRAW; + } + if (argc < 2) { + strncpy(result.szDescription, argv[2], 256); + } + SetGameResultAndDescription(result); + if (g_Options.ePlayMode != FORCE_MODE) + { + DumpPgn(); + TellGamelistThatIPlayColor(BLACK); + g_Options.ePlayMode = FORCE_MODE; + } + } +} + +COMMAND(SearchDepthCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x; + + if (argc < 2) + { + Trace("Current maximum depth limit is %u ply.\n" + "The largest depth the engine can search to is %u ply.\n", + g_Options.uMaxDepth, + MAX_PLY_PER_SEARCH); + } else { + x = atoi(argv[1]); + if (x <= 0) + { + Trace("Error (illegal depth): %d\n", x); + } + else if (x >= MAX_PLY_PER_SEARCH) + { + Trace("Error (my max depth is %u): %u\n", + MAX_PLY_PER_SEARCH - 1, x); + } else { + g_Options.uMaxDepth = x; + } + } +} + +COMMAND(SearchNodesCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + UINT64 x; + + if (argc < 2) + { + g_Options.u64MaxNodeCount = 0; + Trace("Search nodecount limit disabled.\n"); + } else { + x = strtoull(argv[1], NULL, 10); + if (x >= 0) + { + g_Options.u64MaxNodeCount = x; + Trace("Search node limit set to %llu.\n", x); + } else { + g_Options.u64MaxNodeCount = 0; + Trace("Search nodecount limit disabled.\n"); + } + } +} + + +COMMAND(SearchTimeCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x; + + if (argc < 2) + { + Trace("My clock stands at %u sec remaining.\n", + g_Options.uMyClock); + switch (g_Options.eClock) + { + case CLOCK_FIXED: + Trace("The move timer is fixed, %u sec / move.\n", + g_Options.uMyIncrement); + break; + case CLOCK_NORMAL: + if (g_Options.uMovesPerTimePeriod != 0) + { + Trace("The move timer is normal, %u moves / " + "time period.\n", + g_Options.uMovesPerTimePeriod); + } else { + Trace("The move timer is normal, finish entire game in " + "allotted time.\n"); + } + break; + case CLOCK_INCREMENT: + Trace("The move timer is increment, additional %u sec " + "/ move.\n", + g_Options.uMyIncrement); + break; + case CLOCK_NONE: + default: + Trace("The clock and move timer are disabled.\n"); + break; + } + } else { + x = atoi(argv[1]); + if (x >= 0) + { + g_Options.uMyIncrement = x; + g_Options.eClock = CLOCK_FIXED; + } else { + Trace("Error (illegal time per move): %u\n", x); + } + } +} + +COMMAND(SetBoardCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + char *p; + + if (argc < 2) + { + if (NULL != (p = PositionToFen(pos))) + { + Trace("Current board FEN is: %s\n", p); + SystemFreeMemory(p); + } + } else { + p = szInput + (argv[1] - argv[0]); + if (FALSE == SetRootPosition(p)) + { + Trace("Error (malformed FEN): %s\n", p); + return; + } + VERIFY(PreGameReset(FALSE)); + g_Options.ePlayMode = FORCE_MODE; + } +} + +COMMAND(SEECommand) +{ + MOVE mv; + SCORE s; + + if (argc < 3) + { + Trace("Usage: test see \n"); + return; + } + switch(LooksLikeMove(argv[2])) + { + case MOVE_SAN: + mv = ParseMoveSan(argv[2], pos); + break; + case MOVE_ICS: + mv = ParseMoveIcs(argv[2], pos); + break; + default: + mv.uMove = 0; + } + if (!mv.uMove) + { + Trace("Error (invalid move): '%s'\n", argv[2]); + return; + } + s = SEE(pos, mv); + Trace("SEE says that the value of move '%s' is %d\n", argv[2], s); +} + + +COMMAND(TestCommand) +/** + +Routine description: + + This function implements the 'test' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (argc < 2) + { + Trace("Error (missing argument)\n"); + return; + } + + if (!STRCMPI(argv[1], "generate")) + { + GenerateCommand(szInput, argc, argv, pos); + } + else if (!STRCMPI(argv[1], "draw")) + { + Trace("drawcount = %u\n", + CountOccurrancesOfSigInOfficialGameList(pos->u64NonPawnSig ^ + pos->u64PawnSig)); + } + else if (!STRCMPI(argv[1], "see")) + { + SEECommand(szInput, argc, argv, pos); + } +#ifdef EVAL_DUMP + else if (!STRCMPI(argv[1], "eval")) + { + TestEvalWithSymmetry(); + } +#endif + + // + // TODO: #ifdef TEST allow individual tests to be run here. + // +} + +COMMAND(TimeCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x; + + if (argc < 2) + { + Trace("My clock stands at %u sec remaining.\n", + g_Options.uMyClock); + + switch (g_Options.eClock) + { + case CLOCK_FIXED: + Trace("The move timer is fixed, %u sec / move.\n", + g_Options.uMyIncrement); + break; + case CLOCK_NORMAL: + if (g_Options.uMovesPerTimePeriod != 0) + { + Trace("The move timer is normal, %u moves / time " + "period.\n", + g_Options.uMovesPerTimePeriod); + } else { + Trace("The move timer is normal, finish entire " + "game in allotted time.\n"); + } + break; + case CLOCK_INCREMENT: + Trace("The move timer is increment, additional %u sec " + "/ move.\n", + g_Options.uMyIncrement); + break; + case CLOCK_NONE: + default: + Trace("The clock and move timer are disabled.\n"); + break; + } + } else { + x = atoi(argv[1]); + if (x >= 0) + { + g_Options.uMyClock = x / 100; // convert to seconds + } else { + Trace("Error (illegal time): %d\n", x); + } + } +} + +COMMAND(UndoCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + if (FALSE == OfficiallyTakebackMove()) + { + Trace("Error (can't undo): %s\n", argv[0]); + } +} + +COMMAND(UnratedCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fGameIsRated = FALSE; +} + + +COMMAND(VariantCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Trace("Error (not implemented): %s\n", argv[0]); + Trace("tellics abort\n"); + ASSERT(FALSE); +} + +COMMAND(VersionCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + Banner(); +} + +COMMAND(WhiteCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + TellGamelistThatIPlayColor(BLACK); + g_Options.ePlayMode = I_PLAY_BLACK; + pos->uToMove = WHITE; + pos->u64NonPawnSig = ComputeSig(pos); +} + + +COMMAND(XboardCommand) +/** + +Routine description: + + This function implements the '' engine command. + + Usage: + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + g_Options.fRunningUnderXboard = TRUE; + Trace("\n\n"); +} + +COMMAND(AcceptedCommand) +{ + ;; +} + + +// HEREHERE +COMMAND_PARSER_ENTRY g_ParserTable[] = +{ + { "?", + MoveNowCommand, + TRUE, + FALSE, + TRUE, + "Stop thinking and move immediately" }, + { ".", + AnalyzeProgressCommand, + TRUE, + FALSE, + TRUE, + "Show engine's current best line when in analyze mode" }, + { "accepted", + AcceptedCommand, + TRUE, + TRUE, + TRUE, + "Internal, part of the WinBoard protocol" }, + { "analyze", + AnalyzeCommand, + FALSE, + FALSE, + TRUE, + "Enter analyze mode" }, + { "avoid", + AvoidCommand, + FALSE, + FALSE, + FALSE, + "Set a move to avoid (up to three)" }, + { "bench", + BenchCommand, + FALSE, + FALSE, + FALSE, + "Run a crafty benchmark and show results" }, + { "bestmove", + GeneratePositionAndBestMoveSuite, + FALSE, + TRUE, + FALSE, + "Generate a best move suite from a PGN file" }, + { "black", + BlackCommand, + FALSE, + FALSE, + TRUE, + "Sets black to move and computer to play white" }, + { "book", + BookCommand, + FALSE, + FALSE, + FALSE, + "Manage the opening book" }, + { "computer", + ComputerCommand, + TRUE, + FALSE, + FALSE, + "Informs the engine that it is playing another computer" }, + { "dump", + DumpCommand, + TRUE, + FALSE, + FALSE, + "Dumps a structure, position, moves, or pgn" }, + { "easy", + EasyCommand, + FALSE, + FALSE, + TRUE, + "Disable pondering" }, + { "draw", + DrawCommand, + TRUE, + FALSE, + FALSE, + "Offer the engine a draw" }, + { "edit", + EditCommand, + FALSE, + TRUE, + TRUE, + "Depreciated command, do not use" }, + { "eval", + EvalCommand, + FALSE, + FALSE, + FALSE, + "Run a static eval" }, + { "evaldna", + EvalDnaCommand, + FALSE, + FALSE, + FALSE, + "Read or write the DNA from the eval code." }, + { "exit", + ExitCommand, + FALSE, + FALSE, + TRUE, + "Leave analyze mode" }, + { "force", + ForceCommand, + FALSE, + FALSE, + TRUE, + "Enter force mode, engine plays neither side" }, + { "go", + GoCommand, + FALSE, + FALSE, + TRUE, + "Sets engine to play side on move, begin thinking" }, + { "hard", + HardCommand, + FALSE, + FALSE, + TRUE, + "Enable pondering" }, + { "help", + HelpCommand, + TRUE, + FALSE, + FALSE, + "Show a list of commands available" }, + { "hint", + HintCommand, + FALSE, + FALSE, + TRUE, + "Ask the engine for a hint" }, + { "id", + IdCommand, + TRUE, + FALSE, + FALSE, + "Set a problem id name" }, + { "level", + LevelCommand, + FALSE, + FALSE, + TRUE, + "Sets game time controls" }, + { "name", + NameCommand, + TRUE, + FALSE, + FALSE, + "Tell the engine your name" }, + { "new", + NewCommand, + FALSE, + FALSE, + TRUE, + "Start a new game" }, + { "nopost", + NoPostCommand, + TRUE, + FALSE, + TRUE, + "Do not show thinking" }, + { "otim", + OtimCommand, + TRUE, + FALSE, + TRUE, + "Inform the engine about opponent's clock" }, + { "perft", + PerftCommand, + FALSE, + FALSE, + FALSE, + "Run a perft test on the move generator code." }, + { "ping", + PingCommand, + TRUE, + TRUE, + TRUE, + "Internal part of the WinBoard protocol" }, + { "playother", + PlayOtherCommand, + FALSE, + FALSE, + TRUE, + "Play the other side" }, + { "post", + PostCommand, + TRUE, + FALSE, + TRUE, + "Show thinking" }, + { "protover", + ProtoverCommand, + TRUE, + TRUE, + TRUE, + "Internal part of the WinBoard protocol" }, + { "psqt", + LearnPsqtFromPgn, + FALSE, + TRUE, + FALSE, + "Learn a set of PSQT settings from a PGN file" }, + { "quit", + QuitCommand, + TRUE, + FALSE, + FALSE, + "Exit the engine" }, + { "random", + RandomCommand, + TRUE, + TRUE, + TRUE, + "no-op" }, + { "rated", + RatedCommand, + TRUE, + FALSE, + FALSE, + "Inform the engine that this is a rated game" }, + { "rating", + RatingCommand, + TRUE, + FALSE, + TRUE, + "Inform the engine ratings" }, + { "remove", + RemoveCommand, + FALSE, + FALSE, + TRUE, + "Take back a full move" }, + { "result", + ResultCommand, + FALSE, + FALSE, + TRUE, + "Inform the engine about a game result" }, + { "script", + ScriptCommand, + FALSE, + FALSE, + FALSE, + "Run a script" }, + { "sd", + SearchDepthCommand, + TRUE, + FALSE, + TRUE, + "Set engine maximum search depth" }, + { "set", + SetCommand, + TRUE, + FALSE, + FALSE, + "View or change an engine variable" }, + { "setboard", + SetBoardCommand, + FALSE, + FALSE, + TRUE, + "Load a board position" }, + { "solution", + SolutionCommand, + FALSE, + FALSE, + FALSE, + "Set a solution move (up to three)" }, + { "sn", + SearchNodesCommand, + FALSE, + FALSE, + TRUE, + "Set the engine max nodes per search limit" }, + { "st", + SearchTimeCommand, + FALSE, + FALSE, + TRUE, + "Set the engine search time" }, + { "test", + TestCommand, + FALSE, + FALSE, + FALSE, + "Run an internal debugging command" }, + { "time", + TimeCommand, + TRUE, + FALSE, + TRUE, + "Tell the engine how its clock stands" }, + { "undo", + UndoCommand, + FALSE, + FALSE, + TRUE, + "Take back a halfmove" }, + { "unrated", + UnratedCommand, + TRUE, + FALSE, + FALSE, + "Tell the engine that the game is unrated" }, + { "variant", + VariantCommand, + FALSE, + FALSE, + TRUE, + "Tell the engine what variant the game is" }, + { "version", + VersionCommand, + TRUE, + FALSE, + FALSE, + "Display current version number and build options" }, + { "white", + WhiteCommand, + FALSE, + FALSE, + TRUE, + "Sets white to move, engine plays black" }, + { "winboard", + XboardCommand, + TRUE, + TRUE, + TRUE, + "Internal part of the WinBoard protocol" }, + { "xboard", + XboardCommand, + TRUE, + TRUE, + TRUE, + "Internal part of the WinBoard protocol" }, +}; + + +COMMAND(HelpCommand) +{ + char *command = NULL; + ULONG u; + + // + // If passed an argument, give help only about that command. + // TODO: divert to a more specific help page here if available. + // + if (argc > 1) + { + command = argv[1]; + for (u = 0; u < ARRAY_LENGTH(g_ParserTable); u++) + { + if ((!g_ParserTable[u].fInvisible) && + (!STRCMPI(command, g_ParserTable[u].szOpcode))) + { + Trace("%-13s: %s\n", + g_ParserTable[u].szOpcode, + g_ParserTable[u].szSimpleHelp); + } + } + return; + } + + // + // Otherwise general help about all commands. + // + Trace("xboard/WinBoard protocol support commands:\n" + "------------------------------------------\n"); + for (u = 0; u < ARRAY_LENGTH(g_ParserTable); u++) + { + if ((g_ParserTable[u].fWinBoard) && (!g_ParserTable[u].fInvisible)) { + Trace("%-13s: %s\n", + g_ParserTable[u].szOpcode, + g_ParserTable[u].szSimpleHelp); + } + } + Trace("\nInternal engine commands:\n" + "-------------------------\n"); + for (u = 0; u < ARRAY_LENGTH(g_ParserTable); u++) + { + if ((!g_ParserTable[u].fWinBoard) && (!g_ParserTable[u].fInvisible)) { + Trace("%-13s: %s\n", + g_ParserTable[u].szOpcode, + g_ParserTable[u].szSimpleHelp); + } + } +} + + +void +ParseUserInput(FLAG fSearching) +/** + +Routine description: + +Parameters: + + FLAG fSearching + +Return value: + + void + +**/ +{ + CHAR *pCapturedInput = NULL; + CHAR *pFreeThis = NULL; + CHAR *pDontFree; + CHAR *p, *q; + ULONG u; + CHAR *argv[MAX_ARGS]; + ULONG argc = 0; + FLAG fInQuote = FALSE; + MOVE mv; + POSITION *pos = GetRootPosition(); +#if 0 + static ULONG uHeapAllocated = 0; + + if (0 == uHeapAllocated) + { + uHeapAllocated = GetHeapMemoryUsage(); + } else { + ASSERT(uHeapAllocated == GetHeapMemoryUsage()); + uHeapAllocated = GetHeapMemoryUsage(); + } +#endif + // + // If we are in batch mode and there is no waiting input, exit. + // + if (g_Options.fNoInputThread && (0 == NumberOfPendingInputEvents())) + { + Trace("Exhausted input in batch mode, exiting...\n"); + exit(-1); + } + + // + // By the time we see this the input thread is likely already + // exited so don't try to read from the queue... + // + if (g_fExitProgram == TRUE) + { + QuitCommand("quit", 1, NULL, pos); + return; + } + + // + // If we are searching, don't actually read the input event yet. + // Just peek and leave it there until we know whether we can do + // it or not. + // + if (TRUE == fSearching) + { + ASSERT(g_Options.fPondering || g_Options.fThinking); + p = pDontFree = PeekNextInput(); + } else { + p = pFreeThis = BlockingReadInput(); + } + if (NULL == p) + { + goto end; + } + + // + // Skip over leading whitespace and do not parse comment lines + // + while((*p) && (isspace(*p))) p++; + if (((*p) && (*p == '#')) || + ((*p) && (*(p+1)) && (*p == '/') && (*(p+1) == '/'))) + { + goto consume_if_searching; + } + + // + // Chop the last \n out of the string + // + q = p; + while(*q) + { + if (*q == '\n') + { + *q = '\0'; + break; + } + q++; + } + + // + // Break it up into chunks for the COMMAND functions. + // + pCapturedInput = STRDUP(p); + memset(argv, 0, sizeof(argv)); + do + { + while(*p && isspace(*p)) p++; + if (!*p) break; + argv[argc++] = p; + fInQuote = FALSE; + while (*p) + { + if (*p == '"') + { + fInQuote = !fInQuote; + } + else if (*p == '{') + { + fInQuote = TRUE; + } + else if (*p == '}') + { + fInQuote = FALSE; + } + else if (isspace(*p) && (FALSE == fInQuote)) + { + break; + } + p++; + } + if (!*p) break; + *p = '\0'; + p++; + } + while(argc < MAX_ARGS); + if (argc == 0) + { + goto consume_if_searching; + } + + // + // Does it look like a move? + // + mv.uMove = 0; + switch(LooksLikeMove(argv[0])) + { + case MOVE_SAN: + mv = ParseMoveSan(argv[0], pos); + break; + case MOVE_ICS: + mv = ParseMoveIcs(argv[0], pos); + break; + case NOT_MOVE: + for (u = 0; u < ARRAY_LENGTH(g_ParserTable); u++) + { + if (!STRCMPI(g_ParserTable[u].szOpcode, argv[0])) + { + if (TRUE == fSearching) + { + if (TRUE == g_ParserTable[u].fHandleOnTheFly) + { + // + // We can do that command on the fly in + // the middle of the search. Note: these + // commands MUST NOT affect anything that + // the search is doing or you'll get + // corruption. + // + (*g_ParserTable[u].pFunction) + (pCapturedInput, argc, argv, pos); + goto consume_if_searching; + } else { + // + // We can't handle that input without + // unrolling the search first. + // + Trace("COMPLEX INPUT --> stop searching now\n"); + ASSERT(pDontFree); + strcpy(pDontFree, pCapturedInput); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + goto end; + } + } else { + // + // We were called from the main loop or from + // the script parser. No one is searching. + // Just do the command. + // + (*g_ParserTable[u].pFunction) + (pCapturedInput, argc, argv, pos); + goto end; + } + } + } + if ((TRUE == LooksLikeFen(pCapturedInput)) && + (TRUE == SetRootPosition(pCapturedInput))) + { + goto end; + } + break; +#ifdef DEBUG + default: + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + break; +#endif + } + + // + // Was it a move? + // + if (mv.uMove) + { + if (fSearching == TRUE) + { + // + // No one should move (my pieces) while I'm thinking! + // + ASSERT(g_Options.fPondering == TRUE); + ASSERT(g_Options.fThinking == FALSE); + if (IS_SAME_MOVE(mv, g_Options.mvPonder)) + { + Trace("PREDICTED MOVE PLAYED --> converting to search\n"); + g_Options.fSuccessfulPonder = TRUE; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + SetMoveTimerForSearch(TRUE, FLIP(GET_COLOR(mv.pMoved))); + goto consume_if_searching; + } else { + g_MoveTimer.bvFlags |= TIMER_STOPPING; + if (TRUE == OfficiallyMakeMove(mv, 0, FALSE)) + { + Trace("NONPREDICTED MOVE PLAYED --> stop pondering now\n"); + goto end; + } else { + UtilPanic(GOT_ILLEGAL_MOVE_WHILE_PONDERING, + GetRootPosition(), + (void *)mv.uMove, + NULL, + NULL, + __FILE__, __LINE__); + } + } + } else { + if (FALSE == OfficiallyMakeMove(mv, 0, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)mv.uMove, + NULL, + NULL, + __FILE__, __LINE__); + } + } + } else { + Trace("Unknown/illegal move/command: \"%s\"\n", pCapturedInput); + } + + consume_if_searching: + if (TRUE == fSearching) + { + ASSERT(NULL == pFreeThis); + ASSERT(NumberOfPendingInputEvents() > 0); + pFreeThis = BlockingReadInput(); + } + // fall through + + end: + if (NULL != pFreeThis) + { + SystemFreeMemory(pFreeThis); + pFreeThis = NULL; + } + if (NULL != pCapturedInput) + { + SystemFreeMemory(pCapturedInput); + pCapturedInput = NULL; + } +// ASSERT(uHeapAllocated == GetHeapMemoryUsage()); +} diff --git a/src/compiler.h b/src/compiler.h new file mode 100755 index 0000000..a155d4c --- /dev/null +++ b/src/compiler.h @@ -0,0 +1,89 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + system.h + +Abstract: + +Author: + + Scott Gasch (scott@wannabe.guru.org) 8 Apr 2004 + +Revision History: + + $Id: compiler.h 349 2008-06-28 02:48:59Z scott $ + +**/ + +#ifndef COMPILER_H_ +#define COMPILER_H_ + +#if defined _MSC_VER + +#include + +#pragma warning(disable:4201) // nonstandard extension: nameless struct/union +#pragma warning(disable:4214) // nonstandard extension: bitfields struct + +#define PROFILE "" +#define ALIGN64 __declspec(align(64)) +#define TB_FASTCALL __fastcall +#define COMPILER_STRING "Microsoft(R) Visual C/C++ %u\n", _MSC_VER +#define open _open +#define write _write +#define COMPILER_LONGLONG __int64 +#define COMPILER_VSNPRINTF _vsnprintf +#define CDECL __cdecl +#define FASTCALL __fastcall +#define INLINE __inline +#define FORCEINLINE __forceinline +#define NORETURN +#define CONSTFUNCT +#define COMPILER_LONGLONG_HEX_FORMAT "I64x" +#define COMPILER_LONGLONG_UNSIGNED_FORMAT "I64u" +#define STRNCMPI _strnicmp +#define STRCMPI strcmpi +#define STRDUP SystemStrDup + +#elif defined __GNUC__ + +#include + +extern int errno; + +#define COMPILER_STRING "GCC "__VERSION__"\n" +#define BUILD_STRING __OPTIMIZE__ + +#define O_BINARY (0) +#define O_RANDOM (0) +#define _S_IREAD (0) +#define _S_IWRITE (0) + +#define ALIGN64 // __attribute__ (aligned(64)) does not work +#define COMPILER_LONGLONG long long +#define COMPILER_VSNPRINTF vsnprintf +#ifndef SIXTYFOUR +#define CDECL __attribute__((cdecl)) +#endif +#define FASTCALL __attribute__((__regparm__(3))) +#define INLINE __inline__ +#define FORCEINLINE __attribute__((always_inline)) +#define NORETURN __attribute__((noreturn)) +#define CONSTFUNCT __attribute__((const)) +#define COMPILER_LONGLONG_HEX_FORMAT "llx" +#define COMPILER_LONGLONG_UNSIGNED_FORMAT "llu" +#define STRNCMPI strncasecmp +#define STRCMPI strcasecmp +#define STRDUP SystemStrDup +#define TB_FASTCALL // __attribute__((__regparm__(3))) + +#else + +#error "Unknown compiler, please edit compiler.h" + +#endif /* What compiler?! */ + +#endif /* COMPILER_H_ */ diff --git a/src/data.c b/src/data.c new file mode 100755 index 0000000..af43fd0 --- /dev/null +++ b/src/data.c @@ -0,0 +1,598 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + data.c + +Abstract: + + Large data structures and the code that creates/verifies them. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 10 May 2004 + +Revision History: + + $Id: data.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +// Distance between two squares lookup table +ULONG g_uDistance[256]; +ULONG *g_pDistance = &(g_uDistance[128]); + +// Who controls the square lookup table +CHAR g_SwapTable[14][32][32]; + +// Vector (bitvector indicating which pieces can move between squares) and +// Delta (direction to travel to get from square a to square b) lookup table. +VECTOR_DELTA g_VectorDelta[256]; +VECTOR_DELTA *g_pVectorDelta = &(g_VectorDelta[128]); + +// How many generated moves should we bother to sort +ULONG g_uSearchSortLimits[MAX_PLY_PER_SEARCH]; + +// Hardcoded move patterns to terminate PVs with +MOVE NULLMOVE = {0}; +MOVE HASHMOVE = {0x11118888}; +MOVE RECOGNMOVE = {0x22228888}; +MOVE DRAWMOVE = {0x33338888}; +MOVE MATEMOVE = {0x44448888}; + +// Is a square white? +FLAG g_fIsWhiteSquare[128]; + +#ifdef DEBUG +COOR +DistanceBetweenSquares(COOR a, COOR b) +{ + int i = (int)a - (int)b + 128; + int j = (int)b - (int)a + 128; + ASSERT(IS_ON_BOARD(a)); + ASSERT(IS_ON_BOARD(b)); + ASSERT((i >= 0) && (i < 256)); + ASSERT(g_uDistance[i] == REAL_DISTANCE(a, b)); + ASSERT(g_pDistance[a - b] == g_uDistance[i]); + ASSERT(g_pDistance[b - a] == g_uDistance[i]); + ASSERT(g_uDistance[j] == REAL_DISTANCE(a, b)); + return(REAL_DISTANCE(a, b)); +} + +#define VALID_VECTOR(x) \ + (((x) == 0) || \ + ((x) == (1 << KNIGHT)) || \ + ((x) == ( (1 << BISHOP) | (1 << QUEEN))) || \ + ((x) == ( (1 << ROOK) | (1 << QUEEN))) || \ + ((x) == ( (1 << BISHOP) | (1 << QUEEN) | (1 << KING))) || \ + ((x) == ( (1 << ROOK) | (1 << QUEEN) | (1 << KING))) || \ + ((x) == ( (1 << BISHOP) | (1 << QUEEN) | (1 << KING) | (1 << PAWN)))) + + +#define VALID_INDEX(x) \ + (((x) >= -128) && ((x) <= 127)) + +ULONG +CheckVectorWithIndex(int i, ULONG uColor) +{ + ULONG u; + ASSERT(VALID_INDEX(i)); + ASSERT(IS_VALID_COLOR(uColor)); + u = g_pVectorDelta[i].iVector[uColor]; + ASSERT(VALID_VECTOR(u)); + ASSERT(u == g_VectorDelta[i + 128].iVector[uColor]); + ASSERT(&(g_pVectorDelta[i]) == &(g_VectorDelta[i + 128])); + return(u); +} + +#define VALID_DELTA(x) \ + (((x) == 0) || \ + ((x) == +1) || ((x) == -1) || \ + ((x) == +16) || ((x) == -16) || \ + ((x) == +15) || ((x) == -15) || \ + ((x) == +17) || ((x) == -17)) + +int +DirectionBetweenSquaresWithIndex(int i) +{ + int iDir; + ASSERT(VALID_INDEX(i)); + iDir = g_pVectorDelta[i].iDelta; + ASSERT(iDir == g_VectorDelta[i + 128].iDelta); + ASSERT(&(g_pVectorDelta[i]) == &(g_VectorDelta[i + 128])); + ASSERT(VALID_DELTA(iDir)); + ASSERT(iDir == -g_pVectorDelta[i].iNegDelta); + return(iDir); +} + +int +DirectionBetweenSquaresFromTo(COOR from, COOR to) +{ + int i = (int)from - (int)to; + return DirectionBetweenSquaresWithIndex(i); +} + +int +NegativeDirectionBetweenSquaresWithIndex(int i) +{ + int iDir; + ASSERT(VALID_INDEX(i)); + iDir = g_pVectorDelta[i].iNegDelta; + ASSERT(iDir == g_VectorDelta[i + 128].iNegDelta); + ASSERT(&(g_pVectorDelta[i]) == &(g_VectorDelta[i + 128])); + ASSERT(VALID_DELTA(iDir)); + ASSERT(iDir == -g_pVectorDelta[i].iDelta); + return(iDir); +} + +int +DirectionBetweenSquares(COOR cFrom, COOR cTo) +{ + int i = (int)cFrom - (int)cTo; + return(DirectionBetweenSquaresWithIndex(i)); +} + +FLAG +IsSquareWhite(COOR c) +{ + BITBOARD bb; + FLAG f = IS_WHITE_SQUARE_COOR(c); + ASSERT(IS_ON_BOARD(c)); + ASSERT(f == g_fIsWhiteSquare[c]); + bb = COOR_TO_BB(c); + ASSERT(f == ((bb & BBWHITESQ) != 0)); + ASSERT(f == ((bb & BBBLACKSQ) == 0)); + return(f); +} +#endif + +void +VerifyVectorDelta(void) +{ + int iIndex; + int iChecksum = 0; + + for (iIndex = 0; + iIndex < 256; + iIndex++) + { + ASSERT(VALID_VECTOR(g_VectorDelta[iIndex].iVector[BLACK])); + ASSERT(VALID_VECTOR(g_VectorDelta[iIndex].iVector[WHITE])); + ASSERT(VALID_DELTA(g_VectorDelta[iIndex].iDelta)); + ASSERT(VALID_DELTA(g_VectorDelta[iIndex].iNegDelta)); + ASSERT(-g_VectorDelta[iIndex].iDelta == + g_VectorDelta[iIndex].iNegDelta); + iChecksum += g_VectorDelta[iIndex].iVector[BLACK] * iIndex; + iChecksum += g_VectorDelta[iIndex].iVector[WHITE] * iIndex; + iChecksum += g_VectorDelta[iIndex].iDelta * iIndex; + } + + if (iChecksum != 0xb1b58) + { + UtilPanic(DETECTED_INCORRECT_INITIALIZATION, + NULL, + "vector/delta", + (void *)iChecksum, + (void *)0xb1b58, + __FILE__, __LINE__); + } +} + +void +InitializeSearchDepthArray(void) +{ + ULONG x; + + for (x = 0; + x < ARRAY_LENGTH(g_uSearchSortLimits); + x++) + { + g_uSearchSortLimits[x] = 5; + } + g_uSearchSortLimits[0] = 0; + g_uSearchSortLimits[1] = 17; + g_uSearchSortLimits[2] = 12; + g_uSearchSortLimits[3] = 9; + g_uSearchSortLimits[4] = 7; + g_uSearchSortLimits[5] = 6; +} + +#ifdef DEBUG +ULONG +GetSearchSortLimit(ULONG uPly) +{ + ASSERT(uPly > 0); + ASSERT(uPly < MAX_PLY_PER_SEARCH); + ASSERT(g_uSearchSortLimits[uPly] != 0); + return(g_uSearchSortLimits[uPly]); +} +#endif + +void +InitializeWhiteSquaresTable(void) +{ + COOR c; + + FOREACH_SQUARE(c) + { + g_fIsWhiteSquare[c] = FALSE; + if (!IS_ON_BOARD(c)) + { + continue; + } + g_fIsWhiteSquare[c] = IS_WHITE_SQUARE_COOR(c); + } +} + +void +InitializeVectorDeltaTable(void) +{ + COOR cStart; + COOR cNew; + COOR cRay; + int iIndex; + PIECE p; + int iDir; + ULONG u; + static const BYTE _LOCATIONS[] = + { + D4, A5, A3, G3, C1, B5, H4, E5, E3, A6, C5, A5, A5, + G5, A6, D3, D2, A5, E1, E1, A6, H4, B2, D1, D2, E5 + }; + static int iNumDirs[7] = { 0, 0, 8, 4, 4, 8, 8 }; + static int iDelta[7][8] = { { 0, 0, 0, 0, 0, 0, 0, 0 }, + { 0, 0, 0, 0, 0, 0, 0, 0 }, + { -33, -31, -18, -14, +14, +18, +31, +33 }, + { -17, -15, +15, +17, 0, 0, 0, 0 }, + { -16, -1, +1, +16, 0, 0, 0, 0 }, + { -17, -16, -15, -1, +1, +15, +16, +17 }, + { -17, -16, -15, -1, +1, +15, +16, +17 } }; + + memset(g_VectorDelta, 0, sizeof(g_VectorDelta)); + FOREACH_SQUARE(cStart) + { + if (!IS_ON_BOARD(cStart)) continue; + for (u = 0; u < ARRAY_LENGTH(_LOCATIONS); u++) + { + if (cStart == _LOCATIONS[u]) + { + iIndex = 0; + } + } + + // + // Do the pawn bits + // + iIndex = (int)cStart - ((int)cStart - 17) + 128; + g_VectorDelta[iIndex].iVector[WHITE] |= (1 << PAWN); + iIndex = (int)cStart - ((int)cStart - 15) + 128; + g_VectorDelta[iIndex].iVector[WHITE] |= (1 << PAWN); + + iIndex = (int)cStart - ((int)cStart + 17) + 128; + g_VectorDelta[iIndex].iVector[BLACK] |= (1 << PAWN); + iIndex = (int)cStart - ((int)cStart + 15) + 128; + g_VectorDelta[iIndex].iVector[BLACK] |= (1 << PAWN); + + // + // Do the piece bits + // + for (p = KNIGHT; p <= KING; p++) + { + for (iDir = 0; + iDir < iNumDirs[p]; + iDir++) + { + cRay = cStart; + cNew = cRay + iDelta[p][iDir]; + while (IS_ON_BOARD(cNew)) + { + iIndex = (int)cStart - (int)cNew + 128; + + // + // Fill in the vector + // + g_VectorDelta[iIndex].iVector[WHITE] |= (1 << p); + g_VectorDelta[iIndex].iVector[BLACK] |= (1 << p); + + // + // Fill in the delta + // + if (FILE(cStart) == FILE(cNew)) + { + if (cStart < cNew) + { + g_VectorDelta[iIndex].iDelta = 16; + g_VectorDelta[iIndex].iNegDelta = -16; + } + else + { + g_VectorDelta[iIndex].iDelta = -16; + g_VectorDelta[iIndex].iNegDelta = 16; + } + } + else if (RANK(cStart) == RANK(cNew)) + { + if (cStart < cNew) + { + g_VectorDelta[iIndex].iDelta = 1; + g_VectorDelta[iIndex].iNegDelta = -1; + } + else + { + g_VectorDelta[iIndex].iDelta = -1; + g_VectorDelta[iIndex].iNegDelta = 1; + } + } + else if ((cStart % 15) == (cNew % 15)) + { + if (cStart < cNew) + { + g_VectorDelta[iIndex].iDelta = +15; + g_VectorDelta[iIndex].iNegDelta = -15; + } + else + { + g_VectorDelta[iIndex].iDelta = -15; + g_VectorDelta[iIndex].iNegDelta = 15; + } + } + else if ((cStart % 17) == (cNew % 17)) + { + if (cStart < cNew) + { + g_VectorDelta[iIndex].iDelta = +17; + g_VectorDelta[iIndex].iNegDelta = -17; + } + else + { + g_VectorDelta[iIndex].iDelta = -17; + g_VectorDelta[iIndex].iNegDelta = 17; + } + } + cNew += iDelta[p][iDir]; + + if ((KING == p) || (KNIGHT == p)) + { + break; + } + } + } + } + } + + (void)VerifyVectorDelta(); +#ifdef OSX + // + // nasm under OSX/macho has a nasty bug that causes the addresses + // of extern symbols to be screwed up. I only use two extern data + // structs in the x86.asm code: the vector delta table and the + // piece data table. My workaround to the nasm bug is to copy + // these tables into a symbol in the asm module and access them + // locally on OSX. + // + extern VECTOR_DELTA *g_NasmVectorDelta; + extern PIECE_DATA *g_NasmPieceData; + + memcpy(&g_NasmVectorDelta, &g_VectorDelta, sizeof(g_VectorDelta)); + memcpy(&g_NasmPieceData, &g_PieceData, sizeof(g_PieceData)); +#endif +} + +// +// TODO: fix this to use attack counts also +// +void +InitializeSwapTable(void) +{ + ULONG GET_HIGH_BIT[32] = + { + 0, // 00000 = 0 + 1, // 00001 = 1 + 2, // 00010 = 2 + 2, // 00011 = 3 + 4, // 00100 = 4 + 4, // 00101 = 5 + 4, // 00110 = 6 + 4, // 00111 = 7 + 8, // 01000 = 8 + 8, // 01001 = 9 + 8, // 01010 = 10 + 8, // 01011 = 11 + 8, // 01100 = 12 + 8, // 01101 = 13 + 8, // 01110 = 14 + 8, // 01111 = 15 + 16, // 10000 = 16 + 16, // 10001 = 17 + 16, // 10010 = 18 + 16, // 10011 = 19 + 16, // 10100 = 20 + 16, // 10101 = 21 + 16, // 10110 = 22 + 16, // 10111 = 23 + 16, // 11000 = 24 + 16, // 11001 = 25 + 16, // 11010 = 26 + 16, // 11011 = 27 + 16, // 11100 = 28 + 16, // 11101 = 29 + 16, // 11110 = 30 + 16 // 11111 = 31 + }; + ULONG uOnMove; + PIECE p; + ULONG uAtStake; + ULONG uBlack; + ULONG uWhite; + ULONG uOld; + ULONG uGains[2]; + ULONG uAttacks[2]; + INT iDiff; + + for (p = 0; p <= WHITE_KING; p++) + { + if (p > 1) + { + for (uBlack = 0; uBlack < 32; uBlack++) + { + for (uWhite = 0; uWhite < 32; uWhite++) + { + uGains[BLACK] = uGains[WHITE] = 0; + uAttacks[BLACK] = uBlack; + uAttacks[WHITE] = uWhite; + uAtStake = PIECE_VALUE(p); + uOnMove = WHITE; + if (GET_COLOR(p) == WHITE) + { + uOnMove = BLACK; + } + + // + // Ok, if the side on move has an attack, play it + // and give them credit for some plunder. + // + while(uAttacks[uOnMove]) + { + uOld = uAtStake; + uGains[uOnMove] += uAtStake; + uAtStake = GET_HIGH_BIT[uAttacks[uOnMove]]; + if (uAtStake == 16) + { + uAtStake = VALUE_PAWN; + } + else if (uAtStake == 8) + { + uAtStake = VALUE_BISHOP; + } + else if (uAtStake == 4) + { + uAtStake = VALUE_ROOK; + } + else if (uAtStake == 2) + { + uAtStake = VALUE_QUEEN; + } + else if (uAtStake == 1) + { + // + // Don't let them move into check + // + if (uAttacks[FLIP(uOnMove)]) + { + uGains[uOnMove] -= uOld; + uAtStake = 0; + } + break; + } + else + { + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + } + uAttacks[uOnMove] &= ~GET_HIGH_BIT[uAttacks[uOnMove]]; + uOnMove = FLIP(uOnMove); + } + + // + // The side on move doesn't have an attack... does + // the side not on move have an attack? If so they + // get a chance to assert some more control. + // + if (uAttacks[FLIP(uOnMove)]) + { + uGains[FLIP(uOnMove)] += 100; + } + + if (uGains[BLACK] > uGains[WHITE]) + { + iDiff = uGains[BLACK] - uGains[WHITE]; + iDiff /= 100; + iDiff += (iDiff == 0); + g_SwapTable[p][uWhite][uBlack] = MIN(+127, iDiff); + g_SwapTable[p][uWhite][uBlack] *= -1; + } + else if (uGains[WHITE] > uGains[BLACK]) + { + iDiff = uGains[WHITE] - uGains[BLACK]; + iDiff /= 100; + iDiff += (iDiff == 0); + g_SwapTable[p][uWhite][uBlack] = MIN(+127, iDiff); + } + else + { + g_SwapTable[p][uWhite][uBlack] = 0; + } + } + } + } + else // no piece sitting there + { + for (uBlack = 0; uBlack < 32; uBlack++) + { + for (uWhite = 0; uWhite < 32; uWhite++) + { + if (uBlack > uWhite) + { + g_SwapTable[p][uWhite][uBlack] = -1; + } + else if (uWhite > uBlack) + { + g_SwapTable[p][uWhite][uBlack] = +1; + } + else + { + g_SwapTable[p][uWhite][uBlack] = 0; + } + } + } + } + } +} + +void +InitializeDistanceTable(void) +{ + COOR x, y; + int i; +#ifdef DEBUG + int j; +#endif + + for (x = 0; x < 128; x++) + { + if (!IS_ON_BOARD(x)) continue; + for (y = 0; y < 128; y++) + { + if (!IS_ON_BOARD(y)) continue; + i = (int)x - (int)y; + i += 128; + g_uDistance[i] = REAL_DISTANCE(x, y); + ASSERT(g_uDistance[i] >= 0); + ASSERT(g_uDistance[i] <= 7); + } + } + +#ifdef DEBUG + for (x = 0; x < 128; x++) + { + if (!IS_ON_BOARD(x)) continue; + for (y = 0; y < 128; y++) + { + if (!IS_ON_BOARD(y)) continue; + i = (int)x - (int)y + 128; + ASSERT(g_uDistance[i] == REAL_DISTANCE(x, y)); + ASSERT(g_pDistance[x - y] == g_uDistance[i]); + ASSERT(&(g_pDistance[x - y]) == &(g_uDistance[i])); + j = (int)y - (int)x + 128; + ASSERT(g_uDistance[j] == REAL_DISTANCE(x, y)); + ASSERT(g_pDistance[y - x] == g_uDistance[j]); + ASSERT(&(g_pDistance[y - x]) == &(g_uDistance[j])); + } + } +#endif +} diff --git a/src/dox-comments.pl b/src/dox-comments.pl new file mode 100755 index 0000000..2850928 --- /dev/null +++ b/src/dox-comments.pl @@ -0,0 +1,36 @@ +#!/usr/bin/perl + +for $file (@ARGV) +{ + print "$file\n"; + + if (!open(FILE, $file)) + { + print "Cannot open $file: $!\n"; + next; + } + + if (-e "$file.$$") + { + print "$file.$$ already exists, I will not klobber.\n"; + next; + } + + if (!open(OUT, ">$file.$$")) + { + print "Cannot open $file.$$: $!\n"; + next; + } + + while () + { + s#^/\*\+\+#/\*\*#g; + s#^\-\-\*/#\*\*/#g; + print OUT; + } + close(FILE); + close(OUT); + print "processed $file\n"; + + system "/bin/mv -f $file.$$ $file"; +} diff --git a/src/draw.c b/src/draw.c new file mode 100755 index 0000000..75d1cd4 --- /dev/null +++ b/src/draw.c @@ -0,0 +1,79 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + draw.c + +Abstract: + + Function for detecting a draw by repetition from the search tree. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 19 May 2004 + +Revision History: + + $Id: draw.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +FLAG +IsDraw(SEARCHER_THREAD_CONTEXT *ctx) +{ + ULONG uPly; + UINT64 u64CurrentSig; + + // + // Recognize 50-moves w/o progress draw rule + // + if (ctx->sPosition.uFifty >= 100) + { + return(TRUE); + } + + // + // Check for repeated positions if needed. + // + if (ctx->sPosition.uFifty < 4) + { + return(FALSE); + } + + u64CurrentSig = (ctx->sPosition.u64NonPawnSig ^ + ctx->sPosition.u64PawnSig); + uPly = ctx->uPly - 2; + while(uPly < MAX_PLY_PER_SEARCH) + { +#ifdef DEBUG + if ((GET_COLOR(ctx->sPlyInfo[uPly].mv.pMoved) != + ctx->sPosition.uToMove) && + (ctx->sPlyInfo[uPly].mv.uMove != 0)) + { + ASSERT(FALSE); + } + ASSERT(ctx->sPlyInfo[uPly].u64Sig == (ctx->sPlyInfo[uPly].u64PawnSig ^ + ctx->sPlyInfo[uPly].u64NonPawnSig)); +#endif + if (ctx->sPlyInfo[uPly].u64Sig == u64CurrentSig) + { + return(TRUE); + } + + if (IS_PAWN(ctx->sPlyInfo[uPly].mv.pMoved) || + (ctx->sPlyInfo[uPly].mv.pCaptured)) + { + return(FALSE); + } + uPly -= 2; + } + + // + // Keep looking in the official game record. + // + return(DoesSigAppearInOfficialGameList(u64CurrentSig)); +} diff --git a/src/dumptree.c b/src/dumptree.c new file mode 100644 index 0000000..7a8f9e3 --- /dev/null +++ b/src/dumptree.c @@ -0,0 +1,357 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + dumptree.c + +Abstract: + + Support routines for dumping a search tree into an XML file for + offline analysis by typhoonui.exe. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 17 Jul 2004 + +Revision History: + +**/ + +#ifdef DUMP_TREE +#include "chess.h" + +#define NHUMAN_READABLE +#ifdef HUMAN_READABLE +#define SPACES_TO_INDENT_PER_PLY (2) +#else +#define SPACES_TO_INDENT_PER_PLY (0) +#endif +#define DISK_SECTOR_SIZE_BYTES (512) +#define NUM_SECTORS_TO_BUFFER (2) + +FILE *pfTreeDump = NULL; +ULONG g_uBufferSize = 0; +ULONG g_uBufferUsed = 0; +CHAR *g_Buffer = NULL; +#ifdef MP +volatile static ULONG g_uBufferLock = 0; +#define BUF_IS_LOCKED (g_uBufferLock != 0) +#define LOCK_BUF \ + AcquireSpinLock(&g_uBufferLock); \ + ASSERT(BUF_IS_LOCKED); +#define UNLOCK_BUF \ + ASSERT(BUF_IS_LOCKED); \ + ReleaseSpinLock(&g_uBufferLock); +#else // no MP +#define BUF_IS_LOCKED +#define LOCK_BUF +#define UNLOCK_BUF +#endif + +void +InitializeTreeDump(void) +/** + +Routine description: + + Initialize tree dumping system. + +Parameters: + + void + +Return value: + + void + +**/ +{ + // + // Allocate an internal buffer so that our writes to disk + // approximate a sector size. + // + g_uBufferSize = DISK_SECTOR_SIZE_BYTES * NUM_SECTORS_TO_BUFFER; + g_Buffer = SystemAllocateMemory(g_uBufferSize); + + // + // Here's the file we'll want to write to... + // + pfTreeDump = fopen("typhoon.xml", "wb+"); + if (NULL == pfTreeDump) + { + UtilPanic(FATAL_ACCESS_DENIED, + NULL, "typhoon.xml", "write", "NULL", __FILE__, __LINE__); + } + fprintf(pfTreeDump, "\n"); +} + +static +void _FlushTheBuffer(void) +/** + +Routine description: + + Flush the buffer to the disk file. + +Parameters: + + void + +Return value: + + void + +**/ +{ + fprintf(pfTreeDump, g_Buffer); + g_Buffer[0] = '\0'; + g_uBufferUsed = 0; +} + + +static void CDECL +_AppendToBuffer(CHAR *buf) +/** + +Routine description: + + Append a string to the buffer; possibly flush the buffer to disk + first to make enough room for the new string. + +Parameters: + + CHAR *buf : the string to append + +Return value: + + void + +**/ +{ + ULONG uSpaceNeeded; + ASSERT(BUF_IS_LOCKED); + + // + // How much space do we need? + // + uSpaceNeeded = strlen(buf); + ASSERT(uSpaceNeeded < MEDIUM_STRING_LEN_CHAR); + ASSERT(uSpaceNeeded < g_uBufferSize); + + // + // See if we need to flush the real buffer to the disk before we can + // append this new message. + // + LOCK_BUF; + if (g_uBufferUsed + uSpaceNeeded >= g_uBufferSize) + { + _FlushTheBuffer(); + ASSERT(g_uBufferUsed + uSpaceNeeded < g_uBufferSize); + } + + // + // Append the new data to the big buffer + // + strcat(g_Buffer, buf); + g_uBufferUsed += uSpaceNeeded; + ASSERT(g_uBufferUsed < g_uBufferSize); + UNLOCK_BUF; +} + + +static void _IndentTreeDumpMessage(ULONG uPly) +/** + +Routine description: + + Append a number of spaces to the buffer to indent the next output + appropriately based upon the current search ply. + +Parameters: + + ULONG uPly : the current search ply + +Return value: + + void + +**/ +{ + ULONG uSpaces = uPly * SPACES_TO_INDENT_PER_PLY; + ASSERT(uSpaces < g_uBufferSizeBytes); + ASSERT(HUMAN_READABLE); + while(uSpaces) + { + _AppendToBuffer(" "); + uSpaces--; + } +} + + +void CDECL +DTTrace(ULONG uPly, CHAR *szMessage, ...) +/** + +Routine description: + + A printf-like routine for adding a message to the buffer / dumpfile. + Note: messages that exceed MEDIUM_STRING_LEN_CHAR are truncated. + +Parameters: + + ULONG uPly : the current search ply + CHAR *szMessage : the message format string + ... : variable number of interpolated arguments + +Return value: + + void + +**/ +{ + va_list ap; + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + buf[0] = '\0'; + + // + // Populate the local buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 2, szMessage, ap); + va_end(ap); +#ifdef HUMAN_READABLE + strcat(buf, "\n"); + _IndentTreeDumpMessage(uPly); +#endif + _AppendToBuffer(buf); +} + + +void +CleanupTreeDump(void) +/** + +Routine description: + + Tear down the tree dumping system + +Parameters: + + void + +Return value: + + void + +**/ +{ + // + // Cleanup file and buffer + // + if (NULL != pfTreeDump) + { + _FlushTheBuffer(); + fflush(pfTreeDump); + fclose(pfTreeDump); + } + + if (NULL != g_Buffer) + { + SystemFreeMemory(g_Buffer); + g_Buffer = NULL; + g_uBufferSize = 0; + } +} + + +void +DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fIsQNode, + SCORE iAlpha, + SCORE iBeta) +/** + +Routine description: + + Called by search or qsearch upon entering a new node. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : searcher context + ULONG uDepth : depth + FLAG fIsQNode : is it a q node? + SCORE iAlpha : current alpha + SCORE iBeta : current beta + +Return value: + + void + +**/ +{ + ULONG uPly = ctx->uPly; + UINT64 u64NodeNum = ctx->sCounters.tree.u64TotalNodeCount; + CHAR *p; + + if (FALSE == fIsQNode) + { + DTTrace(uPly, "", u64NodeNum); + } + else + { + DTTrace(uPly, "", u64NodeNum); + p = PositionToFen(&ctx->sPosition); + ASSERT(p); + DTTrace(uPly + 1, "", p); + SystemFreeMemory(p); + DTTrace(uPly + 1, "", + iAlpha, iBeta, uPly, uDepth); + } +} + + +void +DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fQNode, + SCORE iBestScore, + MOVE mvBestMove) +/** + +Routine description: + + Called by the search upon leaving a normal (non q) node. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : searcher context + SCORE iBestScore : best score found + MOVE mvBestMove : best move found + +Return value: + + void + +**/ +{ + ULONG uPly = ctx->uPly; + + DTTrace(uPly + 1, "", + iBestScore, MoveToSan(mvBestMove, &ctx->sPosition)); + if (!fQNode) + { + DTTrace(uPly, ""); + } + else + { + DTTrace(uPly, ""); + } +} +#endif diff --git a/src/dynamic.c b/src/dynamic.c new file mode 100755 index 0000000..1c1e741 --- /dev/null +++ b/src/dynamic.c @@ -0,0 +1,515 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + dynamic.c + +Abstract: + + Dynamic move ordering functions/structures. By "dynamic move + ordering" I mean killer moves and history heuristic stuff. + + Note 1: there are two history tables here. One is used for move + ordering and the other is used for pruning decisions. Both only + contain data about non-capture/promote moves. The former is + updated with roughly remaining_depth^2 at a fail high while the + latter is updated so as to maintain an approximate answer to "what + percent of the time does this move fail high." + + Note 2: the globals in this module may be accessed by more than + one searcher thread at the same time; spinlocks used to + synchronize. + + Note 3: All of these tables must be cleared when a new game is + started or a new position is loaded onto the board. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 24 Jun 2004 + +Revision History: + + $Id: dynamic.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +ULONG g_HistoryCounters[14][128]; +#define FH_STATS_TABLE_SIZE (0x20000) + +typedef struct _FH_STATS +{ + union + { + ULONG uWholeThing; + struct + { + USHORT u16FailHighs; + USHORT u16Attempts; + }; + }; +} FH_STATS; + +FH_STATS g_FailHighs[FH_STATS_TABLE_SIZE]; + +#ifdef MP +volatile static ULONG g_uDynamicLock; +#define DYN_IS_LOCKED (g_uDynamicLock != 0) +#define LOCK_DYN \ + AcquireSpinLock(&g_uDynamicLock); \ + ASSERT(DYN_IS_LOCKED) +#define UNLOCK_DYN \ + ASSERT(DYN_IS_LOCKED); \ + ReleaseSpinLock(&g_uDynamicLock) +#else // no MP +#define DYN_IS_LOCKED (1) +#define LOCK_DYN +#define UNLOCK_DYN +#endif + + +FLAG +InitializeDynamicMoveOrdering(void) +/** + +Routine description: + + Initialize dynamic move ordering structures. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ +#ifdef MP + g_uDynamicLock = 0; +#endif + ClearDynamicMoveOrdering(); + return(TRUE); +} + +void +ClearDynamicMoveOrdering(void) +/** + +Routine description: + + Clear the global history table. Killer moves are per-context + structures and must be cleared on a per-context basis. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG u; + + memset(g_HistoryCounters, 0, sizeof(g_HistoryCounters)); + for (u = 0; u < FH_STATS_TABLE_SIZE; u++) + { + g_FailHighs[u].uWholeThing = 0x00010001; + } +} + + +static void +_RecordMoveFailHigh(MOVE mv) +/** + +Routine description: + + Update the "fail high percentage" history table for this move. + The table is used to make pruning decisions, not to rank moves. + +Parameters: + + MOVE mv + +Return value: + + static void + +**/ +{ + ULONG u = MOVE_TO_INDEX(mv); + ULONG v = g_FailHighs[u].uWholeThing; + + ASSERT(DYN_IS_LOCKED); + if (((v & 0x0000FFFF) == 0x0000FFFF) || ((v & 0xFFFF0000) == 0xFFFF0000)) + { + g_FailHighs[u].u16FailHighs >>= 1; + g_FailHighs[u].u16Attempts >>= 1; + } + g_FailHighs[u].u16FailHighs++; + g_FailHighs[u].u16Attempts++; + ASSERT(g_FailHighs[u].u16FailHighs != 0); + ASSERT(g_FailHighs[u].u16Attempts != 0); + ASSERT(g_FailHighs[u].u16Attempts >= g_FailHighs[u].u16FailHighs); +} + + +static void +_RecordMoveFailure(MOVE mv) +/** + +Routine description: + + Update the fail high percentage table with the information that a + move has not produced a fail high cutoff when it was considered. + +Parameters: + + MOVE mv + +Return value: + + static void + +**/ +{ + ULONG u = MOVE_TO_INDEX(mv); + + ASSERT(DYN_IS_LOCKED); + if (g_FailHighs[u].u16Attempts == 0xFFFF) + { + g_FailHighs[u].u16FailHighs >>= 1; + g_FailHighs[u].u16Attempts >>= 1; + } + g_FailHighs[u].u16Attempts++; + ASSERT(g_FailHighs[u].u16Attempts != 0); + ASSERT(g_FailHighs[u].u16Attempts >= g_FailHighs[u].u16FailHighs); +} + + +static void +_NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv, + SCORE iScore) +/** + +Routine description: + + Add a new killer move at a ply. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv, + SCORE iScore + +Return value: + + void + +**/ +{ + ULONG uPly = ctx->uPly; + + ASSERT(uPly >= 0); + ASSERT(uPly < MAX_PLY_PER_SEARCH); + ASSERT(!IS_CAPTURE_OR_PROMOTION(mv)); + ASSERT(mv.uMove); + + if (mv.bvFlags & MOVE_FLAG_ESCAPING_CHECK) + { + if (!IS_SAME_MOVE(mv, ctx->mvKillerEscapes[uPly][0])) + { + ctx->mvKillerEscapes[uPly][1] = ctx->mvKillerEscapes[uPly][0]; + ctx->mvKillerEscapes[uPly][0] = mv; + } + ASSERT(!IS_SAME_MOVE(ctx->mvKillerEscapes[uPly][0], + ctx->mvKillerEscapes[uPly][1])); + } + else + { + mv.bvFlags |= ((iScore >= +NMATE) * MOVE_FLAG_KILLERMATE); + if (!IS_SAME_MOVE(mv, ctx->mvKiller[uPly][0])) + { + ctx->mvKiller[uPly][1] = ctx->mvKiller[uPly][0]; + ctx->mvKiller[uPly][0] = mv; + if (ctx->mvKiller[uPly][1].uMove == 0) + { + ctx->mvKiller[uPly][1] = ctx->mvNullmoveRefutations[uPly]; + } + } + ASSERT(!IS_SAME_MOVE(ctx->mvKiller[uPly][0], ctx->mvKiller[uPly][1])); + } +} + + +static void +_IncrementMoveHistoryCounter(MOVE mv, + ULONG uDepth) +/** + +Routine description: + + Increase a move's history counter in the global history table. + Also affect the history pruning counters in prune.c. + +Parameters: + + MOVE mv, + ULONG uDepth + +Return value: + + void + +**/ +{ + ULONG x, y; + ULONG uVal; + ULONG *pu; + + ASSERT(!IS_CAPTURE_OR_PROMOTION(mv)); + uVal = uDepth / ONE_PLY; + ASSERT(uVal >= 0); + ASSERT(uVal <= MAX_PLY_PER_SEARCH); + uVal += 1; + uVal *= uVal; + ASSERT(uVal > 0); + + pu = &(g_HistoryCounters[mv.pMoved][mv.cTo]); + LOCK_DYN; + *pu += uVal; + + // + // Make sure that the history weight doesn't get large enough to + // affect the move flags or else our move ordering algorithm is + // screwed. + // + while (*pu & ~STRIP_OFF_FLAGS) + { + for (x = 0; x <= WHITE_KING; x++) + { + FOREACH_SQUARE(y) + { + g_HistoryCounters[x][y] >>= 4; + } + } + } + +#ifdef MP + // + // The purpose of this restriction is to ease contention for the + // memory bandwidth of the machine on dual-core / dual proc + // systems. The net result is positive. + // + if (uDepth > THREE_PLY) + { + _RecordMoveFailHigh(mv); + } +#else + _RecordMoveFailHigh(mv); +#endif + UNLOCK_DYN; +} + +static void +_DecrementMoveHistoryCounter(MOVE mv, + ULONG uDepth) +/** + +Routine description: + + Decrease a move's history counter in the global history table. + +Parameters: + + MOVE mv, + ULONG uDepth + +Return value: + + void + +**/ +{ + ULONG uVal; + ULONG *pu; + + ASSERT(!IS_CAPTURE_OR_PROMOTION(mv)); + uVal = uDepth / ONE_PLY; + ASSERT(uVal >= 0); + ASSERT(uVal <= MAX_PLY_PER_SEARCH); + uVal /= 4; + uVal += 1; + ASSERT(uVal > 0); + + pu = &(g_HistoryCounters[mv.pMoved][mv.cTo]); + LOCK_DYN; + if (*pu >= uVal) + { + *pu -= uVal; + } + else + { + *pu = 0; + } + _RecordMoveFailure(mv); + UNLOCK_DYN; +} + + +void +UpdateDynamicMoveOrdering(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN MOVE mvBest, + IN SCORE iScore, + IN ULONG uCurrent) +/** + +Routine description: + + Update dynamic move ordering structs for a particular move (and, + possibly, the other moves that were considered prior to this move + in the move ordering). This is called when a move beats alpha at + the root or in Search (but not in QSearch). + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG uRemainingDepth, + MOVE mvBest, + SCORE iScore, + ULONG uCurrent + +Return value: + + void + +**/ +{ + ULONG u; + MOVE mv; + + // + // Add this move to the killer list and increment its history count + // + if (!IS_CAPTURE_OR_PROMOTION(mvBest)) + { + _NewKillerMove(ctx, mvBest, iScore); + _IncrementMoveHistoryCounter(mvBest, uRemainingDepth); + } + + // + // If this move was not the first we considered at this node, + // decrement the history counters of moves we considered before + // it. + // + uCurrent -= (uCurrent != 0); + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < uCurrent; + u++) + { + ASSERT(IS_SAME_MOVE(ctx->sMoveStack.mvf[uCurrent].mv, mvBest)); + mv = ctx->sMoveStack.mvf[u].mv; + ASSERT(!IS_SAME_MOVE(mv, mvBest)); + if (!IS_CAPTURE_OR_PROMOTION(mv)) + { + _DecrementMoveHistoryCounter(mv, uRemainingDepth); + } + } +} + + + + +ULONG +GetMoveFailHighPercentage(IN MOVE mv) +/** + +Routine description: + + Lookup a move in the fail high percentage history table and return + its approximate fail high percentage. + +Parameters: + + MOVE mv + +Return value: + + ULONG + +**/ +{ + ULONG u = MOVE_TO_INDEX(mv); + ULONG n, d; + + n = g_FailHighs[u].u16FailHighs; + d = g_FailHighs[u].u16Attempts; + if (d == 0) + { + return(0); + } + n *= 100; + return(n / d); +} + + +void +CleanupDynamicMoveOrdering(void) +/** + +Routine description: + + Cleanup dynamic move ordering structs -- basically a noop for now. + +Parameters: + + void + +Return value: + + void + +**/ +{ + NOTHING; +} + + +void +MaintainDynamicMoveOrdering(void) +/** + +Routine description: + + Perform routine maintenance on dynamic move ordering data by + reducing the magnitude of the history counters. + +Parameters: + +Return value: + + void + +**/ +{ + ULONG x, y; + + LOCK_DYN; + for (x = 0; x <= WHITE_KING; x++) + { + FOREACH_SQUARE(y) + { + g_HistoryCounters[x][y] >>= 1; + } + } + UNLOCK_DYN; +} diff --git a/src/egtb.cpp b/src/egtb.cpp new file mode 100644 index 0000000..bc39636 --- /dev/null +++ b/src/egtb.cpp @@ -0,0 +1,6738 @@ +#include +#include +#include +#include +#if defined(_WIN32) +#include +#endif + +#define NEW +#define T41_INCLUDE +#define T42_INCLUDE +#define T33_INCLUDE +#define T_INDEX64 +#define XX 127 + +#if !defined(SMP) && !defined(SUN) +#define lock_t int +#endif + +#if defined (T_INDEX64) && defined (_MSC_VER) +typedef unsigned __int64 INDEX; +#elif defined (T_INDEX64) +typedef unsigned long long INDEX; +#else +typedef unsigned long INDEX; +#endif + +typedef unsigned int square; + +typedef int color; + +#define x_colorWhite 0 +#define x_colorBlack 1 +#define x_colorNeutral 2 + +typedef int piece; + +#define x_pieceNone 0 +#define x_piecePawn 1 +#define x_pieceKnight 2 +#define x_pieceBishop 3 +#define x_pieceRook 4 +#define x_pieceQueen 5 +#define x_pieceKing 6 + +/* + Macro that fetches positions of pieces + */ + +#define C_PIECES 3 /* Maximum # of pieces of one color OTB */ + +#define SqFindKing(psq) (psq[C_PIECES*(x_pieceKing-1)]) +#define SqFindOne(psq, pi) (psq[C_PIECES*(pi-1)]) +#define SqFindFirst(psq, pi) (psq[C_PIECES*(pi-1)]) +#define SqFindSecond(psq, pi) (psq[C_PIECES*(pi-1)+1]) +#define SqFindThird(psq, pi) (psq[C_PIECES*(pi-1)+2]) + +#include "lock.h" + +/* + All defined, now include probing code + */ + +/* -------------------------------------------------------------------- */ +/* */ +/* Probe chess endgame database ("tablebase") */ +/* */ +/* Copyright (c) 1998--2001 Eugene Nalimov */ +/* */ +/* The code listed below should not be used in any product (software or */ +/* hardware, commercial or not, and so on) without written permission */ +/* from the author. */ +/* */ +/* -------------------------------------------------------------------- */ + +#if defined (_WIN32) || defined(_WIN64) +# include +#endif + +#include +#include +#include +#if !defined (DEBUG) && !defined(NDEBUG) +# define NDEBUG +#endif +#include + +// SMP stuff + +#if defined (CPUS) && !defined (SMP) && (CPUS > 1) +# error Cannot use CPUS > 1 without SMP defined +#endif + +static lock_t lockLRU; + +// Declarations + +typedef unsigned char BYTE; +typedef unsigned long ULONG; +typedef signed char tb_t; + +#if !defined (COLOR_DECLARED) +typedef int color; +# define x_colorWhite 0 +# define x_colorBlack 1 +# define x_colorNeutral 2 +# define COLOR_DECLARED +#endif + +#if !defined (PIECES_DECLARED) +typedef int piece; +# define x_pieceNone 0 +# define x_piecePawn 1 +# define x_pieceKnight 2 +# define x_pieceBishop 3 +# define x_pieceRook 4 +# define x_pieceQueen 5 +# define x_pieceKing 6 +# define PIECES_DECLARED +#endif + +#if !defined (SqFind2) +# define SqFind2(psq,pi1,sq1,pi2,sq2) sq1=SqFindFirst(psq,pi1);sq2=SqFindFirst(psq,pi2); +#endif + +// Machine and compiler-specific declarations + +#if defined (_MSC_VER) + +# undef TB_CDECL +# define TB_CDECL __cdecl +# define TB_FASTCALL __fastcall +# if _MSC_VER >= 1200 +# define INLINE __forceinline +# endif + +#else + +# define TB_CDECL +# define TB_FASTCALL + +#endif + +#if !defined (INLINE) +# define INLINE inline +#endif + +// Printf formats + +#if defined (T_INDEX64) && defined (_MSC_VER) +# define HEX_INDEX_FORMAT "%016I64X" +# define DEC_INDEX_FORMAT "%I64u" +#elif defined (T_INDEX64) +# define HEX_INDEX_FORMAT "%016llX" +# define DEC_INDEX_FORMAT "%llu" +#else +# define HEX_INDEX_FORMAT "%08X" +# define DEC_INDEX_FORMAT "%lu" +#endif + +// Directory delimiter + +#if defined (_WIN32) || defined(_WIN64) +# define DELIMITER "\\" +#elif defined (__MWERKS__) +# define DELIMITER ":" +#else +# define DELIMITER "/" +#endif + + +// Some constants from SJE program + +#define pageL 256 + +/* tablebase byte entry semispan length */ + +#define tbbe_ssL ((pageL - 4) / 2) + +/* tablebase signed byte entry values */ + +#define bev_broken (tbbe_ssL + 1) /* illegal or busted */ + +#define bev_mi1 tbbe_ssL /* mate in 1 move */ +#define bev_mimin 1 /* mate in 126 moves */ + +#define bev_draw 0 /* draw */ + +#define bev_limax (-1) /* mated in 125 moves */ +#define bev_li0 (-tbbe_ssL) /* mated in 0 moves */ + +#define bev_limaxx (-tbbe_ssL - 1) /* mated in 126 moves */ +#define bev_miminx (-tbbe_ssL - 2) /* mate in 127 moves */ + +// Some constants for 16-bit tables + +#define L_pageL 65536 + +/* tablebase short entry semispan length */ + +#define L_tbbe_ssL ((L_pageL - 4) / 2) + +/* tablebase signed short entry values */ + +#define L_bev_broken (L_tbbe_ssL + 1) /* illegal or busted */ + +#define L_bev_mi1 L_tbbe_ssL /* mate in 1 move */ +#define L_bev_mimin 1 /* mate in 32766 moves */ + +#define L_bev_draw 0 /* draw */ + +#define L_bev_limax (-1) /* mated in 32765 moves */ +#define L_bev_li0 (-L_tbbe_ssL) /* mated in 0 moves */ + +#define L_bev_limaxx (-L_tbbe_ssL - 1) /* mated in 32766 moves */ +#define L_bev_miminx (-L_tbbe_ssL - 2) /* mate in 32767 moves */ + +// Convertion from 8-bit to 16-bit score +// UNDONE: Maybe implement via lookup table? + +#define S_to_L(tbt)\ + (\ + (0 == tbt) ? 0:\ + (tbt > 0) ? (bev_broken != tbt ? tbt + 32640 : L_bev_broken):\ + (tbt >= bev_li0) ? tbt - 32640:\ + (bev_limaxx == tbt) ? -32640:\ + /*bev_miminx == tbt*/ 32640\ + ) + +// Constants + +#define i8 ((unsigned) 8) +#define i14 ((unsigned) 14) +#define i42 ((unsigned) 42) +#define i43 ((unsigned) 43) +#define i44 ((unsigned) 44) +#define i45 ((unsigned) 45) +#define i46 ((unsigned) 46) +#define i47 ((unsigned) 47) +#define i48 ((unsigned) 48) +#define i57 ((unsigned) 57) +#define i58 ((unsigned) 58) +#define i59 ((unsigned) 59) +#define i60 ((unsigned) 60) +#define i61 ((unsigned) 61) +#define i62 ((unsigned) 62) +#define i63 ((unsigned) 63) +#define i64 ((unsigned) 64) + +#define x_row_1 0 +#define x_row_2 1 +#define x_row_3 2 +#define x_row_4 3 +#define x_row_5 4 +#define x_row_6 5 +#define x_row_7 6 +#define x_row_8 7 + +#define x_column_a 0 +#define x_column_b 1 +#define x_column_c 2 +#define x_column_d 3 +#define x_column_e 4 +#define x_column_f 5 +#define x_column_g 6 +#define x_column_h 7 + +/* reflection macros */ + +#define reflect_x(sq) ((sq) ^ 0x38) +#define reflect_y(sq) ((sq) ^ 0x07) +#define reflect_xy(sq) rgsqReflectXY[sq] + +static const square rgsqReflectXY [] = +{ + 0, 8, 16, 24, 32, 40, 48, 56, + 1, 9, 17, 25, 33, 41, 49, 57, + 2, 10, 18, 26, 34, 42, 50, 58, + 3, 11, 19, 27, 35, 43, 51, 59, + 4, 12, 20, 28, 36, 44, 52, 60, + 5, 13, 21, 29, 37, 45, 53, 61, + 6, 14, 22, 30, 38, 46, 54, 62, + 7, 15, 23, 31, 39, 47, 55, 63, +}; + +static const square rgsqReflectMaskY [] = +{ + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, +}; + +static const square rgsqReflectMaskYandX [] = +{ + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0, 0, 0, 0, 7, 7, 7, 7, + 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7, + 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7, + 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7, + 0x38, 0x38, 0x38, 0x38, 0x38+7, 0x38+7, 0x38+7, 0x38+7, +}; + +static const square rgsqReflectInvertMask[] = { 0, 0x38 }; + +/* useful macros */ + +#define TbRow(sq) ((sq) >> 3) +#define TbColumn(sq) ((sq) & 7) + +#if defined (NEW) +# define PchExt(side) ((x_colorWhite == side) ? ".nbw" : ".nbb") +#else +# define PchExt(side) ((x_colorWhite == side) ? ".tbw" : ".tbb") +#endif + +// Verbose levels + +static bool fPrint = false; // Print some technical statistics +static bool fVerbose = false; // Print additional information + +// Malloc that checks for out-of-memory condition + +static size_t cbAllocated; +static int cOpenFilesAttempts; +static int cOpenFilesSuceed; + +static void* PvMalloc + ( + size_t cb + ) + { + void *pv; + + pv = malloc (cb); + if (NULL == pv) + { + printf ("*** Cannot allocate %d bytes of memory\n", cb); + exit (1); + } + cbAllocated += cb; + return pv; + } + +#if defined (NEW) // New index schema ---------------------------------------- + +// 'Invalid' value have to be large, so index +// of invalid position will be very large, too. + +#define INF 4000 + +// Enumeration: valid positions with 2 kings on board; white king restricted to +// a1-d1-d4 triangle; also, if it's at a1-d4 half-diagonal, then black king +// must be in a1-h1-h8 triangle + +static const short rgsTriKings [64 * 64] = +{ + INF, INF, 0, 1, 2, 3, 4, 5, INF, INF, 6, 7, 8, 9, 10, 11, + INF, INF, 12, 13, 14, 15, 16, 17, INF, INF, INF, 18, 19, 20, 21, 22, + INF, INF, INF, INF, 23, 24, 25, 26, INF, INF, INF, INF, INF, 27, 28, 29, + INF, INF, INF, INF, INF, INF, 30, 31, INF, INF, INF, INF, INF, INF, INF, 32, + INF, INF, INF, 33, 34, 35, 36, 37, INF, INF, INF, 38, 39, 40, 41, 42, + 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, + 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, + 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, + 91, INF, INF, INF, 92, 93, 94, 95, 96, INF, INF, INF, 97, 98, 99, 100, + 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, + 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, + 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, + 149, 150, INF, INF, INF, 151, 152, 153, 154, 155, INF, INF, INF, 156, 157, 158, + 159, 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, + 175, 176, 177, 178, 179, 180, 181, 182, 183, 184, 185, 186, 187, 188, 189, 190, + 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, 202, 203, 204, 205, 206, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, 207, 208, 209, 210, 211, INF, INF, INF, 212, 213, 214, 215, 216, + INF, INF, INF, 217, 218, 219, 220, 221, INF, INF, INF, 222, 223, 224, 225, 226, + INF, INF, INF, INF, 227, 228, 229, 230, INF, INF, INF, INF, INF, 231, 232, 233, + INF, INF, INF, INF, INF, INF, 234, 235, INF, INF, INF, INF, INF, INF, INF, 236, + 237, INF, INF, INF, 238, 239, 240, 241, 242, INF, INF, INF, 243, 244, 245, 246, + 247, INF, INF, INF, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + 292, 293, INF, INF, INF, 294, 295, 296, 297, 298, INF, INF, INF, 299, 300, 301, + 302, 303, INF, INF, INF, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + 347, 348, 349, 350, 351, 352, 353, 354, INF, INF, INF, INF, 355, 356, 357, 358, + INF, INF, INF, INF, 359, 360, 361, 362, INF, INF, INF, INF, 363, 364, 365, 366, + INF, INF, INF, INF, 367, 368, 369, 370, INF, INF, INF, INF, INF, 371, 372, 373, + INF, INF, INF, INF, INF, INF, 374, 375, INF, INF, INF, INF, INF, INF, INF, 376, + 377, 378, 379, 380, 381, 382, 383, 384, 385, 386, INF, INF, INF, 387, 388, 389, + 390, 391, INF, INF, INF, 392, 393, 394, 395, 396, INF, INF, INF, 397, 398, 399, + 400, 401, 402, 403, 404, 405, 406, 407, 408, 409, 410, 411, 412, 413, 414, 415, + 416, 417, 418, 419, 420, 421, 422, 423, 424, 425, 426, 427, 428, 429, 430, 431, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + 432, 433, 434, 435, 436, 437, 438, 439, INF, 440, 441, 442, 443, 444, 445, 446, + INF, INF, INF, INF, INF, 447, 448, 449, INF, INF, INF, INF, INF, 450, 451, 452, + INF, INF, INF, INF, INF, 453, 454, 455, INF, INF, INF, INF, INF, 456, 457, 458, + INF, INF, INF, INF, INF, INF, 459, 460, INF, INF, INF, INF, INF, INF, INF, 461, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, +}; + +// Enumeration: all valid positions with 2 kings on board when white king +// restricted to left half of the board + +static const short rgsHalfKings [64 * 64] = +{ + INF, INF, 0, 1, 2, 3, 4, 5, INF, INF, 6, 7, 8, 9, 10, 11, + 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27, + 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, + 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, + INF, INF, INF, 60, 61, 62, 63, 64, INF, INF, INF, 65, 66, 67, 68, 69, + 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, + 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, + 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, + 118, INF, INF, INF, 119, 120, 121, 122, 123, INF, INF, INF, 124, 125, 126, 127, + 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, + 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, + 160, 161, 162, 163, 164, 165, 166, 167, 168, 169, 170, 171, 172, 173, 174, 175, + 176, 177, INF, INF, INF, 178, 179, 180, 181, 182, INF, INF, INF, 183, 184, 185, + 186, 187, 188, 189, 190, 191, 192, 193, 194, 195, 196, 197, 198, 199, 200, 201, + 202, 203, 204, 205, 206, 207, 208, 209, 210, 211, 212, 213, 214, 215, 216, 217, + 218, 219, 220, 221, 222, 223, 224, 225, 226, 227, 228, 229, 230, 231, 232, 233, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, 234, 235, 236, 237, 238, 239, INF, INF, 240, 241, 242, 243, 244, 245, + INF, INF, 246, 247, 248, 249, 250, 251, 252, 253, 254, 255, 256, 257, 258, 259, + 260, 261, 262, 263, 264, 265, 266, 267, 268, 269, 270, 271, 272, 273, 274, 275, + 276, 277, 278, 279, 280, 281, 282, 283, 284, 285, 286, 287, 288, 289, 290, 291, + INF, INF, INF, 292, 293, 294, 295, 296, INF, INF, INF, 297, 298, 299, 300, 301, + INF, INF, INF, 302, 303, 304, 305, 306, 307, 308, 309, 310, 311, 312, 313, 314, + 315, 316, 317, 318, 319, 320, 321, 322, 323, 324, 325, 326, 327, 328, 329, 330, + 331, 332, 333, 334, 335, 336, 337, 338, 339, 340, 341, 342, 343, 344, 345, 346, + 347, INF, INF, INF, 348, 349, 350, 351, 352, INF, INF, INF, 353, 354, 355, 356, + 357, INF, INF, INF, 358, 359, 360, 361, 362, 363, 364, 365, 366, 367, 368, 369, + 370, 371, 372, 373, 374, 375, 376, 377, 378, 379, 380, 381, 382, 383, 384, 385, + 386, 387, 388, 389, 390, 391, 392, 393, 394, 395, 396, 397, 398, 399, 400, 401, + 402, 403, INF, INF, INF, 404, 405, 406, 407, 408, INF, INF, INF, 409, 410, 411, + 412, 413, INF, INF, INF, 414, 415, 416, 417, 418, 419, 420, 421, 422, 423, 424, + 425, 426, 427, 428, 429, 430, 431, 432, 433, 434, 435, 436, 437, 438, 439, 440, + 441, 442, 443, 444, 445, 446, 447, 448, 449, 450, 451, 452, 453, 454, 455, 456, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + 457, 458, 459, 460, 461, 462, 463, 464, INF, INF, 465, 466, 467, 468, 469, 470, + INF, INF, 471, 472, 473, 474, 475, 476, INF, INF, 477, 478, 479, 480, 481, 482, + 483, 484, 485, 486, 487, 488, 489, 490, 491, 492, 493, 494, 495, 496, 497, 498, + 499, 500, 501, 502, 503, 504, 505, 506, 507, 508, 509, 510, 511, 512, 513, 514, + 515, 516, 517, 518, 519, 520, 521, 522, INF, INF, INF, 523, 524, 525, 526, 527, + INF, INF, INF, 528, 529, 530, 531, 532, INF, INF, INF, 533, 534, 535, 536, 537, + 538, 539, 540, 541, 542, 543, 544, 545, 546, 547, 548, 549, 550, 551, 552, 553, + 554, 555, 556, 557, 558, 559, 560, 561, 562, 563, 564, 565, 566, 567, 568, 569, + 570, 571, 572, 573, 574, 575, 576, 577, 578, INF, INF, INF, 579, 580, 581, 582, + 583, INF, INF, INF, 584, 585, 586, 587, 588, INF, INF, INF, 589, 590, 591, 592, + 593, 594, 595, 596, 597, 598, 599, 600, 601, 602, 603, 604, 605, 606, 607, 608, + 609, 610, 611, 612, 613, 614, 615, 616, 617, 618, 619, 620, 621, 622, 623, 624, + 625, 626, 627, 628, 629, 630, 631, 632, 633, 634, INF, INF, INF, 635, 636, 637, + 638, 639, INF, INF, INF, 640, 641, 642, 643, 644, INF, INF, INF, 645, 646, 647, + 648, 649, 650, 651, 652, 653, 654, 655, 656, 657, 658, 659, 660, 661, 662, 663, + 664, 665, 666, 667, 668, 669, 670, 671, 672, 673, 674, 675, 676, 677, 678, 679, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + 680, 681, 682, 683, 684, 685, 686, 687, 688, 689, 690, 691, 692, 693, 694, 695, + INF, INF, 696, 697, 698, 699, 700, 701, INF, INF, 702, 703, 704, 705, 706, 707, + INF, INF, 708, 709, 710, 711, 712, 713, 714, 715, 716, 717, 718, 719, 720, 721, + 722, 723, 724, 725, 726, 727, 728, 729, 730, 731, 732, 733, 734, 735, 736, 737, + 738, 739, 740, 741, 742, 743, 744, 745, 746, 747, 748, 749, 750, 751, 752, 753, + INF, INF, INF, 754, 755, 756, 757, 758, INF, INF, INF, 759, 760, 761, 762, 763, + INF, INF, INF, 764, 765, 766, 767, 768, 769, 770, 771, 772, 773, 774, 775, 776, + 777, 778, 779, 780, 781, 782, 783, 784, 785, 786, 787, 788, 789, 790, 791, 792, + 793, 794, 795, 796, 797, 798, 799, 800, 801, 802, 803, 804, 805, 806, 807, 808, + 809, INF, INF, INF, 810, 811, 812, 813, 814, INF, INF, INF, 815, 816, 817, 818, + 819, INF, INF, INF, 820, 821, 822, 823, 824, 825, 826, 827, 828, 829, 830, 831, + 832, 833, 834, 835, 836, 837, 838, 839, 840, 841, 842, 843, 844, 845, 846, 847, + 848, 849, 850, 851, 852, 853, 854, 855, 856, 857, 858, 859, 860, 861, 862, 863, + 864, 865, INF, INF, INF, 866, 867, 868, 869, 870, INF, INF, INF, 871, 872, 873, + 874, 875, INF, INF, INF, 876, 877, 878, 879, 880, 881, 882, 883, 884, 885, 886, + 887, 888, 889, 890, 891, 892, 893, 894, 895, 896, 897, 898, 899, 900, 901, 902, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + 903, 904, 905, 906, 907, 908, 909, 910, 911, 912, 913, 914, 915, 916, 917, 918, + 919, 920, 921, 922, 923, 924, 925, 926, INF, INF, 927, 928, 929, 930, 931, 932, + INF, INF, 933, 934, 935, 936, 937, 938, INF, INF, 939, 940, 941, 942, 943, 944, + 945, 946, 947, 948, 949, 950, 951, 952, 953, 954, 955, 956, 957, 958, 959, 960, + 961, 962, 963, 964, 965, 966, 967, 968, 969, 970, 971, 972, 973, 974, 975, 976, + 977, 978, 979, 980, 981, 982, 983, 984, INF, INF, INF, 985, 986, 987, 988, 989, + INF, INF, INF, 990, 991, 992, 993, 994, INF, INF, INF, 995, 996, 997, 998, 999, +1000,1001,1002,1003,1004,1005,1006,1007,1008,1009,1010,1011,1012,1013,1014,1015, +1016,1017,1018,1019,1020,1021,1022,1023,1024,1025,1026,1027,1028,1029,1030,1031, +1032,1033,1034,1035,1036,1037,1038,1039,1040, INF, INF, INF,1041,1042,1043,1044, +1045, INF, INF, INF,1046,1047,1048,1049,1050, INF, INF, INF,1051,1052,1053,1054, +1055,1056,1057,1058,1059,1060,1061,1062,1063,1064,1065,1066,1067,1068,1069,1070, +1071,1072,1073,1074,1075,1076,1077,1078,1079,1080,1081,1082,1083,1084,1085,1086, +1087,1088,1089,1090,1091,1092,1093,1094,1095,1096, INF, INF, INF,1097,1098,1099, +1100,1101, INF, INF, INF,1102,1103,1104,1105,1106, INF, INF, INF,1107,1108,1109, +1110,1111,1112,1113,1114,1115,1116,1117,1118,1119,1120,1121,1122,1123,1124,1125, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, +1126,1127,1128,1129,1130,1131,1132,1133,1134,1135,1136,1137,1138,1139,1140,1141, +1142,1143,1144,1145,1146,1147,1148,1149,1150,1151,1152,1153,1154,1155,1156,1157, + INF, INF,1158,1159,1160,1161,1162,1163, INF, INF,1164,1165,1166,1167,1168,1169, + INF, INF,1170,1171,1172,1173,1174,1175,1176,1177,1178,1179,1180,1181,1182,1183, +1184,1185,1186,1187,1188,1189,1190,1191,1192,1193,1194,1195,1196,1197,1198,1199, +1200,1201,1202,1203,1204,1205,1206,1207,1208,1209,1210,1211,1212,1213,1214,1215, + INF, INF, INF,1216,1217,1218,1219,1220, INF, INF, INF,1221,1222,1223,1224,1225, + INF, INF, INF,1226,1227,1228,1229,1230,1231,1232,1233,1234,1235,1236,1237,1238, +1239,1240,1241,1242,1243,1244,1245,1246,1247,1248,1249,1250,1251,1252,1253,1254, +1255,1256,1257,1258,1259,1260,1261,1262,1263,1264,1265,1266,1267,1268,1269,1270, +1271, INF, INF, INF,1272,1273,1274,1275,1276, INF, INF, INF,1277,1278,1279,1280, +1281, INF, INF, INF,1282,1283,1284,1285,1286,1287,1288,1289,1290,1291,1292,1293, +1294,1295,1296,1297,1298,1299,1300,1301,1302,1303,1304,1305,1306,1307,1308,1309, +1310,1311,1312,1313,1314,1315,1316,1317,1318,1319,1320,1321,1322,1323,1324,1325, +1326,1327, INF, INF, INF,1328,1329,1330,1331,1332, INF, INF, INF,1333,1334,1335, +1336,1337, INF, INF, INF,1338,1339,1340,1341,1342,1343,1344,1345,1346,1347,1348, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, +1349,1350,1351,1352,1353,1354,1355,1356,1357,1358,1359,1360,1361,1362,1363,1364, +1365,1366,1367,1368,1369,1370,1371,1372,1373,1374,1375,1376,1377,1378,1379,1380, +1381,1382,1383,1384,1385,1386,1387,1388, INF, INF,1389,1390,1391,1392,1393,1394, + INF, INF,1395,1396,1397,1398,1399,1400, INF, INF,1401,1402,1403,1404,1405,1406, +1407,1408,1409,1410,1411,1412,1413,1414,1415,1416,1417,1418,1419,1420,1421,1422, +1423,1424,1425,1426,1427,1428,1429,1430,1431,1432,1433,1434,1435,1436,1437,1438, +1439,1440,1441,1442,1443,1444,1445,1446, INF, INF, INF,1447,1448,1449,1450,1451, + INF, INF, INF,1452,1453,1454,1455,1456, INF, INF, INF,1457,1458,1459,1460,1461, +1462,1463,1464,1465,1466,1467,1468,1469,1470,1471,1472,1473,1474,1475,1476,1477, +1478,1479,1480,1481,1482,1483,1484,1485,1486,1487,1488,1489,1490,1491,1492,1493, +1494,1495,1496,1497,1498,1499,1500,1501,1502, INF, INF, INF,1503,1504,1505,1506, +1507, INF, INF, INF,1508,1509,1510,1511,1512, INF, INF, INF,1513,1514,1515,1516, +1517,1518,1519,1520,1521,1522,1523,1524,1525,1526,1527,1528,1529,1530,1531,1532, +1533,1534,1535,1536,1537,1538,1539,1540,1541,1542,1543,1544,1545,1546,1547,1548, +1549,1550,1551,1552,1553,1554,1555,1556,1557,1558, INF, INF, INF,1559,1560,1561, +1562,1563, INF, INF, INF,1564,1565,1566,1567,1568, INF, INF, INF,1569,1570,1571, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, +1572,1573,1574,1575,1576,1577,1578,1579,1580,1581,1582,1583,1584,1585,1586,1587, +1588,1589,1590,1591,1592,1593,1594,1595,1596,1597,1598,1599,1600,1601,1602,1603, +1604,1605,1606,1607,1608,1609,1610,1611,1612,1613,1614,1615,1616,1617,1618,1619, + INF, INF,1620,1621,1622,1623,1624,1625, INF, INF,1626,1627,1628,1629,1630,1631, +1632,1633,1634,1635,1636,1637,1638,1639,1640,1641,1642,1643,1644,1645,1646,1647, +1648,1649,1650,1651,1652,1653,1654,1655,1656,1657,1658,1659,1660,1661,1662,1663, +1664,1665,1666,1667,1668,1669,1670,1671,1672,1673,1674,1675,1676,1677,1678,1679, + INF, INF, INF,1680,1681,1682,1683,1684, INF, INF, INF,1685,1686,1687,1688,1689, +1690,1691,1692,1693,1694,1695,1696,1697,1698,1699,1700,1701,1702,1703,1704,1705, +1706,1707,1708,1709,1710,1711,1712,1713,1714,1715,1716,1717,1718,1719,1720,1721, +1722,1723,1724,1725,1726,1727,1728,1729,1730,1731,1732,1733,1734,1735,1736,1737, +1738, INF, INF, INF,1739,1740,1741,1742,1743, INF, INF, INF,1744,1745,1746,1747, +1748,1749,1750,1751,1752,1753,1754,1755,1756,1757,1758,1759,1760,1761,1762,1763, +1764,1765,1766,1767,1768,1769,1770,1771,1772,1773,1774,1775,1776,1777,1778,1779, +1780,1781,1782,1783,1784,1785,1786,1787,1788,1789,1790,1791,1792,1793,1794,1795, +1796,1797, INF, INF, INF,1798,1799,1800,1801,1802, INF, INF, INF,1803,1804,1805, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, + INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, INF, +}; + +// Useful macro and enumeration tables + +#define IndTriKings(sqk1,sqk2) ((unsigned) rgsTriKings[sqk1*64+sqk2]) +#define IndHalfKings(sqk1,sqk2) ((unsigned) rgsHalfKings[sqk1*64+sqk2]) + +static const bool rgfTriangle[64] = +{ + true, true, true, true, false, false, false, false, + false, true, true, true, false, false, false, false, + false, false, true, true, false, false, false, false, + false, false, false, true, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, + false, false, false, false, false, false, false, false, +}; + +static const bool rgfNotDiagonal[64] = +{ + false, true, true, true, true, true, true, true, + true, false, true, true, true, true, true, true, + true, true, false, true, true, true, true, true, + true, true, true, false, true, true, true, true, + true, true, true, true, false, true, true, true, + true, true, true, true, true, false, true, true, + true, true, true, true, true, true, false, true, + true, true, true, true, true, true, true, false, +}; + +static const bool rgfInLargeTriangle[64] = +{ + true, true, true, true, true, true, true, true, + false, true, true, true, true, true, true, true, + false, false, true, true, true, true, true, true, + false, false, false, true, true, true, true, true, + false, false, false, false, true, true, true, true, + false, false, false, false, false, true, true, true, + false, false, false, false, false, false, true, true, + false, false, false, false, false, false, false, true, +}; + +#define FInTriangle(sqwk,sqbk) (rgfTriangle[sqwk] & (rgfNotDiagonal[sqwk]|rgfInLargeTriangle[sqbk])) + +// Sort pieces + +#define SORT(sq1,sq2) if (sq1>sq2) { square sqTmp; sqTmp=sq1; sq1=sq2; sq2=sqTmp; } + +// Exclude occupied squares + +#define EXCLUDE1(sq,sq1) (sq-(sq>sq1)) +#define EXCLUDE2(sq,sq1,sq2) (sq-((sq>sq1)+(sq>sq2))) +#define EXCLUDE3(sq,sq1,sq2,sq3) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3))) +#define EXCLUDE4(sq,sq1,sq2,sq3,sq4) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4))) +#define EXCLUDE5(sq,sq1,sq2,sq3,sq4,sq5) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5))) +#define EXCLUDE6(sq,sq1,sq2,sq3,sq4,sq5,sq6) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6))) +#define EXCLUDE7(sq,sq1,sq2,sq3,sq4,sq5,sq6,sq7) (sq-((sq>sq1)+(sq>sq2)+(sq>sq3)+(sq>sq4)+(sq>sq5)+(sq>sq6)+(sq>sq7))) + +#if !defined(SWAP) +#define SWAP(sq1, sq2) {square sq_tmp = sq2; sq2 = sq1; sq1 = sq_tmp;} +#endif + +// Calculate index - a lot of functions... + +// Enumeration tables + +static BYTE *rgprgsqPiece[6]; // Enumeration for each piece (0 - black pawn) + // For each position of the King, all legal squares + // of the opposite piece enumerated +static BYTE rgcLegal[6][64]; // # of enumerated positions for each piece and each + // location of enemy king + +// Enumerations - indexed by [piece] and [kings enumeration]. +// In each table for each [piece] and [king enumeration] we store # of preceeding positions. + +static ULONG *rgprgulSinglePawnless[6]; +static ULONG *rgprgulPairPawnless[6][6]; +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + static ULONG *rgprgulTriplePawnless[6][6][6]; +#endif +static ULONG *rgprgulSinglePawnPresent[6]; +static ULONG *rgprgulPairPawnPresent[6][6]; +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + static ULONG *rgprgulTriplePawnPresent[6][6][6]; +#endif + +// Total # of enumerated positions + +static ULONG rgcSinglePawnPresent[6]; +static ULONG rgcSinglePawnless[6]; +static ULONG rgcPairPawnPresent[6][6]; +static ULONG rgcPairPawnless[6][6]; +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + static ULONG rgcTriplePawnPresent[6][6][6]; + static ULONG rgcTriplePawnless[6][6][6]; +#endif + +// Infinities. Have to be larger than any legal enumeration yet small enough +// so there will be no overflow when combining them with remaining pieces. + +#define INF_SINGLE (110000) +#define INF_PAIR (6500000) +#define INF_TRIPLE (500000000) + +// Initialize squares and counters table for one piece. +// Piece can be x_pieceNone - that means 'pawn of the wrong color', e.g. KPK BTM. + +static void VInitSquaresTable + ( + piece pi, + BYTE *prgsqPiece, + BYTE *prgcLegal + ) + { + int sqLo, sqHi; + + memset (prgsqPiece, -1, 64*64); + sqLo = 0; + sqHi = 64; + if (pi <= x_piecePawn) + { + sqLo = 8; + sqHi = 56; + } + for (int sqKing = 0; sqKing < 64; sqKing ++) + { + int iPiece; + + iPiece = 0; + for (int sq = sqLo; sq < sqHi; sq ++) + { + if (sq == sqKing) + continue; + switch (pi) + { + case x_piecePawn: + if ( + 0 != TbColumn (sq) && sqKing == sq+7 || + 7 != TbColumn (sq) && sqKing == sq+9 + ) + continue; + break; + case x_pieceKnight: + if ( + TbRow (sq) >= 2 && TbColumn (sq) >= 1 && sqKing == sq-17 || + TbRow (sq) >= 2 && TbColumn (sq) <= 6 && sqKing == sq-15 || + TbRow (sq) >= 1 && TbColumn (sq) >= 2 && sqKing == sq-10 || + TbRow (sq) >= 1 && TbColumn (sq) <= 5 && sqKing == sq-6 || + TbRow (sq) <= 6 && TbColumn (sq) >= 2 && sqKing == sq+6 || + TbRow (sq) <= 6 && TbColumn (sq) <= 5 && sqKing == sq+10 || + TbRow (sq) <= 5 && TbColumn (sq) >= 1 && sqKing == sq+15 || + TbRow (sq) <= 5 && TbColumn (sq) <= 6 && sqKing == sq+17 + ) + continue; + break; + case x_pieceBishop: + if ( + 0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 || + 0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 || + 7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 || + 7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9 + ) + continue; + break; + case x_pieceRook: + if ( + 0 != TbColumn (sq) && sqKing == sq-1 || + 7 != TbColumn (sq) && sqKing == sq+1 || + 0 != TbRow (sq) && sqKing == sq-8 || + 7 != TbRow (sq) && sqKing == sq+8 + ) + continue; + break; + case x_pieceQueen: + if ( + 0 != TbColumn (sq) && sqKing == sq-1 || + 7 != TbColumn (sq) && sqKing == sq+1 || + 0 != TbRow (sq) && sqKing == sq-8 || + 7 != TbRow (sq) && sqKing == sq+8 || + 0 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq-9 || + 0 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq-7 || + 7 != TbRow (sq) && 0 != TbColumn (sq) && sqKing == sq+7 || + 7 != TbRow (sq) && 7 != TbColumn (sq) && sqKing == sq+9 + ) + continue; + break; + } + prgsqPiece[sqKing*64+sq] = (BYTE) iPiece; + iPiece ++; + } + prgcLegal[sqKing] = (BYTE) iPiece; + } + } + +// Initialize enumeration table for single piece + +static void VInitSingle + ( + ULONG *prgIndex, + const short *prgsKings, + const BYTE *prgcLegal, + const BYTE *prgsqPiece, + ULONG *pcEnumeration + ) + { + ULONG iIndex; + + iIndex = 0; + for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++) + for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++) + { + if (INF != prgsKings[sqKing1*64+sqKing2]) + { + prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex; + iIndex += prgcLegal[sqKing2] - ((BYTE) -1 != prgsqPiece[sqKing2*64+sqKing1]); + } + } + *pcEnumeration = iIndex; + } + +// Initialize enumeration table for pair of pieces + +static void VInitPair + ( + ULONG *prgIndex, + const short *prgsKings, + const BYTE *prgcLegal1, + const BYTE *prgsqPiece1, + const BYTE *prgcLegal2, + const BYTE *prgsqPiece2, + ULONG *pcEnumeration + ) + { + ULONG iIndex; + ULONG cPositions1, cPositions2; + + iIndex = 0; + for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++) + for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++) + { + if (INF != prgsKings[sqKing1*64+sqKing2]) + { + prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex; + cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]); + if (prgcLegal1 == prgcLegal2) + iIndex += cPositions1*(cPositions1-1)/2; + else + { + cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]); + iIndex += cPositions1*cPositions2; + } + } + } + *pcEnumeration = iIndex; + } + +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + +// Initialize enumeration table for triple piece + +static void VInitTriple + ( + ULONG *prgIndex, + const short *prgsKings, + const BYTE *prgcLegal1, + const BYTE *prgsqPiece1, + const BYTE *prgcLegal2, + const BYTE *prgsqPiece2, + const BYTE *prgcLegal3, + const BYTE *prgsqPiece3, + ULONG *pcEnumeration + ) + { + ULONG iIndex; + ULONG cPositions1, cPositions2, cPositions3; + + iIndex = 0; + for (int sqKing1 = 0; sqKing1 < 64; sqKing1 ++) + for (int sqKing2 = 0; sqKing2 < 64; sqKing2 ++) + { + if (INF != prgsKings[sqKing1*64+sqKing2]) + { + prgIndex[prgsKings[sqKing1*64+sqKing2]] = iIndex; + cPositions1 = prgcLegal1[sqKing2] - ((BYTE) -1 != prgsqPiece1[sqKing2*64+sqKing1]); + if (prgcLegal1 == prgcLegal2 && prgcLegal2 == prgcLegal3) + iIndex += cPositions1*(cPositions1-1)*(cPositions1-2)/6; + else if (prgcLegal1 == prgcLegal2) + { + cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]); + iIndex += cPositions1*(cPositions1-1)/2*cPositions3; + } + else if (prgcLegal2 == prgcLegal3) + { + cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]); + iIndex += cPositions1*cPositions2*(cPositions2-1)/2; + } + else + { + cPositions2 = prgcLegal2[sqKing2] - ((BYTE) -1 != prgsqPiece2[sqKing2*64+sqKing1]); + cPositions3 = prgcLegal3[sqKing2] - ((BYTE) -1 != prgsqPiece3[sqKing2*64+sqKing1]); + iIndex += cPositions1*cPositions2*cPositions3; + } + } + } + *pcEnumeration = iIndex; + } + +#endif + +// Initialize all Enumeration tables + +static bool fEnumerationInitted = false; + +static void VInitEnumerations (void) + { + piece pi1; + piece pi2; +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + piece pi3; +#endif + + if (fEnumerationInitted) + return; + fEnumerationInitted = true; + // Initialize square tables + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + { + rgprgsqPiece[pi1] = (BYTE *) PvMalloc (64*64); + VInitSquaresTable (pi1, rgprgsqPiece[pi1], rgcLegal[pi1]); + } + + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + { + // Initialize enumeration tables for single piece + rgprgulSinglePawnPresent[pi1] = (ULONG *) PvMalloc (1806*sizeof (ULONG)); + VInitSingle (rgprgulSinglePawnPresent[pi1], rgsHalfKings, + rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnPresent[pi1]); + if (pi1 > x_piecePawn) + { + rgprgulSinglePawnless[pi1] = (ULONG *) PvMalloc (462*sizeof (ULONG)); + VInitSingle (rgprgulSinglePawnless[pi1], rgsTriKings, + rgcLegal[pi1], rgprgsqPiece[pi1], &rgcSinglePawnless[pi1]); + } + // Initialize enumeration tables for pair of pieces + for (pi2 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi2 <= pi1; pi2 = (piece) (pi2 + 1)) + { + rgprgulPairPawnPresent[pi1][pi2] = (ULONG *) PvMalloc (1806*sizeof (ULONG)); + VInitPair (rgprgulPairPawnPresent[pi1][pi2], rgsHalfKings, + rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2], + &rgcPairPawnPresent[pi1][pi2]); + if (pi1 > x_piecePawn && pi2 > x_piecePawn) + { + rgprgulPairPawnless[pi1][pi2] = (ULONG *) PvMalloc (462*sizeof (ULONG)); + VInitPair (rgprgulPairPawnless[pi1][pi2], rgsTriKings, + rgcLegal[pi1], rgprgsqPiece[pi1], rgcLegal[pi2], rgprgsqPiece[pi2], + &rgcPairPawnless[pi1][pi2]); + } +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + // Initialize enumeration tables for three pieces + for (pi3 = (x_pieceNone == pi1 ? x_pieceNone : x_piecePawn); pi3 <= pi2; pi3 = (piece) (pi3 + 1)) + { + if (pi1 <= x_piecePawn || pi2 <= x_piecePawn || pi3 <= x_piecePawn) + { + rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG)); + VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings, + rgcLegal[pi1], rgprgsqPiece[pi1], + rgcLegal[pi2], rgprgsqPiece[pi2], + rgcLegal[pi3], rgprgsqPiece[pi3], + &rgcTriplePawnPresent[pi1][pi2][pi3]); + } + else + { + rgprgulTriplePawnless[pi1][pi2][pi3] = (ULONG *) PvMalloc (462*sizeof (ULONG)); + VInitTriple (rgprgulTriplePawnless[pi1][pi2][pi3], rgsTriKings, + rgcLegal[pi1], rgprgsqPiece[pi1], + rgcLegal[pi2], rgprgsqPiece[pi2], + rgcLegal[pi3], rgprgsqPiece[pi3], + &rgcTriplePawnless[pi1][pi2][pi3]); +#if defined (T42_INCLUDE) + rgprgulTriplePawnPresent[pi1][pi2][pi3] = (ULONG *) PvMalloc (1806*sizeof (ULONG)); + VInitTriple (rgprgulTriplePawnPresent[pi1][pi2][pi3], rgsHalfKings, + rgcLegal[pi1], rgprgsqPiece[pi1], + rgcLegal[pi2], rgprgsqPiece[pi2], + rgcLegal[pi3], rgprgsqPiece[pi3], + &rgcTriplePawnPresent[pi1][pi2][pi3]); +#endif + } + } +#endif + } + } + + // All done! + if (fPrint) + { + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + printf ("%c - %d enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnPresent[pi1]); + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + { + if (0 != rgcSinglePawnless[pi1]) + printf ("pawnless %c - %d enumerated positions\n", "pPNBRQ"[pi1], rgcSinglePawnless[pi1]); + } + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1)) + { + if (0 != rgcPairPawnPresent[pi1][pi2]) + printf ("%c%c - %d enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2], + rgcPairPawnPresent[pi1][pi2]); + } + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1)) + { + if (0 != rgcPairPawnless[pi1][pi2]) + printf ("pawnless %c%c - %d enumerated positions\n", "pPNBRQ"[pi1], "pPNBRQ"[pi2], + rgcPairPawnless[pi1][pi2]); + } +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1)) + for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1)) + { + if (0 != rgcTriplePawnPresent[pi1][pi2][pi3]) + printf ("%c%c%c - %d enumerated positions\n", + "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3], + rgcTriplePawnPresent[pi1][pi2][pi3]); + } + for (pi1 = x_pieceNone; pi1 <= x_pieceQueen; pi1 = (piece) (pi1 + 1)) + for (pi2 = x_pieceNone; pi2 <= pi1; pi2 = (piece) (pi2 + 1)) + for (pi3 = x_pieceNone; pi3 <= pi2; pi3 = (piece) (pi3 + 1)) + { + if (0 != rgcTriplePawnless[pi1][pi2][pi3]) + printf ("pawnless %c%c%c - %d enumerated positions\n", + "pPNBRQ"[pi1], "pPNBRQ"[pi2], "pPNBRQ"[pi3], + rgcTriplePawnless[pi1][pi2][pi3]); + } +#endif + printf ("\nAllocated %dk\n\n", (cbAllocated + 1023)/1024); + } + } + +// Return enumeration of 2 kings and single piece + +template class TEnumerate1 + { +public: + static INLINE unsigned TB_FASTCALL Index + ( + square sqwk, + square sqw1, + square sqbk + ) + { + unsigned ind; + ULONG ulKings; + + // For black pawn invert the board + if (piw1 <= x_piecePawn && fInvert) + { + sqwk = reflect_x(sqwk); + sqw1 = reflect_x(sqw1); + sqbk = reflect_x(sqbk); + } + + // Get enumerated square + ind = rgprgsqPiece[piw1][sqbk*64+sqw1]; +#if defined (ILLEGAL_POSSIBLE) + if ((BYTE) -1 == ind) + return INF_SINGLE; +#endif + // Get enumerated position of both kings + if (fPawns) + ulKings = rgsHalfKings[sqwk*64+sqbk]; // 0..1805 + else + ulKings = rgsTriKings[sqwk*64+sqbk]; // 0..461 +#if defined (ILLEGAL_POSSIBLE) + if (INF == ulKings) + return INF_SINGLE; +#endif + // Can we remove one extra square? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + ind -= (sqw1 > sqwk); + // Add enumerated square to the # of the preceeding positions + return ind + (fPawns ? rgprgulSinglePawnPresent[piw1][ulKings] : rgprgulSinglePawnless[piw1][ulKings]); + } + }; + +// Return enumeration of 2 kings and 2 pieces + +template class TEnumerate2 + { +public: + static INLINE unsigned TB_FASTCALL Index + ( + square sqwk, + square sqw1, + square sqw2, + square sqbk + ) + { + unsigned ind1, ind2, cInd2; + ULONG ulKings; + + // For black pawn invert the board + if (piw2 <= x_piecePawn && fInvert) + { + sqwk = reflect_x(sqwk); + sqw1 = reflect_x(sqw1); + sqw2 = reflect_x(sqw2); + sqbk = reflect_x(sqbk); + } + + // Get enumerated squares for both pieces + if (piw1 == piw2) + SORT (sqw1, sqw2); + ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1]; + ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2]; +#if defined (ILLEGAL_POSSIBLE) + if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2) + return INF_PAIR; +#endif + // Get enumerated position of both kings + if (fPawns) + ulKings = rgsHalfKings[sqwk*64+sqbk]; // 0..1805 + else + ulKings = rgsTriKings[sqwk*64+sqbk]; // 0..461 +#if defined (ILLEGAL_POSSIBLE) + if (INF == ulKings) + return INF_PAIR; +#endif + if (piw1 == piw2) + { + // Can we remove one extra square? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + { + ind1 -= (sqw1 > sqwk); + ind2 -= (sqw2 > sqwk); + } + // Add enumerated squares to the # of the preceeding positions + return ind2*(ind2-1)/2 + ind1 + + (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]); + } + else + { + // Can we remove WK square from 1st piece Enumeration? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + ind1 -= (sqw1 > sqwk); + // Get # of enumerated positions of 2nd piece + cInd2 = rgcLegal[piw2][sqbk]; + // Can we remove WK square from 2nd piece Enumeration? + if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk])) + { + cInd2 --; + ind2 -= (sqw2 > sqwk); + } + // Add enumerated square to the # of the preceeding positions + return cInd2*ind1 + ind2 + (fPawns ? rgprgulPairPawnPresent[piw1][piw2][ulKings] : rgprgulPairPawnless[piw1][piw2][ulKings]); + } + } + }; + +#if defined (T41_INCLUDE) || defined (T42_INCLUDE) + +// Return enumeration of 2 kings and 3 pieces + +template class TEnumerate3 + { +public: + static INLINE unsigned TB_FASTCALL Index + ( + square sqwk, + square sqw1, + square sqw2, + square sqw3, + square sqbk + ) + { + unsigned ind1, ind2, ind3, cInd1, cInd2, cInd3; + ULONG ulKings; + + // For black pawn invert the board + if (piw3 <= x_piecePawn && fInvert) + { + sqwk = reflect_x(sqwk); + sqw1 = reflect_x(sqw1); + sqw2 = reflect_x(sqw2); + sqw3 = reflect_x(sqw3); + sqbk = reflect_x(sqbk); + } + + // Get enumerated squares for all pieces + if (piw1 == piw2 && piw1 == piw3) + { + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + } + else if (piw1 == piw2) + { + SORT (sqw1, sqw2); + } + else if (piw2 == piw3) + { + SORT (sqw2, sqw3); + } + ind1 = rgprgsqPiece[piw1][sqbk*64+sqw1]; + ind2 = rgprgsqPiece[piw2][sqbk*64+sqw2]; + ind3 = rgprgsqPiece[piw3][sqbk*64+sqw3]; +#if defined (ILLEGAL_POSSIBLE) + if ((BYTE) -1 == ind1 || (BYTE) -1 == ind2 || (BYTE) -1 == ind3) + return INF_TRIPLE; +#endif + // Get enumerated position of both kings + if (fPawns) + ulKings = rgsHalfKings[sqwk*64+sqbk]; // 0..1805 + else + ulKings = rgsTriKings[sqwk*64+sqbk]; // 0..461 +#if defined (ILLEGAL_POSSIBLE) + if (INF == ulKings) + return INF_TRIPLE; +#endif + if (piw1 == piw2 && piw2 == piw3) + { + // Can we remove one extra square? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + { + ind1 -= (sqw1 > sqwk); + ind2 -= (sqw2 > sqwk); + ind3 -= (sqw3 > sqwk); + } + // Add enumerated squares to the # of the preceeding positions + return ind3*(ind3-1)*(ind3-2)/6 + ind2*(ind2-1)/2 + ind1 + + (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] : + rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]); + } + else if (piw1 == piw2) + { + // Can we remove one extra square? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + { + ind1 -= (sqw1 > sqwk); + ind2 -= (sqw2 > sqwk); + } + // Get # of enumerated positions of 3rd piece + cInd3 = rgcLegal[piw3][sqbk]; + // Can we remove WK square from 3rd piece Enumeration? + if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk])) + { + cInd3 --; + ind3 -= (sqw3 > sqwk); + } + // Add enumerated squares to the # of the preceeding positions + return (ind2*(ind2-1)/2 + ind1)*cInd3 + ind3 + + (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] : + rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]); + } + else if (piw2 == piw3) + { + // Can we remove one extra square? + if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk])) + { + ind2 -= (sqw2 > sqwk); + ind3 -= (sqw3 > sqwk); + } + // Get # of enumerated positions of 1st piece + cInd1 = rgcLegal[piw1][sqbk]; + // Can we remove WK square from 3rd piece Enumeration? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + { + cInd1 --; + ind1 -= (sqw1 > sqwk); + } + // Add enumerated squares to the # of the preceeding positions + return (ind3*(ind3-1)/2 + ind2)*cInd1 + ind1 + + (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] : + rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]); + } + else + { + // Can we remove WK square from 1st piece Enumeration? + if ((piw1>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw1][sqbk*64+sqwk])) + ind1 -= (sqw1 > sqwk); + // Get # of enumerated positions of 2nd piece + cInd2 = rgcLegal[piw2][sqbk]; + // Can we remove WK square from 2nd piece Enumeration? + if ((piw2>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw2][sqbk*64+sqwk])) + { + cInd2 --; + ind2 -= (sqw2 > sqwk); + } + // Get # of enumerated positions of 3rd piece + cInd3 = rgcLegal[piw3][sqbk]; + // Can we remove WK square from 3rd piece Enumeration? + if ((piw3>x_pieceKnight) || ((BYTE)-1 != rgprgsqPiece[piw3][sqbk*64+sqwk])) + { + cInd3 --; + ind3 -= (sqw3 > sqwk); + } + // Add enumerated square to the # of the preceeding positions + return cInd3*(cInd2*ind1 + ind2) + ind3 + + (fPawns ? rgprgulTriplePawnPresent[piw1][piw2][piw3][ulKings] : + rgprgulTriplePawnless[piw1][piw2][piw3][ulKings]); + } + } + }; + +#endif + +// Enumerate en passant captures + +static INLINE unsigned TB_FASTCALL IndEnPassant11W + ( + square sqw, + square sqb, + square sqEnP + ) + { + assert (sqb+8 == sqEnP); + if (sqw+7 == sqEnP) + // Capture to the left + return (sqw&7)-1; + else + { + // Capture to the right + assert (sqw+9 == sqEnP); + return (sqw&7)+7; + } + } + +static INLINE unsigned TB_FASTCALL IndEnPassant11B + ( + square sqw, + square sqb, + square sqEnP + ) + { + assert (sqw-8 == sqEnP); + if (sqb-9 == sqEnP) + // Capture to the left + return (sqb&7)-1; + else + { + // Capture to the right + assert (sqb-7 == sqEnP); + return (sqb&7)+7; + } + } + +static INLINE unsigned TB_FASTCALL IndEnPassant21W + ( + square sqw1, + square sqw2, + square sqb, + square sqEnP + ) + { + assert (sqb+8 == sqEnP); + SORT (sqw1, sqw2); + if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1)) + // Capture to the left + return (sqw1&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14; + else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1)) + // Capture to the right + return (sqw1&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP+8)-i8-1)*i14; + else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2)) + // Capture to the left + return (sqw2&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14; + else + { + // Capture to the right + assert (sqw2+9 == sqEnP && 7 != TbColumn(sqw2)); + return (sqw2&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP+8)-i8)*i14; + } + } + +static INLINE unsigned TB_FASTCALL IndEnPassant21B + ( + square sqw1, + square sqw2, + square sqb, + square sqEnP + ) + { + assert (sqw1 < sqw2); // Must be already sorted + if (sqb-9 == sqEnP && 0 != TbColumn(sqb)) + // Capture to the left + if (sqw1-8 == sqEnP) + return (sqb&7)-1+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14; + else + { + assert (sqw2-8 == sqEnP); + return (sqb&7)-1+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14; + } + else + { + // Capture to the right + assert (sqb-7 == sqEnP && 7 != TbColumn(sqb)); + if (sqw1-8 == sqEnP) + return (sqb&7)+7+(EXCLUDE3(sqw2,sqb,sqEnP,sqEnP-8)-i8-1)*i14; + else + { + assert (sqw2-8 == sqEnP); + return (sqb&7)+7+(EXCLUDE3(sqw1,sqb,sqEnP,sqEnP-8)-i8)*i14; + } + } + } + +static INLINE unsigned TB_FASTCALL IndEnPassant12W + ( + square sqw, + square sqb1, + square sqb2, + square sqEnP + ) +{ + if(sqb2+8 == sqEnP) + SWAP(sqb1, sqb2); + + assert(sqb1+8 == sqEnP); + + if (sqw+7 == sqEnP && 0 != TbColumn(sqw)) + // Capture to the left + return TbColumn(sqw)-1+(EXCLUDE4(sqb2,sqb1,sqw,sqEnP,sqEnP+8)-i8)*i14; + + assert(sqw+9 == sqEnP && 7 != TbColumn(sqw)); + + // Capture to the right + return TbColumn(sqw)+7 + (EXCLUDE4(sqb2,sqb1,sqw,sqEnP,sqEnP+8)-i8)*i14; +} + +static INLINE unsigned TB_FASTCALL IndEnPassant12B + ( + square sqw, + square sqb1, + square sqb2, + square sqEnP + ) +{ + assert(sqw-8 == sqEnP); + + SORT(sqb1, sqb2); + + if(sqb1-9 == sqEnP && 0 != TbColumn(sqb1)) + // Capture to the left + return TbColumn(sqb1) - 1 + (sqb2-i8-4)*i14; + else if(sqb1-7 == sqEnP && 7 != TbColumn(sqb1)) + // Capture to the right + return TbColumn(sqb1) + 7 + (sqb2-i8-4)*i14; + else if(sqb2-9 == sqEnP && 0 != TbColumn(sqb2)) + // Capture to the left + return TbColumn(sqb2) - 1 + (EXCLUDE2(sqb1,sqEnP,sqEnP-8)-i8)*i14; + + // Capture to the right + assert(sqb2-7 == sqEnP && 7 != TbColumn(sqb2)); + return TbColumn(sqb2) + 7 + (EXCLUDE2(sqb1,sqEnP,sqEnP-8)-i8)*i14; +} + +static INLINE unsigned TB_FASTCALL IndEnPassant22W + ( + square sqw1, + square sqw2, + square sqb1, + square sqb2, + square sqEnP + ) +{ + square sqEmptyEnP = sqEnP + 8; + + if(sqb2+8== sqEnP) + SWAP(sqb1, sqb2); + + assert(sqb1+8 == sqEnP); + + SORT(sqw1, sqw2); + + if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1)) + // Capture to the left + return TbColumn(sqw1)-1+ + (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+ + (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); + else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1)) + // Capture to the right + return TbColumn(sqw1)+7+ + (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+ + (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); + else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2)) + // Capture to the left + return TbColumn(sqw2)-1+ + (sqw1-i8)*i14+ + (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); + + // Capture to the right + assert(sqw2+9 == sqEnP && 7 != TbColumn(sqw2)); + return TbColumn(sqw2)+7+ + (sqw1-i8)*i14+ + (EXCLUDE5(sqb2,sqb1,sqw1,sqw2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); +} + +static INLINE unsigned TB_FASTCALL IndEnPassant22B + ( + square sqw1, + square sqw2, + square sqb1, + square sqb2, + square sqEnP + ) +{ + square sqEmptyEnP = sqEnP - 8; + + if(sqw2-8 == sqEnP) + SWAP(sqw1, sqw2); + + assert(sqw1-8 == sqEnP); + + SORT(sqb1, sqb2); + + if (sqb1-9 == sqEnP && 0 != TbColumn(sqb1)) + // Capture to the left + return TbColumn(sqb1)-1+ + (sqb2-i8-4)*i14+ + (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); + else if (sqb1-7 == sqEnP && 7 != TbColumn(sqb1)) + // Capture to the right + return TbColumn(sqb1)+7+ + (sqb2-i8-4)*i14+ + (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); + else if (sqb2-9 == sqEnP && 0 != TbColumn(sqb2)) + // Capture to the left + return TbColumn(sqb2)-1+ + (EXCLUDE2(sqb1,sqEnP,sqEmptyEnP)-i8)*i14+ + (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); + + // Capture to the right + assert(sqb2-7 == sqEnP && 7 != TbColumn(sqb2)); + return TbColumn(sqb2)+7+ + (EXCLUDE2(sqb1,sqEnP,sqEmptyEnP)-i8)*i14+ + (EXCLUDE5(sqw2,sqw1,sqb1,sqb2,sqEnP,sqEmptyEnP)-i8)*(i14*i44); +} + +static INLINE unsigned TB_FASTCALL IndEnPassant31W + ( + square sqw1, + square sqw2, + square sqw3, + square sqb, + square sqEnP + ) +{ + square sqEmptyEnP = sqEnP + 8; + + assert(sqb + 8 == sqEnP); + + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + + if (sqw1+7 == sqEnP && 0 != TbColumn(sqw1)) { + // Capture to the left + sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2; + return TbColumn(sqw1)-1+ + (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+ + (sqw3*(sqw3-1)/2)*i14; + } + else if (sqw1+9 == sqEnP && 7 != TbColumn(sqw1)) { + // Capture to the right + sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2; + return TbColumn(sqw1)+7+ + (EXCLUDE2(sqw2,sqEnP,sqEmptyEnP)-i8-2)*i14+ + (sqw3*(sqw3-1)/2)*i14; + } + else if (sqw2+7 == sqEnP && 0 != TbColumn(sqw2)) { + // Capture to the left + sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2; + return TbColumn(sqw2)-1+ + (sqw1-i8)*i14+ + (sqw3*(sqw3-1)/2)*i14; + } + else if (sqw2+9 == sqEnP && 7 != TbColumn(sqw2)) { + // Capture to the right + sqw3 = EXCLUDE2(sqw3,sqEnP,sqEmptyEnP)-i8-2; + return TbColumn(sqw2)+7+ + (sqw1-i8)*i14+ + (sqw3*(sqw3-1)/2)*i14; + } + else if (sqw3+7 == sqEnP && 0 != TbColumn(sqw3)) { + // Capture to the left + sqw2 = sqw2-i8; + return TbColumn(sqw3)-1+ + (sqw1-i8)*i14+ + (sqw2*(sqw2-1)/2)*i14; + } + else { + // Capture to the right + sqw2 = sqw2-i8; + return TbColumn(sqw3)+7+ + (sqw1-i8)*i14+ + (sqw2*(sqw2-1)/2)*i14; + } +} + +static INLINE unsigned TB_FASTCALL IndEnPassant31B + ( + square sqw1, + square sqw2, + square sqw3, + square sqb, + square sqEnP + ) +{ + square sqEmptyEnP = sqEnP - 8; + + if(sqw2 - 8 == sqEnP) + SWAP(sqw1, sqw2); + if(sqw3 - 8 == sqEnP) + SWAP(sqw1, sqw3); + + assert(sqw1 - 8 == sqEnP); + + SORT(sqw2, sqw3); + + if(sqb - 9 == sqEnP && 0 != TbColumn(sqb)) { + sqw3 = EXCLUDE4(sqw3,sqw1,sqb,sqEnP,sqEmptyEnP)-i8; + return TbColumn(sqb)-1+ + (EXCLUDE4(sqw2,sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+ + (sqw3*(sqw3-1)/2)*i14; + } + else { + assert(sqb - 7 == sqEnP && 7 != TbColumn(sqb)); + sqw3 = EXCLUDE4(sqw3,sqw1,sqb,sqEnP,sqEmptyEnP)-i8; + return TbColumn(sqb)+7+ + (EXCLUDE4(sqw2,sqw1,sqb,sqEnP,sqEmptyEnP)-i8)*i14+ + (sqw3*(sqw3-1)/2)*i14; + } +} + +// Index calculation functions for different endgame classes + +template class T21 + { +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqbk, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindOne (psqW, piw1); + sqbk = SqFindKing (psqB); + + if (x_piecePawn == piw1) + sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqwk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + + if (x_piecePawn != piw1) + { + // No pawn + if (! FInTriangle (sqwk, sqbk)) + { + sqwk = reflect_xy(sqwk); + sqbk = reflect_xy(sqbk); + sqw1 = reflect_xy(sqw1); + }; + } + return TEnumerate1::Index(sqwk,sqw1,sqbk); + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqbk, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindOne (psqW, piw1); + sqbk = SqFindKing (psqB); + + if (x_piecePawn == piw1) + sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqbk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + + if (x_piecePawn == piw1) + return TEnumerate1::Index(sqbk,sqw1,sqwk); + else + { + // No pawn + if (! FInTriangle (sqbk, sqwk)) + { + sqwk = reflect_xy(sqwk); + sqbk = reflect_xy(sqbk); + sqw1 = reflect_xy(sqw1); + }; + return IndTriKings(sqbk,sqwk)*i62 + EXCLUDE2(sqw1,sqwk,sqbk); + } + } + }; + +template class T22 + { +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqbk, sqb1, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindOne (psqW, piw1); + sqbk = SqFindKing (psqB); + sqb1 = SqFindOne (psqB, pib1); + + if (x_piecePawn == pib1) + sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqwk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqb1 ^= sqMask; + + if (x_piecePawn == pib1) + { + // There are pawns on the board + if (x_piecePawn == piw1) + { + // One white and one black pawn + if (XX == sqEnP) + return TEnumerate1::Index(sqwk,sqw1,sqbk)*i47 + + EXCLUDE1(sqb1,sqw1)-i8; // 47 + else + return rgcSinglePawnPresent[x_piecePawn]*i47 + + IndHalfKings(sqwk,sqbk)*i14 + + IndEnPassant11W (sqw1, sqb1, sqEnP ^ sqMask); + } + else + // Only black pawn + return TEnumerate1::Index(sqwk,sqw1,sqbk)*i48 + sqb1-i8; + } + else + { + // No pawns at all + if (!FInTriangle (sqwk, sqbk)) + { + sqwk = reflect_xy(sqwk); + sqbk = reflect_xy(sqbk); + sqw1 = reflect_xy(sqw1); + sqb1 = reflect_xy(sqb1); + }; + return TEnumerate1::Index(sqwk,sqw1,sqbk)*i61 + + EXCLUDE3(sqb1,sqwk,sqbk,sqw1); // 61 + } + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqbk, sqb1, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindOne (psqW, piw1); + sqbk = SqFindKing (psqB); + sqb1 = SqFindOne (psqB, pib1); + + if (x_piecePawn == pib1) + sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqbk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqb1 ^= sqMask; + + if (x_piecePawn == pib1) + { + // There are pawns on the board + if (x_piecePawn == piw1) + { + // One white and one black pawn + if (XX == sqEnP) + return TEnumerate1::Index(sqbk,sqb1,sqwk)*i47 + + EXCLUDE1(sqw1,sqb1)-i8; // 47 + else + return rgcSinglePawnPresent[x_piecePawn]*i47 + + IndHalfKings(sqbk,sqwk)*i14 + + IndEnPassant11B (sqw1, sqb1, sqEnP ^ sqMask); + } + } + else + { + // No pawns at all + if (!FInTriangle (sqbk, sqwk)) + { + sqwk = reflect_xy(sqwk); + sqbk = reflect_xy(sqbk); + sqw1 = reflect_xy(sqw1); + sqb1 = reflect_xy(sqb1); + }; + } + return (x_piecePawn == pib1 ? TEnumerate1::Index(sqbk,sqb1,sqwk) : + TEnumerate1::Index(sqbk,sqb1,sqwk))*i61 + + EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61 + } + }; + +template class T31 + { +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqbk, sqMask; + + sqwk = SqFindKing (psqW); + if (piw1 == piw2) + { + sqw1 = SqFindFirst (psqW, piw1); + sqw2 = SqFindSecond (psqW, piw2); + } + else + { + SqFind2 (psqW, piw1, sqw1, piw2, sqw2); + } + sqbk = SqFindKing (psqB); + + if (x_piecePawn == piw2) + sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqwk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + + if (x_piecePawn != piw2) + { + // There are no pawns on the board + if (!FInTriangle (sqwk, sqbk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqbk = reflect_xy(sqbk); + }; + } + return TEnumerate2::Index(sqwk, sqw1, sqw2, sqbk); + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqbk, sqMask; + + sqwk = SqFindKing (psqW); + if (piw1 == piw2) + { + sqw1 = SqFindFirst (psqW, piw1); + sqw2 = SqFindSecond (psqW, piw2); + } + else + { + SqFind2 (psqW, piw1, sqw1, piw2, sqw2); + } + sqbk = SqFindKing (psqB); + + if (x_piecePawn == piw2) + sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqbk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + + if (x_piecePawn == piw2) + { + // There are pawns on the board + if (x_piecePawn == piw1) + // Two white pawns + return TEnumerate2::Index(sqbk,sqw1,sqw2,sqwk); + else + // Only one white pawn + return TEnumerate1::Index(sqbk,sqw2,sqwk)*i61 + + EXCLUDE3(sqw1,sqwk,sqbk,sqw2); // 61 + } + else + { + // No pawns + if (!FInTriangle (sqbk, sqwk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqbk = reflect_xy(sqbk); + }; + if (piw1 == piw2) + { + SORT (sqw1, sqw2); + sqw2 = EXCLUDE2(sqw2,sqwk,sqbk); // 62 + return IndTriKings(sqbk,sqwk)*(i62*i61/2) + + sqw2*(sqw2-1)/2+EXCLUDE2(sqw1,sqwk,sqbk); // 62*61/2 + } + else + return IndTriKings(sqbk,sqwk)*(i62*i61) + + EXCLUDE2(sqw1,sqwk,sqbk)*i61 + // 62 + EXCLUDE3(sqw2,sqwk,sqbk,sqw1); // 61 + } + } + }; + +template class T32 + { +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask; + + sqwk = SqFindKing (psqW); + if (piw1 == piw2) + { + sqw1 = SqFindFirst (psqW, piw1); + sqw2 = SqFindSecond (psqW, piw2); + } + else + { + SqFind2 (psqW, piw1, sqw1, piw2, sqw2); + } + sqbk = SqFindKing (psqB); + sqb1 = SqFindOne (psqB, pib1); + + if (x_piecePawn == piw2 || x_piecePawn == pib1) + sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqwk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqb1 ^= sqMask; + + if (x_piecePawn == piw2 || x_piecePawn == pib1) + { + // There are pawns on the board + if (x_piecePawn == pib1) + { + // Black pawn + if (x_piecePawn == piw1 && x_piecePawn == piw2) + { + // All 3 pieces are pawns + if (XX == sqEnP) + return TEnumerate2:: + Index(sqwk,sqw1,sqw2,sqbk)*i46+ + EXCLUDE2(sqb1,sqw1,sqw2)-i8; // 46 + else + // En passant capture + return rgcPairPawnPresent[x_piecePawn][x_piecePawn]*i46 + + IndHalfKings(sqwk,sqbk)*(i14*i44) + + IndEnPassant21W (sqw1, sqw2, sqb1, sqEnP ^ sqMask); + } + else if (x_piecePawn == piw2) + { + // One white pawn, one black pawn + if (XX == sqEnP) + return TEnumerate2:: + Index(sqwk,sqw1,sqw2,sqbk)*i47 + + EXCLUDE1(sqb1,sqw2)-i8; // 47 + else + // En passant capture + return rgcPairPawnPresent[piw1][x_piecePawn]*i47 + + TEnumerate1::Index(sqwk,sqw1,sqbk)*i14 + + IndEnPassant11W (sqw2, sqb1, sqEnP ^ sqMask); + } + else + // Only black pawn + return TEnumerate2:: + Index(sqwk,sqw1,sqw2,sqbk)*i48 + + sqb1-i8; // 48 + } + } + else + { + // No pawns + if (!FInTriangle (sqwk, sqbk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqbk = reflect_xy(sqbk); + sqb1 = reflect_xy(sqb1); + }; + } + return TEnumerate2:: + Index(sqwk,sqw1,sqw2,sqbk)*i60 + + EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2); // 60 + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqbk, sqb1, sqMask; + + sqwk = SqFindKing (psqW); + if (piw1 == piw2) + { + sqw1 = SqFindFirst (psqW, piw1); + sqw2 = SqFindSecond (psqW, piw2); + } + else + { + SqFind2 (psqW, piw1, sqw1, piw2, sqw2); + } + sqbk = SqFindKing (psqB); + sqb1 = SqFindOne (psqB, pib1); + + if (x_piecePawn == piw2 || x_piecePawn == pib1) + sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqbk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqb1 ^= sqMask; + + if (x_piecePawn == piw2 || x_piecePawn == pib1) + { + // There are pawns on the board + if (x_piecePawn == pib1) + { + // Black pawn + if (x_piecePawn == piw1 && x_piecePawn == piw2) + { + // All 3 pieces are pawns + SORT (sqw1, sqw2); + if (XX == sqEnP) + { + sqw2 = EXCLUDE1(sqw2,sqb1)-i8; // 47 + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i47*i46/2) + + sqw2*(sqw2-1)/2+EXCLUDE1(sqw1,sqb1)-i8; // 47*46/2 + } + else + // En passant capture + return rgcSinglePawnPresent[x_piecePawn]*(i47*i46/2) + + IndHalfKings(sqbk,sqwk)*(i44*i14) + + IndEnPassant21B (sqw1, sqw2, sqb1, sqEnP ^ sqMask); + } + else if (x_piecePawn == piw2) + { + // One white pawn, one black pawn + if (XX == sqEnP) + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i60*i47) + + EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i47 + // 60 + EXCLUDE1(sqw2,sqb1)-i8; // 47 + else + { + // En passant capture + sqEnP ^= sqMask; + return rgcSinglePawnPresent[x_piecePawn]*(i60*i47) + + IndHalfKings(sqbk,sqwk)*(i58*i14) + + EXCLUDE6(sqw1,sqwk,sqbk,sqw2,sqb1,sqEnP,sqEnP-8)*i14 + // 58 + IndEnPassant11B (sqw2, sqb1, sqEnP); + } + } + else + { + // Only black pawn + if (piw1 == piw2) + { + // 2 identical white pieces + SORT (sqw1, sqw2); + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); // 61 + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i61*i60/2) + + sqw2*(sqw2-1)/2 + EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61*60/2 + } + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i61*i60) + + EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61 + EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60 + } + } + else + { + // No black pawn + if (x_piecePawn == piw1) + { + // Only 2 white pawns + SORT (sqw1, sqw2); + sqw2 -= i8; + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i48*47/2) + + sqw2*(sqw2-1)/2+sqw1-i8; // 48*47/2 + } + else + // Only one white pawn + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i60*i48) + + EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqb1)*i48 + // 60 + sqw2-i8; // 48 + } + } + else + { + // No pawns + if (!FInTriangle (sqbk, sqwk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqbk = reflect_xy(sqbk); + sqb1 = reflect_xy(sqb1); + }; + if (piw1 == piw2) + { + // 2 identical white pieces + SORT (sqw1, sqw2); + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); // 61 + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i61*i60/2) + + sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61*60/2 + } + else + return TEnumerate1:: + Index(sqbk,sqb1,sqwk)*(i61*i60) + + EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*i60 + // 61 + EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60 + } + } + }; + +#if defined (T41_INCLUDE) + +template class T41 + { +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindFirst (psqW, piw1); + if (piw1 == piw2 && piw2 == piw3) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindThird (psqW, piw3); + } + else if (piw1 == piw2) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + else if (piw2 == piw3) + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindSecond (psqW, piw3); + } + else + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + sqbk = SqFindKing (psqB); + + if (x_piecePawn == piw3) + sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqwk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqw3 ^= sqMask; + + if (x_piecePawn != piw3) + { + // No pawns + if (!FInTriangle (sqwk, sqbk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqw3 = reflect_xy(sqw3); + sqbk = reflect_xy(sqbk); + }; + } + return TEnumerate3::Index(sqwk,sqw1,sqw2,sqw3,sqbk); + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqw3, sqbk, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindFirst (psqW, piw1); + if (piw1 == piw2 && piw2 == piw3) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindThird (psqW, piw3); + } + else if (piw1 == piw2) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + else if (piw2 == piw3) + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindSecond (psqW, piw3); + } + else + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + sqbk = SqFindKing (psqB); + + if (x_piecePawn == piw3) + sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqbk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqw3 ^= sqMask; + + if (x_piecePawn == piw3) + { + // There are pawns on the board + if (x_piecePawn == piw1) + // 3 white pawns + return TEnumerate3:: + Index(sqbk,sqw1,sqw2,sqw3,sqwk); + else if (x_piecePawn == piw2) + // 2 white pawns + return TEnumerate2:: + Index(sqbk,sqw2,sqw3,sqwk)*i60 + + EXCLUDE4(sqw1,sqwk,sqbk,sqw2,sqw3); // 60 + else if (piw1 == piw2) + { + // 1 pawn, 2 pieces equal + SORT (sqw1, sqw2); + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3); // 61 + return TEnumerate1:: + Index(sqbk,sqw3,sqwk)*(i61*i60/2) + + sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3); // 61*60/2 + } + else + // Only one white pawn + return TEnumerate1::Index(sqbk,sqw3,sqwk)*i61*i60 + + EXCLUDE3(sqw1,sqwk,sqbk,sqw3)*i60 + // 61 + EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqw3); // 60 + } + else + { + // No pawns + if (!FInTriangle (sqbk, sqwk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqw3 = reflect_xy(sqw3); + sqbk = reflect_xy(sqbk); + }; + if (piw1 == piw2 && piw2 == piw3) + { + // All 3 pieces equal + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + sqw3 = EXCLUDE2(sqw3,sqwk,sqbk); // 62 + sqw2 = EXCLUDE2(sqw2,sqwk,sqbk); + return IndTriKings(sqbk,sqwk)*(i62*i61*i60/6) + + sqw3*(sqw3-1)*(sqw3-2)/6+ + sqw2*(sqw2-1)/2+ + EXCLUDE2(sqw1,sqwk,sqbk); // 62*61*60/6 + } + else if (piw1 == piw2) + { + // 2 major pieces equal + SORT (sqw1, sqw2); + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqw3); // 61 + return IndTriKings(sqbk,sqwk)*(i61*i60/2*i62) + + (sqw2*(sqw2-1)/2+EXCLUDE3(sqw1,sqwk,sqbk,sqw3))*i62 + // 61*60/2 + EXCLUDE2(sqw3,sqwk,sqbk); // 62 + } + else if (piw2 == piw3) + { + // 2 minor pieces equal + SORT (sqw2, sqw3); + sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqw1); // 61 + return IndTriKings(sqbk,sqwk)*(i62*i61*i60/2) + + EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60/2) + // 62 + sqw3*(sqw3-1)/2+EXCLUDE3(sqw2,sqwk,sqbk,sqw1); // 61*60/2 + } + else + return IndTriKings(sqbk,sqwk)*(i62*i61*i60) + + EXCLUDE2(sqw1,sqwk,sqbk)*(i61*i60) + // 62 + EXCLUDE3(sqw2,sqwk,sqbk,sqw1)*i60 + // 61 + EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqw2); // 60 + } + } + }; + +#endif // T41 + +#if defined (ILLEGAL_POSSIBLE) + +#define CHECK_INF_SINGLE(ind)\ + if (INF_SINGLE == ind)\ + return (INDEX) -1;\ + +#define CHECK_INF_PAIR(ind)\ + if (INF_PAIR == ind)\ + return (INDEX) -1;\ + +#define CHECK_INF_TRIPLE(ind)\ + if (INF_TRIPLE == ind)\ + return (INDEX) -1;\ + +#else + +#define CHECK_INF_SINGLE(ind) +#define CHECK_INF_PAIR(ind) +#define CHECK_INF_TRIPLE(ind) + +#endif + +#if defined (T33_INCLUDE) + +template class T33 +{ +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask; + unsigned uInd; + + sqwk = SqFindKing (psqW); + if (piw1 == piw2) { + sqw1 = SqFindFirst (psqW, piw1); + sqw2 = SqFindSecond (psqW, piw2); + } + else { + SqFind2 (psqW, piw1, sqw1, piw2, sqw2); + } + sqbk = SqFindKing (psqB); + if (pib1 == pib2) { + sqb1 = SqFindFirst (psqB, pib1); + sqb2 = SqFindSecond (psqB, pib2); + } + else { + SqFind2 (psqB, pib1, sqb1, pib2, sqb2); + } + + if(x_piecePawn == piw2 || x_piecePawn == pib2) + sqMask = rgsqReflectMaskY[sqwk] ^ rgsqReflectInvertMask[fInvert]; + else + sqMask = rgsqReflectMaskYandX[sqwk]; + + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqb1 ^= sqMask; + sqb2 ^= sqMask; + + if(x_piecePawn == piw2 || x_piecePawn == pib2) { + // There are pawns on the board + if(XX == sqEnP) { + // No En Passant possible + uInd = TEnumerate2::Index(sqwk,sqw1,sqw2,sqbk); + CHECK_INF_PAIR(uInd); + if(x_piecePawn == piw1) { + // all 4 pieces are pawns + SORT(sqb1, sqb2); + sqb2 = EXCLUDE2(sqb2,sqw1,sqw2) - i8; + return uInd*(INDEX)(i46*i45/2) + + sqb2*(sqb2-1)/2 + EXCLUDE2(sqb1,sqw1,sqw2) - i8; + } + else if(x_piecePawn == piw2) { + if(x_piecePawn == pib1) { + // 1 white, 2 black pawns + SORT(sqb1, sqb2); + sqb2 = EXCLUDE1(sqb2,sqw2) - i8; + return uInd*(INDEX)(i47*i46/2) + + sqb2*(sqb2-1)/2 + EXCLUDE1(sqb1,sqw2) - i8; + } + else if(x_piecePawn == pib2) { + // 1 white, 1 black pawn + return uInd*(INDEX)(i59*i47) + + (EXCLUDE1(sqb2,sqw2)-i8)*i59 + + EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk); + } + else if(pib2 == pib1) { + // only 1 white pawn, two identical black pieces + SORT(sqb1, sqb2); + sqb2 = EXCLUDE4(sqb2,sqwk,sqw1,sqw2,sqbk); + return uInd*(INDEX)(i60*i59/2) + + sqb2*(sqb2-1)/2 + + EXCLUDE4(sqb1,sqwk,sqw1,sqw2,sqbk); + } + else { + // only 1 white pawn, two different black pieces + return uInd*(INDEX)(i60*i59) + + EXCLUDE4(sqb2,sqwk,sqw1,sqw2,sqbk)*i59 + + EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk); + } + } + else if(x_piecePawn == pib1) { + // no white pawns, two black pawns + SORT(sqb1, sqb2); + sqb2 -= i8; + return uInd*(INDEX)(i48*i47/2) + + sqb2*(sqb2-1)/2 + sqb1 - i8; + } + else { + // no white pawns, 1 black pawn + return uInd*(INDEX)(i48*i59) + + (sqb2 - i8)*i59 + + EXCLUDE5(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk); + } + } + else { + // En Passant possible + sqEnP ^= sqMask; + if(x_piecePawn == piw1) { + // all 4 pieces are pawns + uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn]; + return uInd*(INDEX)(i46*i45/2) + + IndHalfKings(sqwk,sqbk)*(i14*i44*i43) + + IndEnPassant22W(sqw1, sqw2, sqb1, sqb2, sqEnP); + } + else { + assert(x_piecePawn == piw2); + + uInd = TEnumerate1:: + Index(sqwk,sqw1,sqbk); + CHECK_INF_SINGLE(uInd); + + if(x_piecePawn == pib1) { + // 1 white pawn, 2 black pawns + return rgcPairPawnPresent[piw1][x_piecePawn]*((INDEX)(i47*i46/2)) + + (uInd*(i14*i44) + + IndEnPassant12W(sqw2, sqb1, sqb2, sqEnP)); + } + else { + // 1 white pawn, 1 black pawn + assert(x_piecePawn == pib2); + return rgcPairPawnPresent[piw1][x_piecePawn]*((INDEX)(i47*i59))+ + (uInd*(i14*i57) + + EXCLUDE7(sqb1,sqb2,sqwk,sqw1,sqw2,sqbk,sqEnP,sqEnP+8)*i14+ + IndEnPassant11W(sqw2,sqb2,sqEnP)); + } + } + } + } + else { + // no pawns at all + if (!FInTriangle (sqwk, sqbk)) { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqbk = reflect_xy(sqbk); + sqb1 = reflect_xy(sqb1); + sqb2 = reflect_xy(sqb2); + } + + uInd = TEnumerate2::Index(sqwk,sqw1,sqw2,sqbk); + CHECK_INF_PAIR(uInd); + if (pib1 == pib2) { + SORT (sqb1, sqb2); + sqb2 = EXCLUDE4(sqb2,sqwk,sqbk,sqw1,sqw2); + return uInd*(i60*i59/2) + + sqb2*(sqb2-1)/2+ + EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2); + } + else { + // Divide by 2 to avoid overflow on the 32-bit systems, later + // add to itself to produce the correct result. Only the final + // addition have to be done using 64-bit arithmetic. + uInd *= (i60*i59/2); + return ((INDEX) uInd) + + (INDEX) (uInd + + EXCLUDE4(sqb1,sqwk,sqbk,sqw1,sqw2)*i59 + + EXCLUDE5(sqb2,sqwk,sqbk,sqw1,sqw2,sqb1)); + } + } + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sqwk, sqw1, sqw2, sqbk, sqb1, sqb2, sqMask; + unsigned uInd; + + sqwk = SqFindKing (psqW); + if (piw1 == piw2) { + sqw1 = SqFindFirst (psqW, piw1); + sqw2 = SqFindSecond (psqW, piw2); + } + else { + SqFind2 (psqW, piw1, sqw1, piw2, sqw2); + } + sqbk = SqFindKing (psqB); + if (pib1 == pib2) { + sqb1 = SqFindFirst (psqB, pib1); + sqb2 = SqFindSecond (psqB, pib2); + } + else { + SqFind2 (psqB, pib1, sqb1, pib2, sqb2); + } + + if(piw2 == x_piecePawn || pib2 == x_piecePawn) + sqMask = rgsqReflectMaskY[sqbk] ^ rgsqReflectInvertMask[fInvert]; + else + sqMask = rgsqReflectMaskYandX[sqbk]; + + sqwk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqbk ^= sqMask; + sqb1 ^= sqMask; + sqb2 ^= sqMask; + + if(x_piecePawn == piw2 || x_piecePawn == pib2) { + // There are pawns on the board + if(XX == sqEnP) { + // No En Passant possible + uInd = TEnumerate2::Index(sqbk,sqb1,sqb2,sqwk); + CHECK_INF_PAIR(uInd); + if(x_piecePawn == piw1) { + // all 4 pieces are pawns + SORT(sqw1, sqw2); + sqw2 = EXCLUDE2(sqw2,sqb1,sqb2) - i8; + return uInd*(INDEX)(i46*i45/2) + + sqw2*(sqw2-1)/2 + EXCLUDE2(sqw1,sqb1,sqw2) - i8; + } + else if(x_piecePawn == piw2) { + if(x_piecePawn == pib1) { + // 1 white, 2 black pawns + return uInd*(INDEX)(i46*i59) + + (EXCLUDE2(sqw2,sqb1,sqb2)-i8)*i59 + + EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk); + } + else if(x_piecePawn == pib2) { + // 1 white, 1 black pawn + return uInd*(INDEX)(i47*i59) + + (EXCLUDE1(sqw2,sqb2)-i8)*i59 + + EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk); + } + else { + // only 1 white pawn + return uInd*(INDEX)(i48*i59) + + (sqw2 - i8)*i59 + + EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk); + } + } + else if(piw1 == piw2) { + // no white pawns, two identical white pieces + SORT(sqw1, sqw2); + sqw2 = EXCLUDE4(sqw2,sqb1,sqb2,sqwk,sqbk); + return uInd*(INDEX)(i60*i59/2) + + sqw2*(sqw2-1)/2 + + EXCLUDE4(sqw1,sqb1,sqb2,sqwk,sqbk); + } + else { + // no white pawns, two different white pieces + return uInd*(INDEX)(i60*i59) + + EXCLUDE4(sqw2,sqb1,sqb2,sqwk,sqbk)*i59 + + EXCLUDE5(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk); + } + } + else { + // En Passant possible + sqEnP ^= sqMask; + if(x_piecePawn == piw1) { + // all 4 pieces are pawns + uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn]; + return uInd*(INDEX)(i46*i45/2) + + IndHalfKings(sqbk,sqwk)*(i14*i44*i43) + + IndEnPassant22B(sqw1, sqw2, sqb1, sqb2, sqEnP); + } + else if(x_piecePawn == pib1) { + // 1 white, 2 black pawns + assert(x_piecePawn == piw2); + uInd = rgcPairPawnPresent[x_piecePawn][x_piecePawn]; + return uInd*(INDEX)(i46*i59) + + IndHalfKings(sqbk,sqwk)*(i14*i44*i57) + + EXCLUDE7(sqw1,sqw2,sqb1,sqb2,sqbk,sqwk,sqEnP,sqEnP-8)*(i44*i14)+ + IndEnPassant12B(sqw2, sqb1, sqb2, sqEnP); + } + else { + // 1 white, 1 black pawn + assert(x_piecePawn == piw2 && x_piecePawn == pib2); + uInd = TEnumerate1:: + Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + return rgcPairPawnPresent[pib1][x_piecePawn]*((INDEX)(i47*i59)) + + (uInd*(i14*i57) + + EXCLUDE7(sqw1,sqw2,sqb1,sqb2,sqwk,sqbk,sqEnP,sqEnP-8)*i14 + + IndEnPassant11B(sqw2,sqb2,sqEnP)); + } + } + } + else { + // no pawns at all + if (!FInTriangle (sqbk, sqwk)) { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqbk = reflect_xy(sqbk); + sqb1 = reflect_xy(sqb1); + sqb2 = reflect_xy(sqb2); + } + uInd = TEnumerate2::Index(sqbk,sqb1,sqb2,sqwk); + CHECK_INF_PAIR(uInd); + if (piw1 == piw2) { + SORT (sqw1, sqw2); + sqw2 = EXCLUDE4(sqw2,sqbk,sqwk,sqb1,sqb2); + return uInd*(i60*i59/2) + + sqw2*(sqw2-1)/2+ + EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2); + } + else { + // Divide by 2 to avoid overflow on the 32-bit systems, later + // add to itself to produce the correct result. Only the final + // addition have to be done using 64-bit arithmetic. + uInd *= (i60*i59/2); + return ((INDEX) uInd) + + (INDEX) (uInd + + EXCLUDE4(sqw1,sqbk,sqwk,sqb1,sqb2)*i59 + + EXCLUDE5(sqw2,sqbk,sqwk,sqb1,sqb2,sqw1)); + } + } + } + + // IndCalcBF should replace IndCalcB for symmetric endgames + + static INDEX TB_FASTCALL IndCalcBF + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + return IndCalcW(psqB, psqW, sqEnP, !fInvert); + } +}; + +#endif // T33 + +#if defined (T42_INCLUDE) + +// TODO: Add code for the TBs with pawns + +template class T42 + { +public: + static INDEX TB_FASTCALL IndCalcW + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + unsigned uInd; + square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindFirst (psqW, piw1); + if (piw1 == piw2 && piw2 == piw3) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindThird (psqW, piw3); + } + else if (piw1 == piw2) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + else if (piw2 == piw3) + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindSecond (psqW, piw3); + } + else + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + sqbk = SqFindKing (psqB); + sqb1 = SqFindOne (psqB, pib1); + + if (x_piecePawn == piw3 || x_piecePawn == pib1) + sqMask = rgsqReflectMaskY [sqwk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqwk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqw3 ^= sqMask; + sqb1 ^= sqMask; + + if (x_piecePawn == piw3 || x_piecePawn == pib1) + { + // There are pawns on the board + if (x_piecePawn == pib1) + { + // Black pawn + if (x_piecePawn == piw1) + { + // All 4 pieces are pawns + if (XX == sqEnP) + { + uInd = TEnumerate3:: + Index(sqwk,sqw1,sqw2,sqw3,sqbk); + CHECK_INF_TRIPLE(uInd); + return uInd*i45 + EXCLUDE3(sqb1,sqw1,sqw2,sqw3)-i8; // 45 + } + else + { + // En passant capture + uInd = rgcTriplePawnPresent[x_piecePawn][x_piecePawn][x_piecePawn]; + return uInd*i45 + + IndHalfKings(sqwk,sqbk)*(i14*i44*i43/2) + + IndEnPassant31W (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask); + } + } + else if (x_piecePawn == piw2) + { + // Two white pawns, one black pawn + if (XX == sqEnP) + { + uInd = TEnumerate3:: + Index(sqwk,sqw1,sqw2,sqw3,sqbk); + CHECK_INF_TRIPLE(uInd); + return uInd*(INDEX)i46 + (EXCLUDE2(sqb1,sqw2,sqw3)-i8); // 46 + } + else + { + // En passant capture + uInd = TEnumerate1::Index(sqwk,sqw1,sqbk); + CHECK_INF_SINGLE(uInd); + return rgcTriplePawnPresent[piw1][x_piecePawn][x_piecePawn]*(INDEX)i46 + + (uInd*(i14*i44) + IndEnPassant21W (sqw2, sqw3, sqb1, sqEnP ^ sqMask)); + } + } + else if (x_piecePawn == piw3) + { + // One white pawn, one black pawn + if (XX == sqEnP) + { + uInd = TEnumerate3:: + Index(sqwk,sqw1,sqw2,sqw3,sqbk); + CHECK_INF_TRIPLE(uInd); + return uInd*((INDEX)i47) + (EXCLUDE1(sqb1,sqw3)-i8); // 47 + } + else + { + // En passant capture + uInd = TEnumerate2::Index(sqwk,sqw1,sqw2,sqbk); + CHECK_INF_PAIR(uInd); + return rgcTriplePawnPresent[piw1][piw2][x_piecePawn]*(INDEX)i47 + + (uInd*i14 + IndEnPassant11W (sqw3, sqb1, sqEnP ^ sqMask)); + } + } + else + { + // Only black pawn + uInd = TEnumerate3:: + Index(sqwk,sqw1,sqw2,sqw3,sqbk); + CHECK_INF_TRIPLE(uInd); + return (uInd*3)*(INDEX)16 + (sqb1-i8); // 48 + } + } + else + { + // No black pawn + uInd = TEnumerate3:: + Index(sqwk,sqw1,sqw2,sqw3,sqbk); + CHECK_INF_TRIPLE(uInd); + return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3); // 59 + } + } + else + { + // No pawns + if (!FInTriangle (sqwk, sqbk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqw3 = reflect_xy(sqw3); + sqbk = reflect_xy(sqbk); + sqb1 = reflect_xy(sqb1); + }; + uInd = TEnumerate3::Index(sqwk,sqw1,sqw2,sqw3,sqbk); + CHECK_INF_TRIPLE(uInd); + return uInd*(INDEX)i59 + EXCLUDE5(sqb1,sqwk,sqbk,sqw1,sqw2,sqw3); // 59 + } + } + + static INDEX TB_FASTCALL IndCalcB + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + unsigned uInd; + square sqwk, sqw1, sqw2, sqw3, sqbk, sqb1, sqMask, sqTemp; + + sqwk = SqFindKing (psqW); + sqw1 = SqFindFirst (psqW, piw1); + if (piw1 == piw2 && piw2 == piw3) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindThird (psqW, piw3); + } + else if (piw1 == piw2) + { + sqw2 = SqFindSecond (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + else if (piw2 == piw3) + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindSecond (psqW, piw3); + } + else + { + sqw2 = SqFindFirst (psqW, piw2); + sqw3 = SqFindFirst (psqW, piw3); + } + sqbk = SqFindKing (psqB); + sqb1 = SqFindOne (psqB, pib1); + + if (x_piecePawn == piw3 || x_piecePawn == pib1) + sqMask = rgsqReflectMaskY [sqbk] ^ rgsqReflectInvertMask [fInvert]; + else + sqMask = rgsqReflectMaskYandX [sqbk]; + sqwk ^= sqMask; + sqbk ^= sqMask; + sqw1 ^= sqMask; + sqw2 ^= sqMask; + sqw3 ^= sqMask; + sqb1 ^= sqMask; + + if (x_piecePawn == piw3 || x_piecePawn == pib1) + { + // There are pawns on the board + if (x_piecePawn == pib1) + { + // Black pawn + if (x_piecePawn == piw1) + { + // All 4 pieces are pawns + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + if (XX == sqEnP) + { + sqw3 = EXCLUDE1(sqw3,sqb1)-i8; // 47 + sqw2 = EXCLUDE1(sqw2,sqb1)-i8; // 47 + uInd = TEnumerate1::Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + return uInd*(i47*i46*i45/6) + + sqw3*(sqw3-1)*(sqw3-2)/6 + + sqw2*(sqw2-1)/2 + + EXCLUDE1(sqw1,sqb1)-i8; // 47*46*45/6 + } + else + // En passant capture + return rgcSinglePawnPresent[x_piecePawn]*(i47*i46*i45/6) + + IndHalfKings(sqbk,sqwk)*(i44*i43/2*i14) + + IndEnPassant31B (sqw1, sqw2, sqw3, sqb1, sqEnP ^ sqMask); + } + else if (x_piecePawn == piw2) + { + // Two white pawns, one black pawn + SORT (sqw2, sqw3); + if (XX == sqEnP) + { + sqTemp = EXCLUDE1(sqw3,sqb1)-i8; // 47 + uInd = TEnumerate1:: + Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + return (uInd*(i59*i47)*(INDEX)(i46/2)) + + (EXCLUDE5(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1)*(i47*i46/2) + // 59 + sqTemp*(sqTemp-1)/2 + + EXCLUDE1(sqw2,sqb1)-i8); // 47*46/2 + } + else + { + // En passant capture + sqEnP ^= sqMask; + uInd = rgcSinglePawnPresent[x_piecePawn]; + return (uInd*(i59*i47))*(INDEX)(i46/2) + + (IndHalfKings(sqbk,sqwk)*(i57*i44*i14) + + EXCLUDE7(sqw1,sqwk,sqbk,sqw2,sqw3,sqb1,sqEnP,sqEnP-8)*(i44*i14) + // 57 + IndEnPassant21B (sqw2, sqw3, sqb1, sqEnP)); + } + } + else if (x_piecePawn == piw3) + { + // One white pawn, one black pawn + if (piw1 == piw2) + { + // Two identical white pieces + SORT (sqw1, sqw2); + if (XX == sqEnP) + { + sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1); + sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1); + uInd = TEnumerate1::Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + return (uInd*(i59*i47))*((INDEX)i60/2) + + ((sqw2*(sqw2-1)/2+sqw1)*i47 + // 60*59/2 + EXCLUDE1(sqw3,sqb1)-i8); // 47 + } + else + { + // En passant capture + sqEnP ^= sqMask; + sqw2 = EXCLUDE6(sqw2,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8); + sqw1 = EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8); + uInd = rgcSinglePawnPresent[x_piecePawn]; + return (uInd*(i59*i47))*((INDEX)i60/2) + + (IndHalfKings(sqbk,sqwk)*(i58*i57/2*i14) + + (sqw2*(sqw2-1)/2+sqw1)*i14 + // 58*57/2 + IndEnPassant11B (sqw3, sqb1, sqEnP)); + } + } + else + { + // Two different white pieces + if (XX == sqEnP) + { + uInd = TEnumerate1::Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + return (uInd*(i59*i47))*((INDEX)i60) + + (EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1)*i59*i47 + // 60 + EXCLUDE5(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1)*i47 + // 59 + EXCLUDE1(sqw3,sqb1)-i8); // 47 + } + else + { + // En passant capture + sqEnP ^= sqMask; + uInd = rgcSinglePawnPresent[x_piecePawn]; + return (uInd*(i59*i47))*((INDEX)i60) + + (IndHalfKings(sqbk,sqwk)*(i58*i57*i14) + + EXCLUDE6(sqw1,sqwk,sqbk,sqw3,sqb1,sqEnP,sqEnP-8)*(i57*i14) + // 58 + EXCLUDE7(sqw2,sqwk,sqbk,sqw1,sqw3,sqb1,sqEnP,sqEnP-8)*i14 + // 57 + IndEnPassant11B (sqw3, sqb1, sqEnP)); + } + } + } + else + { + // Only black pawn + uInd = TEnumerate1::Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + if (piw1 == piw3) + { + // 3 identical white pieces + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61 + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); // 61 + sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1); // 61 + return uInd*(i61*i60*i59/6) + + sqw3*(sqw3-1)*(sqw3-2)/6 + sqw2*(sqw2-1)/2 + sqw1; // 61*60*59/6 + } + else if (piw1 == piw2) + { + // 2 identical major white pieces + SORT (sqw1, sqw2); + sqw3 = EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1); + sqw1 = EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61 + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); // 61 + return (uInd*(i61*i59))*(INDEX)(i60/2) + + ((sqw2*(sqw2-1)/2 + sqw1)*i59 + // 61*60/2 + sqw3); // 59 + } + else if (piw2 == piw3) + { + // 2 identical minor white pieces + SORT (sqw2, sqw3); + sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60 + sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1); // 60 + return (uInd*(i61*i59))*(INDEX)(i60/2) + + (EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) + // 61 + sqw3*(sqw3-1)/2 + sqw2); // 60*59/2 + } + else + { + // All 3 white pieces are different + return (uInd*(i61*i59))*(INDEX)i60 + + (EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) + // 61 + EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 + // 60 + EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1)); // 59 + } + } + } + else + { + // No black pawn + uInd = TEnumerate1::Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + if (x_piecePawn == piw1) + { + // Only 3 white pawns + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + sqw3 -= i8; + sqw2 -= i8; + return uInd*(i48*47*i46/6) + + sqw3*(sqw3-1)*(sqw3-2)/6+sqw2*(sqw2-1)/2+sqw1-i8; // 48*47*46/6 + } + else if (x_piecePawn == piw2) + { + // 2 white pawns, one non-pawn + SORT (sqw2, sqw3); + sqTemp = sqw3 - i8; + return (uInd*(i59*47))*(INDEX)(i48/2) + + (EXCLUDE5(sqw1,sqwk,sqbk,sqb1,sqw2,sqw3)*(i48*i47/2) + + sqTemp*(sqTemp-1)/2+sqw2-i8); // 48*47/2 + } + else if (piw1 == piw2) + { + // One white pawn, 2 identical white pieces + SORT (sqw1, sqw2); + sqw1 = EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3); + sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqb1,sqw3); + return (uInd*(i60*i59/2))*(INDEX)i48 + + ((sqw2*(sqw2-1)/2+sqw1)*i48 + // 60*59/2 + sqw3-i8); // 48 + } + else + { + // One white pawn, 2 different white pieces + return (uInd*(i60*i59))*(INDEX)i48 + + (EXCLUDE4(sqw1,sqwk,sqbk,sqb1,sqw3)*(i59*i48) + // 60 + EXCLUDE5(sqw2,sqwk,sqbk,sqb1,sqw1,sqw3)*i48 + // 59 + sqw3-i8); // 48 + } + } + } + else + { + // No pawns + if (!FInTriangle (sqbk, sqwk)) + { + sqwk = reflect_xy(sqwk); + sqw1 = reflect_xy(sqw1); + sqw2 = reflect_xy(sqw2); + sqw3 = reflect_xy(sqw3); + sqbk = reflect_xy(sqbk); + sqb1 = reflect_xy(sqb1); + }; + uInd = TEnumerate1::Index(sqbk,sqb1,sqwk); + CHECK_INF_SINGLE(uInd); + if (piw1 == piw2 && piw2 == piw3) + { + // All 3 pieces equal + SORT (sqw1, sqw2); + SORT (sqw2, sqw3); + SORT (sqw1, sqw2); + sqw3 = EXCLUDE3(sqw3,sqwk,sqbk,sqb1); // 61 + sqw2 = EXCLUDE3(sqw2,sqwk,sqbk,sqb1); + return uInd*(i61*i60*i59/6) + + sqw3*(sqw3-1)*(sqw3-2)/6+ + sqw2*(sqw2-1)/2+ + EXCLUDE3(sqw1,sqwk,sqbk,sqb1); // 61*60*59/6 + } + else if (piw1 == piw2) + { + // 2 major pieces equal + SORT (sqw1, sqw2); + sqw2 = EXCLUDE4(sqw2,sqwk,sqbk,sqw3,sqb1); // 60 + return uInd*(i60*i59/2*i61) + + (sqw2*(sqw2-1)/2+EXCLUDE4(sqw1,sqwk,sqbk,sqw3,sqb1))*i61 + // 60*59/2 + EXCLUDE3(sqw3,sqwk,sqbk,sqb1); // 61 + } + else if (piw2 == piw3) + { + // 2 minor pieces equal + SORT (sqw2, sqw3); + sqw3 = EXCLUDE4(sqw3,sqwk,sqbk,sqw1,sqb1); // 60 + return uInd*(i61*i60*i59/2) + + EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59/2) + // 62 + sqw3*(sqw3-1)/2+EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1); // 60*59/2 + } + else + { + uInd *= i61*i60*i59/2; + return (INDEX) uInd + + (INDEX) (uInd + + EXCLUDE3(sqw1,sqwk,sqbk,sqb1)*(i60*i59) + // 61 + EXCLUDE4(sqw2,sqwk,sqbk,sqw1,sqb1)*i59 + // 60 + EXCLUDE5(sqw3,sqwk,sqbk,sqw1,sqw2,sqb1)); // 59 + } + } + } + }; + +#endif // T42 + +#else // Old SJE schema ------------------------------------------------------ + +/* scanning pattern: triangle encoding */ + +static const INDEX sptriv[] = + { + 0, 1, 2, 3, -1, -1, -1, -1, + -1, 4, 5, 6, -1, -1, -1, -1, + -1, -1, 7, 8, -1, -1, -1, -1, + -1, -1, -1, 9, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + -1, -1, -1, -1, -1, -1, -1, -1, + }; + +/* scanning pattern: queenside flank encoding */ + +static const INDEX spqsfv[] = + { + 0, 1, 2, 3, -1, -1, -1, -1, + 4, 5, 6, 7, -1, -1, -1, -1, + 8, 9, 10, 11, -1, -1, -1, -1, + 12, 13, 14, 15, -1, -1, -1, -1, + 16, 17, 18, 19, -1, -1, -1, -1, + 20, 21, 22, 23, -1, -1, -1, -1, + 24, 25, 26, 27, -1, -1, -1, -1, + 28, 29, 30, 31, -1, -1, -1, -1, + }; + +/*--> CalcIndex3A: calculate index, mode 3A */ +INLINE INDEX CalcIndex3A + ( + square sq0, + square sq1, + square sq2 + ) + { + INDEX index; + + if (TbRow(sq2) > x_row_4) + { + sq0 = reflect_x(sq0); + sq1 = reflect_x(sq1); + sq2 = reflect_x(sq2); + }; + + if (TbColumn(sq2) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + }; + + if (TbRow(sq2) > TbColumn(sq2)) + { + sq0 = reflect_xy(sq0); + sq1 = reflect_xy(sq1); + sq2 = reflect_xy(sq2); + }; + + index = + sq0 + + sq1 * i64 + + sptriv [sq2] * i64 * i64; + + return (index); + } + +/*--> CalcIndex3B: calculate index, mode 3B */ +INLINE INDEX CalcIndex3B + ( + square sq0, + square sq1, + square sq2 + ) + { + INDEX index; + + if (TbColumn(sq1) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + }; + + index = + sq0 + + spqsfv [sq1] * i64 + + sq2 * (i64 / 2) * i64; + + return (index); + } + +/*--> CalcIndex4A: calculate index, mode 4A */ +INLINE INDEX CalcIndex4A + ( + square sq0, + square sq1, + square sq2, + square sq3 + ) + { + INDEX index; + + if (TbRow(sq3) > x_row_4) + { + sq0 = reflect_x(sq0); + sq1 = reflect_x(sq1); + sq2 = reflect_x(sq2); + sq3 = reflect_x(sq3); + }; + + if (TbColumn(sq3) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + }; + + if (TbRow(sq3) > TbColumn(sq3)) + { + sq0 = reflect_xy(sq0); + sq1 = reflect_xy(sq1); + sq2 = reflect_xy(sq2); + sq3 = reflect_xy(sq3); + }; + + index = + sq0 + + sq1 * i64 + + sq2 * i64 * i64 + + sptriv [sq3] * i64 * i64 * i64; + + return (index); + } + +/*--> CalcIndex4B: calculate index, mode 4B */ +INLINE INDEX CalcIndex4B + ( + square sq0, + square sq1, + square sq2, + square sq3 + ) + { + INDEX index; + + if (TbColumn(sq3) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + }; + + index = + sq0 + + sq1 * i64 + + sq2 * i64 * i64 + + spqsfv [sq3] * i64 * i64 * i64; + + return (index); + } + +/*--> CalcIndex4C: calculate index, mode 4C */ +INLINE INDEX CalcIndex4C + ( + square sq0, + square sq1, + square sq2, + square sq3 + ) + { + INDEX index; + + if (TbColumn(sq2) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + }; + + index = + sq0 + + sq1 * i64 + + spqsfv [sq2] * i64 * i64 + + sq3 * (i64 / 2) * i64 * i64; + + return (index); + } + +/*--> CalcIndex5A: calculate index, mode 5A */ +INLINE INDEX CalcIndex5A + ( + square sq0, + square sq1, + square sq2, + square sq3, + square sq4 + ) + { + INDEX index; + + if (TbRow(sq4) > x_row_4) + { + sq0 = reflect_x(sq0); + sq1 = reflect_x(sq1); + sq2 = reflect_x(sq2); + sq3 = reflect_x(sq3); + sq4 = reflect_x(sq4); + }; + + if (TbColumn(sq4) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + sq4 = reflect_y(sq4); + }; + + if (TbRow(sq4) > TbColumn(sq4)) + { + sq0 = reflect_xy(sq0); + sq1 = reflect_xy(sq1); + sq2 = reflect_xy(sq2); + sq3 = reflect_xy(sq3); + sq4 = reflect_xy(sq4); + }; + + index = + sq0 + + sq1 * i64 + + sq2 * i64 * i64 + + sq3 * i64 * i64 * i64 + + sptriv [sq4] * i64 * i64 * i64 * i64; + + return (index); + } + +/*--> CalcIndex5B: calculate index, mode 5B */ +INLINE INDEX CalcIndex5B + ( + square sq0, + square sq1, + square sq2, + square sq3, + square sq4 + ) + { + INDEX index; + + if (TbColumn(sq4) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + sq4 = reflect_y(sq4); + }; + + index = + sq0 + + sq1 * i64 + + sq2 * i64 * i64 + + sq3 * i64 * i64 * i64 + + spqsfv [sq4] * i64 * i64 * i64 * i64; + + return (index); + } + +/*--> CalcIndex5C: calculate index, mode 5C */ +INLINE INDEX CalcIndex5C + ( + square sq0, + square sq1, + square sq2, + square sq3, + square sq4 + ) + { + INDEX index; + + if (TbColumn(sq3) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + sq4 = reflect_y(sq4); + }; + + index = + sq0 + + sq1 * i64 + + sq2 * i64 * i64 + + spqsfv [sq3] * i64 * i64 * i64 + + sq4 * (i64 / 2) * i64 * i64 * i64; + + return (index); + } + +/*--> CalcIndex5D: calculate index, mode 5D */ +INLINE INDEX CalcIndex5D + ( + square sq0, + square sq1, + square sq2, + square sq3, + square sq4 + ) + { + INDEX index; + + if (TbColumn(sq2) > x_column_d) + { + sq0 = reflect_y(sq0); + sq1 = reflect_y(sq1); + sq2 = reflect_y(sq2); + sq3 = reflect_y(sq3); + sq4 = reflect_y(sq4); + }; + + index = + sq0 + + sq1 * i64 + + spqsfv [sq2] * i64 * i64 + + sq3 * (i64 / 2) * i64 * i64 + + sq4 * (i64 / 2) * i64 * i64 * i64; + + return (index); + } + +// Calculate index - a lot of functions... + +#define IndCalcW IndCalc +#define IndCalcB IndCalc + +template class T21 + { +public: + static INDEX TB_FASTCALL IndCalc + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sq0, sq1, sq2; + + sq0 = SqFindKing (psqW); + sq1 = SqFindOne (psqW, pi); + sq2 = SqFindKing (psqB); + + if (x_piecePawn == pi) + { + if (fInvert) + { + sq0 = reflect_x (sq0); + sq1 = reflect_x (sq1); + sq2 = reflect_x (sq2); + } + return CalcIndex3B (sq0, sq1, sq2); + } + else + return CalcIndex3A (sq0, sq1, sq2); + } + }; + +template class T22 + { +public: + static INDEX TB_FASTCALL IndCalc + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sq0, sq1, sq2, sq3; + + sq0 = SqFindKing (psqW); + sq1 = SqFindOne (psqW, pi1); + sq2 = SqFindKing (psqB); + sq3 = SqFindOne (psqB, pi2); + + if (x_piecePawn == pi1 || x_piecePawn == pi2) + { + if (fInvert) + { + sq0 = reflect_x (sq0); + sq1 = reflect_x (sq1); + sq2 = reflect_x (sq2); + sq3 = reflect_x (sq3); + } + return CalcIndex4B (sq0, sq1, sq2, sq3); + } + else + return CalcIndex4A (sq0, sq1, sq2, sq3); + } + }; + +template class T31 + { +public: + static INDEX TB_FASTCALL IndCalc + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sq0, sq1, sq2, sq3; + + sq0 = SqFindKing (psqW); + sq1 = SqFindFirst (psqW, pi1); + if (pi1 == pi2) + sq2 = SqFindSecond (psqW, pi2); + else + sq2 = SqFindFirst (psqW, pi2); + sq3 = SqFindKing (psqB); + + if (x_piecePawn == pi1 || x_piecePawn == pi2) + { + if (fInvert) + { + sq0 = reflect_x (sq0); + sq1 = reflect_x (sq1); + sq2 = reflect_x (sq2); + sq3 = reflect_x (sq3); + } + return CalcIndex4C (sq0, sq1, sq2, sq3); + } + else + return CalcIndex4A (sq0, sq1, sq2, sq3); + } + }; + +template class T32 + { +public: + static INDEX TB_FASTCALL IndCalc + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sq0, sq1, sq2, sq3, sq4; + + sq0 = SqFindKing (psqW); + sq1 = SqFindFirst (psqW, pi1); + if (pi1 == pi2) + sq2 = SqFindSecond (psqW, pi2); + else + sq2 = SqFindFirst (psqW, pi2); + sq3 = SqFindKing (psqB); + sq4 = SqFindOne (psqB, pi3); + + if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3) + { + if (fInvert) + { + sq0 = reflect_x (sq0); + sq1 = reflect_x (sq1); + sq2 = reflect_x (sq2); + sq3 = reflect_x (sq3); + sq4 = reflect_x (sq4); + } + if (x_piecePawn == pi3) + return CalcIndex5B (sq0, sq1, sq2, sq3, sq4); + else + return CalcIndex5D (sq0, sq1, sq2, sq3, sq4); + } + else + return CalcIndex5A (sq0, sq1, sq2, sq3, sq4); + } + }; + +#if defined (T41_INCLUDE) + +template class T41 + { +public: + static INDEX TB_FASTCALL IndCalc + ( + square *psqW, + square *psqB, + square sqEnP, + int fInvert + ) + { + square sq0, sq1, sq2, sq3, sq4; + + sq0 = SqFindKing (psqW); + sq1 = SqFindFirst (psqW, pi1); + sq2 = SqFindFirst (psqW, pi2); + sq3 = SqFindFirst (psqW, pi3); + sq4 = SqFindKing (psqB); + + if (x_piecePawn == pi1 || x_piecePawn == pi2 || x_piecePawn == pi3) + { + // There are pawns on the board + if (fInvert) + { + sq0 = reflect_x (sq0); + sq1 = reflect_x (sq1); + sq2 = reflect_x (sq2); + sq3 = reflect_x (sq3); + sq4 = reflect_x (sq4); + } + return CalcIndex5C (sq0, sq1, sq2, sq3, sq4); + } + else // No pawns + return CalcIndex5A (sq0, sq1, sq2, sq3, sq4); + } + }; + +#endif + +#endif //---------------------------------------------------------------------- + +// All tablebases enumerated + +#define tbid_kk 0 +#define tbid_kpk 1 +#define tbid_knk 2 +#define tbid_kbk 3 +#define tbid_krk 4 +#define tbid_kqk 5 +#define tbid_kpkp 6 +#define tbid_knkp 7 +#define tbid_knkn 8 +#define tbid_kbkp 9 +#define tbid_kbkn 10 +#define tbid_kbkb 11 +#define tbid_krkp 12 +#define tbid_krkn 13 +#define tbid_krkb 14 +#define tbid_krkr 15 +#define tbid_kqkp 16 +#define tbid_kqkn 17 +#define tbid_kqkb 18 +#define tbid_kqkr 19 +#define tbid_kqkq 20 +#define tbid_kppk 21 +#define tbid_knpk 22 +#define tbid_knnk 23 +#define tbid_kbpk 24 +#define tbid_kbnk 25 +#define tbid_kbbk 26 +#define tbid_krpk 27 +#define tbid_krnk 28 +#define tbid_krbk 29 +#define tbid_krrk 30 +#define tbid_kqpk 31 +#define tbid_kqnk 32 +#define tbid_kqbk 33 +#define tbid_kqrk 34 +#define tbid_kqqk 35 +#define tbid_kppkp 36 +#define tbid_kppkn 37 +#define tbid_kppkb 38 +#define tbid_kppkr 39 +#define tbid_kppkq 40 +#define tbid_knpkp 41 +#define tbid_knpkn 42 +#define tbid_knpkb 43 +#define tbid_knpkr 44 +#define tbid_knpkq 45 +#define tbid_knnkp 46 +#define tbid_knnkn 47 +#define tbid_knnkb 48 +#define tbid_knnkr 49 +#define tbid_knnkq 50 +#define tbid_kbpkp 51 +#define tbid_kbpkn 52 +#define tbid_kbpkb 53 +#define tbid_kbpkr 54 +#define tbid_kbpkq 55 +#define tbid_kbnkp 56 +#define tbid_kbnkn 57 +#define tbid_kbnkb 58 +#define tbid_kbnkr 59 +#define tbid_kbnkq 60 +#define tbid_kbbkp 61 +#define tbid_kbbkn 62 +#define tbid_kbbkb 63 +#define tbid_kbbkr 64 +#define tbid_kbbkq 65 +#define tbid_krpkp 66 +#define tbid_krpkn 67 +#define tbid_krpkb 68 +#define tbid_krpkr 69 +#define tbid_krpkq 70 +#define tbid_krnkp 71 +#define tbid_krnkn 72 +#define tbid_krnkb 73 +#define tbid_krnkr 74 +#define tbid_krnkq 75 +#define tbid_krbkp 76 +#define tbid_krbkn 77 +#define tbid_krbkb 78 +#define tbid_krbkr 79 +#define tbid_krbkq 80 +#define tbid_krrkp 81 +#define tbid_krrkn 82 +#define tbid_krrkb 83 +#define tbid_krrkr 84 +#define tbid_krrkq 85 +#define tbid_kqpkp 86 +#define tbid_kqpkn 87 +#define tbid_kqpkb 88 +#define tbid_kqpkr 89 +#define tbid_kqpkq 90 +#define tbid_kqnkp 91 +#define tbid_kqnkn 92 +#define tbid_kqnkb 93 +#define tbid_kqnkr 94 +#define tbid_kqnkq 95 +#define tbid_kqbkp 96 +#define tbid_kqbkn 97 +#define tbid_kqbkb 98 +#define tbid_kqbkr 99 +#define tbid_kqbkq 100 +#define tbid_kqrkp 101 +#define tbid_kqrkn 102 +#define tbid_kqrkb 103 +#define tbid_kqrkr 104 +#define tbid_kqrkq 105 +#define tbid_kqqkp 106 +#define tbid_kqqkn 107 +#define tbid_kqqkb 108 +#define tbid_kqqkr 109 +#define tbid_kqqkq 110 + +#if defined (T41_INCLUDE) +# define tbid_kpppk 111 +# define tbid_knppk 112 +# define tbid_knnpk 113 +# define tbid_knnnk 114 +# define tbid_kbppk 115 +# define tbid_kbnpk 116 +# define tbid_kbnnk 117 +# define tbid_kbbpk 118 +# define tbid_kbbnk 119 +# define tbid_kbbbk 120 +# define tbid_krppk 121 +# define tbid_krnpk 122 +# define tbid_krnnk 123 +# define tbid_krbpk 124 +# define tbid_krbnk 125 +# define tbid_krbbk 126 +# define tbid_krrpk 127 +# define tbid_krrnk 128 +# define tbid_krrbk 129 +# define tbid_krrrk 130 +# define tbid_kqppk 131 +# define tbid_kqnpk 132 +# define tbid_kqnnk 133 +# define tbid_kqbpk 134 +# define tbid_kqbnk 135 +# define tbid_kqbbk 136 +# define tbid_kqrpk 137 +# define tbid_kqrnk 138 +# define tbid_kqrbk 139 +# define tbid_kqrrk 140 +# define tbid_kqqpk 141 +# define tbid_kqqnk 142 +# define tbid_kqqbk 143 +# define tbid_kqqrk 144 +# define tbid_kqqqk 145 +#endif + +#if defined (T33_INCLUDE) +# if defined (T41_INCLUDE) +# define BASE_33 145 +# else +# define BASE_33 110 +# endif +# define tbid_knnknn (BASE_33 + 1) +# define tbid_kbnknn (BASE_33 + 2) +# define tbid_kbbknn (BASE_33 + 3) +# define tbid_kbbkbn (BASE_33 + 4) +# define tbid_kbbkbb (BASE_33 + 5) +# define tbid_krnknn (BASE_33 + 6) +# define tbid_krnkbb (BASE_33 + 7) +# define tbid_krbknn (BASE_33 + 8) +# define tbid_krbkbb (BASE_33 + 9) +# define tbid_krrknn (BASE_33 + 10) +# define tbid_krrkbn (BASE_33 + 11) +# define tbid_krrkbb (BASE_33 + 12) +# define tbid_krrkrn (BASE_33 + 13) +# define tbid_krrkrb (BASE_33 + 14) +# define tbid_krrkrr (BASE_33 + 15) +# define tbid_kqnknn (BASE_33 + 16) +# define tbid_kqnkbb (BASE_33 + 17) +# define tbid_kqnkrr (BASE_33 + 18) +# define tbid_kqbknn (BASE_33 + 19) +# define tbid_kqbkbb (BASE_33 + 20) +# define tbid_kqbkrr (BASE_33 + 21) +# define tbid_kqrknn (BASE_33 + 22) +# define tbid_kqrkbb (BASE_33 + 23) +# define tbid_kqrkrr (BASE_33 + 24) +# define tbid_kqqknn (BASE_33 + 25) +# define tbid_kqqkbn (BASE_33 + 26) +# define tbid_kqqkbb (BASE_33 + 27) +# define tbid_kqqkrn (BASE_33 + 28) +# define tbid_kqqkrb (BASE_33 + 29) +# define tbid_kqqkrr (BASE_33 + 30) +# define tbid_kqqkqn (BASE_33 + 31) +# define tbid_kqqkqb (BASE_33 + 32) +# define tbid_kqqkqr (BASE_33 + 33) +# define tbid_kqqkqq (BASE_33 + 34) +# if defined (T_INDEX64) +# define tbid_kbnkbn (BASE_33 + 35) +# define tbid_krnkrn (BASE_33 + 36) +# define tbid_krbkrb (BASE_33 + 37) +# define tbid_kqnkqn (BASE_33 + 38) +# define tbid_kqbkqb (BASE_33 + 39) +# define tbid_kqrkqr (BASE_33 + 40) +# define tbid_krnkbn (BASE_33 + 41) +# define tbid_krbkbn (BASE_33 + 42) +# define tbid_krbkrn (BASE_33 + 43) +# define tbid_kqnkbn (BASE_33 + 44) +# define tbid_kqnkrn (BASE_33 + 45) +# define tbid_kqnkrb (BASE_33 + 46) +# define tbid_kqbkbn (BASE_33 + 47) +# define tbid_kqbkrn (BASE_33 + 48) +# define tbid_kqbkrb (BASE_33 + 49) +# define tbid_kqbkqn (BASE_33 + 50) +# define tbid_kqrkbn (BASE_33 + 51) +# define tbid_kqrkrn (BASE_33 + 52) +# define tbid_kqrkrb (BASE_33 + 53) +# define tbid_kqrkqn (BASE_33 + 54) +# define tbid_kqrkqb (BASE_33 + 55) +# define tbid_kppkpp (BASE_33 + 56) +# define tbid_knpkpp (BASE_33 + 57) +# define tbid_knpknp (BASE_33 + 58) +# define tbid_knnkpp (BASE_33 + 59) +# define tbid_knnknp (BASE_33 + 60) +# define tbid_kbpkpp (BASE_33 + 61) +# define tbid_kbpknp (BASE_33 + 62) +# define tbid_kbpknn (BASE_33 + 63) +# define tbid_kbpkbp (BASE_33 + 64) +# define tbid_kbnkpp (BASE_33 + 65) +# define tbid_kbnknp (BASE_33 + 66) +# define tbid_kbnkbp (BASE_33 + 67) +# define tbid_kbbkpp (BASE_33 + 68) +# define tbid_kbbknp (BASE_33 + 69) +# define tbid_kbbkbp (BASE_33 + 70) +# define tbid_krpkpp (BASE_33 + 71) +# define tbid_krpknp (BASE_33 + 72) +# define tbid_krpknn (BASE_33 + 73) +# define tbid_krpkbp (BASE_33 + 74) +# define tbid_krpkbn (BASE_33 + 75) +# define tbid_krpkbb (BASE_33 + 76) +# define tbid_krpkrp (BASE_33 + 77) +# define tbid_krnkpp (BASE_33 + 78) +# define tbid_krnknp (BASE_33 + 79) +# define tbid_krnkbp (BASE_33 + 80) +# define tbid_krnkrp (BASE_33 + 81) +# define tbid_krbkpp (BASE_33 + 82) +# define tbid_krbknp (BASE_33 + 83) +# define tbid_krbkbp (BASE_33 + 84) +# define tbid_krbkrp (BASE_33 + 85) +# define tbid_krrkpp (BASE_33 + 86) +# define tbid_krrknp (BASE_33 + 87) +# define tbid_krrkbp (BASE_33 + 88) +# define tbid_krrkrp (BASE_33 + 89) +# define tbid_kqpkpp (BASE_33 + 90) +# define tbid_kqpknp (BASE_33 + 91) +# define tbid_kqpknn (BASE_33 + 92) +# define tbid_kqpkbp (BASE_33 + 93) +# define tbid_kqpkbn (BASE_33 + 94) +# define tbid_kqpkbb (BASE_33 + 95) +# define tbid_kqpkrp (BASE_33 + 96) +# define tbid_kqpkrn (BASE_33 + 97) +# define tbid_kqpkrb (BASE_33 + 98) +# define tbid_kqpkrr (BASE_33 + 99) +# define tbid_kqpkqp (BASE_33 + 100) +# define tbid_kqnkpp (BASE_33 + 101) +# define tbid_kqnknp (BASE_33 + 102) +# define tbid_kqnkbp (BASE_33 + 103) +# define tbid_kqnkrp (BASE_33 + 104) +# define tbid_kqnkqp (BASE_33 + 105) +# define tbid_kqbkpp (BASE_33 + 106) +# define tbid_kqbknp (BASE_33 + 107) +# define tbid_kqbkbp (BASE_33 + 108) +# define tbid_kqbkrp (BASE_33 + 109) +# define tbid_kqbkqp (BASE_33 + 110) +# define tbid_kqrkpp (BASE_33 + 111) +# define tbid_kqrknp (BASE_33 + 112) +# define tbid_kqrkbp (BASE_33 + 113) +# define tbid_kqrkrp (BASE_33 + 114) +# define tbid_kqrkqp (BASE_33 + 115) +# define tbid_kqqkpp (BASE_33 + 116) +# define tbid_kqqknp (BASE_33 + 117) +# define tbid_kqqkbp (BASE_33 + 118) +# define tbid_kqqkrp (BASE_33 + 119) +# define tbid_kqqkqp (BASE_33 + 120) +# define C33 (tbid_kqqkqp - BASE_33) +# else +# define C33 (tbid_kqqkqq - BASE_33) +# endif +#else +# define C33 0 +#endif + +#if defined (T41_INCLUDE) +# define BASE_42 (145 + C33) +#else +# define BASE_42 (110 + C33) +#endif + +#if defined (T42_INCLUDE) +# define tbid_knnnkn (BASE_42 + 1) +# define tbid_kbnnkn (BASE_42 + 2) +# define tbid_kbbnkn (BASE_42 + 3) +# define tbid_kbbbkn (BASE_42 + 4) +# define tbid_krnnkn (BASE_42 + 5) +# define tbid_krbbkn (BASE_42 + 6) +# define tbid_krrnkn (BASE_42 + 7) +# define tbid_krrbkn (BASE_42 + 8) +# define tbid_krrrkn (BASE_42 + 9) +# define tbid_kqnnkn (BASE_42 + 10) +# define tbid_kqbbkn (BASE_42 + 11) +# define tbid_kqrrkn (BASE_42 + 12) +# define tbid_kqqnkn (BASE_42 + 13) +# define tbid_kqqbkn (BASE_42 + 14) +# define tbid_kqqrkn (BASE_42 + 15) +# define tbid_kqqqkn (BASE_42 + 16) +# define tbid_knnnkb (BASE_42 + 17) +# define tbid_kbnnkb (BASE_42 + 18) +# define tbid_kbbnkb (BASE_42 + 19) +# define tbid_kbbbkb (BASE_42 + 20) +# define tbid_krnnkb (BASE_42 + 21) +# define tbid_krbbkb (BASE_42 + 22) +# define tbid_krrnkb (BASE_42 + 23) +# define tbid_krrbkb (BASE_42 + 24) +# define tbid_krrrkb (BASE_42 + 25) +# define tbid_kqnnkb (BASE_42 + 26) +# define tbid_kqbbkb (BASE_42 + 27) +# define tbid_kqrrkb (BASE_42 + 28) +# define tbid_kqqnkb (BASE_42 + 29) +# define tbid_kqqbkb (BASE_42 + 30) +# define tbid_kqqrkb (BASE_42 + 31) +# define tbid_kqqqkb (BASE_42 + 32) +# define tbid_knnnkr (BASE_42 + 33) +# define tbid_kbnnkr (BASE_42 + 34) +# define tbid_kbbnkr (BASE_42 + 35) +# define tbid_kbbbkr (BASE_42 + 36) +# define tbid_krnnkr (BASE_42 + 37) +# define tbid_krbbkr (BASE_42 + 38) +# define tbid_krrnkr (BASE_42 + 39) +# define tbid_krrbkr (BASE_42 + 40) +# define tbid_krrrkr (BASE_42 + 41) +# define tbid_kqnnkr (BASE_42 + 42) +# define tbid_kqbbkr (BASE_42 + 43) +# define tbid_kqrrkr (BASE_42 + 44) +# define tbid_kqqnkr (BASE_42 + 45) +# define tbid_kqqbkr (BASE_42 + 46) +# define tbid_kqqrkr (BASE_42 + 47) +# define tbid_kqqqkr (BASE_42 + 48) +# define tbid_knnnkq (BASE_42 + 49) +# define tbid_kbnnkq (BASE_42 + 50) +# define tbid_kbbnkq (BASE_42 + 51) +# define tbid_kbbbkq (BASE_42 + 52) +# define tbid_krnnkq (BASE_42 + 53) +# define tbid_krbbkq (BASE_42 + 54) +# define tbid_krrnkq (BASE_42 + 55) +# define tbid_krrbkq (BASE_42 + 56) +# define tbid_krrrkq (BASE_42 + 57) +# define tbid_kqnnkq (BASE_42 + 58) +# define tbid_kqbbkq (BASE_42 + 59) +# define tbid_kqrrkq (BASE_42 + 60) +# define tbid_kqqnkq (BASE_42 + 61) +# define tbid_kqqbkq (BASE_42 + 62) +# define tbid_kqqrkq (BASE_42 + 63) +# define tbid_kqqqkq (BASE_42 + 64) +# if defined (T_INDEX64) +# define tbid_krbnkn (BASE_42 + 65) +# define tbid_kqbnkn (BASE_42 + 66) +# define tbid_kqrnkn (BASE_42 + 67) +# define tbid_kqrbkn (BASE_42 + 68) +# define tbid_krbnkb (BASE_42 + 69) +# define tbid_kqbnkb (BASE_42 + 70) +# define tbid_kqrnkb (BASE_42 + 71) +# define tbid_kqrbkb (BASE_42 + 72) +# define tbid_krbnkr (BASE_42 + 73) +# define tbid_kqbnkr (BASE_42 + 74) +# define tbid_kqrnkr (BASE_42 + 75) +# define tbid_kqrbkr (BASE_42 + 76) +# define tbid_krbnkq (BASE_42 + 77) +# define tbid_kqbnkq (BASE_42 + 78) +# define tbid_kqrnkq (BASE_42 + 79) +# define tbid_kqrbkq (BASE_42 + 80) + +# define tbid_kpppkp (BASE_42 + 81) +# define tbid_knppkp (BASE_42 + 82) +# define tbid_knnpkp (BASE_42 + 83) +# define tbid_knnnkp (BASE_42 + 84) +# define tbid_kbppkp (BASE_42 + 85) +# define tbid_kbnpkp (BASE_42 + 86) +# define tbid_kbnnkp (BASE_42 + 87) +# define tbid_kbbpkp (BASE_42 + 88) +# define tbid_kbbnkp (BASE_42 + 89) +# define tbid_kbbbkp (BASE_42 + 90) +# define tbid_krppkp (BASE_42 + 91) +# define tbid_krnpkp (BASE_42 + 92) +# define tbid_krnnkp (BASE_42 + 93) +# define tbid_krbpkp (BASE_42 + 94) +# define tbid_krbnkp (BASE_42 + 95) +# define tbid_krbbkp (BASE_42 + 96) +# define tbid_krrpkp (BASE_42 + 97) +# define tbid_krrnkp (BASE_42 + 98) +# define tbid_krrbkp (BASE_42 + 99) +# define tbid_krrrkp (BASE_42 + 100) +# define tbid_kqppkp (BASE_42 + 101) +# define tbid_kqnpkp (BASE_42 + 102) +# define tbid_kqnnkp (BASE_42 + 103) +# define tbid_kqbpkp (BASE_42 + 104) +# define tbid_kqbnkp (BASE_42 + 105) +# define tbid_kqbbkp (BASE_42 + 106) +# define tbid_kqrpkp (BASE_42 + 107) +# define tbid_kqrnkp (BASE_42 + 108) +# define tbid_kqrbkp (BASE_42 + 109) +# define tbid_kqrrkp (BASE_42 + 110) +# define tbid_kqqpkp (BASE_42 + 111) +# define tbid_kqqnkp (BASE_42 + 112) +# define tbid_kqqbkp (BASE_42 + 113) +# define tbid_kqqrkp (BASE_42 + 114) +# define tbid_kqqqkp (BASE_42 + 115) +# define tbid_kpppkn (BASE_42 + 116) +# define tbid_knppkn (BASE_42 + 117) +# define tbid_knnpkn (BASE_42 + 118) +# define tbid_kbppkn (BASE_42 + 119) +# define tbid_kbnpkn (BASE_42 + 120) +# define tbid_kbbpkn (BASE_42 + 121) +# define tbid_krppkn (BASE_42 + 122) +# define tbid_krnpkn (BASE_42 + 123) +# define tbid_krbpkn (BASE_42 + 124) +# define tbid_krrpkn (BASE_42 + 125) +# define tbid_kqppkn (BASE_42 + 126) +# define tbid_kqnpkn (BASE_42 + 127) +# define tbid_kqbpkn (BASE_42 + 128) +# define tbid_kqrpkn (BASE_42 + 129) +# define tbid_kqqpkn (BASE_42 + 130) +# define tbid_kpppkb (BASE_42 + 131) +# define tbid_knppkb (BASE_42 + 132) +# define tbid_knnpkb (BASE_42 + 133) +# define tbid_kbppkb (BASE_42 + 134) +# define tbid_kbnpkb (BASE_42 + 135) +# define tbid_kbbpkb (BASE_42 + 136) +# define tbid_krppkb (BASE_42 + 137) +# define tbid_krnpkb (BASE_42 + 138) +# define tbid_krbpkb (BASE_42 + 139) +# define tbid_krrpkb (BASE_42 + 140) +# define tbid_kqppkb (BASE_42 + 141) +# define tbid_kqnpkb (BASE_42 + 142) +# define tbid_kqbpkb (BASE_42 + 143) +# define tbid_kqrpkb (BASE_42 + 144) +# define tbid_kqqpkb (BASE_42 + 145) +# define tbid_kpppkr (BASE_42 + 146) +# define tbid_knppkr (BASE_42 + 147) +# define tbid_knnpkr (BASE_42 + 148) +# define tbid_kbppkr (BASE_42 + 149) +# define tbid_kbnpkr (BASE_42 + 150) +# define tbid_kbbpkr (BASE_42 + 151) +# define tbid_krppkr (BASE_42 + 152) +# define tbid_krnpkr (BASE_42 + 153) +# define tbid_krbpkr (BASE_42 + 154) +# define tbid_krrpkr (BASE_42 + 155) +# define tbid_kqppkr (BASE_42 + 156) +# define tbid_kqnpkr (BASE_42 + 157) +# define tbid_kqbpkr (BASE_42 + 158) +# define tbid_kqrpkr (BASE_42 + 159) +# define tbid_kqqpkr (BASE_42 + 160) +# define tbid_kpppkq (BASE_42 + 161) +# define tbid_knppkq (BASE_42 + 162) +# define tbid_knnpkq (BASE_42 + 163) +# define tbid_kbppkq (BASE_42 + 164) +# define tbid_kbnpkq (BASE_42 + 165) +# define tbid_kbbpkq (BASE_42 + 166) +# define tbid_krppkq (BASE_42 + 167) +# define tbid_krnpkq (BASE_42 + 168) +# define tbid_krbpkq (BASE_42 + 169) +# define tbid_krrpkq (BASE_42 + 170) +# define tbid_kqppkq (BASE_42 + 171) +# define tbid_kqnpkq (BASE_42 + 172) +# define tbid_kqbpkq (BASE_42 + 173) +# define tbid_kqrpkq (BASE_42 + 174) +# define tbid_kqqpkq (BASE_42 + 175) + +# define C42 175 +# else +# define C42 64 +# endif +#endif + +#if defined (T42_INCLUDE) +# define cTb (BASE_42 + C42 + 1) +#else +# define cTb (BASE_42 + 1) +#endif + +// Compression + +#include "tbdecode.h" + +#if !defined (CPUS) +# define CPUS 1 +#endif + +#if defined (SMP) + static lock_t lockDecode; +#endif +extern "C" int TB_CRC_CHECK = 0; +static int cCompressed = 0; +static decode_block *rgpdbDecodeBlocks[CPUS]; + +// Information about tablebases + +#define MAX_EXTENTS 18 /* Maximum # of 2Gb file extents */ + +#if defined (T33_INCLUDE) || defined (T42_INCLUDE) +# define MAX_TOTAL_PIECES 6 /* Maximum # of pieces on the board */ +#else +# define MAX_TOTAL_PIECES 5 /* Maximum # of pieces on the board */ +#endif +#define MAX_NON_KINGS (MAX_TOTAL_PIECES - 2) + +#if !defined (TB_DIRECTORY_SIZE) +# define TB_DIRECTORY_SIZE 32 /* # of cache buckets */ +#endif + +#if !defined (PFNCALCINDEX_DECLARED) +typedef INDEX (TB_FASTCALL * PfnCalcIndex) (square *psqW, square *psqB, + square sqEnP, int fInverse); +# define PFNCALCINDEX_DECLARED +#endif + +struct CTbCache; + +typedef struct // Hungarian: tbcb + { +#if defined (SMP) + lock_t m_lock; // Lock on this cache bucket list +#endif + volatile CTbCache * volatile m_ptbcFirst; // Cached file chunks in LRU order + } + CTbCacheBucket; + +typedef struct // Hungarian: tbd + { + int m_iTbId; + unsigned int m_fSymmetric:1; + unsigned int m_f16bit:1; + unsigned int m_fSplit:1; + PfnCalcIndex m_rgpfnCalcIndex[2]; + char m_rgchName[MAX_TOTAL_PIECES+1]; + INDEX m_rgcbLength[2]; + char *m_rgpchFileName[2][MAX_EXTENTS]; +#if defined (SMP) + lock_t m_rglockFiles[2]; +#endif + FILE *m_rgfpFiles[2][MAX_EXTENTS]; + decode_info *m_rgpdiDecodeInfo[2][MAX_EXTENTS]; + CTbCacheBucket *m_prgtbcbBuckets[2]; // Cached file chunks in LRU order + BYTE *m_rgpbRead[2]; + } + CTbDesc; + +#if defined (T_INDEX64) && defined (_MSC_VER) +# define TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\ + { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##ui64, cbB##ui64 } }, +#elif defined (T_INDEX64) +# define TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\ + { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##llu, cbB##llu } }, +#else +# define TB(name, fSym, f16bit, fSplit, funW, funB, cbW, cbB)\ + { tbid_##name, fSym, f16bit, fSplit, { funW, funB }, #name, { cbW##u, cbB##u } }, +#endif + +#define P x_piecePawn +#define N x_pieceKnight +#define B x_pieceBishop +#define R x_pieceRook +#define Q x_pieceQueen + +CTbDesc rgtbdDesc[cTb] = + { + TB (kk, true, false, false, NULL, NULL, 0, 0) + + TB (kpk, false, false, false, (T21

::IndCalcW), (T21

::IndCalcB), 81664, 84012) + TB (knk, false, false, false, (T21::IndCalcW), (T21::IndCalcB), 26282, 28644) + TB (kbk, false, false, false, (T21::IndCalcW), (T21::IndCalcB), 27243, 28644) + TB (krk, false, false, false, (T21::IndCalcW), (T21::IndCalcB), 27030, 28644) + TB (kqk, false, false, false, (T21::IndCalcW), (T21::IndCalcB), 25629, 28644) + + TB (kpkp, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 3863492, 3863492) + TB (knkp, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 4931904, 4981504) + TB (knkn, true, false, false, (T22::IndCalcW), (T22::IndCalcB), 1603202, 1603202) + TB (kbkp, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 5112000, 4981504) + TB (kbkn, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 1661823, 1603202) + TB (kbkb, true, false, false, (T22::IndCalcW), (T22::IndCalcB), 1661823, 1661823) + TB (krkp, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 5072736, 4981504) + TB (krkn, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 1649196, 1603202) + TB (krkb, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 1649196, 1661823) + TB (krkr, true, false, false, (T22::IndCalcW), (T22::IndCalcB), 1649196, 1649196) + TB (kqkp, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 4810080, 4981504) + TB (kqkn, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 1563735, 1603202) + TB (kqkb, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 1563735, 1661823) + TB (kqkr, false, false, false, (T22::IndCalcW), (T22::IndCalcB), 1563735, 1649196) + TB (kqkq, true, false, false, (T22::IndCalcW), (T22::IndCalcB), 1563735, 1563735) + TB (kppk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1806671, 1912372) + TB (knpk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 4648581, 5124732) + TB (knnk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 735304, 873642) + TB (kbpk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 4817128, 5124732) + TB (kbnk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1550620, 1747284) + TB (kbbk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 789885, 873642) + TB (krpk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 4779530, 5124732) + TB (krnk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1538479, 1747284) + TB (krbk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1594560, 1747284) + TB (krrk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 777300, 873642) + TB (kqpk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 4533490, 5124732) + TB (kqnk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1459616, 1747284) + TB (kqbk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1512507, 1747284) + TB (kqrk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 1500276, 1747284) + TB (kqqk, false, false, false, (T31::IndCalcW), (T31::IndCalcB), 698739, 873642) + +#if !defined (KPPKP_16BIT) + TB (kppkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 84219361, 89391280) +#else + TB (kppkp, false, true, false, (T32::IndCalcW), (T32::IndCalcB), 84219361, 89391280) +#endif + TB (kppkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 108400260, 115899744) + TB (kppkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 108400260, 120132000) + TB (kppkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 108400260, 119209296) + TB (kppkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 108400260, 113036880) + TB (knpkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 219921779, 231758952) + TB (knpkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 278914860, 295914240) + TB (knpkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 278914860, 306720000) + TB (knpkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 278914860, 304369920) + TB (knpkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 278914860, 288610560) + TB (knnkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 137991648, 149445120) + TB (knnkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 44118240, 48096060) + TB (knnkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 44118240, 49854690) + TB (knnkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 44118240, 49475880) + TB (knnkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 44118240, 46912050) + TB (kbpkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 227896016, 231758952) + TB (kbpkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 289027680, 295914240) + TB (kbpkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 289027680, 306720000) + TB (kbpkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 289027680, 304369920) + TB (kbpkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 289027680, 288610560) + TB (kbnkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 290989584, 298890240) + TB (kbnkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 93037200, 96192120) + TB (kbnkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 93037200, 99709380) + TB (kbnkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 93037200, 98951760) + TB (kbnkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 93037200, 93824100) + TB (kbbkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 148223520, 149445120) + TB (kbbkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 47393100, 48096060) + TB (kbbkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 47393100, 49854690) + TB (kbbkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 47393100, 49475880) + TB (kbbkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 47393100, 46912050) + TB (krpkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 226121876, 231758952) + TB (krpkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 286777440, 295914240) + TB (krpkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 286777440, 306720000) + TB (krpkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 286777440, 304369920) + TB (krpkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 286777440, 288610560) + TB (krnkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 288692928, 298890240) + TB (krnkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 92308740, 96192120) + TB (krnkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 92308740, 99709380) + TB (krnkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 92308740, 98951760) + TB (krnkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 92308740, 93824100) + TB (krbkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 299203200, 298890240) + TB (krbkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 95673600, 96192120) + TB (krbkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 95673600, 99709380) + TB (krbkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 95673600, 98951760) + TB (krbkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 95673600, 93824100) + TB (krrkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 145901232, 149445120) + TB (krrkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 46658340, 48096060) + TB (krrkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 46658340, 49854690) + TB (krrkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 46658340, 49475880) + TB (krrkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 46658340, 46912050) + TB (kqpkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 214481388, 231758952) + TB (kqpkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 272015040, 295914240) + TB (kqpkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 272015040, 306720000) + TB (kqpkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 272015040, 304369920) + TB (kqpkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 272015040, 288610560) + TB (kqnkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 273904512, 298890240) + TB (kqnkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 87576960, 96192120) + TB (kqnkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 87576960, 99709380) + TB (kqnkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 87576960, 98951760) + TB (kqnkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 87576960, 93824100) + TB (kqbkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 283818240, 298890240) + TB (kqbkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90750420, 96192120) + TB (kqbkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90750420, 99709380) + TB (kqbkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90750420, 98951760) + TB (kqbkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90750420, 93824100) + TB (kqrkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 281568240, 298890240) + TB (kqrkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90038460, 96192120) + TB (kqrkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90038460, 99709380) + TB (kqrkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90038460, 98951760) + TB (kqrkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 90038460, 93824100) + TB (kqqkp, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 131170128, 149445120) + TB (kqqkn, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 41944320, 48096060) + TB (kqqkb, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 41944320, 49854690) + TB (kqqkr, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 41944320, 49475880) + TB (kqqkq, false, false, false, (T32::IndCalcW), (T32::IndCalcB), 41944320, 46912050) + +#if defined (T41_INCLUDE) + TB (kpppk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 26061704, 28388716) + TB (knppk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 102898651, 114742320) + TB (knnpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 130135501, 153741960) + TB (knnnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 13486227, 17472840) + TB (kbppk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 106602156, 114742320) + TB (kbnpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 274352939, 307483920) + TB (kbnnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 43406294, 52418520) + TB (kbbpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 139715040, 153741960) + TB (kbbnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 44983618, 52418520) + TB (kbbbk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 15010230, 17472840) + TB (krppk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 105758666, 114742320) + TB (krnpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 272153675, 307483920) + TB (krnnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 43056198, 52418520) + TB (krbpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 281991360, 307483920) + TB (krbnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 90787358, 104837040) + TB (krbbk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 46242089, 52418520) + TB (krrpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 137491197, 153741960) + TB (krrnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 44265261, 52418520) + TB (krrbk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 45873720, 52418520) + TB (krrrk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 14644690, 17472840) + TB (kqppk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 100347220, 114742320) + TB (kqnpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 258294639, 307483920) + TB (kqnnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 40873646, 52418520) + TB (kqbpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 267576632, 307483920) + TB (kqbnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 86166717, 104837040) + TB (kqbbk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 43879679, 52418520) + TB (kqrpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 265421907, 307483920) + TB (kqrnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 85470603, 104837040) + TB (kqrbk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 88557959, 104837040) + TB (kqrrk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 43157690, 52418520) + TB (kqqpk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 123688859, 153741960) + TB (kqqnk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 39840787, 52418520) + TB (kqqbk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 41270973, 52418520) + TB (kqqrk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 40916820, 52418520) + TB (kqqqk, false, false, false, (T41::IndCalcW), (T41::IndCalcB), 12479974, 17472840) +#endif + +#if defined (T33_INCLUDE) + TB (knnknn, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 1301488080, 1301488080) + TB (kbnknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2744597400, 2602976160) + TB (kbbknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 1398096450, 1301488080) + TB (kbbkbn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2796192900, 2744597400) + TB (kbbkbb, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 1398096450, 1398096450) + TB (krnknn, false, true, false, (T33::IndCalcW), (T33::IndCalcB), 2723107830, 2602976160) + TB (krnkbb, false, true, false, (T33::IndCalcW), (T33::IndCalcB), 2723107830, 2796192900) + TB (krbknn, false, true, false, (T33::IndCalcW), (T33::IndCalcB), 2822371200, 2602976160) + TB (krbkbb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2822371200, 2796192900) + TB (krrknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 1376421030, 1301488080) + TB (krrkbn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2752842060, 2744597400) + TB (krrkbb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 1376421030, 1398096450) + TB (krrkrn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2752842060, 2723107830) + TB (krrkrb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2752842060, 2822371200) + TB (krrkrr, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 1376421030, 1376421030) + TB (kqnknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2583520320, 2602976160) + TB (kqnkbb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2583520320, 2796192900) + TB (kqnkrr, false, true, false, (T33::IndCalcW), (T33::IndCalcB), 2583520320, 2752842060) + TB (kqbknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2677137390, 2602976160) + TB (kqbkbb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2677137390, 2796192900) + TB (kqbkrr, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2677137390, 2752842060) + TB (kqrknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2656134570, 2602976160) + TB (kqrkbb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2656134570, 2796192900) + TB (kqrkrr, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2656134570, 2752842060) + TB (kqqknn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 1237357440, 1301488080) + TB (kqqkbn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2474714880, 2744597400) + TB (kqqkbb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 1237357440, 1398096450) + TB (kqqkrn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2474714880, 2723107830) + TB (kqqkrb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2474714880, 2822371200) + TB (kqqkrr, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 1237357440, 1376421030) + TB (kqqkqn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2474714880, 2583520320) + TB (kqqkqb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2474714880, 2677137390) + TB (kqqkqr, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 2474714880, 2656134570) + TB (kqqkqq, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 1237357440, 1237357440) +#if defined (T_INDEX64) + TB (kbnkbn, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 5489194800, 5489194800) + TB (krnkrn, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 5446215660, 5446215660) + TB (krbkrb, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 5644742400, 5644742400) + TB (kqnkqn, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 5167040640, 5167040640) + TB (kqbkqb, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 5354274780, 5354274780) + TB (kqrkqr, true, false, false, (T33::IndCalcW), (T33::IndCalcB), 5312269140, 5312269140) + TB (krnkbn, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 5446215660, 5489194800) + TB (krbkbn, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 5644742400, 5489194800) + TB (krbkrn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5644742400, 5446215660) + TB (kqnkbn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5167040640, 5489194800) + TB (kqnkrn, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 5167040640, 5446215660) + TB (kqnkrb, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 5167040640, 5644742400) + TB (kqbkbn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5354274780, 5489194800) + TB (kqbkrn, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 5354274780, 5446215660) + TB (kqbkrb, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 5354274780, 5644742400) + TB (kqbkqn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5354274780, 5167040640) + TB (kqrkbn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5312269140, 5489194800) + TB (kqrkrn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5312269140, 5446215660) + TB (kqrkrb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5312269140, 5644742400) + TB (kqrkqn, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5312269140, 5167040640) + TB (kqrkqb, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 5312269140, 5354274780) + + TB (kppkpp, true, true, false, (T33::IndCalcW), (T33::IndCalcBF), 1917741812, 1917741812) + TB (knpkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 5088408829, 4966717366) + TB (knpknp, true, false, true, (T33::IndCalcW), (T33::IndCalcBF), 12972508017, 12972508017) + TB (knnkpp, false, true, false, (T33::IndCalcW), (T33::IndCalcB), 3242803728, 3197807670) + TB (knnknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8141507232, 8227988370) + TB (kbpkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 5272919368, 4966717366) + TB (kbpknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 13442882944, 12972508017) + TB (kbpknn, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8526316560, 8141507232) + TB (kbpkbp, true, false, true, (T33::IndCalcW), (T33::IndCalcBF), 13442882944, 13442882944) + TB (kbnkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 6838255224, 6395615340) + TB (kbnknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 17168385456, 16455976740) + TB (kbnkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 17168385456, 17052633120) + TB (kbbkpp, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 3483252720, 3197807670) + TB (kbbknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8745187680, 8227988370) + TB (kbbkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 8745187680, 8526316560) + TB (krpkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 5231873656, 4966717366) + TB (krpknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 13338233184, 12972508017) + TB (krpknn, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8459934480, 8141507232) + TB (krpkbp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 13338233184, 13442882944) + TB (krpkbn, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 16919868960, 17168385456) + TB (krpkbb, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8459934480, 8745187680) + TB (krpkrp, true, false, true, (T33::IndCalcW), (T33::IndCalcBF), 13338233184, 13338233184) + TB (krnkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 6784283808, 6395615340) + TB (krnknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 17032882752, 16455976740) + TB (krnkbp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 17032882752, 17052633120) + TB (krnkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 17032882752, 16919868906) + TB (krbkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 7031275200, 6395615340) + TB (krbknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 17652988800, 16455976740) + TB (krbkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 17652988800, 17052633120) + TB (krbkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 17652988800, 16919868906) + TB (krrkpp, false, true, false, (T33::IndCalcW), (T33::IndCalcB), 3428678952, 3197807670) + TB (krrknp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8608504032, 8227988370) + TB (krrkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 8608504032, 8526316560) + TB (krrkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 8608504032, 8459934426) + TB (kqpkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 4962533664, 4966717366) + TB (kqpknp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 12651597608, 12972508017) + TB (kqpknn, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 8024443680, 8141507232) + TB (kqpkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 12651597608, 13442882944) + TB (kqpkbn, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16048887360, 17168385456) + TB (kqpkbb, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 8024443680, 8745187680) + TB (kqpkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 12651597608, 13338233184) + TB (kqpkrn, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16048887360, 17032882752) + TB (kqpkrb, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 16048887360, 17652988800) + TB (kqpkrr, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 8024443680, 8608504032) + TB (kqpkqp, true, true, true, (T33::IndCalcW), (T33::IndCalcBF), 12651597608, 12651597608) + TB (kqnkpp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 6436756032, 6395615340) + TB (kqnknp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16160366208, 16455976740) + TB (kqnkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16160366208, 17052633120) + TB (kqnkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16160366208, 16919868906) + TB (kqnkqp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 16160366208, 16048887306) + TB (kqbkpp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 6669728640, 6395615340) + TB (kqbknp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16745276160, 16455976740) + TB (kqbkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16745276160, 17052633120) + TB (kqbkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16745276160, 16919868906) + TB (kqbkqp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 16745276160, 16048887306) + TB (kqrkpp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 6616853640, 6395615340) + TB (kqrknp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16612871664, 16455976740) + TB (kqrkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16612871664, 17052633120) + TB (kqrkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 16612871664, 16919868906) + TB (kqrkqp, false, true, true, (T33::IndCalcW), (T33::IndCalcB), 16612871664, 16048887306) + TB (kqqkpp, false, false, false, (T33::IndCalcW), (T33::IndCalcB), 3082498008, 3197807670) + TB (kqqknp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 7739363232, 8227988370) + TB (kqqkbp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 7739363232, 8526316560) + TB (kqqkrp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 7739363232, 8459934426) + TB (kqqkqp, false, false, true, (T33::IndCalcW), (T33::IndCalcB), 7739363232, 8024443626) +#endif // T_INDEX64 +#endif // T33_INCLUDE + +#if defined (T42_INCLUDE) + TB (knnnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 795687393, 945889180) + TB (kbnnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2560971346, 2837667540) + TB (kbbnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2654033462, 2837667540) + TB (kbbbkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 885603570, 945889180) + TB (krnnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2540315682, 2837667540) + TB (krbbkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2728283251, 2837667540) + TB (krrnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2611650399, 2837667540) + TB (krrbkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2706549480, 2837667540) + TB (krrrkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 864592254, 945889180) + TB (kqnnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2411545114, 2837667540) + TB (kqbbkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2588901061, 2837667540) + TB (kqrrkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2547484064, 2837667540) + TB (kqqnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2350606433, 2837667540) + TB (kqqbkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2434987407, 2837667540) + TB (kqqrkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2415271436, 2837667540) + TB (kqqqkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 736854363, 945889180) + TB (knnnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 795687393, 980475570) + TB (kbnnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2560971346, 2941426710) + TB (kbbnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2654033462, 2941426710) + TB (kbbbkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 885603570, 980475570) + TB (krnnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2540315682, 2941426710) + TB (krbbkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2728283251, 2941426710) + TB (krrnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2611650399, 2941426710) + TB (krrbkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2706549480, 2941426710) + TB (krrrkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 864592254, 980475570) + TB (kqnnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2411545114, 2941426710) + TB (kqbbkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2588901061, 2941426710) + TB (kqrrkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2547484064, 2941426710) + TB (kqqnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2350606433, 2941426710) + TB (kqqbkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2434987407, 2941426710) + TB (kqqrkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2415271436, 2941426710) + TB (kqqqkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 736854363, 980475570) + TB (knnnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 795687393, 973025640) + TB (kbnnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2560971346, 2919076920) + TB (kbbnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2654033462, 2919076920) + TB (kbbbkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 885603570, 973025640) + TB (krnnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2540315682, 2919076920) + TB (krbbkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2728283251, 2919076920) + TB (krrnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2611650399, 2919076920) + TB (krrbkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2706549480, 2919076920) + TB (krrrkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 864592254, 973025640) + TB (kqnnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2411545114, 2919076920) + TB (kqbbkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2588901061, 2919076920) + TB (kqrrkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2547484064, 2919076920) + TB (kqqnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2350606433, 2919076920) + TB (kqqbkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2434987407, 2919076920) + TB (kqqrkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2415271436, 2919076920) + TB (kqqqkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 736854363, 973025640) + TB (knnnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 795687393, 922603650) + TB (kbnnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2560971346, 2767810950) + TB (kbbnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2654033462, 2767810950) + TB (kbbbkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 885603570, 922603650) + TB (krnnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2540315682, 2767810950) + TB (krbbkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2728283251, 2767810950) + TB (krrnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2611650399, 2767810950) + TB (krrbkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2706549480, 2767810950) + TB (krrrkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 864592254, 922603650) + TB (kqnnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2411545114, 2767810950) + TB (kqbbkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2588901061, 2767810950) + TB (kqrrkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2547484064, 2767810950) + TB (kqqnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2350606433, 2767810950) + TB (kqqbkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2434987407, 2767810950) + TB (kqqrkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2415271436, 2767810950) + TB (kqqqkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 736854363, 922603650) +#if defined (T_INDEX64) + TB (krbnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5356454122, 5675335080) + TB (kqbnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5083836303, 5675335080) + TB (kqrnkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5042765577, 5675335080) + TB (kqrbkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5224919581, 5675335080) + TB (krbnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5356454122, 5882853420) + TB (kqbnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5083836303, 5882853420) + TB (kqrnkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5042765577, 5882853420) + TB (kqrbkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5224919581, 5882853420) + TB (krbnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5356454122, 5838153840) + TB (kqbnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5083836303, 5838153840) + TB (kqrnkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5042765577, 5838153840) + TB (kqrbkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5224919581, 5838153840) + TB (krbnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5356454122, 5535621900) + TB (kqbnkq, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 5083836303, 5535621900) + TB (kqrnkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5042765577, 5535621900) + TB (kqrbkq, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 5224919581, 5535621900) + + TB (kpppkp, false, true, false, (T42::IndCalcW), (T42::IndCalcB), 1196695343, 1348100424) + TB (knppkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 4796630713, 5271860528) + TB (knnpkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6156616111, 6835422612) + TB (knnnkp, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2531022144, 2939087360) + TB (kbppkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 4969303175, 5271860528) + TB (kbnpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 12979462304, 13670845224) + TB (kbnnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8146120416, 8817262080) + TB (kbbpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 6609838740, 6835422612) + TB (kbbnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8441899104, 8817262080) + TB (kbbbkp, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2816801280, 2939087360) + TB (krppkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 4929998839, 5271860528) + TB (krnpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 12875424829, 13670845224) + TB (krnnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8079921360, 8817262080) + TB (krbpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 13340861520, 13670845224) + TB (krbnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 17036639904, 17634524160) + TB (krbbkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8677177872, 8817262080) + TB (krrpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 6504899238, 6835422612) + TB (krrnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8306047872, 8817262080) + TB (krrbkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8607504960, 8817262080) + TB (krrrkp, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2749283520, 2939087360) + TB (kqppkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 4677701571, 5271860528) + TB (kqnpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 12219736849, 13670845224) + TB (kqnnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7670559696, 8817262080) + TB (kqbpkp, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 12658882024, 13670845224) + TB (kqbnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16170070752, 17634524160) + TB (kqbbkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8234170512, 8817262080) + TB (kqrpkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 12557225406, 13670845224) + TB (kqrnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16038464256, 17634524160) + TB (kqrbkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16617170832, 17634524160) + TB (kqrrkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8101097520, 8817262080) + TB (kqqpkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 5851888362, 6835422612) + TB (kqqnkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7476276864, 8817262080) + TB (kqqbkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7744392000, 8817262080) + TB (kqqrkp, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7680886080, 8817262080) + TB (kqqqkp, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 2343300048, 2939087360) + TB (kpppkn, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 1537640536, 1777129408) + TB (knppkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6071020409, 6838084896) + TB (knnpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7677994559, 8729470080) + TB (kbppkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6289527204, 6838084896) + TB (kbnpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16186823401, 17458940160) + TB (kbbpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8243187360, 8729470080) + TB (krppkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6239761412, 6838084896) + TB (krnpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16057066825, 17458940160) + TB (krbpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16637490240, 17458940160) + TB (krrpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8112305064, 8729470080) + TB (kqppkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 5920486098, 6838084896) + TB (kqnpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15239383701, 17458940160) + TB (kqbpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15787021288, 17458940160) + TB (kqrpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15660230819, 17458940160) + TB (kqqpkn, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7297961576, 8729470080) + TB (kpppkb, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 1537640536, 1842024000) + TB (knppkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6071020409, 7087788000) + TB (knnpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7677994559, 9048240000) + TB (kbppkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6289527204, 7087788000) + TB (kbnpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16186823401, 18096480000) + TB (kbbpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8243187360, 9048240000) + TB (krppkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6239761412, 7087788000) + TB (krnpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16057066825, 18096480000) + TB (krbpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16637490240, 18096480000) + TB (krrpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8112305064, 9048240000) + TB (kqppkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 5920486098, 7087788000) + TB (kqnpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15239383701, 18096480000) + TB (kqbpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15787021288, 18096480000) + TB (kqrpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15660230819, 18096480000) + TB (kqqpkb, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7297961576, 9048240000) + TB (kpppkr, false, false, false, (T42::IndCalcW), (T42::IndCalcB), 1537640536, 1827875872) + TB (knppkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6071020409, 7033481568) + TB (knnpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7677994559, 8978912640) + TB (kbppkr, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 6289527204, 7033481568) + TB (kbnpkr, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 16186823401, 17957825280) + TB (kbbpkr, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 8243187360, 8978912640) + TB (krppkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 6239761412, 7033481568) + TB (krnpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16057066825, 17957825280) + TB (krbpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 16637490240, 17957825280) + TB (krrpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 8112305064, 8978912640) + TB (kqppkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 5920486098, 7033481568) + TB (kqnpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15239383701, 17957825280) + TB (kqbpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15787021288, 17957825280) + TB (kqrpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 15660230819, 17957825280) + TB (kqqpkr, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7297961576, 8978912640) + TB (kpppkq, false, true, false, (T42::IndCalcW), (T42::IndCalcB), 1537640536, 1733232160) + TB (knppkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 6071020409, 6669309024) + TB (knnpkq, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7677994559, 8514011520) + TB (kbppkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 6289527204, 6669309024) + TB (kbnpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 16186823401, 17028023040) + TB (kbbpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 8243187360, 8514011520) + TB (krppkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 6239761412, 6669309024) + TB (krnpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 16057066825, 17028023040) + TB (krbpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 16637490240, 17028023040) + TB (krrpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 8112305064, 8514011520) + TB (kqppkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 5920486098, 6669309024) + TB (kqnpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 15239383701, 17028023040) + TB (kqbpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 15787021288, 17028023040) + TB (kqrpkq, false, true, true, (T42::IndCalcW), (T42::IndCalcB), 15660230819, 17028023040) + TB (kqqpkq, false, false, true, (T42::IndCalcW), (T42::IndCalcB), 7297961576, 8514011520) + +#endif +#endif + }; + +#undef P +#undef N +#undef B +#undef R +#undef Q + +// Helper structure +// Used to classify on-board position + +union CUTbReference // Hungarian: utbr + { + int m_iDesc; // Negative if have to inverse + int m_cPieces; + CUTbReference *m_utbReference; + }; + +// Root of the search tree + +static CUTbReference rgutbReference [MAX_NON_KINGS + 2]; + +// Convert TB name (e.g. KQKR) into set of counters + +static const char *PchSetHalfCounters + ( + int *piCounters, + const char *pch + ) + { + memset (piCounters, 0, 5 * sizeof (int)); + while ('\0' != *pch && 'k' != *pch) + { + piece pi; + + pi = x_piecePawn; // To make compiler happy + switch (*pch) + { + case 'p': + pi = x_piecePawn; + break; + case 'n': + pi = x_pieceKnight; + break; + case 'b': + pi = x_pieceBishop; + break; + case 'r': + pi = x_pieceRook; + break; + case 'q': + pi = x_pieceQueen; + break; + default: + assert (0); + } + piCounters [pi-1] ++; + pch ++; + } + return pch; + }; + +static void VSetCounters + ( + int *piCounters, + const char *pch + ) + { + assert ('k' == *pch); + pch = PchSetHalfCounters (piCounters, pch+1); + assert ('k' == *pch); + pch = PchSetHalfCounters (piCounters+5, pch+1); + assert ('\0' == *pch); + } + +// Following functions return TB index +// They differ by input arguments + +extern "C" int IDescFindFromCounters + ( + int *piCount + ) + { + CUTbReference *putbr = rgutbReference; + + if (piCount[0] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[0]].m_utbReference; + if (piCount[1] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[1]].m_utbReference; + if (piCount[2] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[2]].m_utbReference; + if (piCount[3] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[3]].m_utbReference; + if (piCount[4] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[4]].m_utbReference; + if (piCount[5] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[5]].m_utbReference; + if (piCount[6] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[6]].m_utbReference; + if (piCount[7] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[7]].m_utbReference; + if (piCount[8] > putbr->m_cPieces) + goto not_found; + putbr = putbr[1 + piCount[8]].m_utbReference; + if (piCount[9] <= putbr->m_cPieces) + return putbr[1 + piCount[9]].m_iDesc; +not_found: + return 0; + } + +int IDescFind + ( + square *p_piW, // IN | Pointer to array of white pieces (king excluded) + square *p_piB, // IN | Pointer to array of black pieces (king excluded) + int cWhite, // IN | Counter of white pieces (king excluded) + int cBlack // IN | Counter of black pieces (king excluded) + ) + { + int rgiCount[10]; + + // Set pieces counters + rgiCount[0] = + rgiCount[1] = + rgiCount[2] = + rgiCount[3] = + rgiCount[4] = + rgiCount[5] = + rgiCount[6] = + rgiCount[7] = + rgiCount[8] = + rgiCount[9] = 0; + while (cWhite) + { + rgiCount[(*p_piW)-1] ++; + p_piW ++; + cWhite --; + } + while (cBlack) + { + rgiCount[5-1+(*p_piB)] ++; + p_piB ++; + cBlack --; + } + return IDescFindFromCounters (rgiCount); + } + +int IDescFindByName + ( + char *pchName + ) + { + int rgiCount[10]; + + VSetCounters (rgiCount, pchName); + return IDescFindFromCounters (rgiCount); + } + +//----------------------------------------------------------------------------- +// +// Function used during initialization + +// Set of functions to create search table + +static CUTbReference *PutbrCreateSubtable + ( + int cPieces, // IN | # of pieces ramaining on board + int iDepth // IN | Recursion depth (# of piece classes left) + ) + { + CUTbReference *putbr; + + putbr = (CUTbReference *) PvMalloc ((cPieces + 2) * sizeof (CUTbReference)); + putbr[0].m_cPieces = cPieces; + if (0 == iDepth) + { + for (int i = 0; i <= cPieces; i ++) + putbr[i+1].m_iDesc = 0; + } + else + { + for (int i = 0; i <= cPieces; i ++) + putbr[i+1].m_utbReference = PutbrCreateSubtable (cPieces-i, iDepth-1); + } + return putbr; + } + +static bool fTbTableCreated = false; + +static void VCreateEmptyTbTable (void) + { + if (fTbTableCreated) + return; + fTbTableCreated = true; + rgutbReference[0].m_cPieces = MAX_NON_KINGS; + for (int i = 0; i <= MAX_NON_KINGS; i ++) + rgutbReference[i+1].m_utbReference = PutbrCreateSubtable (MAX_NON_KINGS - i, 8); + } + +// Insert TB (e.g. KQKR) into search table + +static bool FRegisterHalf + ( + int iTb, + int *piCount + ) + { + CUTbReference *putbr; + + putbr = rgutbReference; + for (int i = 0; i < 9; i ++) + { + if (piCount[i] > putbr->m_cPieces) + return false; + putbr = putbr[1 + piCount[i]].m_utbReference; + } + if (piCount[9] > putbr->m_cPieces) + return false; + putbr[1 + piCount[9]].m_iDesc = iTb; + return true; + } + +// Insert TB (both, e.g. KQKR and KRKQ) into search table + +static bool FRegisterTb + ( + CTbDesc *ptbDesc + ) + { + int rgiCount[10]; + bool fInserted; + + VSetCounters (rgiCount, ptbDesc->m_rgchName); + fInserted = FRegisterHalf (ptbDesc->m_iTbId, rgiCount); + if (fInserted) + { + if (ptbDesc->m_fSymmetric) + return true; + for (int i = 0; i < 5; i ++) + { + int iTemp; + + iTemp = rgiCount[i]; + rgiCount[i] = rgiCount[i+5]; + rgiCount[i+5] = iTemp; + } + fInserted = FRegisterHalf (-ptbDesc->m_iTbId, rgiCount); + assert (fInserted); + } + return fInserted; + } + +// File mapping - Win32 code only + +#if defined (_WIN32) || defined(_WIN64) + +static BYTE * PbMapFileForRead + ( + char *szName, + HANDLE *phFile, + HANDLE *phFileMapping + ) + { + HANDLE hFile; + HANDLE hFileMapping; + LPVOID lpFileBase; + + hFile = CreateFileA(szName, GENERIC_READ, FILE_SHARE_READ, + NULL, OPEN_EXISTING, + FILE_ATTRIBUTE_NORMAL | FILE_FLAG_RANDOM_ACCESS, NULL); + if (INVALID_HANDLE_VALUE == hFile) + { + printf("*** Couldn't open file %s with CreateFile()\n", szName); + exit (1); + } + hFileMapping = CreateFileMapping (hFile, NULL, PAGE_READONLY, 0, 0, NULL); + if (0 == hFileMapping) + { + CloseHandle (hFile); + printf ("*** Couldn't open file %s mapping with CreateFileMapping()\n", szName); + exit (1); + } + lpFileBase = MapViewOfFile (hFileMapping, FILE_MAP_READ, 0, 0, 0); + if (0 == lpFileBase) + { + CloseHandle (hFileMapping); + CloseHandle (hFile); + printf ("*** Couldn't map view of file %s with MapViewOfFile()\n", szName); + exit (1); + } + if (NULL != phFile) + *phFile = hFile; + if (NULL != phFileMapping) + *phFileMapping = hFileMapping; + return (BYTE*) lpFileBase; + } + +static void VUnmapFile + ( + BYTE *pbFileBase, + HANDLE hFile, + HANDLE hFileMapping + ) + { + BOOL fFailed; + + fFailed = (0 == UnmapViewOfFile (pbFileBase)) | + (0 == CloseHandle (hFileMapping)) | + (0 == CloseHandle (hFile)); + if (fFailed) + { + printf ("*** Couldn't unmap file\n"); + exit (1); + } + } + +#endif + +//----------------------------------------------------------------------------- +// +// TB caching + +#if !defined (TB_CB_CACHE_CHUNK) +#define TB_CB_CACHE_CHUNK 8192 /* Must be power of 2 */ +#define LOG2_TB_CB_CACHE_CHUNK 13 +#endif + +#define TB_CHUNK(index) ((index) >> LOG2_TB_CB_CACHE_CHUNK) +#define TB_OFFSET(index) ((index) % TB_CB_CACHE_CHUNK) +#define TB_DIRECTORY_ENTRY(chunk) ((chunk) % TB_DIRECTORY_SIZE) + +#define WIDE_TB_CHUNK(index) ((index) >> (LOG2_TB_CB_CACHE_CHUNK-1)) +#define WIDE_TB_OFFSET(index) ((index) % (TB_CB_CACHE_CHUNK/2))*2 + +struct CTbCache //Hungarian: tbc + { + int volatile m_iTb; + color volatile m_color; + unsigned volatile m_indChunk; + volatile CTbCache *volatile m_ptbcNext; // Next element in double-linked general LRU list + volatile CTbCache *volatile m_ptbcPrev; // Previous element in double-linked general LRU list + volatile CTbCache *volatile m_ptbcTbNext; // Next element in double-linked cache bucket LRU list + volatile CTbCache *volatile m_ptbcTbPrev; // Previous element in double-linked cache bucket LRU list + BYTE *m_pbData; + }; + +static CTbCache *ptbcTbCache; // Cache memory +static ULONG ctbcTbCache; // Cache size (in entries) + +static volatile CTbCache * volatile ptbcHead; // Head of that list +static volatile CTbCache * volatile ptbcTail; // Last element in that list +static volatile CTbCache * volatile ptbcFree; // First free cache header + +static INLINE void VTbCloseFile + ( + int iTb, + color side + ) + { + for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) { + if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent]) + { + Lock (rgtbdDesc[iTb].m_rglockFiles[side]); + if (NULL != rgtbdDesc[iTb].m_rgfpFiles[side][iExtent]) + { + fclose (rgtbdDesc[iTb].m_rgfpFiles[side][iExtent]); + rgtbdDesc[iTb].m_rgfpFiles[side][iExtent] = NULL; + } + Unlock (rgtbdDesc[iTb].m_rglockFiles[side]); + } + } + } + +extern "C" void VTbCloseFiles (void) + { + // Initialized? + if (0 == ctbcTbCache) + return; + + // Walk through TB cache and close all opened files + for (int iTb = 1; iTb < cTb; iTb ++) + { + VTbCloseFile (iTb, x_colorWhite); + VTbCloseFile (iTb, x_colorBlack); + } + } + +void VTbClearCache (void) + { + CTbCacheBucket *prgtbcbBuckets; + CTbCache *ptbc; + BYTE *pb; + ULONG i; + + // Initialized? + if (0 == ctbcTbCache) + return; + VTbCloseFiles(); + + // Initialize all lists + pb = (BYTE *) & ptbcTbCache [ctbcTbCache]; + for (i = 0, ptbc = ptbcTbCache; i < ctbcTbCache; i ++, ptbc ++) + { + ptbc->m_pbData = pb + i*(TB_CB_CACHE_CHUNK+32+4); + ptbc->m_ptbcTbPrev = + ptbc->m_ptbcTbNext = + ptbc->m_ptbcPrev = NULL; + ptbc->m_ptbcNext = (ptbc + 1); + } + ptbc[-1].m_ptbcNext = NULL; + + // Clear references from TBs + for (int iTb = 1; iTb < cTb; iTb ++) + { + for (color sd=x_colorWhite; sd <= x_colorBlack; sd ++) + { + prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd]; + if (NULL != prgtbcbBuckets) + { +#if defined (SMP) + for (i = 0; i < TB_DIRECTORY_SIZE; i ++) + LockFree (prgtbcbBuckets[i].m_lock); +#endif + memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE * sizeof (CTbCacheBucket)); +#if defined (SMP) + for (i = 0; i < TB_DIRECTORY_SIZE; i ++) + LockInit (prgtbcbBuckets[i].m_lock); +#endif + } + } + } + + // Set globals + ptbcHead = ptbcTail = NULL; + ptbcFree = ptbcTbCache; + } + +extern "C" int FTbSetCacheSize + ( + void *pv, + ULONG cbSize + ) + { + VTbCloseFiles(); + ctbcTbCache = 0; + ptbcHead = NULL; + if (cbSize < sizeof (CTbCache)) + return false; + ptbcTbCache = (CTbCache*) pv; + ctbcTbCache = cbSize / (sizeof (CTbCache) + TB_CB_CACHE_CHUNK+32+4); + VTbClearCache(); + return true; + } + +// Table registered + +INLINE int FRegisteredExtent + ( + int iTb, + color side, + int iExtent + ) + { + if (rgtbdDesc[iTb].m_fSymmetric) + side = x_colorWhite; + return (NULL != rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]); + } + +INLINE int FRegistered + ( + int iTb, + color side + ) + { + int iExtent, cExtents; + INDEX cBytes; + + if (rgtbdDesc[iTb].m_fSplit) + { + cBytes = rgtbdDesc[iTb].m_rgcbLength[side]; + if (rgtbdDesc[iTb].m_f16bit) + cBytes *= 2; + cExtents = (int) (cBytes >> 31) + 1; + } + else + cExtents = 1; + for (iExtent = 0; iExtent < cExtents; iExtent ++) + { + if (FRegisteredExtent (iTb, side, iExtent)) + return true; + } + return false; + } + +extern "C" int FRegisteredFun + ( + int iTb, + color side + ) + { + return FRegistered (iTb, side); + } + +// Return function that calculates the necessary index: + +#define PfnIndCalc(iTb, side) (rgtbdDesc[iTb].m_rgpfnCalcIndex[side]) +extern "C" PfnCalcIndex PfnIndCalcFun + ( + int iTb, + color side + ) + { + return PfnIndCalc (iTb, side); + } + +// Read whole file into memory + +extern "C" int FReadTableToMemory + ( + int iTb, // IN | Tablebase + color side, // IN | Side to move + BYTE *pb // IN | Either buffer or NULL + ) + { + char *pszName; + INDEX cb; + FILE *fp; + + if (rgtbdDesc[iTb].m_fSymmetric) + side = x_colorWhite; + if (!FRegistered (iTb, side)) + return false; + if (rgtbdDesc[iTb].m_fSplit) + return false; + for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) + { + if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent]) + return false; + } + if (NULL != rgtbdDesc[iTb].m_rgpbRead[side]) + return true; + pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0]; + fp = fopen (pszName, "rb"); + if (NULL == fp) + return false; + + // Find database size +#if defined (NEW) + cb = rgtbdDesc[iTb].m_rgcbLength[side]; + if (0 == cb) + { +#endif + if (0 != fseek (fp, 0L, SEEK_END)) + { + printf ("*** Seek in %s failed\n", pszName); + exit (1); + } + cb = ftell (fp); + if (-1 == (int) cb) + { + printf ("*** Cannot find length of %s\n", pszName); + exit (1); + } + if (0 != fseek (fp, 0L, SEEK_SET)) + { + printf ("*** Seek in %s failed\n", pszName); + exit (1); + } +#if defined (NEW) + } +#if defined (T33_INCLUDE) || defined (KPPKP_16BIT) + else if (rgtbdDesc[iTb].m_f16bit) + { + if ((size_t) cb != cb) // Overflow + { + printf ("*** %s too big to read into memory\n", pszName); + exit (1); + } + } +#endif +#endif + + // If buffer not specified, allocate memory for it + if (NULL == pb) + pb = (BYTE*) PvMalloc (cb); + + // Read file into memory + if (cb != (INDEX) fread (pb, 1, cb, fp)) + { + printf ("*** Read from %s failed\n", pszName); + exit (1); + } + fclose (fp); + + // All done + rgtbdDesc[iTb].m_rgpbRead[side] = pb; + return true; + } + +#if defined (_WIN32) || defined(_WIN64) + +// Map whole file into memory + +extern "C" int FMapTableToMemory + ( + int iTb, // IN | Tablebase + color side // IN | Side to move + ) + { + char *pszName; + + if (rgtbdDesc[iTb].m_fSymmetric) + side = x_colorWhite; + if (!FRegistered (iTb, side)) + return false; + if (rgtbdDesc[iTb].m_fSplit) + return false; + for (int iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) + { + if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent]) + return false; + } + pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0]; + if (NULL == rgtbdDesc[iTb].m_rgpbRead[side]) + { + rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, NULL, NULL); + if (fVerbose) + printf ("%s mapped\n", pszName); + } + return true; + } + +// Map whole file into memory + +int FMapTableToMemory + ( + int iTb, // IN | Tablebase + color side, // IN | Side to move + HANDLE *phFile, // OUT | File handle will be written here + HANDLE *phFileMapping // OUT | File mapping handle will be written here + ) + { + char *pszName; + + if (rgtbdDesc[iTb].m_fSymmetric) + side = x_colorWhite; + if (!FRegistered (iTb, side)) + return false; + if (rgtbdDesc[iTb].m_fSplit) + return false; + pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0]; + if (NULL == rgtbdDesc[iTb].m_rgpbRead[side]) + { + rgtbdDesc[iTb].m_rgpbRead[side] = PbMapFileForRead (pszName, phFile, phFileMapping); + if (fVerbose) + printf ("%s mapped\n", pszName); + } + return true; + } + +// Unmap whole file from memory + +int FUnMapTableFromMemory + ( + int iTb, // IN | Tablebase + color side, // IN | Side to move + HANDLE hFile, // IN | File handle will be written here + HANDLE hFileMapping // IN | File mapping handle will be written here + ) + { + char *pszName; + + if (rgtbdDesc[iTb].m_fSymmetric) + side = x_colorWhite; + if (!FRegistered (iTb, side)) + return false; + if (rgtbdDesc[iTb].m_fSplit) + return false; + pszName = rgtbdDesc[iTb].m_rgpchFileName[side][0]; + if (NULL != rgtbdDesc[iTb].m_rgpbRead[side]) + { + VUnmapFile (rgtbdDesc[iTb].m_rgpbRead[side], hFile, hFileMapping); + rgtbdDesc[iTb].m_rgpbRead[side] = NULL; + if (fVerbose) + printf ("%s unmapped\n", pszName); + } + return true; + } + +#endif + +// Probe TB - lower level (not exportable) function + +static int TB_FASTCALL TbtProbeTable + ( + int iTb, + color side, + unsigned indChunk, + unsigned indInChunk + ) + { + CTbDesc *ptbd; + int iDirectory, iExtent, iPhysicalChunk; + volatile CTbCache * ptbc; + volatile CTbCache * ptbcTbFirst; + const char *pszFileName; + + ptbd = & rgtbdDesc[iTb]; + iDirectory = TB_DIRECTORY_ENTRY (indChunk); + + // Head of the cache bucket LRU list + Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock); + ptbcTbFirst = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst; + + // First, search entry in the cache + for (ptbc = ptbcTbFirst; NULL != ptbc; ptbc = ptbc->m_ptbcTbNext) + { + if (indChunk == ptbc->m_indChunk) + { + // Found - move cache entry to the head of the general LRU list + Lock (lockLRU); + if (ptbc != ptbcHead) + { + // Remove it from its current position + ptbc->m_ptbcPrev->m_ptbcNext = ptbc->m_ptbcNext; + if (NULL == ptbc->m_ptbcNext) + ptbcTail = ptbc->m_ptbcPrev; + else + ptbc->m_ptbcNext->m_ptbcPrev = ptbc->m_ptbcPrev; + // Insert it at the head + ptbc->m_ptbcPrev = NULL; + ptbc->m_ptbcNext = ptbcHead; + ptbcHead->m_ptbcPrev = ptbc; + ptbcHead = ptbc; + } + Unlock (lockLRU); + // Move cache entry to the head of the cache bucket LRU list + if (ptbc != ptbcTbFirst) + { + // Remove it from list + ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext; + if (NULL != ptbc->m_ptbcTbNext) + ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev; + // Insert it at head + ptbc->m_ptbcTbPrev = NULL; + ptbc->m_ptbcTbNext = ptbcTbFirst; + ptbcTbFirst->m_ptbcTbPrev = ptbc; + ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc; + } + int tb; + + tb = (tb_t) (ptbc->m_pbData[(ULONG)indInChunk]); + Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock); + return tb; + } + } + // Not in the cache - have to read it from disk. + // I decided to write simple code - so sometimes it's possible that + // 2 threads will simultaneously read exactly the same chunk into 2 + // different cache entries. In that case, all subsequent cache probes + // will hit the first cache entry, so the second one will 'drift' to + // the end of general LRU list and will be reused. + + // Unlock cache bucket, so other threads can continue execution + Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock); + // First, find cache entry we can use + Lock (lockLRU); + // Get it either from a free list, or reuse last element of the LRU list + if (NULL != ptbcFree) + { + ptbc = ptbcFree; + ptbcFree = ptbc->m_ptbcNext; + Unlock (lockLRU); + } + else + { + unsigned iTailDirectory; + int iTailTb; + color colorTail; + + assert (NULL != ptbcTail); +#if defined (SMP) + // "Optimistic" model - assuming that there is low content + // (not hundreds of threads) + for (;;) + { + ptbc = ptbcTail; + iTailTb = ptbc->m_iTb; + iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk); + colorTail = ptbc->m_color; + // To avoid deadlocks, have to first acquire cache buckets lock, + // and only then general LRU lock. So, free general LRU lock and + // acquire 2 locks in a proper order. + Unlock (lockLRU); + Lock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock); + Lock (lockLRU); + // Have structures been modified while we re-acquired locks? + // (to be more precise, it's Ok, if structures were modified, + // but cache entry again become the last element of the list, + // and TB, color, and cache bucket did not changed, so we locked + // proper locks). + if (ptbc == ptbcTail && ptbc->m_iTb == iTailTb && + ptbc->m_color == colorTail && + TB_DIRECTORY_ENTRY (ptbc->m_indChunk) == iTailDirectory) + break; + // Sorry - try once again... + Unlock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock); + } +#else + ptbc = ptbcTail; + iTailTb = ptbc->m_iTb; + iTailDirectory = TB_DIRECTORY_ENTRY (ptbc->m_indChunk); + colorTail = ptbc->m_color; +#endif + + // Remove cache entry from the general LRU list + ptbcTail = ptbc->m_ptbcPrev; + if (NULL == ptbcTail) + ptbcHead = NULL; + else + ptbcTail->m_ptbcNext = NULL; + Unlock (lockLRU); + + // Remove it from cache bucket list + if (NULL != ptbc->m_ptbcTbNext) + ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc->m_ptbcTbPrev; + if (NULL == ptbc->m_ptbcTbPrev) + rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_ptbcFirst = ptbc->m_ptbcTbNext; + else + ptbc->m_ptbcTbPrev->m_ptbcTbNext = ptbc->m_ptbcTbNext; + Unlock (rgtbdDesc[iTailTb].m_prgtbcbBuckets[colorTail][iTailDirectory].m_lock); + } + + // Ok, now we have "orphan" cache entry - it's excluded from all lists, + // so other threads will never touch it. + ptbc->m_iTb = iTb; + ptbc->m_color = side; + ptbc->m_indChunk = indChunk; + + // Now read it from the disk + FILE *fp; + size_t cb; + + // First, check: is necessary file opened? + // As files are not thread-safe, lock file + Lock (ptbd->m_rglockFiles[side]); + if (ptbd->m_fSplit) + { + iExtent = indChunk >> (31 - LOG2_TB_CB_CACHE_CHUNK); + iPhysicalChunk = indChunk - (iExtent << (31 - LOG2_TB_CB_CACHE_CHUNK)); + } + else + { + iExtent = 0; + iPhysicalChunk = indChunk; + } + fp = ptbd->m_rgfpFiles[side][iExtent]; + if (NULL == fp) + { + // Not - try to open it + pszFileName = ptbd->m_rgpchFileName[side][iExtent]; + if (NULL != pszFileName) + { + fp = fopen (pszFileName, "rb"); + if (NULL == fp) + { + // Failed. Close all the opened files and retry + Unlock (ptbd->m_rglockFiles[side]); + VTbCloseFiles (); + Lock (ptbd->m_rglockFiles[side]); + // Theoretically, it's possible that other threads opened a lot of + // files in the interval between VTbCloseFiles() and Lock(). If + // so, we'll fail - I don't like to have one more global lock + // especially for file open, at least not in first version. + // Problem can happen only on systems with small limit of + // simultaneously open files and high number of threads - unlikely + // combination. + fp = ptbd->m_rgfpFiles[side][iExtent]; + if (NULL == fp) + { + fp = fopen (pszFileName, "rb"); + if (NULL == fp) + { +#if defined (STOP_ON_ERROR) + printf ("*** Unable to open file %s\n", pszFileName); + fflush (stdout); + exit(1); +#endif + goto ERROR_LABEL; + } + } + } + ptbd->m_rgfpFiles[side][iExtent] = fp; + } + else + goto ERROR_LABEL; + } + + // File opened. Now seek and read necessary chunk + if (NULL == ptbd->m_rgpdiDecodeInfo[side][iExtent]) + { + long lPos; + int iResult; + + lPos = (long) (iPhysicalChunk*TB_CB_CACHE_CHUNK); +#if defined (T33_INCLUDE) || defined (T42_INCLUDE) + if (lPos < 0) + { + iResult = fseek (fp, 0L, SEEK_SET); + if (iResult) + { +#if defined (STOP_ON_ERROR) + printf ("*** Unable to seek file %s offset %08X\n", + pszFileName, 0); + fflush (stdout); + exit(1); +#endif + goto ERROR_LABEL; + } + do + { + iResult = fseek (fp, 0x40000000, SEEK_CUR); + if (iResult) + { +#if defined (STOP_ON_ERROR) + printf ("*** Unable to seek file %s offset %08X\n", + pszFileName, 0x40000000); + fflush (stdout); + exit(1); +#endif + goto ERROR_LABEL; + } + lPos -= 0x40000000; + } while (lPos < 0); + iResult = fseek (fp, lPos, SEEK_CUR); + } + else +#endif + iResult = fseek (fp, lPos, SEEK_SET); + // Read uncompressed file + if (iResult) + { +#if defined (STOP_ON_ERROR) + printf ("*** Unable to seek file %s offset %08X\n", + pszFileName, lPos); + fflush (stdout); + exit(1); +#endif + goto ERROR_LABEL; + } + cb = fread (ptbc->m_pbData, 1, TB_CB_CACHE_CHUNK, fp); + if (cb != TB_CB_CACHE_CHUNK) + { + // Could not read TB_CB_CACHE_CHUNK - check for error + if (ferror (fp) || ((size_t) -1 == cb)) + { +#if defined (STOP_ON_ERROR) + printf ("*** Read error, file %s\n", pszFileName); + fflush (stdout); + exit(1); +#endif + goto ERROR_LABEL; + } + } + Unlock (ptbd->m_rglockFiles[side]); + } + else + { + // Read compressed file + int fWasError; + decode_block *block; + decode_info *info = ptbd->m_rgpdiDecodeInfo[side][iExtent]; + +#if defined (SMP) + // Find free decode block + decode_block **pBlock; + + Lock (lockDecode); + pBlock = rgpdbDecodeBlocks; + while (NULL == *pBlock) + pBlock ++; + block = *pBlock; + *pBlock = NULL; + Unlock (lockDecode); +#else + block = rgpdbDecodeBlocks[0]; +#endif + + // Initialize decode block and read chunk + fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, ptbc->m_pbData) || + 0 != comp_read_block (block, info, fp, iPhysicalChunk); + + // Release lock on file, so other threads can proceed with that file + Unlock (ptbd->m_rglockFiles[side]); + + // Decompress chunk + if (!fWasError) + fWasError |= (0 != comp_decode_and_check_crc (block, info, block->orig.size, TB_CRC_CHECK)); + + // Release block +#if defined (SMP) + Lock (lockDecode); + *pBlock = block; + Unlock (lockDecode); +#endif + + // Read Ok? + if (fWasError) + { +#if defined (STOP_ON_ERROR) + printf ("*** Decompression error, file %s\n", pszFileName); + fflush (stdout); + exit(1); +#endif + goto ERROR_LABEL_2; + } + } + + // Read - now acquire locks and insert cache entry in both lists + Lock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock); + Lock (lockLRU); + + // Insert cache entry into general LRU list + ptbc->m_ptbcPrev = NULL; + ptbc->m_ptbcNext = ptbcHead; + if (NULL == ptbcHead) + ptbcTail = ptbc; + else + ptbcHead->m_ptbcPrev = ptbc; + ptbcHead = ptbc; + + // Insert cache entry into cache bucket LRU list + ptbc->m_ptbcTbPrev = NULL; + ptbc->m_ptbcTbNext = ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst; + if (NULL != ptbc->m_ptbcTbNext) + ptbc->m_ptbcTbNext->m_ptbcTbPrev = ptbc; + ptbd->m_prgtbcbBuckets[side][iDirectory].m_ptbcFirst = ptbc; + + // All done + int tb; + + tb = (tb_t) (ptbc->m_pbData[indInChunk]); + // Release locks + Unlock (ptbd->m_prgtbcbBuckets[side][iDirectory].m_lock); + Unlock (lockLRU); + return tb; + + // I/O error. Here I don't want to halt the program, because that can + // happen in the middle of the important game. Just return failure. +ERROR_LABEL: + Unlock (ptbd->m_rglockFiles[side]); +ERROR_LABEL_2: + Lock (lockLRU); + ptbd->m_rgpchFileName[side][iExtent] = NULL; + ptbc->m_ptbcNext = ptbcFree; + ptbcFree = ptbc; + Unlock (lockLRU); + return L_bev_broken; + } + +// Probe TB - upper level function + +static int TB_FASTCALL TbtProbeTable + ( + int iTb, + color side, + INDEX indOffset + ) + { + CTbDesc *ptbd; + + assert (iTb > 0 && iTb < cTb); + ptbd = & rgtbdDesc[iTb]; + if (ptbd->m_fSymmetric) + side = x_colorWhite; + + // It's better for offset be smaller than TB size + assert (!FRegistered (iTb, side) || indOffset < ptbd->m_rgcbLength[side]); + + // Entire file read/mapped to memory? + if (NULL != ptbd->m_rgpbRead[side]) + return (tb_t) ptbd->m_rgpbRead[side][indOffset]; + + // Cache initialized? TB registered? + if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side]) + return bev_broken; + +#if defined (T33_INCLUDE) || defined (KPPKP_16BIT) + if (ptbd->m_f16bit) + return bev_broken; +#endif + + int tb; + + tb = TbtProbeTable (iTb, side,(unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset)); + return (L_bev_broken == tb) ? bev_broken : (tb_t) tb; + } + +// 16-bit version (recommended) + +#define FOutOfBound(iTb, side, indOffset)\ + (tbid_kppkp == iTb && x_colorBlack == side &&\ + (indOffset == 0x0362BC7C || indOffset == 0x0362DE44 || indOffset == 0x03637648 ||\ + indOffset == 0x03639810 || indOffset == 0x038D4F29 || indOffset == 0x040A2CAB ||\ + indOffset == 0x043C778C)) + +extern "C" int TB_FASTCALL L_TbtProbeTable + ( + int iTb, + color side, + INDEX indOffset + ) + { + int tbtScore; + CTbDesc *ptbd; + + assert (iTb > 0 && iTb < cTb); + ptbd = & rgtbdDesc[iTb]; + if (ptbd->m_fSymmetric) + side = x_colorWhite; + + // Entire file read/mapped to memory? + if (NULL != ptbd->m_rgpbRead[side]) + { +#if defined (KPPKP_16BIT) + if (!ptbd->m_f16bit) + { + tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset]; + return S_to_L (tbtScore); + } + else + return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) << 8) + + ptbd->m_rgpbRead[side][indOffset*2]; +#elif defined (T33_INCLUDE) + if (!ptbd->m_f16bit) + { + if (FOutOfBound (iTb, side, indOffset)) + return -32639; + else + { + tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset]; + return S_to_L (tbtScore); + } + } + else + return (((int) (((signed char) ptbd->m_rgpbRead[side][indOffset*2+1]))) << 8) + + ptbd->m_rgpbRead[side][indOffset*2]; +#else + if (FOutOfBound (iTb, side, indOffset)) + return -32639; + else + { + tbtScore = (tb_t) ptbd->m_rgpbRead[side][indOffset]; + return S_to_L (tbtScore); + } +#endif + } + + // Cache initialized? TB registered? + if (0 == ctbcTbCache || NULL == ptbd->m_prgtbcbBuckets[side]) + return L_bev_broken; + +#if defined (T33_INCLUDE) || defined (T42_INCLUDE) + if (ptbd->m_f16bit) + { + // Inefficient, but very simple, code + int iLo; + int iHi; + + iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)); + iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)+1); + tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken : ((iHi << 8) + (iLo & 0xFF)); + } + else + { +#if !defined (KPPKP_16BIT) + if (FOutOfBound (iTb, side, indOffset)) + return -32639; +#endif + tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset)); + tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore); + } +#elif !defined (KPPKP_16BIT) + if (FOutOfBound (iTb, side, indOffset)) + return -32639; + tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset)); + tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore); +#else + if (tbid_kppkp != iTb) + { + // All tables but kppkp are 8-bit tables + tbtScore = TbtProbeTable (iTb, side, (unsigned) TB_CHUNK (indOffset), (unsigned) TB_OFFSET (indOffset)); + tbtScore = L_bev_broken == tbtScore ? L_bev_broken : S_to_L (tbtScore); + } + else + { + // Special handling of kppkp - it's 16-bit table + // Inefficient, but very simple, code + int iLo; + int iHi; + + iLo = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)); + iHi = TbtProbeTable (iTb, side, (unsigned) WIDE_TB_CHUNK (indOffset), (unsigned) WIDE_TB_OFFSET (indOffset)+1); + tbtScore = (L_bev_broken == iLo || L_bev_broken == iHi) ? L_bev_broken : ((iHi << 8) + (iLo & 0xFF)); + } +#endif + return tbtScore; + } + +//----------------------------------------------------------------------------- +// +// Global initialization + +// TODO: Check size of split tables, too + +static void VCheckSize + ( + int iTb, + color side, + int iExtent, + INDEX cb, + char *rgchTbName + ) + { +#if defined (NEW) + INDEX cbOk1, cbOk2; + + if (0 == rgtbdDesc[iTb].m_rgcbLength[side]) + return; + + cbOk1 = rgtbdDesc[iTb].m_rgcbLength[side]; + cbOk2 = cbOk1; +#if defined (T_INDEX64) + if (rgtbdDesc[iTb].m_fSplit) + { + cbOk1 = (1u << (rgtbdDesc[iTb].m_f16bit ? 30 : 31)); + cbOk2 = cbOk2 % (1u << (rgtbdDesc[iTb].m_f16bit ? 30 : 31)); + } +#endif + + if (cb != cbOk1 && cb != cbOk2) + { + printf ("*** %s corrupted " + DEC_INDEX_FORMAT" "DEC_INDEX_FORMAT" "DEC_INDEX_FORMAT"\n", + rgchTbName, cbOk1, cbOk2, cb); + exit (1); + } +#endif + } + + +#if defined (_WIN32) || defined (_WIN64) +int iDrivesMap; +BOOL rgfAccessed[26]; +BOOL rgfNotReady[26]; +#endif + +static int FCheckExtentExistance + ( + char *pszPath, + int iTb, + color side, + int iExtent + ) + { + FILE *fp; + char *pchCopy; + const char *pchExt = PchExt (side); + char rgchTbName[1024]; + char rgchExtent[4]; + CTbCacheBucket *prgtbcbBuckets; + INDEX cb; + decode_info *comp_info = NULL; + int fWasError; + decode_block *block; + BYTE rgbBuffer[TB_CB_CACHE_CHUNK+32+4]; + + if (FRegisteredExtent (iTb, side, iExtent) || NULL != rgtbdDesc[iTb].m_rgpbRead[side]) + return true; + +#if defined (_WIN32) || defined (_WIN64) + // Do not repeatedely probe device that is not ready + // (i.e. unmapped disk or CD-ROM that does not contain the disk). + if (NULL != pszPath && 0 != pszPath[0] && ':' == pszPath[1]) + { + int iDrive; + char szRoot[5]; + WIN32_FIND_DATAA fd; + HANDLE hResult; + + iDrive = tolower(pszPath[0]) - 'a'; + if (iDrive >= 0 && iDrive < 26) + { + if (rgfNotReady[iDrive]) + return false; + if (!rgfAccessed[iDrive]) + { + if (iDrivesMap && 0 == (iDrivesMap & (1 << iDrive))) + return false; + szRoot[0] = pszPath[0]; + szRoot[1] = pszPath[1]; + szRoot[2] = '\\'; + szRoot[3] = '*'; + szRoot[4] = 0; + hResult = FindFirstFileA (szRoot, &fd); + if (INVALID_HANDLE_VALUE == hResult) + { + if (ERROR_NOT_READY == GetLastError()) + { + rgfNotReady[iDrive] = true; + return false; + } + } + else + FindClose (hResult); + rgfAccessed[iDrive] = true; + } + } + } +#endif + + strcpy (rgchTbName, pszPath); + if (0 != pszPath[0] && DELIMITER[0] != pszPath[strlen(pszPath)-1]) + strcat (rgchTbName, DELIMITER); + strcat (rgchTbName, rgtbdDesc[iTb].m_rgchName); + if (rgtbdDesc[iTb].m_fSplit) + { + rgchExtent[0] = '.'; + if (iExtent >= 10) + rgchExtent[1] = (char) (iExtent + 'a' - 10); + else + rgchExtent[1] = (char) (iExtent + '0'); + rgchExtent[2] = '\0'; + strcat (rgchTbName, rgchExtent); + } + strcat (rgchTbName, pchExt); + cOpenFilesAttempts ++; + fp = fopen (rgchTbName, "rb"); + //printf (">>> Opening %s\n", rgchTbName); + cOpenFilesSuceed += (NULL != fp); +#if !defined (NEW) && !defined (_WIN32) && !defined(_WIN64) + // For case-sensitive systems, have to try once more + if (NULL == fp) + { + for (int i = strchr(rgchTbName,'.')-rgchTbName-1; i>=0 && isalpha(rgchTbName[i]); i--) + rgchTbName[i] = toupper (rgchTbName[i]); + cOpenFilesAttempts ++; + fp = fopen (rgchTbName, "rb"); + //printf (">>> Opening %s\n", rgchTbName); + cOpenFilesSuceed += (NULL != fp); + } +#endif + if (NULL != fp) + { + // Found uncompressed table + if (rgtbdDesc[iTb].m_f16bit || + ((int)(cb = rgtbdDesc[iTb].m_rgcbLength[side])) < 0 || + cb != (unsigned) cb) + { + // Do not check the length for too large files + cb = rgtbdDesc[iTb].m_rgcbLength[side]; + } + else + { + if (0 != fseek (fp, 0L, SEEK_END)) + { + printf ("*** Seek in %s failed\n", rgchTbName); + exit (1); + } + cb = (INDEX) ftell (fp); + VCheckSize (iTb, side, iExtent, cb, rgchTbName); + } + } + else + { + // Check for compressed table. + // First, check for kxykz.nb?.emd + strcat (rgchTbName, ".emd"); + cOpenFilesAttempts ++; + fp = fopen (rgchTbName, "rb"); + //printf (">>> Opening %s\n", rgchTbName); + cOpenFilesSuceed += (NULL != fp); + if ((NULL == fp) && !rgtbdDesc[iTb].m_fSplit) + { + // Check for kxykz_nb?.emd + rgchTbName [strlen(rgchTbName)-8] = '_'; + cOpenFilesAttempts ++; + fp = fopen (rgchTbName, "rb"); + //printf (">>> Opening %s\n", rgchTbName); + cOpenFilesSuceed += (NULL != fp); + } + if ((NULL == fp) && !rgtbdDesc[iTb].m_fSplit) + { + // Check for kxykz_nb?_emd + rgchTbName [strlen(rgchTbName)-4] = '_'; + cOpenFilesAttempts ++; + fp = fopen (rgchTbName, "rb"); + //printf (">>> Opening %s\n", rgchTbName); + cOpenFilesSuceed += (NULL != fp); + } +#if defined (T41_INCLUDE) + if ((NULL == fp) && (iTb <= tbid_kqqqk)) +#else + if ((NULL == fp) && (iTb <= tbid_kqqkq)) +#endif + { + // Check for kxykznb?.emd (8+3 format) + int cch; + + rgchTbName [strlen(rgchTbName)-4] = '.'; + cch = strlen (rgchTbName); + memmove (rgchTbName+cch-8, rgchTbName+cch-7, 8); + cOpenFilesAttempts ++; + fp = fopen (rgchTbName, "rb"); + //printf (">>> Opening %s\n", rgchTbName); + cOpenFilesSuceed += (NULL != fp); + } + if (NULL == fp) + return false; + cCompressed ++; + int iResult = comp_open_file (&comp_info, fp, TB_CRC_CHECK); + if (0 != iResult) + { + printf ("*** Unable to read %s - ", rgchTbName); + switch (iResult & 0xFF) + { + case COMP_ERR_READ: + printf ("read error\n"); + break; + case COMP_ERR_NOMEM: + printf ("out of memory\n"); + break; + case COMP_ERR_BROKEN: + printf ("file broken\n"); + break; + default: + printf ("error %d\n", iResult); + break; + } + exit (1); + } + if (comp_info->block_size != TB_CB_CACHE_CHUNK) + { + printf ("*** %s: Unsupported block size %d\n", rgchTbName, comp_info->block_size); + exit (1); + } + if (rgtbdDesc[iTb].m_f16bit) + { + cb = ((INDEX)comp_info->block_size/2)*(comp_info->n_blk-1) + + (INDEX)comp_info->last_block_size/2; + VCheckSize (iTb, side, iExtent, cb, rgchTbName); + } + else + { + cb = ((INDEX)comp_info->block_size)*(comp_info->n_blk-1) + + (INDEX)comp_info->last_block_size; + VCheckSize (iTb, side, iExtent, cb, rgchTbName); + } + +#if 0 + block = rgpdbDecodeBlocks[0]; + if (NULL == block) + { + int iResult = comp_alloc_block (&rgpdbDecodeBlocks[0], TB_CB_CACHE_CHUNK); + if (0 != iResult) + { + printf ("*** Cannot allocate decode block: error code %d\n", iResult); + exit (1); + } + block = rgpdbDecodeBlocks[0]; + } + // Initialize decode block and read chunk + fWasError = 0 != comp_init_block (block, TB_CB_CACHE_CHUNK, rgbBuffer) || + 0 != comp_read_block (block, comp_info, fp, TB_CHUNK (cb-1)) || + 0 != comp_decode_and_check_crc (block, comp_info, block->orig.size, TB_CRC_CHECK); + if (fWasError) + { + printf ("*** Sanity check on %s failed\n", rgchTbName); + exit (1); + } +#endif + } + + fclose (fp); + if (FRegisterTb (& (rgtbdDesc[iTb]))) + { + pchCopy = (char*) PvMalloc (strlen(rgchTbName)+1); + strcpy (pchCopy, rgchTbName); + free (rgtbdDesc[iTb].m_rgpchFileName[side][iExtent]); + rgtbdDesc[iTb].m_rgpchFileName[side][iExtent] = pchCopy; + if (NULL == rgtbdDesc[iTb].m_prgtbcbBuckets[side]) + { + prgtbcbBuckets = (CTbCacheBucket*) PvMalloc (TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket)); + memset (prgtbcbBuckets, 0, TB_DIRECTORY_SIZE*sizeof(CTbCacheBucket)); +#if defined (SMP) + for (int i = 0; i < TB_DIRECTORY_SIZE; i ++) + LockInit (prgtbcbBuckets[i].m_lock); +#endif + rgtbdDesc[iTb].m_prgtbcbBuckets[side] = prgtbcbBuckets; + if (fVerbose) + printf ("%s registered\n", pchCopy); + } + else + { + if (fVerbose) + printf ("%s found\n", pchCopy); + } + rgtbdDesc[iTb].m_rgpdiDecodeInfo[side][iExtent] = comp_info; + return true; + } + else + { + printf ("*** Unable to register %s\n", rgchTbName); + exit (1); + } + return false; + } + +int FCheckExistance + ( + char *pszPath, + int iTb, + color side + ) + { + int fFound; + int cExtents; + INDEX cBytes; + + if (rgtbdDesc[iTb].m_fSplit) + { + cBytes = rgtbdDesc[iTb].m_rgcbLength[side]; + if (rgtbdDesc[iTb].m_f16bit) + cBytes *= 2; + cExtents = (int) (cBytes >> 31) + 1; + } + else + cExtents = 1; + fFound = false; + for (int iExtent = 0; iExtent < cExtents; iExtent++) + { + if (!FCheckExtentExistance (pszPath, iTb, side, iExtent)) + break; + fFound = true; + } + return fFound; + } + +extern "C" int IInitializeTb + ( + char *pszPath + ) + { + char szTemp[1024]; + color sd; + int iTb, iMaxTb, iExtent, i; + CTbCacheBucket *prgtbcbBuckets; + +#if defined (_WIN32) || defined (_WIN64) + // For Windows, get bit map of ready devices + iDrivesMap = GetLogicalDrives(); + memset (rgfAccessed, 0, sizeof(rgfAccessed)); + memset (rgfNotReady, 0, sizeof(rgfNotReady)); +#endif + + cOpenFilesAttempts = cOpenFilesSuceed = 0; + cbAllocated = cbEGTBCompBytes = 0; + // If there are open files, close those + VTbCloseFiles (); +#if defined (SMP) + // Init all locks + LockInit (lockLRU); + LockInit (lockDecode); + for (iTb = 1; iTb < cTb; iTb ++) + { + LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorWhite]); + LockInit (rgtbdDesc[iTb].m_rglockFiles[x_colorBlack]); + } +#endif +#if defined (NEW) + // Create enumeration tables + VInitEnumerations (); +#endif + // Create empty TB search table + VCreateEmptyTbTable (); + // Free memory from TB table + for (iTb = 1; iTb < cTb; iTb ++) + { + for (sd = x_colorWhite; sd <= x_colorBlack; sd = (color) (sd + 1)) + { + if (NULL != rgtbdDesc[iTb].m_prgtbcbBuckets[sd] && + NULL == rgtbdDesc[iTb].m_rgpbRead[sd]) + { + prgtbcbBuckets = rgtbdDesc[iTb].m_prgtbcbBuckets[sd]; +#if defined (SMP) + for (i = 0; i < TB_DIRECTORY_SIZE; i ++) + LockFree (prgtbcbBuckets[i].m_lock); +#endif + free (prgtbcbBuckets); + rgtbdDesc[iTb].m_prgtbcbBuckets[sd] = NULL; + } + for (iExtent = 0; iExtent < MAX_EXTENTS; iExtent ++) + { + if (NULL != rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent]) + { + free (rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent]); + rgtbdDesc[iTb].m_rgpchFileName[sd][iExtent] = NULL; + } + if (NULL != rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent]) + { + free (rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent]); + rgtbdDesc[iTb].m_rgpdiDecodeInfo[sd][iExtent] = NULL; + } + } + } + } + // Free compressed blocks + for (i = 0; i < CPUS; i ++) + { + if (NULL != rgpdbDecodeBlocks[i]) + { + free (rgpdbDecodeBlocks[i]); + rgpdbDecodeBlocks[i] = NULL; + } + } + + if(pszPath == NULL) + return 0; + + // Search for existing TBs + iMaxTb = 0; + for (;;) + { + for (i = 0; pszPath[i] != '\0' && pszPath[i] != ',' && pszPath[i] != ';' +#if !defined (_WIN32) && !defined (__MWERKS__) && !defined(_WIN64) + && pszPath[i] != ':' +#endif + ; i ++) + { + szTemp[i] = pszPath[i]; + } + szTemp[i] = '\0'; + for (iTb = 1; iTb < cTb; iTb ++) + { + if (FCheckExistance (szTemp, iTb, x_colorWhite)) + { + if (iTb > iMaxTb) + iMaxTb = iTb; + } + if (! rgtbdDesc[iTb].m_fSymmetric && FCheckExistance (szTemp, iTb, x_colorBlack)) + { + if (iTb > iMaxTb) + iMaxTb = iTb; + } + } + pszPath += i; + if ('\0' == *pszPath) + break; + pszPath ++; + } + + // If there were compressed files, have to allocate buffer(s) + if (0 != cCompressed) + { + for (i = 0; i < CPUS; i ++) + { + if (NULL == rgpdbDecodeBlocks[i]) + { + int iResult = comp_alloc_block (&rgpdbDecodeBlocks[i], TB_CB_CACHE_CHUNK); + if (0 != iResult) + { + printf ("*** Cannot allocate decode block: error code %d\n", iResult); + exit (1); + } + } + } + if (fVerbose) + printf ("Allocated %dKb for decompression tables, indices, and buffers.\n", + (cbEGTBCompBytes+1023)/1024); + } + + if (fVerbose) + printf ("Tried to open %d files. Opened %d files.\n", + cOpenFilesAttempts, cOpenFilesSuceed); + // All done! +#if defined T33_INCLUDE + if (iMaxTb >= tbid_knnknn) + return 6; +#elif defined (T42_INCLUDE) + if (iMaxTb >= tbid_knnnkn) + return 6; +#endif + if (iMaxTb >= tbid_kppkp) + return 5; + if (iMaxTb >= tbid_kpkp) + return 4; + if (iMaxTb >= tbid_kpk) + return 3; + return 0; + } diff --git a/src/epd.c b/src/epd.c new file mode 100644 index 0000000..b63c872 --- /dev/null +++ b/src/epd.c @@ -0,0 +1,29 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + epd.c + +Abstract: + +Author: + + Scott Gasch (scott.gasch@gmail.com) 26 Aug 2004 + +Revision History: + + $Id: epd.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +FLAG +ParseEPDLine(char *szEpd) +{ + char *szFen = FindChunk(szEpd, 1); + + +} diff --git a/src/eval.c b/src/eval.c new file mode 100755 index 0000000..944642a --- /dev/null +++ b/src/eval.c @@ -0,0 +1,6118 @@ +/** +Copyright (c) Scott Gasch + +Module Name: + + eval.c + +Abstract: + + Position evaluation routines. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 14 Jun 2004 + +Revision History: + + $Id: eval.c 357 2008-07-03 16:18:11Z scott $ + +**/ + +#include "chess.h" + +typedef void (*PEVAL_HELPER)(POSITION *, COOR, PAWN_HASH_ENTRY *); +typedef FLAG (FASTCALL *PMOBILITY_HELPER)(POSITION *, COOR, ULONG *, ULONG *); + +// +// To simplify code / maintenance I use the same loop for both colors +// in some places. These globals coorespond to "ahead of the piece" +// or "behind the piece" for each color. +// +const int g_iAhead[2] = { +1, -1 }; +const int g_iBehind[2] = { -1, +1 }; + +// +// General eval terms +// --------------------------------------------------------------------------- +// +static SCORE TRADE_PIECES[3][17] = +{// 0 1 2 3 4 5 6 7 8 | 9..15 -- down piece count + { -1, 90, 81, 73, 67, 62, 57, 52, 50, 50,50,50,50,50,50,50,-1}, + { -1, 125, 117, 109, 100, 91, 84, 78, 71, 66,66,66,66,66,66,66,-1}, + { -1, 150, 132, 124, 116, 109, 102, 94, 87, 77,77,77,77,77,77,77,-1}, +}; + +static SCORE DONT_TRADE_PAWNS[3][9] = +{// 0 1 2 3 4 5 6 7 8 -- up pawn count + { -43, -15, 0, +3, +6, +10, +15, +21, +28 }, // 0 + { -63, -25, 0, +4, +9, +14, +19, +25, +32 }, // 1 + { -10, 0, 0, +7, +15, +20, +24, +29, +36 }, // 2 +}; + +static ULONG REDUCED_MATERIAL_DOWN_SCALER[32] = +{ +// none na na m na R 2m na + 0, 0, 0, 0, 0, 0, 0, 0, + +// Rm 3m/Q 2R R2m 4m/Qm 2Rm R3m/QR Q2m + 0, 1, 1, 1, 1, 1, 2, 3, + +// 2R2m R4m/QRm Q3m 2R3m/ QR2m Q4m 2R4m/ QR3m +// Q2R Q2Rm + 4, 5, 6, 6, 7, 7, 7, 7, + +// na Q2R2m QR4m na Q2R3m na na full + 8, 8, 8, 8, 8, 8, 8, 8, +}; + +static ULONG REDUCED_MATERIAL_UP_SCALER[32] = +{ +// none na na m na R 2m na + 8, 8, 8, 8, 8, 8, 8, 8, + +// Rm 3m/Q 2R R2m 4m/Qm 2Rm R3m/QR Q2m + 8, 7, 7, 7, 7, 6, 6, 5, + +// 2R2m R4m/QRm Q3m 2R3m/ QR2m Q4m 2R4m/ QR3m +// Q2R Q2Rm + 4, 3, 3, 3, 2, 2, 2, 1, + +// na Q2R2m QR4m na Q2R3m na na full + 1, 1, 0, 0, 0, 0, 0, 0, +}; + +static ULONG PASSER_MATERIAL_UP_SCALER[32] = +{ +// none na na m na R 2m na + 8, 8, 8, 8, 8, 8, 7, 7, + +// Rm 3m/Q 2R R2m 4m/Qm 2Rm R3m/QR Q2m + 7, 6, 7, 5, 4, 5, 4, 3, + +// 2R2m R4m/QRm Q3m 2R3m/ QR2m Q4m 2R4m/ QR3m +// Q2R Q2Rm + 2, 2, 1, 1, 0, 0, 0, 0, + +// na Q2R2m QR4m na Q2R3m na na full + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +COOR QUEENING_RANK[2] = { 1, 8 }; +COOR JUMPING_RANK[2] = { 7, 2 }; + +// +// Pawn eval terms +// --------------------------------------------------------------------------- +// +// "There is one case which can be treated as positional or material, +// namely the rook's pawn, which differs from other pawns in that it +// can only capture one way instead of two. Since this handicap cannot +// be corrected without the opponent's help, I teach my students to +// regard the rook's pawn as a different piece type, a crippled +// pawn. Database statistics indicate that it is on average worth +// about 15% less than a normal pawn. The difference is enough so that +// it is usually advantageous to make a capture with a rook's pawn, +// promoting it to a knights pawn, even if that produces doubled pawns +// and even if there is no longer a rook on the newly opened rook's +// file." +// --Larry Kaufman, IM +// "Evaluation of Material Imbalance" +// +static SCORE PAWN_CENTRALITY_BONUS[128] = +{ + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + -8, 0, 0, 0, 0, 0, 0, -8, 0,0,0,0,0,0,0,0, + -8, 0, 5, 5, 5, 5, 0, -8, 0,0,0,0,0,0,0,0, + -8, 0, 5, 9, 9, 5, 0, -8, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------- + -8, 0, 5, 9, 9, 5, 0, -8, 0,0,0,0,0,0,0,0, + -8, 0, 5, 5, 5, 5, 0, -8, 0,0,0,0,0,0,0,0, + -8, 0, 0, 0, 0, 0, 0, -8, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0 +}; + +static SCORE BACKWARD_SHIELDED_BY_LOCATION[128] = +{ + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0, + -7, -5, -5, -7, -7, -5, -5, -7, 0,0,0,0,0,0,0,0, + -5, -4, -4, -5, -5, -4, -4, -5, 0,0,0,0,0,0,0,0, + -4, -3, -3, -4, -4, -3, -3, -4, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------- + -4, -3, -3, -4, -4, -3, -3, -4, 0,0,0,0,0,0,0,0, + -5, -4, -4, -5, -5, -4, -4, -5, 0,0,0,0,0,0,0,0, + -7, -5, -5, -7, -7, -5, -5, -7, 0,0,0,0,0,0,0,0, + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0 +}; + +static SCORE BACKWARD_EXPOSED_BY_LOCATION[128] = +{ + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0, + -12, -9, -9, -11, -11, -9, -9, -12, 0,0,0,0,0,0,0,0, + -9, -7, -7, -9, -9, -7, -7, -9, 0,0,0,0,0,0,0,0, + -7, -6, -6, -7, -7, -6, -6, -7, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------- + -7, -6, -6, -7, -7, -6, -6, -7, 0,0,0,0,0,0,0,0, + -9, -7, -7, -9, -9, -7, -7, -9, 0,0,0,0,0,0,0,0, + -12, -9, -9, -11, -11, -9, -9, -12, 0,0,0,0,0,0,0,0, + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0 +}; + +// +// "The first statement I can confirm is that doubled pawns are indeed +// on average undesirable. However this statistic needs to be broken +// down to be useful. Doubled pawns themselves are really more +// serious than this generally, but when your pawns are doubled you +// automatically get an extra half-open file for your rooks (or queen, +// but the queen can also use diagonals). So it follows logically +// that the net cost of doubled pawns is much greater in the absence +// of major pieces. The database shows that with all rooks present, +// doubled pawns "cost" only about 1/16th of a pawn on average. With +// one rook each the cost rises to 1/4th of a pawn and with no rooks +// present to 3/8ths of a pawn. With the queens present the cost is +// again only 1/16th of a pawn; without them it's a quarter pawn. So +// the lessons are clear; beware of doubled pawns when major pieces +// have been exchanged, and beware of exchanging major pieces when you +// are the one with the doubled pawns." +// --Larry Kaufman, IM +// "All About Doubled Pawns" +// +// Note: indexed by number of files with 1+ pawn on them. +static SCORE DOUBLED_PAWN_PENALTY_BY_COUNT[4][9] = +{ // ------------ count of doubled+ pawns ------------ + {// 0 1 2 3 4 5 6 7 8 : no majors alive + +0, -32, -65, -99, -134, -170, -207, -222, -250 + }, + {// : 1 rook + +0, -23, -47, -76, -108, -144, -184, -200, -216 + }, + {// : 2 rooks or 1 queen + +0, -13, -23, -34, -46, -64, -86, -111, -138 + }, + {// : all majors alive + +0, -7, -13, -25, -39, -55, -73, -95, -121 + }, +}; + +static SCORE ISOLATED_PAWN_PENALTY_BY_COUNT[9] = +{// 0 1 2 3 4 5 6 7 8 + +0, -3, -7, -9, -16, -35, -50, -85, -100 +}; + +static SCORE ISOLATED_PAWN_BY_PAWNFILE[9] = +{ + 0, -7, -8, -9, -10, -10, -9, -8, -7 +}; + +static SCORE ISOLATED_EXPOSED_PAWN = -5; + +static SCORE ISOLATED_DOUBLED_PAWN = -11; + +// +// Note: -25% to -33% if the enemy occupies or controls the next sq. +// +static SCORE PASSER_BY_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +0,+162,+111, +62, +36, +18, +13, +0 }, // black + { +0, +0, +13, +18, +36, +62,+111,+162, +0 } // white +}; + +static SCORE CANDIDATE_PASSER_BY_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +0, +0, +48, +34, +22, +13, +9, +0 }, // black + { +0, +0, +9, +13, +22, +34, +48, +0, +0 } // white +}; + +// Note: x2 +static SCORE CONNECTED_PASSERS_BY_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +0, +96, +74, +48, +21, +10, +5, +0 }, // black + { +0, +0, +5, +10, +21, +48, +74, +96, +0 } // white +}; + +static SCORE SUPPORTED_PASSER_BY_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +0, +60, +40, +13, +6, +3, +1, +0 }, // black + { +0, +0, +1, +3, +6, +13, +40, +60, +0 } // white +}; + +static SCORE OUTSIDE_PASSER_BY_DISTANCE[9] = +{// 0 1 2 3 4 5 6 7 8 + +0, +0, +7, +14, +21, +28, +34, +41, +55 +}; + +static SCORE PASSER_BONUS_AS_MATERIAL_COMES_OFF[32] = +{ +// none na na m na R 2m na + +60, -1, -1, +37, -1, +43, +19, -1, + +// Rm 3m/Q 2R R2m 4m/Qm 2Rm R3m/QR Q2m + +14, +9, +20, +4, +3, +3, 0, 0, + +// 2R2m R4m/QRm Q3m 2R3m/ QR2m Q4m 2R4m/ QR3m +// Q2R Q2Rm + 0, 0, 0, 0, 0, 0, 0, 0, + +// na Q2R2m QR4m na Q2R3m na na full + 0, 0, 0, 0, 0, 0, 0, 0, +}; + +SCORE RACER_WINS_RACE = +800; + +static SCORE UNDEVELOPED_MINORS_IN_OPENING[5] = +{// 0 1 2 3 4 + 0, -6, -10, -16, -22 +}; + +// +// Bishop eval terms +// --------------------------------------------------------------------------- +// +static SCORE BISHOP_OVER_KNIGHT_IN_ENDGAME = +33; + +// +// "The bishop pair has an average value of half a pawn (more when the +// opponent has no minor pieces to exchange for one of the bishops), +// enough to regard it as part of the material evaluation of the +// position, and enough to overwhelm most positional considerations. +// Moreover, this substantial bishop pair value holds up in all +// situations tested, regardless of what else is on the board... +// +// ...One rule which I often teach to students is that if you have the +// bishop pair, and your opponent's single bishop is a bad bishop +// (hemmed in by his own pawns), you already have full compensation +// for a pawn... Kasparov has said something similar... +// +// As noted before, the bishop pair is worth more with fewer pawns on +// the board. Aside from this factor, the half pawn value of the +// bishop pair is remarkably constant, applying even when there are no +// pieces on the board except two minors each." +// --Larry Kaufman, IM +// "Evaluation of Material Imbalance" +static SCORE BISHOP_PAIR[2][17] = +{ + { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }, + { 53, 52, 51, 50, 49, 48, 47, 45, 43, 41, 40, 40, 40, 40, 40, 40, 40 } +}; + +static SCORE STATIONARY_PAWN_ON_BISHOP_COLOR[128] = +{ + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0, + -4, -6, -7, -7, -7, -7, -6, -4, 0,0,0,0,0,0,0,0, + -6, -7, -9, -8, -8, -9, -7, -6, 0,0,0,0,0,0,0,0, + -7, -8, -10, -11, -11, -10, -8, -7, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------- + -7, -8, -10, -11, -11, -10, -8, -7, 0,0,0,0,0,0,0,0, + -6, -7, -9, -8, -8, -9, -7, -6, 0,0,0,0,0,0,0,0, + -4, -6, -7, -7, -7, -7, -6, -4, 0,0,0,0,0,0,0,0, + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0 +}; + +static SCORE TRANSIENT_PAWN_ON_BISHOP_COLOR[128] = +{ + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0, + -1, -1, -2, -2, -2, -2, -1, -1, 0,0,0,0,0,0,0,0, + -3, -4, -4, -4, -4, -4, -4, -3, 0,0,0,0,0,0,0,0, + -4, -5, -7, -8, -8, -7, -5, -4, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------- + -4, -5, -7, -8, -8, -7, -5, -4, 0,0,0,0,0,0,0,0, + -3, -4, -4, -4, -4, -4, -4, -3, 0,0,0,0,0,0,0,0, + -1, -1, -2, -2, -2, -2, -1, -1, 0,0,0,0,0,0,0,0, + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0 +}; + +// +// A bishop can move to between 0..13 squares. +// +static SCORE BISHOP_MOBILITY_BY_SQUARES[14] = +{// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 + -22, -14, -10, -5, -1, 0, +1, +3, +4, +5, +6, +7, +8, +9 +};// ^ | + +static SCORE BISHOP_MAX_MOBILITY_IN_A_ROW_BONUS[8] = +{// 0 1 2 3 4 5 6 7 + -10, -4, +1, +3, +4, +5, +5, +5 +}; + +static SCORE BISHOP_UNASSAILABLE_BY_DIST_FROM_EKING[9] = +{// 0 1 2 3 4 5 6 7 8 + +0, +33, +28, +18, +8, +4, +0, -10, -16 +}; + +static SCORE BISHOP_IN_CLOSED_POSITION[33] = +{// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 10, 10, 10, 9, 9, 8, 8, 7, 7, 6, 5, 4, 3, 2, 1, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 +// 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 +}; + +// +// Knight eval terms +// --------------------------------------------------------------------------- +// +static SCORE KNIGHT_CENTRALITY_BONUS[128] = +{ + -12, -8, -8, -8, -8, -8, -8, -12, 0,0,0,0,0,0,0,0, + -8, -2, -2, 0, 0, -2, -2, -8, 0,0,0,0,0,0,0,0, + -8, -2, +4, +5, +5, +4, -2, -8, 0,0,0,0,0,0,0,0, + -8, -2, +5, +8, +8, +5, -2, -8, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------- + -8, -2, +5, +8, +8, +5, -2, -8, 0,0,0,0,0,0,0,0, + -8, -2, +4, +5, +5, +4, -2, -8, 0,0,0,0,0,0,0,0, + -8, -2, -2, 0, 0, -2, -2, -8, 0,0,0,0,0,0,0,0, + -12, -8, -8, -8, -8, -8, -8, -12, 0,0,0,0,0,0,0,0 +}; + +static SCORE KNIGHT_KING_TROPISM_BONUS[9] = +{// 0 1 2 3 4 5 6 7 8 + 0, +15, +12, +9, +4, +0, +0, +0, +0 +}; + + +static SCORE KNIGHT_UNASSAILABLE_BY_DIST_FROM_EKING[9] = +{// 0 1 2 3 4 5 6 7 8 + +0, +25, +19, +14, +6, +0, +0, +0, +0 +}; + +static SCORE KNIGHT_ON_INTERESTING_SQUARE_BY_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +12, +11, +9, +6, +3, +0, +0, +0 }, // black + { +0, +0, +0, +0, +3, +6, +9, +11, +12 } // white +}; + +// +// A knight can move to between 0..8 squares +// ----------------------------------------- +// 0 = supported enemy pawn +// 1 = unsupported enemy pawn, friend pawn, enemy B/N +// enemy controlled empty sq. +// 2 = enemy >B, friend controlled empty sq, no one controlled empty sq +// +// Total: 16 mobility max +// +static SCORE KNIGHT_MOBILITY_BY_COUNT[9] = +{// 0 1 2 3 4 5 6 7 8 + -17, -10, -6, 0, +3, +5, +7, +8, +8 +};// ^ | + +static SCORE KNIGHT_WITH_N_PAWNS_SUPPORTING[3] = +{ + +0, +4, +8 +}; + +static SCORE KNIGHT_IN_CLOSED_POSITION[33] = +{// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 4, 6, 9, 11, + 12, 13, 15, 17, 19, 21, 21, 22, 22, 23, 23, 24, 24, 25, 25, 26, 27 +// 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 +}; + +// +// Rook eval terms +// --------------------------------------------------------------------------- +// +static SCORE ROOK_ON_FULL_OPEN_BY_DIST_FROM_EKING[8] = +{// 0 1 2 3 4 5 6 7 + +24, +22, +17, +14, +13, +13, +12, +12 +}; + +static SCORE ROOK_ON_HALF_OPEN_WITH_ENEMY_BY_DIST_FROM_EKING[8] = +{// 0 1 2 3 4 5 6 7 + +12, +11, +9, +9, +8, +8, +8, +7 +}; + +static SCORE ROOK_ON_HALF_OPEN_WITH_FRIEND_BY_DIST_FROM_EKING[8] = +{// 0 1 2 3 4 5 6 7 + +13, +12, +11, +11, +9, +9, +9, +8 +}; + +static SCORE ROOK_BEHIND_PASSER_BY_PASSER_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +0, +25, +17, +12, +6, +1, +0, +0 }, // black + { +0, +0, +0, +1, +6, +12, +17, +25, +0 } // white +}; + +static SCORE ROOK_LEADS_PASSER_BY_PASSER_RANK[2][9] = +{// 0 1 2 3 4 5 6 7 8 + { +0, +0, -22, -16, -13, -9, -5, -3, +0 }, // black + { +0, +0, -3, -5, -9, -13, -16, -22, +0 } // white +}; + +static SCORE KING_TRAPPING_ROOK = -40; + +static SCORE ROOK_TRAPPING_EKING = +22; + +static SCORE ROOK_VALUE_AS_PAWNS_COME_OFF[17] = +{// 0 1 2 3 4 5 6 7 8 + +55, +51, +44, +38, +33, +27, +22, +16, +7, + // 9 10 11 12 13 14 15 16 + +1, -3, -6, -9, -12, -18, -22, -25 +}; + +// +// Note: these are multiplied by two (one per rook). +// +static SCORE ROOK_CONNECTED_VERT = +7; // x2 +static SCORE ROOK_CONNECTED_HORIZ = +4; // x2 + +// +// A rook can move to between 0..14 squares +// ---------------------------------------- +// 0 = supported enemy P/N/B, friend piece +// 1 = unsupported enemy piece, enemy controlled empty sq, enemy R +// 2 = enemy >R, friend controlled empty sq, no one controlled empty sq +// +// Total: 28 mobility max +// +static SCORE ROOK_MOBILITY_BY_SQUARES[15] = +{// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + -28, -24, -20, -14, -7, -2, +0, +4, +8, +12, +15, +17, +19, +21, +22 +};// ^ | + +static SCORE ROOK_MAX_MOBILITY_IN_A_ROW_BONUS[8] = +{// 0 1 2 3 4 5 6 7 + -15, -6, +0, +4, +8, +8, +8, +8 +}; + +// +// Queen eval terms +// --------------------------------------------------------------------------- +// + + +// +// A queen can move to between 0..27 squares +// ----------------------------------------- +// 0 = supported enemy P/N/B/R, friend piece +// 1 = unsupported enemy piece, enemy controlled empty sq, enemy Q +// 2 = enemy K, no one controlled empty sq, friend controlled empty sq +// +// Total: 54 mobility max +// +static SCORE QUEEN_MOBILITY_BY_SQUARES[28] = +{// 0 1 2 3 4 5 6 7 8 9 10 11 12 13 14 + -30, -26, -22, -17, -11, -8, -4, -2, -1, +2, +4, +7, +10, +12, +14, +// | + + //15 16 17 18 19 20 21 22 23 24 25 26 27 + +15, +16, +17, +18, +19, +20, +20, +21, +21, +22, +22, +23, +23 +}; + +static SCORE QUEEN_OUT_EARLY[5] = +{// 0 1 2 3 4 : num unmoved minors + 0, -14, -22, -26, -33 +}; + +// +// In "Evaluation of Material Imbalance", IM Larry Kaufman makes the +// point that queens are worth more then the standard nine "points". +// Thus, this scale is biased upwards by about 0.15 pawn. +// +static SCORE QUEEN_KING_TROPISM[8] = +{// 0 1 2 3 4 5 6 7 + 0, +34, +28, +22, +19, +17, +16, +15 +}; + +static SCORE QUEEN_ATTACKS_SQ_NEXT_TO_KING = 8; // x #sq_attacked + +// +// King eval terms +// --------------------------------------------------------------------------- +// +static ULONG KING_INITIAL_COUNTER_BY_LOCATION[2][128] = +{ + { + 1, 0, 0, 0, 1, 0, 0, 1, 0,0,0,0,0,0,0,0, + 1, 1, 1, 1, 1, 1, 1, 1, 0,0,0,0,0,0,0,0, + 3, 3, 3, 3, 3, 3, 3, 3, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + // ------------------------------------------------------------------- + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0 + }, + { + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + // ------------------------------------------------------------------- + 4, 4, 4, 4, 4, 4, 4, 4, 0,0,0,0,0,0,0,0, + 3, 3, 3, 3, 3, 3, 3, 3, 0,0,0,0,0,0,0,0, + 1, 1, 1, 1, 1, 1, 1, 1, 0,0,0,0,0,0,0,0, + 1, 0, 0, 0, 1, 0, 0, 1, 0,0,0,0,0,0,0,0 + } +}; + +static SCORE KING_TO_CENTER[128] = +{ + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0, + +1, +3, +5, +7, +7, +5, +3, +1, 0,0,0,0,0,0,0,0, + +3, +5, +13, +15, +15, +13, +5, +3, 0,0,0,0,0,0,0,0, + +5, +7, +17, +23, +23, +17, +7, +5, 0,0,0,0,0,0,0,0, +// ------------------------------------------------------------------ + +5, +7, +17, +23, +23, +17, +7, +5, 0,0,0,0,0,0,0,0, + +3, +5, +13, +15, +15, +13, +5, +3, 0,0,0,0,0,0,0,0, + +1, +3, +5, +7, +7, +5, +3, +1, 0,0,0,0,0,0,0,0, + +0, +0, +0, +0, +0, +0, +0, +0, 0,0,0,0,0,0,0,0 +}; + +// +// If a side has less than this much material we don't bother scoring +// the other side's king safety. Note: this doesn't incl pawn +// material. +// +#define DO_KING_SAFETY_THRESHOLD \ + (VALUE_ROOK + VALUE_BISHOP + VALUE_KING + 1) + +// +// If a side has less than this much material the other side's king +// can come out. Note: this doesn't incl pawn material. +// +#define KEEP_KING_AT_HOME_THRESHOLD \ + (VALUE_ROOK + VALUE_ROOK + VALUE_BISHOP + VALUE_KING + 1) + +static ULONG KING_COUNTER_BY_ATTACK_PATTERN[32] = +{ +//p 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 +//m 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 +//r 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 0 0 0 0 1 1 1 1 +//q 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 0 0 1 1 +//k 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 0 1 + 0,0,2,2,1,1,3,3,1,1,3,3,2,2,4,4,2,2,3,3,2,2,4,4,2,2,4,4,3,4,5,5 +}; + +static SCORE KING_SAFETY_BY_COUNTER[42] = +{ + -0, -4, -8, -12, -16, -20, -25, -31, -38, -50, -63, -76, -90, + -105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290, + -310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500, + -500,-500,-500 +}; + +static SCORE KING_MISSING_ONE_CASTLE_OPTION = -23; +typedef struct _DNA_BASE_SIZE { + SCORE *pBase; + ULONG uCount; +} DNA_BASE_SIZE; + +#define DNA_VAR(x) {(SCORE *)&(x), 1} +#define DNA_ARRAY(x) {(SCORE *)(x), ARRAY_LENGTH(x)} +#define DNA_MATRIX(x) {(SCORE *)(x), ARRAY_LENGTH(x) * ARRAY_LENGTH((x)[0])} +static DNA_BASE_SIZE g_EvalDNA[] = { + DNA_MATRIX(TRADE_PIECES), + DNA_MATRIX(DONT_TRADE_PAWNS), + DNA_ARRAY(REDUCED_MATERIAL_DOWN_SCALER), + DNA_ARRAY(REDUCED_MATERIAL_UP_SCALER), + DNA_ARRAY(PASSER_MATERIAL_UP_SCALER), + DNA_ARRAY(PAWN_CENTRALITY_BONUS), + DNA_ARRAY(BACKWARD_SHIELDED_BY_LOCATION), + DNA_ARRAY(BACKWARD_EXPOSED_BY_LOCATION), + DNA_MATRIX(DOUBLED_PAWN_PENALTY_BY_COUNT), + DNA_ARRAY(ISOLATED_PAWN_PENALTY_BY_COUNT), + DNA_ARRAY(ISOLATED_PAWN_BY_PAWNFILE), + DNA_VAR(ISOLATED_EXPOSED_PAWN), + DNA_VAR(ISOLATED_DOUBLED_PAWN), + DNA_MATRIX(PASSER_BY_RANK), + DNA_MATRIX(CANDIDATE_PASSER_BY_RANK), + DNA_MATRIX(CONNECTED_PASSERS_BY_RANK), + DNA_MATRIX(SUPPORTED_PASSER_BY_RANK), + DNA_ARRAY(OUTSIDE_PASSER_BY_DISTANCE), + DNA_ARRAY(PASSER_BONUS_AS_MATERIAL_COMES_OFF), + DNA_VAR(RACER_WINS_RACE), + DNA_ARRAY(UNDEVELOPED_MINORS_IN_OPENING), + DNA_VAR(BISHOP_OVER_KNIGHT_IN_ENDGAME), + DNA_MATRIX(BISHOP_PAIR), + DNA_ARRAY(STATIONARY_PAWN_ON_BISHOP_COLOR), + DNA_ARRAY(TRANSIENT_PAWN_ON_BISHOP_COLOR), + DNA_ARRAY(BISHOP_MOBILITY_BY_SQUARES), + DNA_ARRAY(BISHOP_MAX_MOBILITY_IN_A_ROW_BONUS), + DNA_ARRAY(BISHOP_UNASSAILABLE_BY_DIST_FROM_EKING), + DNA_ARRAY(BISHOP_IN_CLOSED_POSITION), + DNA_ARRAY(KNIGHT_CENTRALITY_BONUS), + DNA_ARRAY(KNIGHT_KING_TROPISM_BONUS), + DNA_ARRAY(KNIGHT_UNASSAILABLE_BY_DIST_FROM_EKING), + DNA_MATRIX(KNIGHT_ON_INTERESTING_SQUARE_BY_RANK), + DNA_ARRAY(KNIGHT_MOBILITY_BY_COUNT), + DNA_ARRAY(KNIGHT_WITH_N_PAWNS_SUPPORTING), + DNA_ARRAY(KNIGHT_IN_CLOSED_POSITION), + DNA_ARRAY(ROOK_ON_FULL_OPEN_BY_DIST_FROM_EKING), + DNA_ARRAY(ROOK_ON_HALF_OPEN_WITH_ENEMY_BY_DIST_FROM_EKING), + DNA_ARRAY(ROOK_ON_HALF_OPEN_WITH_FRIEND_BY_DIST_FROM_EKING), + DNA_MATRIX(ROOK_BEHIND_PASSER_BY_PASSER_RANK), + DNA_MATRIX(ROOK_LEADS_PASSER_BY_PASSER_RANK), + DNA_VAR(KING_TRAPPING_ROOK), + DNA_VAR(ROOK_TRAPPING_EKING), + DNA_ARRAY(ROOK_VALUE_AS_PAWNS_COME_OFF), + DNA_VAR(ROOK_CONNECTED_VERT), + DNA_VAR(ROOK_CONNECTED_HORIZ), + DNA_ARRAY(ROOK_MOBILITY_BY_SQUARES), + DNA_ARRAY(ROOK_MAX_MOBILITY_IN_A_ROW_BONUS), + DNA_ARRAY(QUEEN_MOBILITY_BY_SQUARES), + DNA_ARRAY(QUEEN_OUT_EARLY), + DNA_ARRAY(QUEEN_KING_TROPISM), + DNA_VAR(QUEEN_ATTACKS_SQ_NEXT_TO_KING), + DNA_MATRIX(KING_INITIAL_COUNTER_BY_LOCATION), + DNA_ARRAY(KING_TO_CENTER), + DNA_ARRAY(KING_SAFETY_BY_COUNTER), + DNA_VAR(KING_MISSING_ONE_CASTLE_OPTION) +}; + +ULONG +DNABufferSizeBytes() +{ + ULONG u; + ULONG uSize = 0; + for (u = 0; u < ARRAY_LENGTH(g_EvalDNA); u++) { + uSize += 10 * g_EvalDNA[u].uCount; + } + return uSize + 1; +} + + +char * +ExportEvalDNA() +{ + ULONG uSize = DNABufferSizeBytes(); + char *p = malloc(uSize); + ULONG u, v; + SCORE *q; + FLAG fFirst = TRUE; + + memset(p, 0, uSize); + for (u = 0; u < ARRAY_LENGTH(g_EvalDNA); u++) { + q = g_EvalDNA[u].pBase; + for (v = 0; v < g_EvalDNA[u].uCount; v++) { + if (!fFirst) { + sprintf(p, "%s,%d", p, *q); + } else { + sprintf(p, "%s%d", p, *q); + fFirst = FALSE; + } + q++; + } + strcat(p, "\n"); + fFirst = TRUE; + } + return p; // caller must free +} + +FLAG +WriteEvalDNA(char *szFilename) +{ + FILE *p = NULL; + char *q = NULL; + FLAG fRet = FALSE; + + if (SystemDoesFileExist(szFilename)) goto end; + p = fopen(szFilename, "a+b"); + if (!p) goto end; + q = ExportEvalDNA(); + if (!q) goto end; + fprintf(p, q); + fRet = TRUE; + end: + if (p) fclose(p); + if (q) free(q); + return fRet; +} + +FLAG +ImportEvalDNA(char *p) +{ + ULONG u, v; + + for (u = 0; u < ARRAY_LENGTH(g_EvalDNA); u++) { + for (v = 0; v < g_EvalDNA[u].uCount; v++) { + while(*p && (!isdigit(*p) && (*p != '-'))) p++; + if (*p == '\0') return FALSE; + *(g_EvalDNA[u].pBase + v) = atoi(p); + while(*p && (isdigit(*p) || (*p == '-'))) p++; + } + } + return TRUE; +} + +FLAG +ReadEvalDNA(char *szFilename) +{ + FILE *p = NULL; + ULONG uSize = DNABufferSizeBytes(); + char *q = malloc(uSize); + FLAG fRet = FALSE; + static char line[1024]; + char *c; + + if (!q) goto end; + memset(q, 0, uSize); + p = fopen(szFilename, "rb"); + if (!p) { + Trace("Failed to open file \"%s\"\n", szFilename); + goto end; + } + while(fgets(line, 1024, p) != NULL) { + c = strchr(line, '#'); + if (c) *c = '\0'; + c = line; + strcat(q, c); + } + fRet = ImportEvalDNA(q); + end: + if (q) free(q); + if (p) fclose(p); + return fRet; +} + + + +// +// Misc stuff +// --------------------------------------------------------------------------- +// + +// +// The three ranks "around" a rank (indexed by rank, used in eval.c) +// +BITBOARD BBADJACENT_RANKS[9] = +{ + 0, + BBRANK11 | BBRANK22, + BBRANK11 | BBRANK22 | BBRANK33, + BBRANK22 | BBRANK33 | BBRANK44, + BBRANK33 | BBRANK44 | BBRANK55, + BBRANK44 | BBRANK55 | BBRANK66, + BBRANK55 | BBRANK66 | BBRANK77, + BBRANK66 | BBRANK77 | BBRANK88, + BBRANK77 | BBRANK88 +}; + + +// +// The files "around" one, indexed by file (used in eval.c) +// +BITBOARD BBADJACENT_FILES[8] = +{ + // A = 0 + BBFILEB, + + // B = 1 + BBFILEA | BBFILEC, + + // C = 2 + BBFILEB | BBFILED, + + // D = 3 + BBFILEC | BBFILEE, + + // E = 4 + BBFILED | BBFILEF, + + // F = 5 + BBFILEE | BBFILEG, + + // G = 6 + BBFILEF | BBFILEH, + + // H = 7 + BBFILEG +}; + +// +// The ranks preceeding one, indexed by rank/color of pawn (used in +// eval.c) +// +BITBOARD BBPRECEEDING_RANKS[8][2] = +{ + // BLACK WHITE + // ----- ----- + { // 0 == RANK8 + BBRANK72, 0 + }, + { // 1 == RANK7 + BBRANK62, 0 + }, + { // 2 == RANK6 + BBRANK52, BBRANK77 + }, + { // 3 == RANK5 + BBRANK42, BBRANK67 + }, + { // 4 == RANK4 + BBRANK32, BBRANK57 + }, + { // 5 == RANK3 + BBRANK22, BBRANK47 + }, + { // 6 == RANK2 + 0, BBRANK37 + }, + { // 7 == RANK1 + 0, BBRANK27 + } +}; + + +static FLAG +_IsSquareSafeFromEnemyPawn(IN POSITION *pos, + IN COOR c, + IN BITBOARD bb) +/** + +Routine description: + + Determine if a piece in square c is "outposted". A piece is + outposted if no enemy pawns can advance to attack it / drive + it away. + +Parameters: + + POSITION *pos : the board + COOR c : the square (must not be empty!) + BITBOARD bb : the bitboard of pawns you want to consider + +Return value: + + FLAG : TRUE if the piece is safe/outposted, FALSE otherwise + +**/ +{ + ULONG uColor = GET_COLOR(pos->rgSquare[c].pPiece); + ULONG uFile, uRank; +#ifdef DEBUG + COOR cSquare; + PIECE p = pos->rgSquare[c].pPiece; + BITBOARD dbb = bb; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(p && (IS_BISHOP(p) || IS_KNIGHT(p) || IS_PAWN(p))); + ASSERT(IS_VALID_COLOR(uColor)); +#endif + + uFile = FILE(c); + ASSERT(uFile < 8); + bb &= BBADJACENT_FILES[uFile]; + + ASSERT(((c & 0x70) >> 4) == (c >> 4)); + uRank = c >> 4; + ASSERT(uRank < 8); + bb &= BBPRECEEDING_RANKS[uRank][uColor]; + +#ifdef DEBUG + if (bb != 0) + { + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&dbb))) + { + ASSERT(pos->rgSquare[cSquare].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + if ((FILE(cSquare) == (FILE(c) - 1)) || + (FILE(cSquare) == (FILE(c) + 1))) + { + switch(uColor) + { + case WHITE: + if (RANK(cSquare) > RANK(c)) + { + return(FALSE); + } + break; + case BLACK: + if (RANK(cSquare) < RANK(c)) + { + return(FALSE); + } + break; + } + } + } + ASSERT(FALSE); + } + else + { + ASSERT(bb == 0); + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&dbb))) + { + ASSERT(pos->rgSquare[cSquare].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + if ((FILE(cSquare) == (FILE(c) - 1)) || + (FILE(cSquare) == (FILE(c) + 1))) + { + switch(uColor) + { + case WHITE: + if (RANK(cSquare) > RANK(c)) + { + ASSERT(FALSE); + } + break; + case BLACK: + if (RANK(cSquare) < RANK(c)) + { + ASSERT(FALSE); + } + break; + } + } + } + } +#endif + return(bb == 0); +} + + +static ULONG +_WhoControlsSquareFast(IN POSITION *pos, + IN COOR c) +/** + +Routine description: + + Determine which side controls a board square. + +Parameters: + + POSITION *pos : the board + COOR c : the square in question + +Return value: + + static ULONG : (ULONG)-1 if neither side controls it or the sides + control it evenly, WHITE if white controls the square, or BLACK if + black controls the square. + + TODO: fix this to use counts / xrays + +**/ +{ + ULONG uWhite = pos->rgSquare[c|8].bvAttacks[WHITE].uSmall | + pos->rgSquare[c|8].bvAttacks[WHITE].uXray; + ULONG uBlack = pos->rgSquare[c|8].bvAttacks[BLACK].uSmall | + pos->rgSquare[c|8].bvAttacks[BLACK].uXray; + ULONG u; + PIECE p; + CHAR ch; + + ASSERT((c + 8) == (c | 8)); + ASSERT((uWhite & 0xFFFFFF00) == 0); + ASSERT((uBlack & 0xFFFFFF00) == 0); + + // TODO: keep these and update the table to use them + uWhite >>= 3; + uBlack >>= 3; + + p = pos->rgSquare[c].pPiece; + // p -= 2; + ch = g_SwapTable[p][uWhite][uBlack]; + if (ch != 0) + { + u = ch; + u >>= 7; + u = u & 1; + ASSERT(((u == 1) && (ch < 0)) || + ((u == 0) && (ch > 0))); + return(FLIP(u)); + } + return((ULONG)-1); +} + +/** + +Routine description: + + Zero out the attack table before building it. + +Parameters: + + POSITION *pos + +Return value: + + void + +**/ +#define CLEAR_A_SQ \ + pos->rgSquare[c].bvAttacks[0].uWholeThing = 0; \ + pos->rgSquare[c].bvAttacks[1].uWholeThing = 0; + +#define CLEAR_A_RANK \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c += 9; + +#define CLEAR_SHORT_RANK \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c++; \ + CLEAR_A_SQ; c += 10; + +static void +_ClearAttackTables(IN OUT POSITION *pos) +{ + register COOR c = 8; +#if 1 + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c += 16; + CLEAR_A_SQ; c = 9; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; + CLEAR_SHORT_RANK; +#else + CLEAR_A_RANK; + CLEAR_A_RANK; + CLEAR_A_RANK; + CLEAR_A_RANK; + CLEAR_A_RANK; + CLEAR_A_RANK; + CLEAR_A_RANK; + CLEAR_A_RANK; +#endif +} + + +static INLINE void +_InitializePawnHashEntry(IN OUT PAWN_HASH_ENTRY *pHash, + IN POSITION *pos) +/** + +Routine description: + +Parameters: + + PAWN_HASH_ENTRY *pHash, + POSITION *pos + +Return value: + + static INLINE void + +**/ +{ + memset(pHash, 0, sizeof(PAWN_HASH_ENTRY)); + pHash->u64Key = pos->u64PawnSig; +} + + +static INLINE void +_EvaluateCandidatePasser(IN POSITION *pos, + IN OUT PAWN_HASH_ENTRY *pHash, + IN COOR c) +/** + +Routine description: + +Parameters: + + POSITION *pos, + PAWN_HASH_ENTRY *pHash, + COOR c + +Return value: + + static INLINE + +**/ +{ + COOR c1, cSquare; + PIECE pSentry, pHelper; + ULONG uPawnFile = FILE(c) + 1; + BITBOARD bb; + ULONG uSentries, uHelpers; + ULONG uColor; + int d1; +#ifdef DEBUG + COOR cVerifySquare; + ULONG uVerifySentries; +#endif + + ASSERT(IS_ON_BOARD(c)); + ASSERT(RANK(c) >= 2); + ASSERT(RANK(c) <= 7); + pHelper = pos->rgSquare[c].pPiece; + ASSERT(IS_PAWN(pHelper)); + uColor = GET_COLOR(pHelper); + ASSERT(IS_VALID_COLOR(uColor)); + + if (pHash->uCountPerFile[FLIP(uColor)][uPawnFile] != 0) + { + ASSERT((pHash->bbPawnLocations[FLIP(uColor)] & BBFILE[FILE(c)]) != 0); + + // + // The only way a pawn can be a passer/candidate if the other + // side has a pawn on its same file is if that enemy pawn is + // behind it. This is a corner case but it is important to + // detect all passers. + // + switch(uColor) + { + case WHITE: + bb = pHash->bbPawnLocations[BLACK] & BBFILE[FILE(c)]; + ASSERT(bb); + while(IS_ON_BOARD(c1 = CoorFromBitBoardRank8ToRank1(&bb))) + { + ASSERT(FILE(c1) == FILE(c)); + if (c1 < c) return; + } + break; + case BLACK: + bb = pHash->bbPawnLocations[WHITE] & BBFILE[FILE(c)]; + ASSERT(bb); + while(IS_ON_BOARD(c1 = CoorFromBitBoardRank1ToRank8(&bb))) + { + ASSERT(FILE(c1) == FILE(c)); + if (c1 > c) return; + } + break; + } + } + + // + // Count FLIP(uColor)'s sentries and determine the location of the + // critical square. Note if there are no sentries then this + // pawn (on square c) is a passer already, not a candidate. + // + bb = pHash->bbPawnLocations[FLIP(uColor)] & BBADJACENT_FILES[FILE(c)]; + bb &= BBPRECEEDING_RANKS[(c & 0x70) >> 4][uColor]; + if (!bb) + { + ASSERT(CountBits(bb) == 0); + + // + // There are no sentries so this pawn is a passer. + // + pHash->bbPasserLocations[uColor] |= COOR_TO_BB(c); + ASSERT(CountBits(pHash->bbPasserLocations[uColor]) > 0); + ASSERT(CountBits(pHash->bbPasserLocations[uColor]) <= 8); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + PASSER_BY_RANK[uColor][RANK(c)], + "passed pawn"); + + // + // However, don't give doubled passers such a big bonus. + // + if (IS_PAWN(pos->rgSquare[c - 16 * g_iAhead[uColor]].pPiece)) + { + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + -(PASSER_BY_RANK[uColor][RANK(c)] / 2), + "doubled passer"); + } + return; + } + uSentries = CountBits(bb); + + // + // There's one or more sentry pawns so we'll look for helpers to + // decide if this pawn is a candidate passer. + // + if (uColor == WHITE) + { + pSentry = BLACK_PAWN; + cSquare = CoorFromBitBoardRank1ToRank8(&bb); + cSquare += 0x10; + } + else + { + pSentry = WHITE_PAWN; + cSquare = CoorFromBitBoardRank8ToRank1(&bb); + cSquare -= 0x10; + } + cSquare &= 0xF0; + cSquare |= FILE(c); + ASSERT(IS_ON_BOARD(cSquare)); + ASSERT(FILE(cSquare) == FILE(c)); + +#ifdef DEBUG + uVerifySentries = 0; + cVerifySquare = 0; + d1 = 16 * g_iAhead[uColor]; + c1 = c + d1; + do + { + if (IS_ON_BOARD(c1 - 1)) + { + if (pos->rgSquare[c1 - 1].pPiece == pSentry) + { + uVerifySentries++; + if (0 == cVerifySquare) + { + cVerifySquare = c1 - d1; + ASSERT(cVerifySquare == cSquare); + } + } + } + if (IS_ON_BOARD(c1 + 1)) + { + if (pos->rgSquare[c1 + 1].pPiece == pSentry) + { + uVerifySentries++; + if (0 == cVerifySquare) + { + cVerifySquare = c1 - d1; + ASSERT(cVerifySquare == cSquare); + } + } + } + c1 = c1 + d1; + } + while(!RANK8(c1) && !RANK1(c1)); + ASSERT(uVerifySentries == uSentries); +#endif + + // + // Note: we don't do this with bitboards because we want to not + // consider a pawn to be a potential passer if it can't safely + // advance to get into helper position. + // + // IDEA: scale the candidate passer bonus based on rank AND on + // the distance the helper(s) have to go to get into position. + // + uHelpers = 0; + d1 = 16 * g_iAhead[uColor]; + ASSERT(-d1 == 16 * g_iBehind[uColor]); + c1 = cSquare + 1 - d1; + if ((IS_ON_BOARD(c1)) && (pHash->uCountPerFile[uColor][FILE(c1) + 1])) + { + ASSERT(pHash->bbPawnLocations[uColor] & BBFILE[FILE(c1)]); + if (!(pos->rgSquare[c1 + 8].bvAttacks[FLIP(uColor)].uWholeThing) || + (pos->rgSquare[c1 + 8].bvAttacks[uColor].uWholeThing)) + { + // + // The square c1 the place a helper pawn must get to in + // order to aide the candidate past a sentry. + // + if (pos->rgSquare[c1].pPiece == pHelper) + { + uHelpers = 1; + goto do_left; + } + + // + // There is no helper pawn in the support position yet. + // See if one can get there. + // + c1 = c1 - d1; + while (IS_ON_BOARD(c1) && + ((!(pos->rgSquare[c1+8].bvAttacks[FLIP(uColor)].uWholeThing)) || + (pos->rgSquare[c1+8].bvAttacks[uColor].uWholeThing))) + { + if (pos->rgSquare[c1].pPiece == pHelper) + { + uHelpers = 1; + break; + } + else if (pos->rgSquare[c1].pPiece == pSentry) + { + break; + } + c1 = c1 - d1; + } + } + } + + do_left: + c1 = cSquare - 1 - d1; + if ((IS_ON_BOARD(c1)) && (pHash->uCountPerFile[uColor][FILE(c1) + 1])) + { + ASSERT(pHash->bbPawnLocations[uColor] & BBFILE[FILE(c1)]); + + if (!(pos->rgSquare[c1 + 8].bvAttacks[FLIP(uColor)].uWholeThing) || + (pos->rgSquare[c1 + 8].bvAttacks[uColor].uWholeThing)) + { + // + // The square c1 is the place a helper pawn must get to in + // order to aide the candidate. + // + if (pos->rgSquare[c1].pPiece == pHelper) + { + uHelpers++; + goto done_helpers; + } + + // + // There is no pawn in the left support position yet. See + // if one can get there. + // + c1 -= d1; + while (IS_ON_BOARD(c1) && + ((!(pos->rgSquare[c1+8].bvAttacks[FLIP(uColor)].uWholeThing)) || + (pos->rgSquare[c1 + 8].bvAttacks[uColor].uWholeThing))) + { + if (pos->rgSquare[c1].pPiece == pHelper) + { + uHelpers++; + break; + } + else if (pos->rgSquare[c1].pPiece == pSentry) + { + break; + } + c1 -= d1; + } + } + } + + done_helpers: + if ((uHelpers >= uSentries) || + ((pHash->uCountPerFile[uColor][uPawnFile + 1] + + pHash->uCountPerFile[uColor][uPawnFile - 1]) && + (((WHITE == uColor) && (RANK(c) > 5)) || + ((BLACK == uColor) && (RANK(c) < 4))))) + { + ASSERT(CANDIDATE_PASSER_BY_RANK[uColor][RANK(c)] > 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + CANDIDATE_PASSER_BY_RANK[uColor][RANK(c)], + "candidate passer"); + + // + // If the other side has no pieces then give this candidate an + // extra bonus. + // + if (pos->uNonPawnCount[FLIP(uColor)][0] == 1) + { + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + CANDIDATE_PASSER_BY_RANK[uColor][RANK(c)], + "candidate passer in endgame"); + } + } +} + +static void +_EvaluateConnectedSupportedOutsidePassers(IN POSITION *pos, + IN OUT PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + +Parameters: + + POSITION *pos, + PAWN_HASH_ENTRY *pHash + +Return value: + + void + +**/ +{ + ULONG uColor; + ULONG u, v; + COOR c; + COOR cLeftmostPasser, cRightmostPasser; + PIECE pFriend; + COOR cSupport; + BITBOARD bb; + static const INT iDelta[5] = + { + -1, +1, +17, +15, 0 + }; + + FOREACH_COLOR(uColor) + { + ASSERT(IS_VALID_COLOR(uColor)); + + if (pHash->bbPasserLocations[uColor]) + { + ASSERT(pos->uPawnCount[uColor] > 0); + pFriend = BLACK_PAWN | uColor; + cLeftmostPasser = cRightmostPasser = ILLEGAL_COOR; + for (u = A; u <= H; u++) + { + bb = pHash->bbPasserLocations[uColor] & BBFILE[u]; + if (bb != 0) + { + ASSERT(pHash->uCountPerFile[uColor][u+1] != 0); + while(IS_ON_BOARD(c = CoorFromBitBoardRank8ToRank1(&bb))) + { + // + // Keep track of leftmost/rightmost passer for + // outside passer code later on. + // + ASSERT(FILE(c) == u); + ASSERT(RANK(c) > 1); + ASSERT(RANK(c) < 8); + if (cLeftmostPasser == ILLEGAL_COOR) + { + cLeftmostPasser = c; + } + cRightmostPasser = c; + + v = 0; + while(iDelta[v] != 0) + { + cSupport = c + iDelta[v] * g_iBehind[uColor]; + if (IS_ON_BOARD(cSupport)) + { + if (pHash->bbPasserLocations[uColor] & + COOR_TO_BB(cSupport)) + { + ASSERT(CONNECTED_PASSERS_BY_RANK[uColor] + [RANK(c)] > 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + CONNECTED_PASSERS_BY_RANK[uColor] + [RANK(c)], + "connected passers"); + + // + // TODO: connected passers vs a R is + // strong. + // + } + else if (pos->rgSquare[cSupport].pPiece == + pFriend) + { + ASSERT(SUPPORTED_PASSER_BY_RANK[uColor] + [RANK(c)] > 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + SUPPORTED_PASSER_BY_RANK[uColor] + [RANK(c)], + "supported passer"); + } + } + v++; + } + } + } + } + +#ifdef DEBUG + ASSERT(IS_ON_BOARD(cLeftmostPasser)); + ASSERT(IS_ON_BOARD(cRightmostPasser)); + ASSERT(RANK(cLeftmostPasser) > 1); + ASSERT(RANK(cRightmostPasser) > 1); + ASSERT(RANK(cLeftmostPasser) < 8); + ASSERT(RANK(cRightmostPasser) < 8); + if (CountBits(pHash->bbPasserLocations[uColor]) == 1) + { + ASSERT(cLeftmostPasser == cRightmostPasser); + } +#endif + for (u = A; u <= D; u++) + { + if (pHash->uCountPerFile[FLIP(uColor)][u + 1] != 0) + { + ASSERT(pHash->bbPawnLocations[FLIP(uColor)] & BBFILE[u]); + if (!(pHash->bbPasserLocations[FLIP(uColor)] & BBFILE[u])) + { + break; + } + } + } + if (u > FILE(cLeftmostPasser)) + { + EVAL_TERM(uColor, + PAWN, + ILLEGAL_COOR, + pHash->iScore[uColor], + OUTSIDE_PASSER_BY_DISTANCE[u-FILE(cLeftmostPasser)], + "left outside passer"); + } + + for (u = H; u >= E; u--) + { + if (pHash->uCountPerFile[FLIP(uColor)][u + 1] != 0) + { + ASSERT(pHash->bbPawnLocations[FLIP(uColor)] & BBFILE[u]); + if (!(pHash->bbPasserLocations[FLIP(uColor)] & BBFILE[u])) + { + break; + } + } + } + if (u < FILE(cRightmostPasser)) + { + EVAL_TERM(uColor, + PAWN, + ILLEGAL_COOR, + pHash->iScore[uColor], + OUTSIDE_PASSER_BY_DISTANCE[FILE(cRightmostPasser)-u], + "right outside passer"); + } + } + } +} + + +#define PAWN_ATTACK_BLACK_DELTA (+15) +#define PAWN_ATTACK_WHITE_DELTA (-17) + +static void +_PopulatePawnAttackBits(IN OUT POSITION *pos) +/** + +Routine description: + + Populate the attack table with pawn bits. + +Parameters: + + POSITION *pos : the board + +Return value: + + void + +**/ +{ + ULONG u; + COOR c; + COOR cAttack; + + // + // IDEA: combine clearing and initial population somehow? + // + // r - - - - - - l : only check L- and R- + // r - - - - - - l + // R A A A A A A L + // R A A A A A A L + // R A A A A A A L + // R A A A A A A L + // r - - - - - - l + // r - - - - - - l : only check L+ and R+ + _ClearAttackTables(pos); + + ASSERT(pos->uPawnCount[BLACK] <= 8); + for (u = 0; + u < pos->uPawnCount[BLACK]; + u++) + { + c = pos->cPawns[BLACK][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(pos->rgSquare[c].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[c].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[c].pPiece) == BLACK); + + // + // IDEA: These IS_ON_BOARD checks can be removed by a lookup table. + // + cAttack = c + PAWN_ATTACK_BLACK_DELTA; + if (IS_ON_BOARD(cAttack)) + { + ASSERT((cAttack + 8) == (cAttack|8)); + ASSERT(!IS_ON_BOARD(cAttack|8)); + pos->rgSquare[cAttack|8].bvAttacks[BLACK].small.uPawn = 1; + } + cAttack += 2; + if (IS_ON_BOARD(cAttack)) + { + ASSERT((cAttack + 8) == (cAttack|8)); + cAttack |= 8; + ASSERT(!IS_ON_BOARD(cAttack)); + pos->rgSquare[cAttack].bvAttacks[BLACK].small.uPawn = 1; + } + } + + ASSERT(pos->uPawnCount[WHITE] <= 8); + for (u = 0; + u < pos->uPawnCount[WHITE]; + u++) + { + c = pos->cPawns[WHITE][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(pos->rgSquare[c].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[c].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[c].pPiece) == WHITE); + + cAttack = c + PAWN_ATTACK_WHITE_DELTA; + if (IS_ON_BOARD(cAttack)) + { + ASSERT((cAttack + 8) == (cAttack|8)); + ASSERT(!IS_ON_BOARD(cAttack|8)); + pos->rgSquare[cAttack|8].bvAttacks[WHITE].small.uPawn = 1; + } + cAttack += 2; + if (IS_ON_BOARD(cAttack)) + { + ASSERT((cAttack + 8) == (cAttack|8)); + cAttack |= 8; + ASSERT(!IS_ON_BOARD(cAttack)); + pos->rgSquare[cAttack].bvAttacks[WHITE].small.uPawn = 1; + } + } +} + + +static PAWN_HASH_ENTRY * +_EvalPawns(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + OUT FLAG *pfDeferred) +/** + +Routine description: + + Evaluate pawn structures; return a ptr to a pawn hash entry. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : the searcher thread context + +Return value: + + PAWN_HASH_ENTRY * + +**/ +{ + static ULONG uUnmovedRank[2] = { 0x10, 0x60 }; + POSITION *pos = &ctx->sPosition; + PAWN_HASH_ENTRY *pHash; + COOR c, cSquare; + PIECE p; + ULONG uIsolated[2]; + ULONG uDoubled[2]; + SCORE iDuos[2]; + ULONG u, uPawnFile; + ULONG uColor; + ULONG uUnsupportable; + BITBOARD bb; + int d1; +#ifdef DEBUG + SCORE t; +#endif + + // + // Now, look up the hash entry for this position. + // + INC(ctx->sCounters.pawnhash.u64Probes); + pHash = PawnHashLookup(ctx); + ASSERT(NULL != pHash); + if (pHash->u64Key == pos->u64PawnSig) + { + *pfDeferred = TRUE; + INC(ctx->sCounters.pawnhash.u64Hits); + return(pHash); + } + + // + // We need the attack table to evaluate the pawns... and we missed + // the hash table so we have to populate it now. Can't defer this + // one. :( + // + *pfDeferred = FALSE; + _InitializePawnHashEntry(pHash, pos); + _PopulatePawnAttackBits(pos); + uIsolated[BLACK] = uIsolated[WHITE] = 0; + uDoubled[BLACK] = uDoubled[WHITE] = 0; + iDuos[BLACK] = iDuos[WHITE] = 0; + + // + // First pass + // + FOREACH_COLOR(uColor) + { + ASSERT(IS_VALID_COLOR(uColor)); + ASSERT(pos->uPawnCount[uColor] <= 8); + + d1 = 16 * g_iAhead[uColor]; + for (u = 0; + u < pos->uPawnCount[uColor]; + u++) + { + c = pos->cPawns[uColor][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(pos->rgSquare[c].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[c].pPiece)); + uPawnFile = FILE(c) + 1; + ASSERT((1 <= uPawnFile) && (uPawnFile <= 8)); + + // + // Update files counter + // + ASSERT(pHash->uCountPerFile[uColor][uPawnFile] < 6); + pHash->uCountPerFile[uColor][uPawnFile]++; + + // + // Update bitboard bit + // + ASSERT(CountBits(pHash->bbPawnLocations[uColor] & + BBFILE[uPawnFile-1]) < 6); + ASSERT((pHash->bbPawnLocations[uColor] & COOR_TO_BB(c)) == 0); + pHash->bbPawnLocations[uColor] |= COOR_TO_BB(c); + ASSERT(CountBits(pHash->bbPawnLocations[uColor] & + BBFILE[uPawnFile-1]) == + pHash->uCountPerFile[uColor][uPawnFile]); + + // + // Count unmoved pawns + // + pHash->uNumUnmovedPawns[uColor] += + ((c & 0xF0) == uUnmovedRank[uColor]); + ASSERT(pHash->uNumUnmovedPawns[uColor] <= 8); + + // + // Detect rammed and other stationary pawns. + // + cSquare = c + d1; + ASSERT(IS_ON_BOARD(cSquare)); + p = pos->rgSquare[cSquare].pPiece; + if (IS_PAWN(p)) + { + pHash->bbStationaryPawns[uColor] |= COOR_TO_BB(c); + ASSERT(CountBits(pHash->bbStationaryPawns[uColor]) <= 8); + pHash->uNumRammedPawns += OPPOSITE_COLORS(p, uColor); + ASSERT(pHash->uNumRammedPawns <= 16); + } + + // + // Give central pawns a small bonus; penalize rook pawns: + // + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + PAWN_CENTRALITY_BONUS[c], + "centrality"); + } + } + + // + // We counted rammed pawns twice (once for the black pawn and once + // for the white one). Fix this now. + // + ASSERT(!(pHash->uNumRammedPawns & 1)); + pHash->uNumRammedPawns /= 2; + + // + // Second pass + // + FOREACH_COLOR(uColor) + { + ASSERT(IS_VALID_COLOR(uColor)); + ASSERT(pos->uPawnCount[uColor] <= 8); + ASSERT(CountBits(pHash->bbPawnLocations[uColor]) <= 8); + + d1 = 16 * g_iAhead[uColor]; + for (u = 0; + u < pos->uPawnCount[uColor]; + u++) + { + c = pos->cPawns[uColor][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_PAWN(pos->rgSquare[c].pPiece)); + ASSERT((1 < RANK(c)) && (RANK(c) < 8)); + + // + // Find weak pawns... pawns that are isolated are weak as + // are pawns that have advanced beyond their support. + // Both of these can tie up one or more pieces in order to + // defend them. + // + uUnsupportable = 0; + uPawnFile = FILE(c) - 1; + if (pHash->uCountPerFile[uColor][uPawnFile + 1] > 0) + { + bb = (pHash->bbPawnLocations[uColor] & + BBFILE[uPawnFile] & + BBADJACENT_RANKS[RANK(c)]); + if (!bb) + { + bb = (pHash->bbPawnLocations[FLIP(uColor)] & + BBFILE[uPawnFile]); + while(IS_ON_BOARD(cSquare = + CoorFromBitBoardRank8ToRank1(&bb))) + { + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + if (uColor == WHITE) + { + if ((cSquare & 0xF0) >= (c & 0xF0)) + { + ASSERT(RANK(cSquare) <= RANK(c)); + uUnsupportable = 1; + break; + } + } + else + { + ASSERT(uColor == BLACK); + if ((cSquare & 0xF0) <= (c & 0xF0)) + { + ASSERT(RANK(cSquare) >= RANK(c)); + uUnsupportable = 1; + break; + } + } + } + } + } + else + { + uUnsupportable = 1; // no friend pawn on that file + } + if (0 == uUnsupportable) + { + goto fast_skip; + } + ASSERT(1 == uUnsupportable); + + uPawnFile = FILE(c) + 1; + if (pHash->uCountPerFile[uColor][uPawnFile + 1] > 0) + { + bb = (pHash->bbPawnLocations[uColor] & + BBFILE[uPawnFile] & + BBADJACENT_RANKS[RANK(c)]); + if (!bb) + { + bb = (pHash->bbPawnLocations[FLIP(uColor)] & + BBFILE[uPawnFile]); + while(IS_ON_BOARD(cSquare = + CoorFromBitBoardRank8ToRank1(&bb))) + { + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + if (uColor == WHITE) + { + if ((cSquare & 0xF0) >= (c & 0xF0)) + { + ASSERT(RANK(cSquare) <= RANK(c)); + uUnsupportable = 2; + break; + } + } + else + { + ASSERT(uColor == BLACK); + if ((cSquare & 0xF0) <= (c & 0xF0)) + { + ASSERT(RANK(cSquare) >= RANK(c)); + uUnsupportable = 2; + break; + } + } + } + } + } + else + { + uUnsupportable = 2; + } + + // + // If this pawn is not supportable from either side then + // it is either isolated or has been pushed too far ahead + // of its support. Either way it's a target -- penalize + // it. + // + if (2 == uUnsupportable) + { + uPawnFile = FILE(c) + 1; + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + ISOLATED_PAWN_BY_PAWNFILE[uPawnFile], + "target/isolated pawn"); + + // + // Isolated + exposed? Extra penalty. + // + ASSERT(ISOLATED_EXPOSED_PAWN < 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + ((pHash->uCountPerFile[FLIP(uColor)][uPawnFile]==0)* + ISOLATED_EXPOSED_PAWN), + "exposed target"); + + // + // Exponential penalty term + // + uIsolated[uColor] += 1; + ASSERT(uIsolated[uColor] > 0); + ASSERT(uIsolated[uColor] <= 8); + + // + // Isolated + doubled? Extra penalty. + // + ASSERT(ISOLATED_DOUBLED_PAWN < 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + ((pHash->uCountPerFile[uColor][uPawnFile] > 1) * + ISOLATED_DOUBLED_PAWN), + "doubled + target"); + } + + fast_skip: + uPawnFile = FILE(c) + 1; + ASSERT((1 <= uPawnFile) && (uPawnFile <= 8)); + ASSERT(CountBits(pHash->bbPawnLocations[uColor] & BBFILE[FILE(c)]) + == pHash->uCountPerFile[uColor][uPawnFile]); + + // + // Keep count of doubled pawns + // + uDoubled[uColor] += (pHash->uCountPerFile[uColor][uPawnFile] > 1); + ASSERT((0 <= uDoubled[uColor]) && (uDoubled[uColor] <= 8)); + + // + // We can detect pawn duos (triads, etc...) and backward pawns + // by considering the control of the pawn's stopsquare. + // + cSquare = c + d1; + ASSERT(IS_ON_BOARD(cSquare)); + ASSERT((cSquare + 8) == (cSquare | 8)); + if (pos->rgSquare[cSquare|8].bvAttacks[uColor].uWholeThing) + { + // + // Count pawn duos. See "Pawn Power in Chess" pp 10-16 + // +#ifdef DEBUG + t = ((uColor * RANK(cSquare)) + + (FLIP(uColor) * (9 - RANK(cSquare)))); + if (uColor == WHITE) + { + ASSERT(t == RANK(cSquare)); + } + else + { + ASSERT(uColor == BLACK); + ASSERT(t == (9 - RANK(cSquare))); + } +#endif + iDuos[uColor] += ((uColor * RANK(cSquare)) + + (FLIP(uColor) * (9 - RANK(cSquare)))); + ASSERT(iDuos[uColor] <= (7 * 8)); + } + else if (pos->rgSquare[cSquare|8].bvAttacks[FLIP(uColor)].uWholeThing) + { + // + // Detect backwards pawns. See "Pawn Power in Chess" pp 25-27 + // + if (!IS_PAWN(pos->rgSquare[cSquare].pPiece)) + { + p = (BLACK_PAWN | uColor); + if (((WHITE == uColor) && (RANK(c) < 4)) || + ((BLACK == uColor) && (RANK(c) > 5))) + { + if ((IS_ON_BOARD(cSquare - 1) && + pos->rgSquare[cSquare - 1].pPiece == p) || + (IS_ON_BOARD(cSquare + 1) && + pos->rgSquare[cSquare + 1].pPiece == p)) + { + // + // The pawn at c is backward. Determine + // whether it is shielded or exposed. + // + pHash->bbStationaryPawns[uColor] |= COOR_TO_BB(c); + ASSERT(CountBits(pHash->bbStationaryPawns[uColor]) + <= 8); + if (pHash->uCountPerFile[FLIP(uColor)][uPawnFile]) + { + ASSERT(BACKWARD_SHIELDED_BY_LOCATION[c] < 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + BACKWARD_SHIELDED_BY_LOCATION[c], + "shielded backward pawn"); + } + else + { + ASSERT(BACKWARD_EXPOSED_BY_LOCATION[c] < 0); + EVAL_TERM(uColor, + PAWN, + c, + pHash->iScore[uColor], + BACKWARD_EXPOSED_BY_LOCATION[c], + "exposed backward pawn"); + } + } + } + } + // + // TODO: Think about backward doubled pawns; read Kauffman's + // paper "All About Doubled Pawns". + // + } + + // + // Handle passers / candidate passers + // + _EvaluateCandidatePasser(pos, pHash, c); + } + } + + // + // Reward pawn duos, see "Pawn Power in Chess" pp. 10-16 + // + ASSERT(iDuos[WHITE] >= 0); + ASSERT(iDuos[WHITE] <= 56); + ASSERT(iDuos[BLACK] >= 0); + ASSERT(iDuos[BLACK] <= 56); + EVAL_TERM(WHITE, + PAWN, + ILLEGAL_COOR, + pHash->iScore[WHITE], + iDuos[WHITE] / 2, + "pawn duos"); + EVAL_TERM(BLACK, + PAWN, + ILLEGAL_COOR, + pHash->iScore[BLACK], + iDuos[BLACK] / 2, + "pawn duos"); + + // + // The penalty for doubled pawns is scaled based on two primary + // factors: the presence of major pieces for the side with doubled + // pawns and the number of doubled pawns on the board. The + // presence of major pieces makes the doubled pawns less severe + // while the presence of many doubled pawns makes the penalty for + // each more severe. + // + ASSERT((uDoubled[WHITE] >= 0) && (uDoubled[WHITE] <= 8)); + ASSERT((uDoubled[BLACK] >= 0) && (uDoubled[BLACK] <= 8)); + u = pos->uNonPawnCount[BLACK][ROOK] + pos->uNonPawnCount[BLACK][QUEEN] * 2; + u = MINU(u, 3); + EVAL_TERM(BLACK, + PAWN, + ILLEGAL_COOR, + pHash->iScore[BLACK], + DOUBLED_PAWN_PENALTY_BY_COUNT[u][uDoubled[BLACK]], + "exponential doubled"); + u = pos->uNonPawnCount[WHITE][ROOK] + pos->uNonPawnCount[WHITE][QUEEN] * 2; + u = MINU(u, 3); + EVAL_TERM(WHITE, + PAWN, + ILLEGAL_COOR, + pHash->iScore[WHITE], + DOUBLED_PAWN_PENALTY_BY_COUNT[u][uDoubled[WHITE]], + "exponential doubled"); + + ASSERT(uIsolated[WHITE] >= 0); + ASSERT(uIsolated[WHITE] <= 8); + ASSERT(uIsolated[BLACK] >= 0); + ASSERT(uIsolated[BLACK] <= 8); + EVAL_TERM(BLACK, + PAWN, + ILLEGAL_COOR, + pHash->iScore[BLACK], + ISOLATED_PAWN_PENALTY_BY_COUNT[uIsolated[BLACK]], + "exponential isolated"); + EVAL_TERM(WHITE, + PAWN, + ILLEGAL_COOR, + pHash->iScore[WHITE], + ISOLATED_PAWN_PENALTY_BY_COUNT[uIsolated[WHITE]], + "exponential isolated"); + + // + // Look for connected, supported and outside passed pawns to give + // extra bonuses. + // + _EvaluateConnectedSupportedOutsidePassers(pos, pHash); + + // + // TODO: recognize quartgrips and stonewalls + // + return(pHash); +} + + +ULONG +CountKingSafetyDefects(IN OUT POSITION *pos, + IN ULONG uSide) +/** + +Routine description: + + Determine how many defects uSide's king position has _quickly_. + TODO: add more knowledge as cheaply as possible... + +Parameters: + + POSITION *pos, + ULONG uSide + +Return value: + + ULONG + +**/ +{ + ULONG uCounter = 0; + ULONG xSide = FLIP(uSide); + COOR cKing; + COOR c; + int i; + PIECE p; + ULONG u; + + // + // Don't count king safety defects if the real eval code in + // _EvalKing would not... + // + if (pos->uNonPawnMaterial[xSide] < DO_KING_SAFETY_THRESHOLD) { + return 0; + } + + cKing = pos->cNonPawns[uSide][0]; + uCounter = KING_INITIAL_COUNTER_BY_LOCATION[uSide][cKing] >> 1; + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + ASSERT(pos->rgSquare[cKing].uIndex == 0); + ASSERT(IS_ON_BOARD(cKing)); + ASSERT(GET_COLOR(pos->rgSquare[cKing].pPiece) == uSide); + + // + // Make sure cKing - 1, cKing and cKing + 1 are on the board + // + cKing += (!IS_ON_BOARD(cKing - 1)); + cKing -= (!IS_ON_BOARD(cKing + 1)); + ASSERT(IS_ON_BOARD(cKing)); + ASSERT(IS_ON_BOARD(cKing + 1)); + ASSERT(IS_ON_BOARD(cKing - 1)); + + // + // Consider all enemy pieces except the king (not including pawns) + // + for (u = 1; + u < pos->uNonPawnCount[xSide][0]; + u++) + { + c = pos->cNonPawns[xSide][u]; + ASSERT(IS_ON_BOARD(c)); + i = (int)c - (int)(cKing + 1); + ASSERT((i >= -128) && (i <= 125)); + p = pos->rgSquare[c].pPiece; + ASSERT(pos->rgSquare[c].uIndex == u); + ASSERT(!IS_KING(p)); + ASSERT(GET_COLOR(p) == xSide); + p = 1 << PIECE_TYPE(p); + + uCounter += ((i == 0) | (i == -2) | + ((CHECK_VECTOR_WITH_INDEX(i, xSide) & p) != 0) | + ((CHECK_VECTOR_WITH_INDEX(i + 1, xSide) & p) != 0) | + ((CHECK_VECTOR_WITH_INDEX(i + 2, xSide) & p) != 0)); + } + ASSERT(uCounter < 15); + + // Save the number of enemy pieces pointing at this king for later use. + pos->uPiecesPointingAtKing[uSide] = + (uCounter - (KING_INITIAL_COUNTER_BY_LOCATION[uSide][cKing] >> 1)); + return uCounter; +} + + +static void +_QuicklyEstimateKingSafetyTerm(IN POSITION *pos, + IN OUT SCORE *piAlphaMargin, + IN OUT SCORE *piBetaMargin) +/** + +Routine description: + + Before doing an early lazy eval, look at the position and try to + quickly see if there is a large king safety positional component + to the score. + +Parameters: + + POSITION *pos + +Return value: + + void + +**/ +{ + // + // IDEA: make this stuff dynamic like ctx->uPositional + // + static const SCORE iScoreByDefectCount[15] = { + 33, 50, 88, 146, 215, 245, 280, 430, 550, 630, 646, 646, 646, 646, 646 + }; + SCORE iPenaltyEst[2]; + SCORE iRet; + + ASSERT(CountKingSafetyDefects(pos, pos->uToMove) < 15); + iPenaltyEst[WHITE] = + iScoreByDefectCount[CountKingSafetyDefects(pos, WHITE)]; + ASSERT(iPenaltyEst[WHITE] > 0); + + ASSERT(CountKingSafetyDefects(pos, BLACK) < 15); + iPenaltyEst[BLACK] = + iScoreByDefectCount[CountKingSafetyDefects(pos, BLACK)]; + ASSERT(iPenaltyEst[BLACK] > 0); + + // + // For the beta margin, assume our king safety penalty will stand + // and our opponents will be less severe than we guess... net bonus + // to them / our bonus not as high. + // + iRet = iPenaltyEst[pos->uToMove] - iPenaltyEst[FLIP(pos->uToMove)] / 2; + iRet = MAX0(iRet); + ASSERT(iRet >= 0); + *piBetaMargin += iRet; + + // + // For the alpha margin, assume our king safety penalty will not + // be too bad and our opponents will be as bad as we guess... net + // bonus to us / their offsetting bonus not as high. + // + iRet = iPenaltyEst[FLIP(pos->uToMove)] - iPenaltyEst[pos->uToMove] / 2; + iRet = MAX0(iRet); + ASSERT(iRet >= 0); + *piAlphaMargin += iRet; +} + + +static void +_QuicklyEstimatePasserBonuses(POSITION *pos, + PAWN_HASH_ENTRY *pHash, + SCORE *piAlphaMargin, + SCORE *piBetaMargin) +{ + SCORE iBonusEst[2] = {0, 0}; + SCORE iRet; + ULONG u; + + // + // Guess about the passer bonuses + // + if (pHash->bbPasserLocations[WHITE]) + { + u = pos->uNonPawnMaterial[BLACK] - VALUE_KING; + u /= VALUE_PAWN; + u = MINU(31, u); + ASSERT(PASSER_BONUS_AS_MATERIAL_COMES_OFF[u] >= 0); + iBonusEst[WHITE] = + (CountBits(pHash->bbPasserLocations[WHITE]) * + PASSER_BONUS_AS_MATERIAL_COMES_OFF[u]); + } + if (pHash->bbPasserLocations[BLACK]) + { + u = pos->uNonPawnMaterial[WHITE] - VALUE_KING; + u /= VALUE_PAWN; + u = MINU(31, u); + ASSERT(PASSER_BONUS_AS_MATERIAL_COMES_OFF[u] >= 0); + iBonusEst[BLACK] = + (CountBits(pHash->bbPasserLocations[BLACK]) * + PASSER_BONUS_AS_MATERIAL_COMES_OFF[u]); + } + + // + // For the beta margin, assume our passer bonus gets reduced and + // our opponent's is enhanced... net bonus to them / our bonus + // not as high. + // + iRet = iBonusEst[pos->uToMove] / 2 - iBonusEst[FLIP(pos->uToMove)]; + iRet = MAX0(iRet); + *piBetaMargin += iRet; + + // + // For the alpha bonus, assume our passer bonus gets doubled and + // our opponent's is reduced. Net bonus to us / their bonus not + // as high. + // + iRet = iBonusEst[pos->uToMove] - iBonusEst[FLIP(pos->uToMove)] / 2; + iRet = MAX0(iRet); + *piAlphaMargin += iRet; +} + + +static void +_InvalidEvaluator(UNUSED POSITION *pos, + UNUSED COOR c, + UNUSED PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + + This code should never be called + +Parameters: + + POSITION *pos, + COOR c, + PAWN_HASH_ENTRY *pHash, + +Return value: + + void + +**/ +{ + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +} + +// +// ====================================================================== +// + +static FLAG FASTCALL +_InvalidMobilityHelper(UNUSED POSITION *pos, + UNUSED COOR c, + UNUSED ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + + This code should never be called + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + return(TRUE); +} + +// ---------------------------------------------------------------------- + +static FLAG FASTCALL +_BMinorToEnemyLess(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + + Consider a black minor (knight | bishop) taking an enemy pawn + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL : always TRUE, stop scanning in this direction + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(!IS_EMPTY(p)); + ASSERT(PIECE_VALUE(p) < VALUE_BISHOP); + ASSERT(!IS_EMPTY(pMinor)); + ASSERT(IS_PAWN(p)); + ASSERT(IS_BISHOP(pMinor) || IS_KNIGHT(pMinor)); + ASSERT(OPPOSITE_COLORS(p, pMinor)); + ASSERT(GET_COLOR(pMinor) == BLACK); +#endif + *puMobility += (!UNSAFE_FOR_MINOR(pos->rgSquare[c|8].bvAttacks[WHITE])); + ASSERT(*puMobility <= 8); + return(TRUE); // stop scanning this dir +} + +static FLAG FASTCALL +_WMinorToEnemyLess(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_PAWN(p)); + ASSERT(PIECE_VALUE(p) < VALUE_BISHOP); + ASSERT(!IS_EMPTY(pMinor)); + ASSERT(IS_BISHOP(pMinor) || IS_KNIGHT(pMinor)); + ASSERT(OPPOSITE_COLORS(p, pMinor)); + ASSERT(GET_COLOR(pMinor) == WHITE); +#endif + *puMobility += (!UNSAFE_FOR_MINOR(pos->rgSquare[c|8].bvAttacks[BLACK])); + ASSERT(*puMobility <= 8); + return(TRUE); // stop scanning this dir +} + +static FLAG FASTCALL +_WRookToEnemyLess(POSITION *pos, + COOR c, + ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ROOK(pRook)); + ASSERT(!IS_EMPTY(p)); + ASSERT(OPPOSITE_COLORS(p, pRook)); + ASSERT(PIECE_VALUE(p) < VALUE_ROOK); + ASSERT(WHITE == GET_COLOR(pRook)); +#endif + *puMobility += (!UNSAFE_FOR_ROOK(pos->rgSquare[c|8].bvAttacks[BLACK])); + ASSERT(*puMobility <= 7); + return(TRUE); // stop scanning this dir +} + +static FLAG FASTCALL +_BRookToEnemyLess(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_ROOK(pRook)); + ASSERT(OPPOSITE_COLORS(p, pRook)); + ASSERT(PIECE_VALUE(p) < VALUE_ROOK); + ASSERT(BLACK == GET_COLOR(pRook)); +#endif + *puMobility += (!UNSAFE_FOR_ROOK(pos->rgSquare[c|8].bvAttacks[WHITE])); + ASSERT(*puMobility <= 7); + return(TRUE); // stop scanning this dir +} + + +static FLAG FASTCALL +_BQueenToEnemyLess(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(PIECE_VALUE(p) < VALUE_QUEEN); + ASSERT(GET_COLOR(pQueen) == BLACK); + ASSERT(OPPOSITE_COLORS(pQueen, p)); +#endif + *puMobility += (!UNSAFE_FOR_QUEEN(pos->rgSquare[c|8].bvAttacks[WHITE])); + ASSERT(*puMobility <= 27); + return(TRUE); // stop scanning this dir +} + + +static FLAG FASTCALL +_WQueenToEnemyLess(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(PIECE_VALUE(p) < VALUE_QUEEN); + ASSERT(GET_COLOR(pQueen) == WHITE); + ASSERT(OPPOSITE_COLORS(pQueen, p)); +#endif + *puMobility += (!UNSAFE_FOR_QUEEN(pos->rgSquare[c|8].bvAttacks[BLACK])); + ASSERT(*puMobility <= 27); + return(TRUE); // stop scanning this dir +} + +// ---------------------------------------------------------------------- + +static FLAG FASTCALL +_EMinorToEnemySame(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(!IS_EMPTY(p)); + ASSERT(!IS_EMPTY(pMinor)); + ASSERT(OPPOSITE_COLORS(p, pMinor)); + + if (IS_BISHOP(pMinor)) + { + ASSERT(PIECE_VALUE(p) == VALUE_BISHOP); + } + else + { + ASSERT(IS_KNIGHT(pMinor)); + ASSERT(PIECE_VALUE(p) >= VALUE_KNIGHT); + } +#endif + *puMobility += 1; + ASSERT(*puMobility <= 8); + return(TRUE); // stop scanning this dir +} + + +static FLAG FASTCALL +_ERookToEnemySame(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_ROOK(pRook)); + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_ROOK(p)); + ASSERT(OPPOSITE_COLORS(p, pRook)); +#endif + *puMobility += 1; + ASSERT(*puMobility <= 7); + return(TRUE); // stop scanning this dir +} + + +static FLAG FASTCALL +_EQueenToEnemyGreaterEqual(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(!IS_EMPTY(p)); + ASSERT(PIECE_VALUE(p) >= VALUE_QUEEN); + ASSERT(OPPOSITE_COLORS(pQueen, p)); +#endif + *puMobility += 1; + ASSERT(*puMobility <= 27); + return(TRUE); // stop scanning this dir +} + +// ---------------------------------------------------------------------- + +static FLAG FASTCALL +_EMinorToEnemyGreater(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(!IS_EMPTY(p)); + ASSERT(PIECE_VALUE(p) > VALUE_BISHOP); + ASSERT(IS_BISHOP(pMinor) || IS_KNIGHT(pMinor)); + ASSERT(OPPOSITE_COLORS(p, pMinor)); +#endif + *puMobility += 1; + ASSERT(*puMobility <= 8); + *puBit = MINOR_XRAY_BIT; + return(FALSE); // keep scanning this dir +} + +static FLAG FASTCALL +_ERookToEnemyGreater(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_ROOK(pRook)); + ASSERT(!IS_EMPTY(p)); + ASSERT(OPPOSITE_COLORS(p, pRook)); + ASSERT(PIECE_VALUE(p) > VALUE_ROOK); +#endif + *puMobility += 1; + ASSERT(*puMobility <= 7); + *puBit = ROOK_XRAY_BIT; + return(FALSE); // keep scanning this dir +} + +// ---------------------------------------------------------------------- + +static FLAG FASTCALL +_AnythingToFriendNoXray(IN POSITION *pos, + IN COOR c, + UNUSED ULONG *puMobility, + UNUSED ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + COOR cMover = pos->cPiece; + PIECE pMover = pos->rgSquare[cMover].pPiece; + PIECE pFriend = pos->rgSquare[c].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(cMover)); + ASSERT(!IS_EMPTY(pFriend)); + ASSERT(!IS_EMPTY(pMover)); + ASSERT(GET_COLOR(pMover) == GET_COLOR(pFriend)); + if (IS_BISHOP(pMover)) + { + ASSERT(!IS_BISHOP(pFriend)); + ASSERT(!IS_QUEEN(pFriend)); + } + else if (IS_ROOK(pMover)) + { + ASSERT(!IS_QUEEN(pFriend)); + ASSERT(!IS_ROOK(pFriend)); + } + else if (IS_QUEEN(pMover)) + { + ASSERT(!IS_BISHOP(pFriend)); + ASSERT(!IS_ROOK(pFriend)); + ASSERT(!IS_QUEEN(pFriend)); + } +#endif + return(TRUE); // stop scanning this dir +} + +// ---------------------------------------------------------------------- + +static FLAG FASTCALL +_EMinorToFriendXray(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(!IS_EMPTY(p)); + ASSERT(!IS_EMPTY(pMinor)); + ASSERT(IS_BISHOP(pMinor)); + ASSERT(GET_COLOR(p) == GET_COLOR(pMinor)); +#endif + *puBit = MINOR_XRAY_BIT; + return(FALSE); +} + +static FLAG FASTCALL +_BRookToFriendRook(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ + COOR cRook = pos->cPiece; + FLAG fHoriz = ((c & 0xF0) == (cRook & 0xF0)); +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[cRook].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(cRook)); + ASSERT(IS_ROOK(pRook)); + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_ROOK(p)); + ASSERT(GET_COLOR(p) == GET_COLOR(pRook)); + ASSERT(GET_COLOR(p) == BLACK); + ASSERT((fHoriz && (RANK(c) == RANK(pos->cPiece))) || + (!fHoriz && (FILE(c) == FILE(pos->cPiece)))); +#endif + EVAL_TERM(BLACK, + ROOK, + c, + pos->iScore[BLACK], + (ROOK_CONNECTED_HORIZ * fHoriz + + ROOK_CONNECTED_VERT * FLIP(fHoriz)), + "rook connected"); + *puBit = ROOK_XRAY_BIT; + return(FALSE); +} + + +static FLAG FASTCALL +_WRookToFriendRook(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ + COOR cRook = pos->cPiece; + FLAG fHoriz = ((c & 0xF0) == (cRook & 0xF0)); +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[cRook].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(cRook)); + ASSERT(IS_ROOK(pRook)); + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_ROOK(p)); + ASSERT(GET_COLOR(p) == GET_COLOR(pRook)); + ASSERT(GET_COLOR(p) == WHITE); + ASSERT((fHoriz && (RANK(c) == RANK(pos->cPiece))) || + (!fHoriz && (FILE(c) == FILE(pos->cPiece)))); +#endif + EVAL_TERM(WHITE, + ROOK, + c, + pos->iScore[WHITE], + (ROOK_CONNECTED_HORIZ * fHoriz + + ROOK_CONNECTED_VERT * FLIP(fHoriz)), + "rook connected"); + *puBit = ROOK_XRAY_BIT; + return(FALSE); +} + + +static FLAG FASTCALL +_ERookToFriendQueen(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_ROOK(pRook)); + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_QUEEN(p)); + ASSERT(GET_COLOR(p) == GET_COLOR(pRook)); +#endif + *puBit = ROOK_XRAY_BIT; + return(FALSE); +} + +static FLAG FASTCALL +_EQueenToFriendBishop(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ + COOR cQueen = pos->cPiece; +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[cQueen].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(cQueen)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(IS_BISHOP(p)); + ASSERT(GET_COLOR(p) == GET_COLOR(pQueen)); +#endif + *puBit = QUEEN_XRAY_BIT; + return((((c & 0xF0) == (cQueen & 0xF0)) || + ((c & 0x0F) == (cQueen & 0x0F)))); +} + + +static FLAG FASTCALL +_EQueenToFriendRook(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ + COOR cQueen = pos->cPiece; +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[cQueen].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(cQueen)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(IS_ROOK(p)); + ASSERT(GET_COLOR(p) == GET_COLOR(pQueen)); +#endif + *puBit = QUEEN_XRAY_BIT; + return(FLIP((((c & 0xF0) == (cQueen & 0xF0)) || + ((c & 0x0F) == (cQueen & 0x0F))))); +} + + +static FLAG FASTCALL +_EQueenToFriendQueen(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + COOR cQueen = pos->cPiece; + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[cQueen].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(cQueen)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(IS_QUEEN(p)); + ASSERT(GET_COLOR(p) == GET_COLOR(pQueen)); +#endif + *puBit = QUEEN_XRAY_BIT; + return(FALSE); +} + + +// ---------------------------------------------------------------------- + +static FLAG FASTCALL +_BMinorToEmpty(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(IS_EMPTY(p)); + ASSERT(!IS_EMPTY(pMinor)); + ASSERT(IS_BISHOP(pMinor) || IS_KNIGHT(pMinor)); + ASSERT(GET_COLOR(pMinor) == BLACK); +#endif + *puMobility += (!UNSAFE_FOR_MINOR(pos->rgSquare[c|8].bvAttacks[WHITE])); + ASSERT(*puMobility <= 8); + return(FALSE); +} + +static FLAG FASTCALL +_WMinorToEmpty(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pMinor = pos->rgSquare[pos->cPiece].pPiece; + PIECE p = pos->rgSquare[c].pPiece; + + ASSERT(IS_EMPTY(p)); + ASSERT(!IS_EMPTY(pMinor)); + ASSERT(IS_BISHOP(pMinor) || IS_KNIGHT(pMinor)); + ASSERT(GET_COLOR(pMinor) == WHITE); +#endif + *puMobility += (!UNSAFE_FOR_MINOR(pos->rgSquare[c|8].bvAttacks[BLACK])); + ASSERT(*puMobility <= 8); + return(FALSE); +} + +static FLAG FASTCALL +_WRookToEmpty(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_ROOK(pRook)); + ASSERT(IS_EMPTY(p)); + ASSERT(GET_COLOR(pRook) == WHITE); +#endif + *puMobility += (!UNSAFE_FOR_ROOK(pos->rgSquare[c|8].bvAttacks[BLACK])); + ASSERT(*puMobility <= 7); + return(FALSE); +} + +static FLAG FASTCALL +_BRookToEmpty(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pRook = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_ROOK(pRook)); + ASSERT(IS_EMPTY(p)); + ASSERT(GET_COLOR(pRook) == BLACK); +#endif + *puMobility += (!UNSAFE_FOR_ROOK(pos->rgSquare[c|8].bvAttacks[WHITE])); + ASSERT(*puMobility <= 7); + return(FALSE); +} + +static FLAG FASTCALL +_BQueenToEmpty(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(IS_EMPTY(p)); + ASSERT(GET_COLOR(pQueen) == BLACK); +#endif + *puMobility += (!UNSAFE_FOR_QUEEN(pos->rgSquare[c|8].bvAttacks[WHITE])); + ASSERT(*puMobility <= 27); + return(FALSE); +} + +static FLAG FASTCALL +_WQueenToEmpty(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE p = pos->rgSquare[c].pPiece; + PIECE pQueen = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_QUEEN(pQueen)); + ASSERT(IS_EMPTY(p)); + ASSERT(GET_COLOR(pQueen) == WHITE); +#endif + *puMobility += (!UNSAFE_FOR_QUEEN(pos->rgSquare[c|8].bvAttacks[BLACK])); + ASSERT(*puMobility <= 27); + return(FALSE); +} + + + +static FLAG FASTCALL +_EBishopToFriendPawn(IN POSITION *pos, + IN COOR c, + IN OUT ULONG *puMobility, + IN OUT ULONG *puBit) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + ULONG *puMobility, + ULONG *puBit + +Return value: + + static FLAG FASTCALL + +**/ +{ +#ifdef DEBUG + PIECE pPawn = pos->rgSquare[c].pPiece; + PIECE pBishop = pos->rgSquare[pos->cPiece].pPiece; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ON_BOARD(pos->cPiece)); + ASSERT(IS_BISHOP(pBishop)); + ASSERT(IS_PAWN(pPawn)); + ASSERT(GET_COLOR(pBishop) == GET_COLOR(pPawn)); +#endif + *puMobility += ((pos->bb & COOR_TO_BB(c)) != 0); + return(TRUE); +} + + + + +// +// ====================================================================== +// + + +static void +_EvalBishop(IN OUT POSITION *pos, + IN COOR c, + IN PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + PAWN_HASH_ENTRY *pHash, + +Return value: + + FLAG + +**/ +{ + static const BITBOARD bbColorSq[2] = { 0x55aa55aa55aa55aaULL, + 0xaa55aa55aa55aa55ULL }; + static const PMOBILITY_HELPER BMobJumpTable[2][14] = + { + {// (black) + _BMinorToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _EBishopToFriendPawn, // BLACK_PAWN (2) + _BMinorToEnemyLess, // WHITE_PAWN (3) + _AnythingToFriendNoXray, // BLACK_KNIGHT (4) + _EMinorToEnemySame, // WHITE_KNIGHT (5) + _EMinorToFriendXray, // BLACK_BISHOP (6) + _EMinorToEnemySame, // WHITE_BISHOP (7) + _AnythingToFriendNoXray, // BLACK_ROOK (8) + _EMinorToEnemyGreater, // WHITE_ROOK (9) + _EMinorToFriendXray, // BLACK_QUEEN (10) + _EMinorToEnemyGreater, // WHITE_QUEEN (11) + _AnythingToFriendNoXray, // BLACK_KING (12) + _EMinorToEnemyGreater, // WHITE_KING (13) + }, + {// (white) + _WMinorToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _WMinorToEnemyLess, // BLACK_PAWN (2) + _EBishopToFriendPawn, // WHITE_PAWN (3) + _EMinorToEnemySame, // BLACK_KNIGHT (4) + _AnythingToFriendNoXray, // WHITE_KNIGHT (5) + _EMinorToEnemySame, // BLACK_BISHOP (6) + _EMinorToFriendXray, // WHITE_BISHOP (7) + _EMinorToEnemyGreater, // BLACK_ROOK (8) + _AnythingToFriendNoXray, // WHITE_ROOK (9) + _EMinorToEnemyGreater, // BLACK_QUEEN (10) + _EMinorToFriendXray, // WHITE_QUEEN (11) + _EMinorToEnemyGreater, // BLACK_KING (12) + _AnythingToFriendNoXray, // WHITE_KING (13) + } + }; + static const COOR cBishopAtHome[2][2] = + { + { C8, F8 }, // BLACK + { C1, F1 } // WHITE + }; + ULONG uColor; + BITBOARD bb; + BITBOARD bbMask; + BITBOARD bbPc; + COOR cSquare; + SCORE i; + ULONG u; + ULONG uTotalMobility; + ULONG uMaxMobility; + ULONG uCurrentMobility; + ULONG uBit; + PIECE p; + PMOBILITY_HELPER pFun; + + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(p && IS_BISHOP(p)); + uColor = GET_COLOR(p); + +#ifdef DEBUG + pos->cPiece = c; +#endif + + // + // Unmoved piece + // + pos->uMinorsAtHome[uColor] += (c == cBishopAtHome[uColor][0]); + pos->uMinorsAtHome[uColor] += (c == cBishopAtHome[uColor][1]); + ASSERT(pos->uMinorsAtHome[uColor] <= 4); + + // + // Good and bad bishops + // + i = 16; + bbMask = bbColorSq[IS_SQUARE_WHITE(c)]; + bb = pHash->bbStationaryPawns[uColor] & bbMask; + ASSERT(CountBits(bb) <= 16); + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&bb))) + { + // + // Consider stationary (rammed or backward) pawns of the same + // color as the bishop. + // + ASSERT(pos->rgSquare[cSquare].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cSquare].pPiece) == uColor); + i += STATIONARY_PAWN_ON_BISHOP_COLOR[cSquare]; + } + EVAL_TERM(uColor, + BISHOP, + c, + pos->iScore[uColor], + i, + "good/bad stationary pawns ++"); + + i = 0; + bbPc = ~(pHash->bbStationaryPawns[WHITE] | + pHash->bbStationaryPawns[BLACK]); + bbPc &= bbMask; + bb = pHash->bbPawnLocations[uColor] & bbPc; + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&bb))) + { + ASSERT(pos->rgSquare[cSquare].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cSquare].pPiece) == uColor); + ASSERT(pHash->bbPawnLocations[uColor] & COOR_TO_BB(cSquare)); + i += TRANSIENT_PAWN_ON_BISHOP_COLOR[cSquare]; + } + + bb = pHash->bbPawnLocations[FLIP(uColor)] & bbPc; + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&bb))) + { + // + // N.B. Only count enemy pawns that are supported by another + // pawn. + // + ASSERT(pos->rgSquare[cSquare].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cSquare].pPiece) == FLIP(uColor)); + ASSERT(pHash->bbPawnLocations[FLIP(uColor)] & COOR_TO_BB(cSquare)); + i += + (pos->rgSquare[cSquare|8].bvAttacks[FLIP(uColor)].small.uPawn != 0) * + TRANSIENT_PAWN_ON_BISHOP_COLOR[cSquare] / 2; + } + EVAL_TERM(uColor, + BISHOP, + c, + pos->iScore[uColor], + i, + "good/bad transient pawns"); + + // + // Bonus to bishops in very open positions. + // + ASSERT(pos->uClosedScaler <= 32); + EVAL_TERM(uColor, + BISHOP, + c, + pos->iScore[uColor], + BISHOP_IN_CLOSED_POSITION[pos->uClosedScaler], + "in closed/open position"); + + // + // Bishop mobility (and update attack table bits) + // + u = uMaxMobility = uTotalMobility = 0; + pos->bb = bbPc; + ASSERT(g_iBDeltas[u] != 0); + do + { + uCurrentMobility = 0; + uBit = MINOR_BIT; + cSquare = c + g_iBDeltas[u]; + + while(IS_ON_BOARD(cSquare)) + { + // + // Always toggle attack table bits. + // + ASSERT((cSquare|8) == (cSquare + 8)); + pos->rgSquare[cSquare|8].bvAttacks[uColor].uWholeThing |= uBit; + + // + // What did we hit? + // + p = pos->rgSquare[cSquare].pPiece; + pFun = BMobJumpTable[uColor][p]; + ASSERT(pFun); + if (TRUE == (*pFun)(pos, + cSquare, + &uCurrentMobility, + &uBit)) + { + break; + } + cSquare += g_iBDeltas[u]; + } + uTotalMobility += uCurrentMobility; + ASSERT((uMaxMobility & 0x80000000) == 0); + ASSERT((uCurrentMobility & 0x80000000) == 0); + uMaxMobility = MAXU(uMaxMobility, uCurrentMobility); + ASSERT(uMaxMobility <= 7); + u++; + } + while(g_iBDeltas[u] != 0); + ASSERT(uTotalMobility <= 13); + EVAL_TERM(uColor, + BISHOP, + c, + pos->iScore[uColor], + BISHOP_MOBILITY_BY_SQUARES[uTotalMobility], + "bishop mobility"); + EVAL_TERM(uColor, + BISHOP, + c, + pos->iScore[uColor], + BISHOP_MAX_MOBILITY_IN_A_ROW_BONUS[uMaxMobility], + "consecutive bishop mobility"); + + // + // Look for bishops with no mobility who are under attack. These + // pieces are trapped! + // + if (uTotalMobility == 0) + { + pos->cTrapped[uColor] = c; + } + uTotalMobility /= 2; + ASSERT((pos->uMinMobility[uColor] & 0x80000000) == 0); + ASSERT((uTotalMobility & 0x80000000) == 0); + pos->uMinMobility[uColor] = MINU(pos->uMinMobility[uColor], + uTotalMobility); + + // + // Look for "active bad bishops". See if square c is safe from + // enemy pawns. + // + bb = pHash->bbPawnLocations[FLIP(uColor)] & + (~pHash->bbStationaryPawns[FLIP(uColor)]); + if (TRUE == _IsSquareSafeFromEnemyPawn(pos, c, bb)) + { + // + // Give a bonus based on distance from enemy king + // + if (pos->rgSquare[c|8].bvAttacks[uColor].small.uPawn) + { +#ifdef DEBUG + p = BLACK_PAWN | uColor; + ASSERT(((IS_ON_BOARD(c + 17 * g_iBehind[uColor]) && + (pos->rgSquare[c + 17 * g_iBehind[uColor]].pPiece==p)) || + ((IS_ON_BOARD(c + 15 * g_iBehind[uColor])) && + (pos->rgSquare[c + 15 * g_iBehind[uColor]].pPiece==p)))); +#endif + u = DISTANCE(c, pos->cNonPawns[FLIP(uColor)][0]); + i = BISHOP_UNASSAILABLE_BY_DIST_FROM_EKING[u]; + EVAL_TERM(uColor, + BISHOP, + c, + pos->iReducedMaterialDownScaler[uColor], + i, + "[scaled] unassailable"); + } + } +} + +static void +_EvalKnight(IN OUT POSITION *pos, + IN COOR c, + IN PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + PAWN_HASH_ENTRY *pHash, + +Return value: + + FLAG + +**/ +{ + static const int iPawnStart[2] = { -17, +15 }; + static const PMOBILITY_HELPER NMobJumpTable[2][14] = + { + {// (black) + _BMinorToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _AnythingToFriendNoXray, // BLACK_PAWN (2) + _BMinorToEnemyLess, // WHITE_PAWN (3) + _AnythingToFriendNoXray, // BLACK_KNIGHT (4) + _EMinorToEnemySame, // WHITE_KNIGHT (5) + _AnythingToFriendNoXray, // BLACK_BISHOP (6) + _EMinorToEnemySame, // WHITE_BISHOP (7) + _AnythingToFriendNoXray, // BLACK_ROOK (8) + _EMinorToEnemySame, // WHITE_ROOK (9) + _AnythingToFriendNoXray, // BLACK_QUEEN (10) + _EMinorToEnemySame, // WHITE_QUEEN (11) + _AnythingToFriendNoXray, // BLACK_KING (12) + _EMinorToEnemySame, // WHITE_KING (13) + }, + {// (white) + _WMinorToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _WMinorToEnemyLess, // BLACK_PAWN (2) + _AnythingToFriendNoXray, // WHITE_PAWN (3) + _EMinorToEnemySame, // BLACK_KNIGHT (4) + _AnythingToFriendNoXray, // WHITE_KNIGHT (5) + _EMinorToEnemySame, // BLACK_BISHOP (6) + _AnythingToFriendNoXray, // WHITE_BISHOP (7) + _EMinorToEnemySame, // BLACK_ROOK (8) + _AnythingToFriendNoXray, // WHITE_ROOK (9) + _EMinorToEnemySame, // BLACK_QUEEN (10) + _AnythingToFriendNoXray, // WHITE_QUEEN (11) + _EMinorToEnemySame, // BLACK_KING (12) + _AnythingToFriendNoXray, // WHITE_KING (13) + } + }; + static const COOR cKnightAtHome[2][2] = + { + { B8, G8 }, // BLACK + { B1, G1 } // WHITE + }; + PIECE p; + COOR cSquare; + BITBOARD bb; + ULONG uColor; + ULONG uPawnsSupporting; + ULONG u; + ULONG uPawnFile; + ULONG uMobilitySquares; + SCORE i; + ULONG uDist; + PMOBILITY_HELPER pFun; + + p = pos->rgSquare[c].pPiece; + ASSERT(p && IS_KNIGHT(p)); + uColor = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(uColor)); +#ifdef DEBUG + pos->cPiece = c; +#endif + + // + // Unmoved piece + // + pos->uMinorsAtHome[uColor] += (c == cKnightAtHome[uColor][0]); + pos->uMinorsAtHome[uColor] += (c == cKnightAtHome[uColor][1]); + ASSERT(pos->uMinorsAtHome[uColor] <= 4); + + // + // TODO: Don't block unmoved E2/D2 pawns + // + + // + // Centrality bonus + // + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + KNIGHT_CENTRALITY_BONUS[c], + "board centrality"); + + // + // Give a bonus to knights on a closed / busy board + // + ASSERT(pos->uClosedScaler <= 32); + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + KNIGHT_IN_CLOSED_POSITION[pos->uClosedScaler], + "in closed/open position"); + + // + // See if square c is safe from enemy pawns; if so give bonus for + // outposted knight which increases the closer it is to the enemy + // king and the more pawns it has supporting it. + // + uDist = DISTANCE(c, pos->cNonPawns[FLIP(uColor)][0]); + ASSERT((uDist > 0) && (uDist <= 8)); + bb = pHash->bbPawnLocations[FLIP(uColor)] & + (~pHash->bbStationaryPawns[FLIP(uColor)]); + if (TRUE == _IsSquareSafeFromEnemyPawn(pos, c, bb)) + { + // + // Count the number of supporting pawns the knight has + // + uPawnsSupporting = 0; + p = BLACK_PAWN | uColor; + cSquare = c + iPawnStart[uColor]; + uPawnsSupporting = (IS_ON_BOARD(cSquare) && + (pos->rgSquare[cSquare].pPiece == p)); + cSquare += 2; + uPawnsSupporting += (IS_ON_BOARD(cSquare) && + (pos->rgSquare[cSquare].pPiece == p)); + ASSERT(uPawnsSupporting <= 2); + + // + // Give a bonus based on distance from enemy king + // + i = KNIGHT_UNASSAILABLE_BY_DIST_FROM_EKING[uDist] + + KNIGHT_WITH_N_PAWNS_SUPPORTING[uPawnsSupporting]; + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iReducedMaterialDownScaler[uColor], + i, + "[scaled] unassailable/support"); + + // + // Now, if there's zero or one supporter see if the enemy has a + // bishop the color of the knight it could capture with. + // + if (uPawnsSupporting != 2) + { + if (IS_SQUARE_WHITE(c)) + { + if (pos->uWhiteSqBishopCount[FLIP(uColor)]) + { + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + -(i / 2), + "not safe from enemy B"); + } + } + else + { + if (pos->uNonPawnCount[FLIP(uColor)][BISHOP] - + pos->uWhiteSqBishopCount[FLIP(uColor)]) + { + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + -(i / 2), + "not safe from enemy B"); + } + } + } + } + else // not outposted + { + // + // Still good to be close to the enemy king. + // + i = KNIGHT_KING_TROPISM_BONUS[uDist]; + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iReducedMaterialDownScaler[uColor], + i, + "[scaled] enemy king tropism"); + } + + // + // Give a bonus for blockading an enemy backward pawn. Note: + // we also reward pieces for blocking enemy passers in the + // passer code. + // + cSquare = c + 16 * g_iAhead[uColor]; + bb = pHash->bbStationaryPawns[FLIP(uColor)]; + if (bb & COOR_TO_BB(cSquare)) + { + ASSERT(pos->rgSquare[cSquare].pPiece); + ASSERT(IS_PAWN(pos->rgSquare[cSquare].pPiece)); + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + KNIGHT_ON_INTERESTING_SQUARE_BY_RANK[uColor][RANK(c)], + "blockades enemy pawn"); + } + + // + // A knight with an open file behind it is good. + // + uPawnFile = FILE(c) + 1; + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + ((pHash->uCountPerFile[uColor][uPawnFile] == 0) * + KNIGHT_ON_INTERESTING_SQUARE_BY_RANK[uColor][RANK(c)]), + "open file behind"); + + // + // Do mobilility and piece relevance. Also update attack tables. + // + uMobilitySquares = 0; + u = 0; + ASSERT(g_iNDeltas[u] != 0); + do + { + cSquare = c + g_iNDeltas[u]; + if (IS_ON_BOARD(cSquare)) + { + // + // Always update the attack bits + // + ASSERT((cSquare + 8) == (cSquare | 8)); + pos->rgSquare[cSquare|8].bvAttacks[uColor].small.uMinor = 1; + + // + // See what we hit + // + p = pos->rgSquare[cSquare].pPiece; + pFun = NMobJumpTable[uColor][p]; + if (pFun != _AnythingToFriendNoXray) + { + (void)(*pFun)(pos, + cSquare, + &uMobilitySquares, + NULL); + } + + // + // IDEA: bonus for hitting friendly pawn? + // + } + u++; + } + while(g_iNDeltas[u] != 0); + ASSERT(uMobilitySquares >= 0); + ASSERT(uMobilitySquares <= 8); + EVAL_TERM(uColor, + KNIGHT, + c, + pos->iScore[uColor], + KNIGHT_MOBILITY_BY_COUNT[uMobilitySquares], + "knight mobility"); + if (uMobilitySquares == 0) + { + pos->cTrapped[uColor] = c; + } + ASSERT((pos->uMinMobility[uColor] & 0x80000000) == 0); + ASSERT((uMobilitySquares & 0x80000000) == 0); + pos->uMinMobility[uColor] = MINU(pos->uMinMobility[uColor], + uMobilitySquares); +} + +static void +_EvalRook(IN OUT POSITION *pos, + IN COOR c, + IN PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + +Parameters: + + IN POSITION *pos, + IN COOR c, + IN PAWN_HASH_ENTRY *pHash, + +Return value: + + FLAG + +**/ +{ + static const PMOBILITY_HELPER RMobJumpTable[2][14] = + { + {// (black) + _BRookToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _AnythingToFriendNoXray, // BLACK_PAWN (2) + _BRookToEnemyLess, // WHITE_PAWN (3) + _AnythingToFriendNoXray, // BLACK_KNIGHT (4) + _BRookToEnemyLess, // WHITE_KNIGHT (5) + _AnythingToFriendNoXray, // BLACK_BISHOP (6) + _BRookToEnemyLess, // WHITE_BISHOP (7) + _BRookToFriendRook, // BLACK_ROOK (8) + _ERookToEnemySame, // WHITE_ROOK (9) + _ERookToFriendQueen, // BLACK_QUEEN (10) + _ERookToEnemyGreater, // WHITE_QUEEN (11) + _AnythingToFriendNoXray, // BLACK_KING (12) + _ERookToEnemyGreater, // WHITE_KING (13) + }, + {// (white) + _WRookToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _WRookToEnemyLess, // BLACK_PAWN (2) + _AnythingToFriendNoXray, // WHITE_PAWN (3) + _WRookToEnemyLess, // BLACK_KNIGHT (4) + _AnythingToFriendNoXray, // WHITE_KNIGHT (5) + _WRookToEnemyLess, // BLACK_BISHOP (6) + _AnythingToFriendNoXray, // WHITE_BISHOP (7) + _ERookToEnemySame, // BLACK_ROOK (8) + _WRookToFriendRook, // WHITE_ROOK (9) + _ERookToEnemyGreater, // BLACK_QUEEN (10) + _ERookToFriendQueen, // WHITE_QUEEN (11) + _ERookToEnemyGreater, // BLACK_KING (12) + _AnythingToFriendNoXray, // WHITE_KING (13) + }, + }; + + PIECE p; + PIECE pFriendRook; + ULONG uPawnFile = FILE(c) + 1; + ULONG uColor; + ULONG u; + ULONG uCurrentMobility; + ULONG uMaxMobility; + ULONG uTotalMobility; + COOR cSquare; + BITBOARD bb; + ULONG uBit; + PMOBILITY_HELPER pFun; + SCORE i; + + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(p && IS_ROOK(p)); + uColor = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(uColor)); + pos->cPiece = c; + + // + // Reward being on a half open or full open file. + // + if (0 == pHash->uCountPerFile[uColor][uPawnFile]) + { + u = FILE_DISTANCE(c, pos->cNonPawns[FLIP(uColor)][0]); + if (0 == pHash->uCountPerFile[FLIP(uColor)][uPawnFile]) + { + // + // Full open + // + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + ROOK_ON_FULL_OPEN_BY_DIST_FROM_EKING[u], + "on full open"); + } + else + { + // + // Half open, no friendly, just enemy. + // + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + ROOK_ON_HALF_OPEN_WITH_ENEMY_BY_DIST_FROM_EKING[u], + "on half open"); + + // + // Added bonus if the enemy pawn is a passer. + // + bb = pHash->bbPasserLocations[FLIP(uColor)] & BBFILE[FILE(c)]; + if (bb) + { + cSquare = CoorFromBitBoardRank8ToRank1(&bb); + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + PASSER_BY_RANK[FLIP(uColor)][RANK(cSquare)] / 4, + "hassles enemy passer"); + } + } + } + else if (0 == pHash->uCountPerFile[FLIP(uColor)][uPawnFile]) + { + // + // Half open, no enemy pawn, just a friendly + // + u = FILE_DISTANCE(c, pos->cNonPawns[FLIP(uColor)][0]); + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + ROOK_ON_HALF_OPEN_WITH_FRIEND_BY_DIST_FROM_EKING[u], + "on half open"); + + // + // See if the friend is a passed pawn and if the rook's in + // front of it or behind it. + // + bb = pHash->bbPasserLocations[uColor] & BBFILE[FILE(c)]; + if (bb) + { + // + // IDEA: Rook behind candidates, helpers or sentries is good + // because the file may open soon. + // + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&bb))) + { + if (uColor == WHITE) + { + if (cSquare < c) + { + EVAL_TERM(WHITE, + ROOK, + c, + pos->iScore[WHITE], + ROOK_BEHIND_PASSER_BY_PASSER_RANK[WHITE] + [RANK(cSquare)], + "behind own passer"); + } + else + { + EVAL_TERM(WHITE, + ROOK, + c, + pos->iScore[WHITE], + ROOK_LEADS_PASSER_BY_PASSER_RANK[WHITE] + [RANK(cSquare)], + "in the way of passer"); + } + } else { + ASSERT(uColor == BLACK); + if (cSquare > c) + { + EVAL_TERM(BLACK, + ROOK, + c, + pos->iScore[BLACK], + ROOK_BEHIND_PASSER_BY_PASSER_RANK[BLACK] + [RANK(cSquare)], + "behind own passer"); + } + else + { + EVAL_TERM(BLACK, + ROOK, + c, + pos->iScore[BLACK], + ROOK_LEADS_PASSER_BY_PASSER_RANK[BLACK] + [RANK(cSquare)], + "in the way of passer"); + } + } + } + } + } + + // + // Look for rooks that are trapping enemy kings. + // + if (uColor == WHITE) + { + pFriendRook = WHITE_ROOK; + + // + // Rook on 7th/8th rank with an enemy king back there. + // + if ((c < A6) && (pos->cNonPawns[BLACK][0] < A6)) + { + ASSERT(RANK(c) > 6); + ASSERT(RANK(pos->cNonPawns[BLACK][0]) > 6); + + EVAL_TERM(WHITE, + ROOK, + c, + pos->iScore[WHITE], + ROOK_TRAPPING_EKING, + "rook trapping enemy king"); + } + } + else + { + pFriendRook = BLACK_ROOK; + + // + // Rook on 7th/8th rank with an enemy king back there. + // + if ((c > H3) && (pos->cNonPawns[WHITE][0] > H3)) + { + ASSERT(RANK(c) < 3); + ASSERT(RANK(pos->cNonPawns[WHITE][0]) < 3); + EVAL_TERM(BLACK, + ROOK, + c, + pos->iScore[BLACK], + ROOK_TRAPPING_EKING, + "rook trapping enemy king"); + } + } + + // + // Rooks increase in value as pawns come off: + // + // "A further refinement would be to raise the knight's value by + // 1/16 and lower the rook's value by 1/8 for each pawn above five + // of the side being valued, with the opposite adjustment for each + // pawn short of five." + // --Larry Kaufman, IM + // "Evaluation of Material Imbalance" + // + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + ROOK_VALUE_AS_PAWNS_COME_OFF[pos->uPawnCount[uColor] + + pos->uPawnCount[FLIP(uColor)]], + "increase in value/pawns"); + + // + // Rook mobility + // + u = uMaxMobility = uTotalMobility = 0; + ASSERT(g_iRDeltas[u] != 0); + do + { + uCurrentMobility = 0; + uBit = ROOK_BIT; + cSquare = c + g_iRDeltas[u]; + + while(IS_ON_BOARD(cSquare)) + { + // + // Twiddle our attack table bits. + // + pos->rgSquare[cSquare|8].bvAttacks[uColor].uWholeThing |= uBit; + ASSERT((cSquare | 8) == (cSquare + 8)); + + // + // What did we hit? + // + p = pos->rgSquare[cSquare].pPiece; + pFun = RMobJumpTable[uColor][p]; + if (TRUE == (*pFun)(pos, + cSquare, + &uCurrentMobility, + &uBit)) + { + break; + } + cSquare += g_iRDeltas[u]; + } + uTotalMobility += uCurrentMobility; + ASSERT(uTotalMobility <= 14); + ASSERT((uMaxMobility & 0x80000000) == 0); + ASSERT((uCurrentMobility & 0x80000000) == 0); + uMaxMobility = MAXU(uCurrentMobility, uMaxMobility); + ASSERT(uMaxMobility <= 7); + u++; + } + while(g_iRDeltas[u] != 0); + ASSERT(uTotalMobility <= 14); + + ASSERT(pos->uArmyScaler[FLIP(uColor)] <= 31); + ASSERT(REDUCED_MATERIAL_UP_SCALER[pos->uArmyScaler[FLIP(uColor)]] <= 8); + i = ROOK_MOBILITY_BY_SQUARES[uTotalMobility]; + i *= (int)(REDUCED_MATERIAL_UP_SCALER[pos->uArmyScaler[FLIP(uColor)]] + 1); + i /= 8; + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + i, + "rook mobility"); + EVAL_TERM(uColor, + ROOK, + c, + pos->iScore[uColor], + ROOK_MAX_MOBILITY_IN_A_ROW_BONUS[uMaxMobility], + "consecutive rook mobility"); + + ASSERT((pos->uMinMobility[uColor] & 0x80000000) == 0); + ASSERT((uTotalMobility & 0x80000000) == 0); + pos->uMinMobility[uColor] = MINU(pos->uMinMobility[uColor], + uTotalMobility); + if (uTotalMobility < 3) + { + // + // Look for rooks with no mobility who are under attack. These + // pieces are trapped! + // + if (uTotalMobility == 0) + { + pos->cTrapped[uColor] = c; + } + + // + // Rook trapped in the corner by a stupid friendly king? + // + ASSERT(IS_VALID_COLOR(uColor)); + if (uColor == WHITE) + { + ASSERT(IS_ON_BOARD(c)); + if (RANK1(c)) + { + cSquare = pos->cNonPawns[WHITE][0]; + ASSERT(IS_ON_BOARD(cSquare)); + if (RANK1(cSquare)) + { + if (((cSquare > E1) && (c > cSquare)) || + ((cSquare < D1) && (c < cSquare))) + { + EVAL_TERM(WHITE, + ROOK, + c, + pos->iScore[WHITE], + KING_TRAPPING_ROOK, + "king trapping rook"); + } + } + } + } + else + { + ASSERT(uColor == BLACK); + ASSERT(IS_ON_BOARD(c)); + if (RANK8(c)) + { + cSquare = pos->cNonPawns[BLACK][0]; + ASSERT(IS_ON_BOARD(cSquare)); + + if (RANK8(cSquare)) + { + if (((cSquare > E8) && (c > cSquare)) || + ((cSquare < D8) && (c < cSquare))) + { + EVAL_TERM(BLACK, + ROOK, + c, + pos->iScore[BLACK], + KING_TRAPPING_ROOK, + "king trapping rook"); + } + } + } + } + } // if low mobility +} + + +static void +_EvalQueen(IN OUT POSITION *pos, + IN COOR c, + IN PAWN_HASH_ENTRY *pHash) +/** + +Parameters: + + POSITION *pos, + COOR c, + PAWN_HASH_ENTRY *pHash, + +Return value: + + FLAG + +**/ +{ + static const PMOBILITY_HELPER QMobJumpTable[2][14] = + { + { + _BQueenToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _AnythingToFriendNoXray, // BLACK_PAWN (2) + _BQueenToEnemyLess, // WHITE_PAWN (3) + _AnythingToFriendNoXray, // BLACK_KNIGHT (4) + _BQueenToEnemyLess, // WHITE_KNIGHT (5) + _EQueenToFriendBishop, // BLACK_BISHOP (6) + _BQueenToEnemyLess, // WHITE_BISHOP (7) + _EQueenToFriendRook, // BLACK_ROOK (8) + _BQueenToEnemyLess, // WHITE_ROOK (9) + _EQueenToFriendQueen, // BLACK_QUEEN (10) + _EQueenToEnemyGreaterEqual, // WHITE_QUEEN (11) + _AnythingToFriendNoXray, // BLACK_KING (12) + _EQueenToEnemyGreaterEqual, // WHITE_KING (13) + }, + { + _WQueenToEmpty, // EMPTY_SQUARE (0) + _InvalidMobilityHelper, // INVALID_PIECE (1) + _WQueenToEnemyLess, // BLACK_PAWN (2) + _AnythingToFriendNoXray, // WHITE_PAWN (3) + _WQueenToEnemyLess, // BLACK_KNIGHT (4) + _AnythingToFriendNoXray, // WHITE_KNIGHT (5) + _WQueenToEnemyLess, // BLACK_BISHOP (6) + _EQueenToFriendBishop, // WHITE_BISHOP (7) + _WQueenToEnemyLess, // BLACK_ROOK (8) + _EQueenToFriendRook, // WHITE_ROOK (9) + _EQueenToEnemyGreaterEqual, // BLACK_QUEEN (10) + _EQueenToFriendQueen, // WHITE_QUEEN (11) + _EQueenToEnemyGreaterEqual, // BLACK_KING (12) + _AnythingToFriendNoXray, // WHITE_KING (13) + }, + }; + + PIECE p = pos->rgSquare[c].pPiece; + ULONG uColor; + COOR cSquare; + ULONG uTotalMobility; + ULONG u; + ULONG uBit; + PMOBILITY_HELPER pFun; + ULONG uNearKing = 0; + COOR cKing; + + ASSERT(IS_ON_BOARD(c)); + ASSERT(p && IS_QUEEN(p)); + uColor = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(uColor)); + pos->cPiece = c; + cKing = pos->cNonPawns[FLIP(uColor)][0]; + ASSERT(IS_ON_BOARD(cKing)); + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + + if ((FALSE == pos->fCastled[uColor]) && (pos->uMinorsAtHome[uColor] > 1)) + { + // + // Discourage queen being out too early + // + if (!RANK1(c) && !RANK8(c)) + { + ASSERT(QUEEN_OUT_EARLY[pos->uMinorsAtHome[uColor]] < 0); + ASSERT(pos->uMinorsAtHome[uColor] <= 4); + EVAL_TERM(uColor, + QUEEN, + c, + pos->iScore[uColor], + QUEEN_OUT_EARLY[pos->uMinorsAtHome[uColor]], + "queen out too early"); + } + } + else + { + // + // Encourage enemy king tropism + // + u = DISTANCE(c, cKing); + ASSERT((u <= 7) && (u > 0)); + EVAL_TERM(uColor, + QUEEN, + c, + pos->iScore[uColor], + QUEEN_KING_TROPISM[u], + "enemy king tropism"); + } + + // + // Do queen mobility + // + uTotalMobility = 0; + u = 0; + ASSERT(g_iQKDeltas[u] != 0); + do + { + uBit = QUEEN_BIT; + cSquare = c + g_iQKDeltas[u]; + while(IS_ON_BOARD(cSquare)) + { + // + // Toggle attack table bits. + // + pos->rgSquare[cSquare|8].bvAttacks[uColor].uWholeThing |= uBit; + + // + // What did we hit? + // + p = pos->rgSquare[cSquare].pPiece; + uNearKing += (DISTANCE(cSquare, cKing) <= 1); + pFun = QMobJumpTable[uColor][p]; + if (TRUE == (*pFun)(pos, + cSquare, + &uTotalMobility, + &uBit)) + { + break; + } + cSquare += g_iQKDeltas[u]; + } + u++; + } + while(g_iQKDeltas[u] != 0); + + ASSERT(uTotalMobility <= 27); + EVAL_TERM(uColor, + QUEEN, + c, + pos->iScore[uColor], + QUEEN_MOBILITY_BY_SQUARES[uTotalMobility], + "queen mobility"); + + // + // Look for queens with no mobility who are under attack. These + // pieces are trapped! + // + if (uTotalMobility == 0) + { + pos->cTrapped[uColor] = c; + } + ASSERT((pos->uMinMobility[uColor] & 0x80000000) == 0); + ASSERT((uTotalMobility & 0x80000000) == 0); + pos->uMinMobility[uColor] = MINU(pos->uMinMobility[uColor], + uTotalMobility); + + // + // If queen points near enemy king, that's a good thing too. + // + ASSERT(uNearKing <= 6); + EVAL_TERM(uColor, + QUEEN, + c, + pos->iScore[uColor], + (uNearKing * QUEEN_ATTACKS_SQ_NEXT_TO_KING), + "pointing near enemy K"); +} + +static void +_EvalKing(IN OUT POSITION *pos, + IN const COOR c, + IN const PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR c, + PAWN_HASH_ENTRY *pHash, + +Return value: + + FLAG + +**/ +{ + PIECE p; + ULONG uColor, ufColor; + COOR cSquare; + ULONG u, v; + ULONG uCounter; + BITV bvAttack; + BITV bvXray; + BITV bvDefend; + BITV bvPattern = 0; + ULONG uFlightSquares; + BITBOARD bb; + SCORE i; + SCORE iKingScore = 0; + + static ULONG KingFlightDefects[9] = + { + +4, +2, +1, 0, 0, 0, 0, 0, 0 + }; + + static ULONG KingStormingPawnDefects[8] = + { + +0, +4, +3, +1, +0, +0, +0, +0 + }; + + static ULONG KingFileDefects[3] = + { + +2, +1, +0 + }; + + static INT KingSafetyDeltas[11] = + { + -17, -16, -15, + -1, +1, + +15, +16, +17, -2, +2, 0 + }; + + static ULONG EmptyAttackedSquare[2][11] = + { + { + 1, 1, 1, + 1, 1, + 2, 2, 2, 1, 1, 0 + }, + { + 2, 2, 2, + 1, 1, + 1, 1, 1, 1, 1, 0 + }, + }; + + static ULONG EmptyUnattackedSquare[2][11] = + { + { + 0, 0, 0, + 0, 0, + 1, 1, 1, 0, 0, 0 + }, + { + 1, 1, 1, + 0, 0, + 0, 0, 0, 0, 0, 0 + }, + }; + + static ULONG OccupiedAttackedSquare[2] = + { + 1, + 2 + }; + + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(p && IS_KING(p)); + uColor = GET_COLOR(p); + ufColor = FLIP(uColor); + ASSERT(IS_VALID_COLOR(uColor)); + + u = pos->uNonPawnMaterial[ufColor]; + ASSERT(u >= VALUE_KING); + if (u < DO_KING_SAFETY_THRESHOLD) + { + u = 0; + ASSERT(g_iQKDeltas[u] != 0); + do + { + cSquare = c + g_iQKDeltas[u]; + if (IS_ON_BOARD(cSquare)) + { + pos->rgSquare[cSquare|8].bvAttacks[uColor].small.uKing = 1; + } + u++; + } + while(g_iQKDeltas[u] != 0); + goto skip_safety; + } + + // Prepare to do king safety + uCounter = (u >= KEEP_KING_AT_HOME_THRESHOLD) * + KING_INITIAL_COUNTER_BY_LOCATION[uColor][c]; +#ifdef EVAL_DUMP + Trace("%s Initial KS Counter: %u\n", COLOR_NAME(uColor), uCounter); +#endif + + uCounter += pos->uPiecesPointingAtKing[uColor] / 2; +#ifdef EVAL_DUMP + Trace("%s KS Counter after pieces pointing: %u\n", + COLOR_NAME(uColor), uCounter); +#endif + uFlightSquares = 0; + u = 0; + ASSERT(KingSafetyDeltas[u] != 0); + do + { + cSquare = c + KingSafetyDeltas[u]; + if (IS_ON_BOARD(cSquare)) + { + p = pos->rgSquare[cSquare].pPiece; + + cSquare |= 8; + bvAttack = pos->rgSquare[cSquare].bvAttacks[ufColor].uSmall; + bvXray = pos->rgSquare[cSquare].bvAttacks[ufColor].uXray; + pos->rgSquare[cSquare].bvAttacks[uColor].small.uKing = 1; + bvDefend = pos->rgSquare[cSquare].bvAttacks[uColor].uSmall; + + if (bvAttack != 0) + { + bvPattern |= (bvAttack | bvXray); + if (bvXray || (bvAttack & (bvAttack - 1))) + { + bvDefend &= ~8; + } + if (IS_EMPTY(p)) + { + ASSERT(u < 11); + uCounter += EmptyAttackedSquare[uColor][u]; + } + else + { + uCounter += + OccupiedAttackedSquare[OPPOSITE_COLORS(p, uColor)]; + } + uCounter += (bvDefend == 0); + } + else + { + uCounter += (bvXray != 0); + ASSERT(u < 11); + uCounter += EmptyUnattackedSquare[uColor][u]; + ASSERT((IS_EMPTY(p) == 0) || (IS_EMPTY(p) == 1)); + uFlightSquares += ((IS_EMPTY(p)) && (u < 8)); + } + } + u++; + } + while(KingSafetyDeltas[u] != 0); +#ifdef EVAL_DUMP + Trace("%s KS Counter post-squares: %u\n", COLOR_NAME(uColor), uCounter); +#endif + + if (IS_ON_BOARD(c - 1)) + { + u = FILE(c - 1) + 1; + v = (pHash->uCountPerFile[WHITE][u] > 0) + + (pHash->uCountPerFile[BLACK][u] > 0); + ASSERT((v >= 0) && (v <= 2)); + + // Note: open rook files are worse than open interior files + uCounter += (KingFileDefects[v] + ((v < 2) && ((u == 1) || (u == 8)))); + + bb = pHash->bbPawnLocations[ufColor] & BBFILE[u - 1]; + if (bb) + { + if (uColor == WHITE) + { + cSquare = CoorFromBitBoardRank1ToRank8(&bb); + } + else + { + cSquare = CoorFromBitBoardRank8ToRank1(&bb); + } + ASSERT(IS_ON_BOARD(cSquare)); + uCounter += KingStormingPawnDefects[DISTANCE(cSquare, c)]; + } + } + + u = FILE(c) + 1; + v = (pHash->uCountPerFile[WHITE][u] > 0) + + (pHash->uCountPerFile[BLACK][u] > 0); + ASSERT((v >= 0) && (v <= 2)); + + // Note: open rook files are worse than open interior files + uCounter += (KingFileDefects[v] + ((v < 2) && ((u == 1) || (u == 8)))); + bb = pHash->bbPawnLocations[ufColor] & BBFILE[u - 1]; + if (bb) + { + if (uColor == WHITE) + { + cSquare = CoorFromBitBoardRank1ToRank8(&bb); + } + else + { + cSquare = CoorFromBitBoardRank8ToRank1(&bb); + } + ASSERT(IS_ON_BOARD(cSquare)); + uCounter += KingStormingPawnDefects[DISTANCE(cSquare, c)]; + } + + if (IS_ON_BOARD(c + 1)) + { + ASSERT((FILE(c + 1) + 1) == (u + 1)); + u += 1; + v = (pHash->uCountPerFile[WHITE][u] > 0) + + (pHash->uCountPerFile[BLACK][u] > 0); + ASSERT((v >= 0) && (v <= 2)); + + // Note: open rook files are worse than open interior files + uCounter += (KingFileDefects[v] + ((v < 2) && ((u == 1) || (u == 8)))); + + bb = pHash->bbPawnLocations[ufColor] & BBFILE[u - 1]; + if (bb) + { + if (uColor == WHITE) + { + cSquare = CoorFromBitBoardRank1ToRank8(&bb); + } + else + { + cSquare = CoorFromBitBoardRank8ToRank1(&bb); + } + ASSERT(IS_ON_BOARD(cSquare)); + uCounter += KingStormingPawnDefects[DISTANCE(cSquare, c)]; + } + } +#ifdef EVAL_DUMP + Trace("%s KS Counter post-open file/stormers: %u\n", COLOR_NAME(uColor), + uCounter); +#endif + + bvPattern >>= 3; + ASSERT(bvPattern >= 0); + ASSERT(bvPattern < 32); + v = KING_COUNTER_BY_ATTACK_PATTERN[bvPattern]; + uCounter += v; +#ifdef EVAL_DUMP + Trace("%s KS Counter post-attack pattern: %u\n", COLOR_NAME(uColor), + uCounter); +#endif + + ASSERT(uFlightSquares <= 8); + uCounter += KingFlightDefects[uFlightSquares] * (v > 1); +#ifdef EVAL_DUMP + Trace("%s KS Counter post-flight sq: %u\n", COLOR_NAME(uColor), uCounter); +#endif + + // + // Note: can't use pos->iReducedMaterialDownScaler here because we + // are scaling it based on the _other_ side's material. + // + uCounter = MINU(uCounter, 41); + i = KING_SAFETY_BY_COUNTER[uCounter]; + i *= REDUCED_MATERIAL_DOWN_SCALER[pos->uArmyScaler[ufColor]]; + i /= 8; + EVAL_TERM(uColor, + KING, + c, + iKingScore, + i, + "king safety"); + + // + // Bonus for castling / penalty for loss of castle. Also, if side has + // not yet castled, be concerned with undeveloped minor pieces. + // + if (FALSE == pos->fCastled[uColor]) + { + if (pos->uNonPawnCount[uColor][0] > 4) + { + ASSERT(pos->uMinorsAtHome[uColor] <= 4); + EVAL_TERM(uColor, + 0, + ILLEGAL_COOR, + pos->iScore[uColor], + UNDEVELOPED_MINORS_IN_OPENING[pos->uMinorsAtHome[uColor]], + "development"); + if (uColor == BLACK) + { + EVAL_TERM(BLACK, + KING, + c, + iKingScore, + (KING_MISSING_ONE_CASTLE_OPTION * + ((CASTLE_BLACK_SHORT & pos->bvCastleInfo) == 0)), + "can't castle short"); + EVAL_TERM(BLACK, + KING, + c, + iKingScore, + (KING_MISSING_ONE_CASTLE_OPTION * + ((CASTLE_BLACK_LONG & pos->bvCastleInfo) == 0)), + "can't castle long"); + } + else + { + ASSERT(uColor == WHITE); + EVAL_TERM(WHITE, + KING, + c, + iKingScore, + (KING_MISSING_ONE_CASTLE_OPTION * + ((CASTLE_WHITE_SHORT & pos->bvCastleInfo) == 0)), + "can't castle short"); + EVAL_TERM(WHITE, + KING, + c, + iKingScore, + (KING_MISSING_ONE_CASTLE_OPTION * + ((CASTLE_WHITE_LONG & pos->bvCastleInfo) == 0)), + "can't castle long"); + } + } + } + + skip_safety: + // + // Special code for kings in the endgame + // + u = pos->uNonPawnCount[WHITE][0] + pos->uNonPawnCount[BLACK][0]; + if (u < 8) + { + // + // Encourage kings to come to the center + // + i = KING_TO_CENTER[c]; + EVAL_TERM(uColor, + KING, + c, + iKingScore, + i, + "centralize king"); + + // + // Kings in front of passers in the late endgame are strong... + // + cSquare = FILE(c); + bb = pHash->bbPasserLocations[uColor] & + (BBADJACENT_FILES[cSquare] | BBFILE[cSquare]); + if (bb) + { + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&bb))) + { + if (DISTANCE(cSquare, c) == 1) + { + ASSERT(abs((INT)FILE(c) - (INT)FILE(cSquare)) <= 1); + ASSERT(abs((INT)RANK(c) - (INT)RANK(cSquare)) <= 1); + + i = 2; + i += SUPPORTED_PASSER_BY_RANK[uColor][RANK(cSquare)]; + switch(uColor) + { + case WHITE: + i += 8 * (c < (cSquare - 1)); + break; + + case BLACK: + i += 8 * (c > (cSquare + 1)); + break; + } + EVAL_TERM(uColor, + KING, + c, + iKingScore, + i, + "supporting own passer"); + } + } + } + + // + // Detect kings way out of the action in KP endgames: + // + // 8/8/1p6/p6k/P3K3/8/1P6/8 w - - 0 11 + // + if ((u == 2) && (uColor == WHITE)) + { + i = 0; + bb = (pHash->bbPawnLocations[WHITE] | + pHash->bbPawnLocations[BLACK]); + while(IS_ON_BOARD(cSquare = CoorFromBitBoardRank8ToRank1(&bb))) + { + i += (DISTANCE(cSquare, pos->cNonPawns[BLACK][0]) - + DISTANCE(cSquare, pos->cNonPawns[WHITE][0])); + } + EVAL_TERM(WHITE, + KING, + c, + iKingScore, + i * 12, + "in/out of \"action\""); + } + } + pos->iScore[uColor] += iKingScore; + pos->iTempScore = iKingScore; +} + + +FLAG +EvalPasserRaces(IN OUT POSITION *pos, + IN PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + + Determine if one side has a pawn that is unstoppable. + + This is broken for positions like: + +Parameters: + + POSITION *pos, + PAWN_HASH_ENTRY *pHash, + +Return value: + + void + +**/ +{ + BITBOARD bb[2]; + ULONG uColor; + int d1; + COOR cQueen; + COOR cKing, c; + ULONG uKingDist, uPawnDist, uFriendDist; + ULONG uRacerDist[2] = { 99, 99 }; + FLAG fDontCountMeOut[2] = { ((RANK(pos->cNonPawns[BLACK][0]) <= 3) && + (pos->uPawnCount[BLACK] != 0)), + ((RANK(pos->cNonPawns[WHITE][0]) >= 6) && + (pos->uPawnCount[WHITE] != 0)) }; + bb[BLACK] = pHash->bbPasserLocations[BLACK]; + bb[WHITE] = pHash->bbPasserLocations[WHITE]; + if (!(bb[BLACK] | bb[WHITE])) + { + return(FALSE); + } + ASSERT((pos->uNonPawnCount[WHITE][0] == 1) || + (pos->uNonPawnCount[BLACK][0] == 1)) + FOREACH_COLOR(uColor) + { + if (pos->uNonPawnCount[FLIP(uColor)][0] == 1) + { + d1 = 16 * g_iAhead[uColor]; + ASSERT((d1 * 2) == (32 * g_iAhead[uColor])); + if (bb[uColor]) + { + while(IS_ON_BOARD(c = CoorFromBitBoardRank8ToRank1( + &(bb[uColor])))) + { + // If the enemy king can take this passer and is + // on the move, all bets are off! + cKing = pos->cNonPawns[FLIP(uColor)][0]; + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKing].pPiece) != uColor); + if (pos->uToMove == FLIP(uColor) && + (DISTANCE(cKing, c) == 1)) + { + // TODO: something clever here about protected pawns + continue; + } + + cQueen = FILE_RANK_TO_COOR(FILE(c), QUEENING_RANK[uColor]); + ASSERT(FILE(cQueen) == FILE(c)); + uPawnDist = RANK_DISTANCE(cQueen, c); + if ((RANK(c) == JUMPING_RANK[uColor]) && + (IS_EMPTY(pos->rgSquare[c + d1].pPiece) && + IS_EMPTY(pos->rgSquare[c + d1 * 2].pPiece))) + { + uPawnDist--; + } + ASSERT((uPawnDist >= 1) && (uPawnDist <= 6)); + + uKingDist = DISTANCE(cKing, cQueen); + if (uKingDist > 0) + { + uKingDist -= (pos->uToMove == FLIP(uColor)); + } + ASSERT((uKingDist >= 0) && (uPawnDist <= 7)); + + if (uPawnDist < uKingDist) + { + uRacerDist[uColor] = MINU(uRacerDist[uColor], + uPawnDist); + } + + cKing = pos->cNonPawns[uColor][0]; + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKing].pPiece) == uColor); + + uFriendDist = DISTANCE(cKing, cQueen); + if ((uFriendDist <= 1) && (DISTANCE(cKing, c) <= 1)) + { + if (FILE(c) != FILE(cKing)) + { + uRacerDist[uColor] = MINU(uRacerDist[uColor], + uPawnDist); + } + else if ((FILE(cKing) != A) && + (FILE(cKing) != H)) + { + uRacerDist[uColor] = MINU(uRacerDist[uColor], + (uPawnDist + 1)); + } + } + fDontCountMeOut[uColor] = TRUE; + + // + // TODO: winning connected passers + // + } + } + } + } + + if ((uRacerDist[WHITE] < uRacerDist[BLACK]) && + (FALSE == fDontCountMeOut[BLACK])) + { + EVAL_TERM(WHITE, + PAWN, + ILLEGAL_COOR, + pos->iScore[WHITE], + RACER_WINS_RACE - uRacerDist[WHITE] * 4, + "winning racer pawn"); + return(TRUE); + } + else if ((uRacerDist[BLACK] < uRacerDist[WHITE]) && + (FALSE == fDontCountMeOut[WHITE])) + { + EVAL_TERM(BLACK, + PAWN, + ILLEGAL_COOR, + pos->iScore[BLACK], + RACER_WINS_RACE - uRacerDist[BLACK] * 4, + "winning racer pawn"); + return(TRUE); + } + return(FALSE); +} + + +static void +_EvalPassers(IN OUT POSITION *pos, + IN PAWN_HASH_ENTRY *pHash) +/** + +Routine description: + +Parameters: + + POSITION *pos, + PAWN_HASH_ENTRY *pHash, + +Return value: + + void + +**/ +{ + ULONG u; + ULONG uColor; + COOR c; + COOR cSquare; + BITBOARD bb; + PIECE p; + SCORE i; + ULONG uNumPassers[2] = { 0, 0 }; + int d1; + + ASSERT(pHash->bbPasserLocations[WHITE] | + pHash->bbPasserLocations[BLACK]); + + FOREACH_COLOR(uColor) + { + bb = pHash->bbPasserLocations[uColor]; + if (bb != 0) + { + uNumPassers[uColor] = CountBits(bb); + ASSERT(uNumPassers[uColor] > 0); + d1 = 16 * g_iAhead[uColor]; + ASSERT((d1 * 2) == (32 * g_iAhead[uColor])); + + while(IS_ON_BOARD(c = CoorFromBitBoardRank8ToRank1(&bb))) + { + // + // Consider the control of the square in front of the passer + // + cSquare = c + d1; + ASSERT(IS_ON_BOARD(cSquare)); + u = _WhoControlsSquareFast(pos, cSquare); + if (u == FLIP(uColor)) + { + EVAL_TERM(uColor, + PAWN, + c, + pos->iScore[uColor], + -((PASSER_BY_RANK[uColor][RANK(c)] / 4) + + (PASSER_BY_RANK[uColor][RANK(c)] / 16)), + "enemy controls sq ahead"); + } + else if (u == (ULONG)-1) + { + p = pos->rgSquare[cSquare].pPiece; + if (!IS_EMPTY(p) && (OPPOSITE_COLORS(p, uColor))) + { + ASSERT(GET_COLOR(p) != uColor); + EVAL_TERM(uColor, + PAWN, + c, + pos->iScore[uColor], + -(PASSER_BY_RANK[uColor][RANK(c)] / 4), + "enemy occupies sq ahead"); + } + } +#ifdef DEBUG + else + { + ASSERT(u == uColor); + } +#endif + + // + // Consider distance from friend king / enemy king + // + i = (8 - DISTANCE(c, pos->cNonPawns[uColor][0])); + if (((uColor == WHITE) && + ((pos->cNonPawns[BLACK][0] >> 4) <= (c >> 4))) || + ((uColor == BLACK) && + ((pos->cNonPawns[WHITE][0] >> 4) >= (c >> 4)))) { + // + // The enemy king is ahead of the passer + // + i += FILE_DISTANCE(c, pos->cNonPawns[FLIP(uColor)][0]) * 4; + } + else + { + // + // The enemy king is behind the passer + // + i += 10 + DISTANCE(c, pos->cNonPawns[FLIP(uColor)][0]) * 4; + } + i *= PASSER_MATERIAL_UP_SCALER[pos->uArmyScaler[FLIP(uColor)]]; + i /= 8; + EVAL_TERM(uColor, + PAWN, + c, + pos->iScore[uColor], + i, + "passer distance to kings"); + + // + // If a side is a piece down then the other side's passers + // are even more dangerous. + // + if (pos->uNonPawnCount[uColor][0] > + pos->uNonPawnCount[FLIP(uColor)][0]) + { + i = (PASSER_BY_RANK[uColor][RANK(c)] / 2); + EVAL_TERM(uColor, + PAWN, + c, + pos->iScore[uColor], + i, + "passer and piece up"); + } + + // + // TODO: For connected passers vs KR, consult the oracle + // + } + } + } + + // + // Game stage bonus + // + u = pos->uArmyScaler[BLACK]; + EVAL_TERM(WHITE, + PAWN, + ILLEGAL_COOR, + pos->iScore[WHITE], + uNumPassers[WHITE] * PASSER_BONUS_AS_MATERIAL_COMES_OFF[u], + "passer value material"); + ASSERT(PASSER_BONUS_AS_MATERIAL_COMES_OFF[u] >= 0); + u = pos->uArmyScaler[WHITE]; + EVAL_TERM(BLACK, + PAWN, + ILLEGAL_COOR, + pos->iScore[BLACK], + uNumPassers[BLACK] * PASSER_BONUS_AS_MATERIAL_COMES_OFF[u], + "passer value material"); + ASSERT(PASSER_BONUS_AS_MATERIAL_COMES_OFF[u] >= 0); +} + + +static void +_EvalBadTrades(IN OUT POSITION *pos) +/** + +Routine description: + +Parameters: + + POSITION *pos, + +Return value: + + void + +**/ +{ + ULONG uAhead, uBehind; + ULONG uMagnitude; + + // + // See who is ahead + // + ASSERT(pos->uNonPawnMaterial[WHITE] != pos->uNonPawnMaterial[BLACK]); + uAhead = (pos->uNonPawnMaterial[WHITE] > pos->uNonPawnMaterial[BLACK]); + uBehind = FLIP(uAhead); +#ifdef DEBUG + if (pos->uNonPawnMaterial[WHITE] > pos->uNonPawnMaterial[BLACK]) + { + ASSERT(uAhead == WHITE); + ASSERT(uBehind == BLACK); + } + else + { + ASSERT(pos->uNonPawnMaterial[BLACK] > pos->uNonPawnMaterial[WHITE]); + ASSERT(uAhead == BLACK); + ASSERT(uBehind == WHITE); + } +#endif + uMagnitude = ((pos->uNonPawnMaterial[uAhead] + + pos->uNonPawnCount[uAhead][0] * 128) - + (pos->uNonPawnMaterial[uBehind] + + pos->uNonPawnCount[uBehind][0] * 128)); + uMagnitude /= 128; + uMagnitude -= (uMagnitude != 0); + ASSERT(!(uMagnitude & 0x80000000)); + uMagnitude = MINU(2, uMagnitude); + ASSERT(uMagnitude <= 2); + + // + // Encourage the side that is ahead in piece material to continue + // trading pieces and not to trade pawns. This also has the + // effect of making the side that is behind in material want to + // trade pawns and not pieces. This also gives the side that is + // ahead a bit of a "bad trade" bonus. Note that the bonus is not + // given if the side "ahead" has no pawns; this is so that the + // engine will not like positions like KNB vs KRP - the side with + // the pawn has the winning chances. + // + EVAL_TERM(uAhead, + 0, + ILLEGAL_COOR, + pos->iScore[uAhead], + ((pos->uPawnCount[uAhead] != 0) * + TRADE_PIECES[uMagnitude][pos->uNonPawnCount[uBehind][0]]), + "trade pieces"); + ASSERT(TRADE_PIECES[uMagnitude][pos->uNonPawnCount[uBehind][0]] > 0); + EVAL_TERM(uAhead, + 0, + ILLEGAL_COOR, + pos->iScore[uAhead], + DONT_TRADE_PAWNS[uMagnitude][pos->uPawnCount[uAhead]], + "don't trade pawns"); +} + +static void +_EvalLookForDanger(IN OUT SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + This routine looks for squares on the board where the side to move + has a piece that is en prise. So far in eval we will have tagged + pieces in situations where they are attacked by lesser-valued + enemy pieces as "in danger". However, because of the order in + which the attack table was generated, we will have missed + situations where a piece is undefended (or underdefended) and + attacked by an enemy piece that is the same (or greater) value. + + Note: This routine only considers side to move. + + Also Note: this routine does not find pawns that are en prise, only + pieces. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + COOR c; + ULONG u; + POSITION *pos = &ctx->sPosition; + ULONG uSide = pos->uToMove; +#ifdef DEBUG + PIECE p; +#endif + + for (u = 1; + u < pos->uNonPawnCount[uSide][0]; + u++) + { + c = pos->cNonPawns[uSide][u]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(p); + ASSERT(GET_COLOR(p) == uSide); + ASSERT(!IS_PAWN(p)); +#endif + if (_WhoControlsSquareFast(pos, c) == FLIP(uSide)) + { + StoreEnprisePiece(pos, c); + } + } +} + + +static void +_EvalTrappedPieces(IN OUT SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + static void + +**/ +{ + COOR c; + ULONG uColor; + POSITION *pos = &ctx->sPosition; +#ifdef DEBUG + PIECE p; +#endif + + FOREACH_COLOR(uColor) + { + c = pos->cTrapped[uColor]; + if (IS_ON_BOARD(c)) + { + if (_WhoControlsSquareFast(pos, c) == FLIP(uColor)) + { +#ifdef DEBUG + p = pos->rgSquare[c].pPiece; + ASSERT(p); + ASSERT(!IS_PAWN(p)); + ASSERT(GET_COLOR(p) == uColor); +#endif + if (OPPOSITE_COLORS(uColor, pos->uToMove)) + { + StoreEnprisePiece(pos, c); + } + else + { + StoreTrappedPiece(pos, c); + } + } + } + } +} + + +static void +_EvalBishopPairs(IN POSITION *pos) +/*++ + +Routine description: + + Give a bonus to sides that have a viable bishop pair based; scale + the bonus by the number of pawns remaining on the board. + +Parameters: + + IN POSITION *pos - position + +Return value: + + static void + +--*/ +{ + ULONG uPawnSum = pos->uPawnCount[WHITE] + pos->uPawnCount[BLACK]; + FLAG fPair; + ULONG uBishopCount = pos->uNonPawnCount[BLACK][BISHOP]; + ULONG uWhiteSqBishopCount = pos->uWhiteSqBishopCount[BLACK]; + ASSERT(uPawnSum <= 16); + ASSERT(uBishopCount <= 10); + ASSERT(uWhiteSqBishopCount <= 10); + fPair = ((uBishopCount > 1) & + (uWhiteSqBishopCount != 0) & + (uWhiteSqBishopCount != uBishopCount)); + EVAL_TERM(BLACK, + 0, + ILLEGAL_COOR, + pos->iScore[BLACK], + BISHOP_PAIR[fPair][uPawnSum], + "bishop pair"); + uBishopCount = pos->uNonPawnCount[WHITE][BISHOP]; + uWhiteSqBishopCount = pos->uWhiteSqBishopCount[WHITE]; + ASSERT(uBishopCount <= 10); + ASSERT(uWhiteSqBishopCount <= 10); + fPair = ((uBishopCount > 1) & + (uWhiteSqBishopCount != 0) & + (uWhiteSqBishopCount != uBishopCount)); + EVAL_TERM(WHITE, + 0, + ILLEGAL_COOR, + pos->iScore[WHITE], + BISHOP_PAIR[fPair][uPawnSum], + "bishop pair"); +} + + + +SCORE +Eval(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta) +/** + +Routine description: + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + +Return value: + + SCORE + +**/ +{ + static const PEVAL_HELPER JumpTable[] = + { + _InvalidEvaluator, // EMPTY_SQUARE (0) + _InvalidEvaluator, // INVALID_PIECE (1) + _InvalidEvaluator, // BLACK_PAWN (2) + _InvalidEvaluator, // WHITE_PAWN (3) + _EvalKnight, // BLACK_KNIGHT (4) + _EvalKnight, // WHITE_KNIGHT (5) + _EvalBishop, // BLACK_BISHOP (6) + _EvalBishop, // WHITE_BISHOP (7) + _InvalidEvaluator, // BLACK_ROOK (8) + _InvalidEvaluator, // WHITE_ROOK (9) + _InvalidEvaluator, // BLACK_QUEEN (10) + _InvalidEvaluator, // WHITE_QUEEN (11) + _InvalidEvaluator, // BLACK_KING (12) + _InvalidEvaluator // WHITE_KING (13) + }; + ULONG uDefer[2][2]; + COOR cDefer[2][2][10]; + POSITION *pos = &(ctx->sPosition); + SCORE iScoreForSideToMove; + SCORE iAlphaMargin, iBetaMargin; + PAWN_HASH_ENTRY *pHash; + COOR c; + PIECE p; + ULONG u; + ULONG uColor; + BITBOARD bb; + FLAG fDeferred; +#ifdef EVAL_TIME + UINT64 uTimer = SystemReadTimeStampCounter(); +#endif + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT((pos->iMaterialBalance[WHITE] * -1) == + pos->iMaterialBalance[BLACK]); + // ASSERT(!InCheck(pos, pos->uToMove)); + + pos->uMinMobility[BLACK] = pos->uMinMobility[WHITE] = 100; + pos->cTrapped[BLACK] = pos->cTrapped[WHITE] = ILLEGAL_COOR; + +#ifdef EVAL_HASH + // + // Check the eval hash + // + iScoreForSideToMove = ProbeEvalHash(ctx); + if (iScoreForSideToMove != INVALID_SCORE) + { + INC(ctx->sCounters.tree.u64EvalHashHits); + goto end; + } +#endif + + pos->iScore[BLACK] = + (pos->uPawnMaterial[BLACK] + pos->uNonPawnMaterial[BLACK]); + pos->iScore[WHITE] = + (pos->uPawnMaterial[WHITE] + pos->uNonPawnMaterial[WHITE]); +#ifdef EVAL_DUMP + EvalTraceClear(); + Trace("Material:\n%d\t\t%d\n", pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + + // + // Pawn eval. Note: if fDeferred comes back as TRUE then we have + // neither cleared nor initialized the attack tables. This is + // because we hope that we can get a lazy eval cutoff here and + // save some time. BEFORE ANY CODE BELOW TOUCHES THE ATTACK + // TABLES IT NEEDS TO CLEAR/POPULATE THEM THOUGH!!! + // + pHash = _EvalPawns(ctx, &fDeferred); + ASSERT(NULL != pHash); + ASSERT(IS_VALID_FLAG(fDeferred)); + pos->iScore[WHITE] += pHash->iScore[WHITE]; + pos->iScore[BLACK] += pHash->iScore[BLACK]; + ASSERT(IS_VALID_SCORE(pos->iScore[WHITE] - pos->iScore[BLACK])); +#ifdef EVAL_DUMP + Trace("After pawns:\n%d\t\t%d\n", pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + + // + // Look for won passers races. Note: This code cannot trust the + // state of the attack tables yet! + // + if ((pos->uNonPawnCount[WHITE][0] == 1) || + (pos->uNonPawnCount[BLACK][0] == 1)) + { + (void)EvalPasserRaces(pos, pHash); +#ifdef EVAL_DUMP + Trace("After passer races:\n%d\t\t%d\n", pos->iScore[WHITE], + pos->iScore[BLACK]); +#endif + } + + // + // Bad trade code. Right. Note: this code cannot trust the state + // of the attack tables... + // + if (pos->uNonPawnMaterial[WHITE] != pos->uNonPawnMaterial[BLACK]) + { + _EvalBadTrades(pos); +#ifdef EVAL_DUMP + Trace("After bad trades:\n%d\t\t%d\n", pos->iScore[WHITE], + pos->iScore[BLACK]); +#endif + } + + // + // Bishop pairs. Again... Note: this code cannot trust the state + // of the attack tables. + // + _EvalBishopPairs(pos); +#ifdef EVAL_DUMP + Trace("After bishop pair bonus:\n%d\t\t%d\n", pos->iScore[WHITE], + pos->iScore[BLACK]); +#endif + +#ifdef LAZY_EVAL + // + // Compute an estimate of the score for the side to move based on the + // eval terms we have already considered: + // + // 1. Material balance + // 2. Pawn structure bonuses/penalties (incl passers/candidates) + // 3. Passer races are detected already + // 4. "Bad trade" code has already run + // 5. We've already detected unwinnable endgames + // 6. Bishop pairs + // + iScoreForSideToMove = (pos->iScore[pos->uToMove] - + pos->iScore[FLIP(pos->uToMove)]); + ASSERT(IS_VALID_SCORE(iScoreForSideToMove)); + + // + // Eval has not considered several potentially large terms: + // + // 1. Piece positional components (such as mobility, trapped) + // 2. King safety penalties + // 3. Other miscellaneous bonuses/penalties + // + // We build two "margins" to account for these components of the + // score. + // + iAlphaMargin = iBetaMargin = (50 + (SCORE)ctx->uPositional); + + // + // If (score + alpha_margin) is already > alpha -OR- + // (score - beta_margin) is already < beta + // + // ...then we can stop thinking about lazy eval; the rest of the + // computation only increases the margin so we know LE will fail + // and can save some work here. + // + if ((iScoreForSideToMove + iAlphaMargin < iAlpha) || + (iScoreForSideToMove - iBetaMargin > iBeta)) + { + // + // Ok, we can't say for sure that we won't take a lazy exit + // yet. So do the expensive part of lazy eval estimation and + // widen the margin further for king safety issues and passed + // pawns. + // + _QuicklyEstimateKingSafetyTerm(pos, &iAlphaMargin, &iBetaMargin); + _QuicklyEstimatePasserBonuses(pos, pHash, &iAlphaMargin, &iBetaMargin); + + if ((iScoreForSideToMove + iAlphaMargin <= iAlpha) || + (iScoreForSideToMove - iBetaMargin >= iBeta)) + { + ctx->uPositional = MINU(200, ctx->uPositional); + INC(ctx->sCounters.tree.u64LazyEvals); + goto end; + } + } +#endif + + // + // If we have to clear/populate the attack table, do it now that + // we know we aren't taking a lazy exit. + // + if (TRUE == fDeferred) + { + _PopulatePawnAttackBits(pos); + } + + // + // Pre-compute some common terms used in per-piece evals: + // + // This is a scaler based on the size of the army for each side. + // + pos->uArmyScaler[BLACK] = pos->uNonPawnMaterial[BLACK] - VALUE_KING; + pos->uArmyScaler[WHITE] = pos->uNonPawnMaterial[WHITE] - VALUE_KING; + pos->uArmyScaler[BLACK] /= VALUE_PAWN; + pos->uArmyScaler[WHITE] /= VALUE_PAWN; + ASSERT(!(pos->uArmyScaler[BLACK] & 0x80000000)); + ASSERT(!(pos->uArmyScaler[WHITE] & 0x80000000)); + pos->uArmyScaler[BLACK] = MINU(31, pos->uArmyScaler[BLACK]); + pos->uArmyScaler[WHITE] = MINU(31, pos->uArmyScaler[WHITE]); + ASSERT(pos->uArmyScaler[BLACK] >= 0); + ASSERT(pos->uArmyScaler[BLACK] <= 31); + ASSERT(pos->uArmyScaler[WHITE] >= 0); + ASSERT(pos->uArmyScaler[WHITE] <= 31); + pos->iReducedMaterialDownScaler[BLACK] = + pos->iReducedMaterialDownScaler[WHITE] = 0; + + // + // This is a "position is closed|open" number. + // + pos->uClosedScaler = (pos->uPawnCount[WHITE] + pos->uPawnCount[BLACK]) - + (pHash->uNumUnmovedPawns[WHITE] + pHash->uNumUnmovedPawns[BLACK]) + + (pHash->uNumRammedPawns); + ASSERT(pos->uClosedScaler >= 0); + ASSERT(pos->uClosedScaler <= 32); + + // + // Evaluate individual pieces. + // + pos->uMinorsAtHome[BLACK] = pos->uMinorsAtHome[WHITE] = 0; + uDefer[BLACK][0] = uDefer[BLACK][1] = + uDefer[WHITE][0] = uDefer[WHITE][1] = 0; + uColor = pos->uToMove; + for (u = 1; // skips the king + u < pos->uNonPawnCount[uColor][0]; + u++) + { + c = pos->cNonPawns[uColor][u]; + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(IS_VALID_PIECE(p)); + ASSERT(GET_COLOR(p) == uColor); + ASSERT(!IS_PAWN(p) && !IS_KING(p)); + + if (p & 0x4) + { + ASSERT(IS_BISHOP(p) || IS_KNIGHT(p)); + + // + // Note: The side on move's pieces of value X are + // evaluated and have their mobility counted and added to + // the attack table before the other side's pieces. Also, + // we do not care if JumpTable tells us this piece is in + // danger b/c we will find out later on in + // EvalLookForDanger anyway. + // + ASSERT(JumpTable[p]); + (void)(JumpTable[p])(pos, c, pHash); +#ifdef EVAL_DUMP + Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + else + { + ASSERT(IS_ROOK(p) || IS_QUEEN(p)); + cDefer[uColor][IS_QUEEN(p)][uDefer[uColor][IS_QUEEN(p)]++] = c; + } + } + + uColor = FLIP(uColor); + ASSERT(uColor != pos->uToMove); + for (u = 1; + u < pos->uNonPawnCount[uColor][0]; + u++) + { + c = pos->cNonPawns[uColor][u]; + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(IS_VALID_PIECE(p)); + ASSERT(GET_COLOR(p) == uColor); + ASSERT(!IS_PAWN(p) && !IS_KING(p)); + if (p & 0x4) + { + // + // This time we are evaluating a piece from the side not + // on move. We will not go back later and look at this + // piece again so if JumpTable tells us it's in danger + // then record it. The drawback, of course, is that the + // JumpTable routines only detect danger if a piece is + // attacked by an enemy of lesser value! + // + ASSERT(JumpTable[p]); + (void)(JumpTable[p])(pos, c, pHash); +#ifdef EVAL_DUMP + Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + else + { + ASSERT(IS_ROOK(p) || IS_QUEEN(p)); + cDefer[uColor][IS_QUEEN(p)][uDefer[uColor][IS_QUEEN(p)]++] = c; + } + } + + // + // Evaluate any rook(s) for side on move then for side not on move. + // + uColor = FLIP(uColor); + for (u = 0; + u < uDefer[uColor][0]; + u++) + { + c = cDefer[uColor][0][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ROOK(pos->rgSquare[c].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[c].pPiece) == uColor); + _EvalRook(pos, c, pHash); +#ifdef EVAL_DUMP + p = BLACK_ROOK | uColor; + Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + + uColor = FLIP(uColor); + for (u = 0; + u < uDefer[uColor][0]; + u++) + { + c = cDefer[uColor][0][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_ROOK(pos->rgSquare[c].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[c].pPiece) == uColor); + _EvalRook(pos, c, pHash); +#ifdef EVAL_DUMP + p = BLACK_ROOK | uColor; + Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + + // + // Evaluate any queen(s) for side on move then for side not on move. + // + uColor = FLIP(uColor); + for (u = 0; + u < uDefer[uColor][1]; + u++) + { + c = cDefer[uColor][1][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_QUEEN(pos->rgSquare[c].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[c].pPiece) == uColor); + _EvalQueen(pos, c, pHash); +#ifdef EVAL_DUMP + p = BLACK_ROOK | uColor; + Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + + uColor = FLIP(uColor); + for (u = 0; + u < uDefer[uColor][1]; + u++) + { + c = cDefer[uColor][1][u]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(IS_QUEEN(pos->rgSquare[c].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[c].pPiece) == uColor); + _EvalQueen(pos, c, pHash); +#ifdef EVAL_DUMP + p = BLACK_ROOK | uColor; + Trace("After %s:\n%d\t\t%d\n", PieceAbbrev(p), + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + + // + // Evaluate the two kings last. + // + c = pos->cNonPawns[BLACK][0]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(IS_VALID_PIECE(p)); + ASSERT(GET_COLOR(p) == BLACK); + ASSERT(IS_KING(p)); + ASSERT(JumpTable[p]); +#endif + _EvalKing(pos, c, pHash); + ctx->sPlyInfo[ctx->uPly].iKingScore[BLACK] = pos->iTempScore; +#ifdef EVAL_DUMP + Trace("After *k:\n%d\t\t%d\n", pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + + c = pos->cNonPawns[WHITE][0]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(IS_VALID_PIECE(p)); + ASSERT(GET_COLOR(p) == WHITE); + ASSERT(IS_KING(p)); + ASSERT(JumpTable[p]); +#endif + _EvalKing(pos, c, pHash); + ctx->sPlyInfo[ctx->uPly].iKingScore[WHITE] = pos->iTempScore; +#ifdef EVAL_DUMP + Trace("After .k:\n%d\t\t%d\n", pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + + // + // Now that we have the whole attack table generated, think about + // passed pawns identified by the pawn eval routine again. Also + // see if the side not on move has a trapped piece. + // + bb = (pHash->bbPasserLocations[WHITE] | pHash->bbPasserLocations[BLACK]); + if (0 != bb) + { + _EvalPassers(pos, pHash); +#ifdef EVAL_DUMP + Trace("After passers:\n%d\t\t%d\n", pos->iScore[WHITE], + pos->iScore[BLACK]); +#endif + } + + // + // Make one more pass over the piece list for the side on move now + // that the full attack table is computed to detect + // under/unprotected pieces en prise to more valuable enemy pieces + // which we missed when building the attack table incrementally. + // + ctx->sPlyInfo[ctx->uPly].uMinMobility[BLACK] = pos->uMinMobility[BLACK]; + ctx->sPlyInfo[ctx->uPly].uMinMobility[WHITE] = pos->uMinMobility[WHITE]; + _EvalLookForDanger(ctx); + _EvalTrappedPieces(ctx); + + // + // B over N in the endgame with 2 pawn wings. + // + if ((pos->uNonPawnCount[WHITE][0] <= 2) && + (pos->uNonPawnCount[BLACK][0] <= 2)) + { + if ((pos->uNonPawnCount[WHITE][BISHOP] > 0) && + (pos->uNonPawnCount[BLACK][BISHOP] > 0)) + { + if ((pos->uNonPawnCount[BLACK][0] == 2) && + (pos->uNonPawnCount[WHITE][0] == 2)) + { + ASSERT(pos->uNonPawnCount[BLACK][BISHOP] == 1); + ASSERT(pos->uNonPawnCount[WHITE][BISHOP] == 1); + if (pos->uWhiteSqBishopCount[BLACK] + + pos->uWhiteSqBishopCount[WHITE] == 1) + { + pos->iScore[WHITE] /= 2; + pos->iScore[BLACK] /= 2; + } + } + } + else + { + // + // At least one side has no bishop. Look for positions + // with two pawn wings where having a bishop is an + // advantage. + // + bb = (pHash->bbPawnLocations[WHITE] | + pHash->bbPawnLocations[BLACK]); + ASSERT((BBFILE[A] | BBFILE[B] | BBFILE[C]) == + 0x0707070707070707ULL); + ASSERT((BBFILE[F] | BBFILE[G] | BBFILE[H]) == + 0xe0e0e0e0e0e0e0e0ULL); + if ((bb & 0x0707070707070707ULL) && + (bb & 0xe0e0e0e0e0e0e0e0ULL)) + { + if ((pos->uNonPawnCount[BLACK][BISHOP] == 0) && + (pos->uNonPawnCount[WHITE][BISHOP] > 0)) + { + EVAL_TERM(WHITE, + BISHOP, + 0x88, + pos->iScore[WHITE], + BISHOP_OVER_KNIGHT_IN_ENDGAME * + pos->uNonPawnCount[WHITE][BISHOP], + "endgame w/ 2 pawn flanks"); + } + else if ((pos->uNonPawnCount[BLACK][BISHOP] > 0) && + (pos->uNonPawnCount[WHITE][BISHOP] == 0)) + { + EVAL_TERM(BLACK, + BISHOP, + 0x88, + pos->iScore[BLACK], + BISHOP_OVER_KNIGHT_IN_ENDGAME * + pos->uNonPawnCount[BLACK][BISHOP], + "endgame w/ 2 pawn flanks"); + } + } + } +#ifdef EVAL_DUMP + Trace("After BOOC / BvsN:\n%d\t\t%d\n", + pos->iScore[WHITE], pos->iScore[BLACK]); +#endif + } + + // + // Roll in the reduced material down scaler terms. + // + ASSERT(pos->iReducedMaterialDownScaler[BLACK] > -200); + ASSERT(pos->iReducedMaterialDownScaler[BLACK] < +200); + iAlphaMargin = (pos->iReducedMaterialDownScaler[BLACK] * + (SCORE)REDUCED_MATERIAL_DOWN_SCALER[pos->uArmyScaler[BLACK]]) / 8; + pos->iScore[BLACK] += iAlphaMargin; + ASSERT(pos->iReducedMaterialDownScaler[WHITE] > -200); + ASSERT(pos->iReducedMaterialDownScaler[WHITE] < +200); + iAlphaMargin = (pos->iReducedMaterialDownScaler[WHITE] * + (SCORE)REDUCED_MATERIAL_DOWN_SCALER[pos->uArmyScaler[WHITE]]) / 8; + pos->iScore[WHITE] += iAlphaMargin; + + // + // Almost done + // + iScoreForSideToMove = (pos->iScore[pos->uToMove] - + pos->iScore[FLIP(pos->uToMove)]); +#ifdef EVAL_DUMP + Trace("At the end:\n%d\t\t%d\n", pos->iScore[WHITE], + pos->iScore[BLACK]); +#endif + + // + // TODO: detect and discourage blocked positions? + // + + // + // TODO: drive the score towards zero as we approach a 50 move w/o + // progress draw. + // + + // + // Adjust dynamic positional component. + // + iAlphaMargin = abs(pos->iMaterialBalance[pos->uToMove] - iScoreForSideToMove); + if ((ULONG)iAlphaMargin > ctx->uPositional) + { + ctx->uPositional = (ULONG)iAlphaMargin; + } + else + { + ctx->uPositional -= (ctx->uPositional - (ULONG)iAlphaMargin) / 4; + ctx->uPositional = MAXU(ctx->uPositional, VALUE_PAWN); + } + g_Options.iLastEvalScore = iScoreForSideToMove; + +#ifdef EVAL_TIME + ctx->sCounters.tree.u64CyclesInEval += (SystemReadTimeStampCounter() - + uTimer); +#endif + INC(ctx->sCounters.tree.u64FullEvals); + +#ifdef EVAL_HASH + // + // Store in eval hash. + // + StoreEvalHash(ctx, iScoreForSideToMove); +#endif + + end: + ASSERT(IS_VALID_SCORE(iScoreForSideToMove)); + ASSERT((iScoreForSideToMove > -NMATE) && + (iScoreForSideToMove < +NMATE)); + ASSERT(abs(ctx->sPlyInfo[ctx->uPly].iKingScore[BLACK]) < 700); + ASSERT(abs(ctx->sPlyInfo[ctx->uPly].iKingScore[WHITE]) < 700); + ASSERT(ctx->sPlyInfo[ctx->uPly].uMinMobility[BLACK] <= 100); + ASSERT(ctx->sPlyInfo[ctx->uPly].uMinMobility[WHITE] <= 100); + ASSERT((ctx->uPositional < 2500) && (ctx->uPositional >= VALUE_PAWN)); + return(iScoreForSideToMove); +} diff --git a/src/evalhash.c b/src/evalhash.c new file mode 100644 index 0000000..e0bc75e --- /dev/null +++ b/src/evalhash.c @@ -0,0 +1,148 @@ +/*++ + +Copyright (c) Scott Gasch + +Module Name: + + evalhash.c + +Abstract: + + Evaluation score hashing code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 11 Jul 2006 + +Revision History: + +--*/ + +#include "chess.h" +#ifdef EVAL_HASH + +extern ULONG g_uIterateDepth; + +SCORE +GetRoughEvalScore(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash) +/*++ + +Routine description: + + This is meant to be the "one place" that code looks when it needs to + get an idea of the estimated evaluation of a position (in mid tree, + not at the leaves... at the leaves just call Eval directly). + + The thought is that: + + 1. The top of the tree (near the root) represents very few nodes + which have big subtrees. Use the real Eval here. + + 2. Otherwise possibly probe the eval hash -- if there's a score in + it then we can return quickly. + + 3. Otherwise do a (very) rough material estimate. + +Parameters: + + IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash + +Return value: + + SCORE + +--*/ +{ + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key; + ULONG u; + + if (ctx->uPly <= 4) + { + return Eval(ctx, iAlpha, iBeta); + } + else if ((fUseHash) || (ctx->uPly <= (g_uIterateDepth / 2))) + { + u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig); + u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1); + if (ctx->rgEvalHash[u].u64Key == u64Key) + { + ctx->uPositional = ctx->rgEvalHash[u].uPositional; + return(ctx->rgEvalHash[u].iEval); + } + } + return(pos->iMaterialBalance[pos->uToMove] + ctx->uPositional); +} + + +SCORE +ProbeEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx) +/*++ + +Routine description: + + Probe the eval hash; return a real score if there's a hit + otherwise return INVALID_SCORE. + +Parameters: + + IN OUT SEARCHER_THREAD_CONTEXT *ctx : note that in the case + of a hit, *ctx is modified also. + +Return value: + + SCORE + +--*/ +{ + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig); + ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1); + + if (ctx->rgEvalHash[u].u64Key == u64Key) + { + ctx->uPositional = ctx->rgEvalHash[u].uPositional; + pos->cTrapped[WHITE] = ctx->rgEvalHash[u].cTrapped[WHITE]; + pos->cTrapped[BLACK] = ctx->rgEvalHash[u].cTrapped[BLACK]; + return(ctx->rgEvalHash[u].iEval); + } + return(INVALID_SCORE); +} + +void +StoreEvalHash(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iScore) +/*++ + +Routine description: + + Store a score in the eval hash table (which is pointed to + indirectly via ctx). + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iScore + +Return value: + + void + +--*/ +{ + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key = (pos->u64PawnSig ^ pos->u64NonPawnSig); + ULONG u = (ULONG)u64Key & (EVAL_HASH_TABLE_SIZE - 1); + ctx->rgEvalHash[u].u64Key = u64Key; + ctx->rgEvalHash[u].iEval = iScore; + ctx->rgEvalHash[u].uPositional = ctx->uPositional; + ctx->rgEvalHash[u].cTrapped[WHITE] = pos->cTrapped[WHITE]; + ctx->rgEvalHash[u].cTrapped[BLACK] = pos->cTrapped[BLACK]; +} +#endif // EVAL_HASH diff --git a/src/fen.c b/src/fen.c new file mode 100755 index 0000000..4d9b526 --- /dev/null +++ b/src/fen.c @@ -0,0 +1,715 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + fen.c + +Abstract: + + Routines that translate from an internal POSITION structure into a + FEN string and vice versa. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: fen.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +char g_chPieceTypeToAbbrev[] = { '_', 'p', 'n', 'b', 'r', 'q', 'k' }; +char *g_szPieceAbbrevs = "pPnNbBrRqQkK"; + +FLAG LooksLikeFen(char *p) +/** + +Routine description: + + Does some string look like a FEN? + +Parameters: + + char *p : the string in question + +Return value: + + FLAG : TRUE if yes, FALSE otherwise + +**/ +{ + POSITION q; + return(FenToPosition(&q, p)); +} + + +#define MAX_FEN_LEN_BYTES (128) + +char * +PositionToFen(IN POSITION *pos) +/** + +Routine description: + + Translate a POSITION structure into a FEN string and return a pointer + to that string. This function allocates memory that the caller must + free. This code _is_ thread safe. + +Parameters: + + POSITION *p : the position to translate + +Return value: + + char * : FEN representing POSITION *p. NULL on error. + +**/ +{ + ULONG uNumEmpty; // num emmpty squares in a row + COOR c; // square + PIECE p; // the piece there + char *pHeap = NULL; // ptr to a block of heap + char *pch; // used to build the string + + // + // Alloc a buffer. The caller must free this. Note: I contend that + // the longest possible FEN string capable of being generated by this + // code is something like: + // + // "k1q1r1r1/b1b1n1n1/p1p1p1p1/p1p1p1p1/K1Q1R1R1/B1B1N1N1/P1P1P1P1/P1P1P1P1 w KQkq d3 49" + // + // ...which is 85 characters long. I allocate 128 here to be safe. + // + pHeap = SystemAllocateMemory(MAX_FEN_LEN_BYTES); + ASSERT(pHeap); + pch = pHeap; + memset(pHeap, 0, MAX_FEN_LEN_BYTES); + + // + // The first field represents the placement of the pieces on the + // board. The board contents are specified starting with the + // eighth rank and ending with the first rank. For each rank, the + // squares are specified from file a to file h. White pieces are + // identified by uppercase SAN piece letters ("PNBRQK") and black + // pieces are identified by lowercase SAN piece letters + // ("pnbrqk"). Empty squares are represented by the digits one + // through eight; the digit used represents the count of + // contiguous empty squares along a rank. A solidus character "/" + // is used to separate data of adjacent ranks. + // + uNumEmpty = 0; + FOREACH_SQUARE(c) + { + if (!IS_ON_BOARD(c)) + { + if (0 != uNumEmpty) + { + ASSERT(uNumEmpty < 9); + *pch++ = (char)(uNumEmpty + '0'); + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + uNumEmpty = 0; + } + if ((c % 8) == 0) *pch++ = '/'; + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + continue; + } + + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + uNumEmpty++; + } + else + { + ASSERT(IS_VALID_PIECE(p)); + if (0 != uNumEmpty) + { + ASSERT(uNumEmpty < 9); + *pch++ = (char)(uNumEmpty + '0'); + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + uNumEmpty = 0; + } + + *pch = g_chPieceTypeToAbbrev[PIECE_TYPE(p)]; + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + if (IS_WHITE_PIECE(p)) + { + *pch = (char)toupper(*pch); + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + } + pch++; + } + } + if (0 != uNumEmpty) + { + ASSERT(uNumEmpty < 9); + *pch++ = (char)(uNumEmpty + '0'); + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + uNumEmpty = 0; + } + + // + // The second field represents the active color. A lower case "w" + // is used if White is to move; a lower case "b" is used if Black + // is the active player. + // + *pch++ = ' '; + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + ASSERT(IS_VALID_COLOR(pos->uToMove)); + if (WHITE == pos->uToMove) + { + *pch++ = 'w'; + } + else + { + *pch++ = 'b'; + } + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + + // + // The third field represents castling availability. This + // indicates potential future castling that may of may not be + // possible at the moment due to blocking pieces or enemy attacks. + // If there is no castling availability for either side, the + // single character symbol "-" is used. Otherwise, a combination + // of from one to four characters are present. If White has + // kingside castling availability, the uppercase letter "K" + // appears. If White has queenside castling availability, the + // uppercase letter "Q" appears. If Black has kingside castling + // availability, the lowercase letter "k" appears. If Black has + // queenside castling availability, then the lowercase letter "q" + // appears. Those letters which appear will be ordered first + // uppercase before lowercase and second kingside before + // queenside. There is no white space between the letters. + // + *pch++ = ' '; + *pch++ = '\0'; + ASSERT(strlen(pHeap) < MAX_FEN_LEN_BYTES); + sprintf(pHeap, + "%s%s %s %u %u", + pHeap, + CastleInfoString(pos->bvCastleInfo), + CoorToString(pos->cEpSquare), + pos->uFifty, + 0); + return(pHeap); // Note: caller must free +} + + +static FLAG +_FenToPosition_DoPiecePart(IN OUT POSITION *pos, + IN char *pPieces) +/** + +Routine description: + + The part of FenToPosition that parses the board/piece data in the + FEN string and sets the appropriate parts of POSITION *p. + +Parameters: + + POSITION *pos, + char *pPieces + +Return value: + + static FLAG : TRUE on success, FALSE otherwise + +**/ +{ + char *pPieceIndex; + ULONG uPieceIndex; + ULONG uPieceCounters[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }; + ULONG uNumNonPawns[2] = { 0, 0 }; + ULONG uColor; + ULONG uFile = 0; + ULONG uIndex; + PIECE p; + COOR cSquare; + + // + // Parse board position + // + cSquare = A8; + ASSERT(!isspace(*pPieces)); + while(!isspace(*pPieces) && *pPieces) + { + if (cSquare > ARRAY_SIZE(pos->rgSquare)) + { + Trace("FenToPosition: Ignoring extra piece/board information.\n"); + break; + } + + pPieceIndex = strchr(g_szPieceAbbrevs, *pPieces); + if (NULL == pPieceIndex) + { + switch(*pPieces) + { + case ('/'): + case ('\\'): + uFile++; + cSquare = 16 * uFile; + break; + + case ('-'): + // + // Incrementing the file here handles fens without + // delimiting slashes too. + // + cSquare++; + break; + + case ('\n'): + break; + + default: + if (isdigit(*pPieces)) + { + cSquare += (*pPieces - '0'); + } + else + { + Trace("FenToPosition: Ignoring bad piece '%c' in FEN " + "information.\n"); + } + } + } + else + { + // + // The position of the piece code in the g_szPieceAbbrevs array + // cooresponds to the piece type. + // + uPieceIndex = (ULONG)((BYTE *)pPieceIndex - + (BYTE *)g_szPieceAbbrevs); + uPieceIndex += 2; + p = (PIECE)uPieceIndex; + ASSERT(IS_VALID_PIECE(p)); + uColor = PIECE_COLOR(p); + ASSERT(IS_VALID_COLOR(uColor)); + + if (IS_PAWN(p)) + { + // + // The pawn list is not ordered at all, add the new pawn's + // location to the list and point from the pawn to the list. + // + pos->cPawns[uColor][uPieceCounters[uPieceIndex]] = cSquare; + pos->rgSquare[cSquare].uIndex = uPieceCounters[uPieceIndex]; + pos->rgSquare[cSquare].pPiece = p; + pos->uPawnMaterial[uColor] += VALUE_PAWN; + } + else + { + if (IS_KING(p)) + { + if (pos->cNonPawns[uColor][0] != ILLEGAL_COOR) + { + Trace("_FenToPosition: I can't handle positions with " + "more than one king, sorry.\n"); + return(FALSE); + } + pos->cNonPawns[uColor][0] = cSquare; + uIndex = 0; + } + else + { + if (IS_BISHOP(p)) + { + if (IS_WHITE_SQUARE_COOR(cSquare)) + { + pos->uWhiteSqBishopCount[uColor]++; + } + } + uIndex = uNumNonPawns[uColor] + 1; + pos->cNonPawns[uColor][uIndex] = cSquare; + uNumNonPawns[uColor]++; + } + pos->rgSquare[cSquare].pPiece = p; + pos->rgSquare[cSquare].uIndex = uIndex; + pos->uNonPawnMaterial[uColor] += PIECE_VALUE(p); + } + uPieceCounters[uPieceIndex]++; + cSquare++; + } + pPieces++; + } + + // + // Set the piece counts based on uPieceCounter contents + // + if (IS_ON_BOARD(pos->cNonPawns[WHITE][0])) + { + uNumNonPawns[WHITE]++; + } + pos->uNonPawnCount[WHITE][0] = uNumNonPawns[WHITE]; + if (IS_ON_BOARD(pos->cNonPawns[BLACK][0])) + { + uNumNonPawns[BLACK]++; + } + pos->uNonPawnCount[BLACK][0] = uNumNonPawns[BLACK]; + FOREACH_COLOR(uColor) + { + pos->uPawnCount[uColor] = uPieceCounters[(PAWN << 1) | uColor]; + for (p = KNIGHT; p <= KING; p++) + { + pos->uNonPawnCount[uColor][p] = + uPieceCounters[(p << 1) | uColor]; + } + } + ASSERT((pos->uPawnCount[WHITE] * VALUE_PAWN) == pos->uPawnMaterial[WHITE]); + ASSERT((pos->uPawnCount[BLACK] * VALUE_PAWN) == pos->uPawnMaterial[BLACK]); + + if ((ILLEGAL_COOR == pos->cNonPawns[BLACK][0]) || + (ILLEGAL_COOR == pos->cNonPawns[WHITE][0])) + { + Trace("FenToPosition: Warning, missing king location.\n"); + } + return(TRUE); +} + + + +static FLAG +_FenToPosition_DoSideToMove(IN OUT POSITION *p, + IN char *pFen) +/** + +Routine description: + + The part of FenToPosition that parses side to move part of the FEN + string and sets POSITION *p appropriately. + +Parameters: + + POSITION *p, + char *pFen + +Return value: + + static FLAG : TRUE on success, FALSE otherwise + +**/ +{ + p->uToMove = BAD_COLOR; + while(!isspace(*pFen) && *pFen) + { + if ((toupper(*pFen) == 'W') || + (*pFen == '-')) + { + p->uToMove = WHITE; + break; + } + else if ((toupper(*pFen) == 'B')) + { + p->uToMove = BLACK; + break; + } + else + { + Trace("FenToPosition: Ignoring invalid side to move '%c'.\n", + *pFen); + } + pFen++; + } + + if (BAD_COLOR == p->uToMove) + { + Trace("FenToPosition: Never figured out a side to move, defaulting to " + "WHITE to move.\n"); + p->uToMove = WHITE; + } + return(TRUE); +} + + +static FLAG +_FenToPosition_DoCastlingPermissions(IN OUT POSITION *p, + IN char *pCastle) +/** + +Routine description: + + Do the castling part of the FenToPosition function. Sets the proper + castling bits in the POSITION pointed to by p based on the text in + *pCastle. + +Parameters: + + POSITION *p : position to affect + char *pCastle : pointer to castle part of FEN string + +Return value: + + static FLAG : TRUE on success, FALSE otherwise + +**/ +{ + ASSERT(p->bvCastleInfo == 0); + while(!isspace(*pCastle) && *pCastle) + { + switch (*pCastle) + { + case ('K'): + if ((p->rgSquare[E1].pPiece == WHITE_KING) && + (p->rgSquare[H1].pPiece == WHITE_ROOK)) + { + p->bvCastleInfo |= CASTLE_WHITE_SHORT; + } + break; + case ('Q'): + if ((p->rgSquare[E1].pPiece == WHITE_KING) && + (p->rgSquare[A1].pPiece == WHITE_ROOK)) + { + p->bvCastleInfo |= CASTLE_WHITE_LONG; + } + break; + case ('k'): + if ((p->rgSquare[E8].pPiece == BLACK_KING) && + (p->rgSquare[H8].pPiece == BLACK_ROOK)) + { + p->bvCastleInfo |= CASTLE_BLACK_SHORT; + } + break; + case ('q'): + if ((p->rgSquare[E8].pPiece == BLACK_KING) && + (p->rgSquare[A8].pPiece == BLACK_ROOK)) + { + p->bvCastleInfo |= CASTLE_BLACK_LONG; + } + break; + case ('-'): + case ('\n'): + break; + default: + Trace("FenToPosition: Ignoring invalid castling option char" + "acter '%c'.\n", *pCastle); + } + pCastle++; + } + return(TRUE); +} + + + +static FLAG +_FenToPosition_DoEnPassant(IN OUT POSITION *p, + IN char *pEnPassant) +/** + +Routine description: + + The part of FenToPosition that handles translating an en-passant + square in the FEN string into the appropriate settings in the + POSITION structure. + +Parameters: + + POSITION *p : the position to populate + char *pEnPassant : the string that describes how to populate it + +Return value: + + static FLAG : TRUE on success, FALSE otherwise + +**/ +{ + COOR cEp = ILLEGAL_COOR; + ASSERT(!isspace(*pEnPassant)); + + if (*pEnPassant != '-') + { + cEp = FILE_RANK_TO_COOR((tolower(pEnPassant[0]) - 'a'), + (tolower(pEnPassant[1]) - '0')); + if ((!RANK3(cEp)) && (!RANK6(cEp))) + { + Trace("FenToPosition: Ignoring bogus enpassant coord '%c%c'\n", + pEnPassant[0], pEnPassant[1]); + } + else + { + if (WHITE == p->uToMove) + { + if ((p->rgSquare[cEp + 15].pPiece != WHITE_PAWN) && + (p->rgSquare[cEp + 17].pPiece != WHITE_PAWN)) + { + Trace("FenToPosition: Ignoring bogus en-passant " + "coordinate '%c%c'\n", pEnPassant[0], pEnPassant[1]); + cEp = ILLEGAL_COOR; + } + } + else + { + ASSERT(p->uToMove == BLACK); + if ((p->rgSquare[cEp - 15].pPiece != BLACK_PAWN) && + (p->rgSquare[cEp - 17].pPiece != BLACK_PAWN)) + { + Trace("FenToPosition: Ignoring bogus en-passant " + "coordinate '%c%c'\n", pEnPassant[0], pEnPassant[1]); + cEp = ILLEGAL_COOR; + } + } + } + } + ASSERT(VALID_EP_SQUARE(cEp)); + p->cEpSquare = cEp; + return(TRUE); +} + +void +_FenToPosition_DoFiftyOrEpdOpcodes(POSITION *p, + char *szFifty) +/** + +Routine description: + + Do the fifty-moves-without-progress part or handle the EPD + opcodes. + +Parameters: + + POSITION *p, + char *szFifty + +Return value: + + void + +**/ +{ + ULONG u = 0; + int i; + CHAR *q, *op; + + p->uFifty = 0; + q = FindChunk(szFifty, u); + u++; + while(NULL != q) + { + //printf("%u: %s\n", u-1, q); + + i = atoi(q); + if ((i > 0) && (i < 100)) + { + p->uFifty = (ULONG)i; + } + else + { + if (!STRCMPI(q, "bm")) + { + op = FindChunk(szFifty, u); + u++; + if (NULL == op) break; + } + + } + q = FindChunk(szFifty, u); + u++; + } +} + + + +FLAG +FenToPosition(IN OUT POSITION *p, + IN char *szFen) +/** + +Routine description: + + Translates a FEN string into a POSITION structure. + +Parameters: + + POSITION *p : the POSITION structure to populate + char *szFen : the FEN string that describes how to populate it + +Return value: + + FLAG : TRUE on success, FALSE otherwise + +**/ +{ + char *szCapturedFen = SystemAllocateMemory((ULONG)strlen(szFen) + 2); + char *szPieces, *szToMove, *szCastle, *szEnPassant, *szFifty; + ULONG u; + + // + // Initialize the captured fen buffer with a trailing whitespace char + // + ASSERT(NULL != szCapturedFen); + strcpy(szCapturedFen, szFen); + strcat(szCapturedFen, " "); + + // + // Parse it into chunks + // + szPieces = FindChunk(szCapturedFen, 1); + szToMove = FindChunk(szCapturedFen, 2); + szCastle = FindChunk(szCapturedFen, 3); + szEnPassant = FindChunk(szCapturedFen, 4); + szFifty = FindChunk(szCapturedFen, 5); + if ((NULL == szPieces) || + (NULL == szToMove) || + (NULL == szCastle) || + (NULL == szEnPassant)) + { + return(FALSE); + } + + // + // Clear the position struct + // + memset(p, 0, sizeof(POSITION)); + for (u = 0; u < ARRAY_SIZE(p->cPawns[WHITE]); u++) + { + p->cPawns[WHITE][u] = p->cPawns[BLACK][u] = ILLEGAL_COOR; + } + + for (u = 0; u < ARRAY_SIZE(p->cNonPawns[WHITE]); u++) + { + p->cNonPawns[WHITE][u] = p->cNonPawns[BLACK][u] = ILLEGAL_COOR; + } + + // + // Do the pieces / board + // + if (FALSE == _FenToPosition_DoPiecePart(p, szPieces)) + { + return(FALSE); + } + + if (FALSE == _FenToPosition_DoSideToMove(p, szToMove)) + { + return(FALSE); + } + + if (FALSE == _FenToPosition_DoCastlingPermissions(p, szCastle)) + { + return(FALSE); + } + + if (FALSE == _FenToPosition_DoEnPassant(p, szEnPassant)) + { + return(FALSE); + } + _FenToPosition_DoFiftyOrEpdOpcodes(p, szFifty); + + p->u64NonPawnSig = ComputeSig(p); + p->u64PawnSig = ComputePawnSig(p); + p->iMaterialBalance[WHITE] = + ((SCORE)(p->uNonPawnMaterial[WHITE] + p->uPawnMaterial[WHITE]) - + (SCORE)(p->uNonPawnMaterial[BLACK] + p->uPawnMaterial[BLACK])); + p->iMaterialBalance[BLACK] = p->iMaterialBalance[WHITE] * -1; + +#ifdef DEBUG + VerifyPositionConsistency(p, FALSE); +#endif + SystemFreeMemory(szCapturedFen); + return(TRUE); +} diff --git a/src/gamelist.c b/src/gamelist.c new file mode 100755 index 0000000..70f7e47 --- /dev/null +++ b/src/gamelist.c @@ -0,0 +1,1367 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + gamelist.c + +Abstract: + + Maintain a list of game moves. This list is used to take back + official moves. It's also used to produce PGN at the end of a + game and to detect draws by repetition. This code also maintains + the official "current position" of the game in progress. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 14 May 2004 + +Revision History: + + $Id: gamelist.c 355 2008-07-01 15:46:43Z scott $ + +**/ + +#include "chess.h" + +GAME_DATA g_GameData; +ULONG g_uMoveNumber[2] = { 1, 1 }; +ULONG g_uToMove; +ALIGN64 POSITION g_RootPosition; + +#ifdef DEBUG +ULONG g_uAllocs = 0; +#endif + +#define MOVE_POOL_SIZE (256) +GAME_MOVE g_MovePool[MOVE_POOL_SIZE]; + +static GAME_MOVE * +_GetMoveFromPool(void) +/** + +Routine description: + + Fast GAME_MOVE allocator that uses a preallocated pool. + +Parameters: + + void + +Return value: + + static GAME_MOVE * + +**/ +{ + ULONG x = (rand() % (MOVE_POOL_SIZE - 15)); + ULONG y; + + for (y = x; y < x + 15; y++) + { + if (g_MovePool[y].fInUse == FALSE) + { + LockIncrement(&(g_MovePool[y].fInUse)); + return(&(g_MovePool[y])); + } + } +#ifdef DEBUG + g_uAllocs++; +#endif + return(SystemAllocateMemory(sizeof(GAME_MOVE))); +} + +static void +_ReturnMoveToPool(GAME_MOVE *p) +/** + +Routine description: + + Return a GAME_MOVE to the pool. + +Parameters: + + GAME_MOVE *p + +Return value: + + static void + +**/ +{ + ULONG x = (ULONG)((BYTE *)p - (BYTE *)&g_MovePool); + + x /= sizeof(GAME_MOVE); + if (x < MOVE_POOL_SIZE) + { + g_MovePool[x].fInUse = FALSE; + } + else + { +#ifdef DEBUG + g_uAllocs--; +#endif + SystemFreeMemory(p); + } +} + +static void +_FreeIfNotNull(void *p) +/** + +Routine description: + + Free a pointer if it's not null. + +Parameters: + + void *p + +Return value: + + static void + +**/ +{ + if (NULL != p) + { + SystemFreeMemory(p); +#ifdef DEBUG + g_uAllocs--; +#endif + } +} + +static void +_FreeGameMove(GAME_MOVE *p) +/** + +Routine description: + + Free memory allocated to store a game move. + +Parameters: + + GAME_MOVE *p + +Return value: + + static void + +**/ +{ + ASSERT(NULL != p); + + _FreeIfNotNull(p->szComment); + _FreeIfNotNull(p->szDecoration); + _FreeIfNotNull(p->szMoveInSan); + _FreeIfNotNull(p->szMoveInIcs); + _FreeIfNotNull(p->szUndoPositionFen); + _ReturnMoveToPool(p); +} + +static void +_FreeGameList(void) +/** + +Routine description: + + Free the whole game list. + +Parameters: + + void + +Return value: + + static void + +**/ +{ + DLIST_ENTRY *p; + GAME_MOVE *q; + + if (NULL != g_GameData.sMoveList.pFlink) + { + while(FALSE == IsListEmpty(&(g_GameData.sMoveList))) + { + p = RemoveHeadList(&(g_GameData.sMoveList)); + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + ASSERT(NULL != q); + _FreeGameMove(q); + } + } + _FreeIfNotNull(g_GameData.sHeader.szGameDescription); + _FreeIfNotNull(g_GameData.sHeader.szLocation); + _FreeIfNotNull(g_GameData.sHeader.sPlayer[WHITE].szName); + _FreeIfNotNull(g_GameData.sHeader.sPlayer[WHITE].szDescription); + _FreeIfNotNull(g_GameData.sHeader.sPlayer[BLACK].szName); + _FreeIfNotNull(g_GameData.sHeader.sPlayer[BLACK].szDescription); + _FreeIfNotNull(g_GameData.sHeader.szInitialFen); + memset(&g_GameData, 0, sizeof(g_GameData)); +} + +void +ResetGameList(void) +/** + +Routine description: + + Reset the game list (between games etc...) + +Parameters: + + void + +Return value: + + void + +**/ +{ + _FreeGameList(); + ASSERT(g_uAllocs == 0); + memset(g_MovePool, 0, sizeof(g_MovePool)); + g_uMoveNumber[BLACK] = g_uMoveNumber[WHITE] = 1; + g_uToMove = WHITE; + InitializeListHead(&(g_GameData.sMoveList)); + g_GameData.sHeader.result.eResult = RESULT_IN_PROGRESS; +} + +FLAG +SetRootPosition(CHAR *szFen) +/** + +Routine description: + + Set the root position. + +Parameters: + + CHAR *szFen + +Return value: + + FLAG + +**/ +{ + if (TRUE == FenToPosition(&g_RootPosition, szFen)) + { + ResetGameList(); + g_uToMove = g_RootPosition.uToMove; + TellGamelistThatIPlayColor(FLIP(g_RootPosition.uToMove)); + if (0 != strcmp(szFen, STARTING_POSITION_IN_FEN)) + { + g_GameData.sHeader.szInitialFen = STRDUP(szFen); +#ifdef DEBUG + if (g_GameData.sHeader.szInitialFen) + { + g_uAllocs++; + } +#endif + } + if (g_Options.fShouldPost) + { + DumpPosition(&g_RootPosition); + } + return(TRUE); + } + return(FALSE); +} + +POSITION * +GetRootPosition(void) +/** + +Routine description: + + Get the root position. + +Parameters: + + void + +Return value: + + POSITION + +**/ +{ +#ifdef DEBUG + static POSITION p; + + memcpy(&p, &g_RootPosition, sizeof(POSITION)); + + return(&p); +#else + return(&g_RootPosition); +#endif +} + +void +SetGameResultAndDescription(GAME_RESULT result) +/** + +Routine description: + + Set the game result and a description (both for PGN). + +Parameters: + + GAME_RESULT result + +Return value: + + void + +**/ +{ + g_GameData.sHeader.result = result; +} + +GAME_RESULT GetGameResult(void) +/** + +Routine description: + + Get the game result. + +Parameters: + + void + +Return value: + + INT + +**/ +{ + return g_GameData.sHeader.result; +} + + +GAME_MOVE * +GetNthOfficialMoveRecord(ULONG n) +/** + +Routine description: + + Get the official move record for move N. + +Parameters: + + ULONG n + +Return value: + + GAME_MOVE + +**/ +{ + DLIST_ENTRY *p = g_GameData.sMoveList.pFlink; + GAME_MOVE *q; + + while((p != &(g_GameData.sMoveList)) && + (n != 0)) + { + p = p->pFlink; + n--; + } + + if (n == 0) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + return(q); + } + return(NULL); +} + + +FLAG +DoesSigAppearInOfficialGameList(UINT64 u64Sig) +/** + +Routine description: + + Does sig X appear in the official move list? + +Parameters: + + UINT64 u64Sig + +Return value: + + FLAG + +**/ +{ + DLIST_ENTRY *p = g_GameData.sMoveList.pBlink; + GAME_MOVE *q; + + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if (q->u64PositionSigAfterMove == u64Sig) + { + return(TRUE); + } + if ((q->mv.pCaptured) || (IS_PAWN(q->mv.pMoved))) + { + break; + } + p = p->pBlink; + } + return(FALSE); +} + +ULONG CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig) +/** + +Routine description: + + How many times does sig X appear in the official move list? + +Parameters: + + UINT64 u64Sig + +Return value: + + ULONG + +**/ +{ + DLIST_ENTRY *p = g_GameData.sMoveList.pBlink; + GAME_MOVE *q; + ULONG uCount = 0; + + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if (q->u64PositionSigAfterMove == u64Sig) + { + uCount++; + } + if ((q->mv.pCaptured) || (IS_PAWN(q->mv.pMoved))) + { + break; + } + p = p->pBlink; + } + return(uCount); +} + + +FLAG +IsLegalDrawByRepetition(void) +/** + +Routine description: + + Have we just drawn the game by repetition? + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + POSITION *pos = GetRootPosition(); + UINT64 u64Sig = (pos->u64PawnSig ^ pos->u64NonPawnSig); + + if (3 == CountOccurrancesOfSigInOfficialGameList(u64Sig)) + { + return(TRUE); + } + return(FALSE); +} + + +void +DumpGameList(void) +/** + +Routine description: + + Dump the move list to stdout. + +Parameters: + + void + +Return value: + + void + +**/ +{ + GAME_MOVE *q; + ULONG u = 0; + + Trace("\twhite\tblack\n" + "\t-----\t-----\n"); + q = GetNthOfficialMoveRecord(u); + while((q != NULL) && (q->mv.uMove != 0)) + { + if (GET_COLOR(q->mv.pMoved) == WHITE) + { + Trace("%2u.\t%s\t", q->uNumber, q->szMoveInSan); + } + else + { + Trace("%s\n", q->szMoveInSan); + } + u++; + q = GetNthOfficialMoveRecord(u); + } + Trace("\n"); +} + +void +DumpPgn(void) +/** + +Routine description: + + Dump the PGN of the current game to stdout. + +Parameters: + + void + +Return value: + + void + +**/ +{ + DLIST_ENTRY *p = g_GameData.sMoveList.pFlink; + GAME_MOVE *q; + ULONG u = 0; + + Trace("[Event \"Computer Chess Game\"]\n"); + if (g_GameData.sHeader.szLocation != NULL) + { + Trace("[Site \"%s\"]\n", g_GameData.sHeader.szLocation); + } + Trace("[Date \"%s\"]\n", SystemGetDateString()); + Trace("[Round 0]\n"); + Trace("[White \"%s\"]\n", g_GameData.sHeader.sPlayer[WHITE].szName); + Trace("[Black \"%s\"]\n", g_GameData.sHeader.sPlayer[BLACK].szName); + switch(g_GameData.sHeader.result.eResult) + { + case RESULT_BLACK_WON: + Trace("[Result \"0-1\"]\n"); + break; + case RESULT_WHITE_WON: + Trace("[Result \"1-0\"]\n"); + break; + case RESULT_DRAW: + Trace("[Result \"1/2-1/2\"]\n"); + break; + default: + Trace("[Result \"*\"]\n"); + break; + } + if (g_GameData.sHeader.sPlayer[WHITE].uRating != 0) + { + Trace("[WhiteElo \"%u\"]\n", g_GameData.sHeader.sPlayer[WHITE].uRating); + } + if (g_GameData.sHeader.sPlayer[BLACK].uRating != 0) + { + Trace("[BlackElo \"%u\"]\n", g_GameData.sHeader.sPlayer[BLACK].uRating); + } + if (NULL != g_GameData.sHeader.szInitialFen) + { + Trace("[InitialFEN \"%s\"]\n", g_GameData.sHeader.szInitialFen); + } + // [ECO: XX] + Trace("[Time \"%s\"]\n", SystemGetTimeString()); + /* +9.6.1: Tag: TimeControl + +This uses a list of one or more time control fields. Each field contains a +descriptor for each time control period; if more than one descriptor is present +then they are separated by the colon character (":"). The descriptors appear +in the order in which they are used in the game. The last field appearing is +considered to be implicitly repeated for further control periods as needed. + +There are six kinds of TimeControl fields. + +The first kind is a single question mark ("?") which means that the time +control mode is unknown. When used, it is usually the only descriptor present. + +The second kind is a single hyphen ("-") which means that there was no time +control mode in use. When used, it is usually the only descriptor present. + +The third Time control field kind is formed as two positive integers separated +by a solidus ("/") character. The first integer is the number of moves in the +period and the second is the number of seconds in the period. Thus, a time +control period of 40 moves in 2 1/2 hours would be represented as "40/9000". + +The fourth TimeControl field kind is used for a "sudden death" control period. +It should only be used for the last descriptor in a TimeControl tag value. It +is sometimes the only descriptor present. The format consists of a single +integer that gives the number of seconds in the period. Thus, a blitz game +would be represented with a TimeControl tag value of "300". + +The fifth TimeControl field kind is used for an "incremental" control period. +It should only be used for the last descriptor in a TimeControl tag value and +is usually the only descriptor in the value. The format consists of two +positive integers separated by a plus sign ("+") character. The first integer +gives the minimum number of seconds allocated for the period and the second +integer gives the number of extra seconds added after each move is made. So, +an incremental time control of 90 minutes plus one extra minute per move would +be given by "4500+60" in the TimeControl tag value. + +The sixth TimeControl field kind is used for a "sandclock" or "hourglass" +control period. It should only be used for the last descriptor in a +TimeControl tag value and is usually the only descriptor in the value. The +format consists of an asterisk ("*") immediately followed by a positive +integer. The integer gives the total number of seconds in the sandclock +period. The time control is implemented as if a sandclock were set at the +start of the period with an equal amount of sand in each of the two chambers +and the players invert the sandclock after each move with a time forfeit +indicated by an empty upper chamber. Electronic implementation of a physical +sandclock may be used. An example sandclock specification for a common three +minute egg timer sandclock would have a tag value of "*180". + +Additional TimeControl field kinds will be defined as necessary. + */ + + Trace("\n"); + + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if (GET_COLOR(q->mv.pMoved) == WHITE) + { + Trace("%2u. %s ", q->uNumber, q->szMoveInSan); + } + else + { + Trace("%s ", q->szMoveInSan); + } + u++; + if (u > 10) + { + Trace("\n"); + u = 0; + } + p = p->pFlink; + } + switch(g_GameData.sHeader.result.eResult) + { + case RESULT_BLACK_WON: + Trace("0-1\n"); + break; + case RESULT_WHITE_WON: + Trace("1-0\n"); + break; + case RESULT_DRAW: + Trace("1/2-1/2\n"); + break; + default: + Trace("*\n"); + break; + } + Trace("\n"); + if (strlen(g_GameData.sHeader.result.szDescription)) { + Trace("%s\n", g_GameData.sHeader.result.szDescription); + } +} + +FLAG +OfficiallyTakebackMove(void) +/** + +Routine description: + + Take back a move (i.e. unmake it and delete it from the move + list). + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + DLIST_ENTRY *p; + GAME_MOVE *q; + POSITION *pos = &g_RootPosition; + + if (FALSE == IsListEmpty(&(g_GameData.sMoveList))) + { + p = RemoveTailList(&(g_GameData.sMoveList)); + ASSERT(p); + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if (FALSE == FenToPosition(pos, q->szUndoPositionFen)) + { + UtilPanic(INCONSISTENT_STATE, + pos, + q->szUndoPositionFen, + NULL, + NULL, + __FILE__, __LINE__); + } + _FreeGameMove(q); + VerifyPositionConsistency(pos, FALSE); + + ASSERT(g_uMoveNumber[g_uToMove] > 0); + g_uMoveNumber[g_uToMove] -= 1; + g_uToMove = FLIP(g_uToMove); + return(TRUE); + } + return(FALSE); +} + +FLAG +OfficiallyMakeMove(MOVE mv, + SCORE iMoveScore, + FLAG fFast) +/** + +Routine description: + + Officially make a move (i.e. add it to the game list) + +Parameters: + + MOVE mv, + SCORE iMoveScore + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + FLAG fRet = FALSE; + GAME_MOVE *q; + POSITION *pos = &g_RootPosition; + UINT64 u64SigBefore = pos->u64PawnSig ^ pos->u64NonPawnSig; + + ReInitializeSearcherContext(pos, &ctx); + ASSERT(mv.uMove); + ASSERT(GET_COLOR(mv.pMoved) == g_uToMove); + if (FALSE == MakeUserMove(&ctx, mv)) + { + goto end; + } + + q = _GetMoveFromPool(); + if (NULL == q) + { + goto end; + } + q->uNumber = g_uMoveNumber[g_uToMove]; + ASSERT(q->uNumber > 0); + g_uMoveNumber[g_uToMove] += 1; + ASSERT(g_uMoveNumber[g_uToMove] != 0); + q->mv.uMove = mv.uMove; + q->szComment = NULL; + q->szDecoration = NULL; + q->iMoveScore = iMoveScore; + + q->szMoveInSan = STRDUP(MoveToSan(mv, pos)); +#ifdef DEBUG + if (q->szMoveInSan) + { + g_uAllocs++; + } +#endif + q->szMoveInIcs = STRDUP(MoveToIcs(mv)); +#ifdef DEBUG + if (q->szMoveInIcs) + { + g_uAllocs++; + } +#endif + q->szUndoPositionFen = PositionToFen(pos); +#ifdef DEBUG + g_uAllocs++; +#endif + InsertTailList(&(g_GameData.sMoveList), &(q->links)); + q->u64PositionSigAfterMove = (ctx.sPosition.u64NonPawnSig ^ + ctx.sPosition.u64PawnSig); + q->u64PositionSigBeforeMove = u64SigBefore; + g_uToMove = FLIP(g_uToMove); + + // + // Update the root position + // + memcpy(pos, &(ctx.sPosition), sizeof(POSITION)); + VerifyPositionConsistency(&(ctx.sPosition), FALSE); + fRet = TRUE; + + end: + return(fRet); +} + +ULONG +GetMyColor(void) +/** + +Routine description: + + What color am I playing? + +Parameters: + + void + +Return value: + + ULONG + +**/ +{ + switch(g_Options.ePlayMode) + { + case I_PLAY_WHITE: + return(WHITE); + case I_PLAY_BLACK: + default: + return(BLACK); + } +} + +ULONG +GetOpponentsColor(void) +/** + +Routine description: + + What color is the opponent playing? + +Parameters: + + void + +Return value: + + ULONG + +**/ +{ + return(FLIP(GetMyColor())); +} + +void +SetOpponentsName(CHAR *sz) +/** + +Routine description: + + Set my opponent's name for the PGN record. Hello, my name is + Inigo Montoya. You killed my father. Prepare to die. + +Parameters: + + CHAR *sz + +Return value: + + void + +**/ +{ + _FreeIfNotNull(g_GameData.sHeader.sPlayer[GetOpponentsColor()].szName); + g_GameData.sHeader.sPlayer[GetOpponentsColor()].szName = STRDUP(sz); +#ifdef DEBUG + if (g_GameData.sHeader.sPlayer[GetOpponentsColor()].szName) + { + g_uAllocs++; + } +#endif +} + +void SetMyName(void) +/** + +Routine description: + + Set my name for the PGN record. Some people call me... Tim? + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG u = GetMyColor(); + + _FreeIfNotNull(g_GameData.sHeader.sPlayer[u].szName); + g_GameData.sHeader.sPlayer[u].szName = STRDUP("typhoon"); +#ifdef DEBUG + if (g_GameData.sHeader.sPlayer[u].szName) + { + g_uAllocs++; + } +#endif + _FreeIfNotNull(g_GameData.sHeader.sPlayer[u].szDescription); + g_GameData.sHeader.sPlayer[u].szDescription = + STRDUP("Ver: " VERSION " Build Time: " __TIME__ " " __DATE__); +#ifdef DEBUG + if (g_GameData.sHeader.sPlayer[u].szDescription) + { + g_uAllocs++; + } +#endif + g_GameData.sHeader.sPlayer[u].fIsComputer = TRUE; +} + +void +SetMyRating(ULONG u) +/** + +Routine description: + + Set my rating for the PGN record. + +Parameters: + + ULONG u + +Return value: + + void + +**/ +{ + g_GameData.sHeader.sPlayer[GetMyColor()].uRating = u; +} + +void +SetOpponentsRating(ULONG u) +/** + +Routine description: + + Set the opponent's rating for the PGN record. + +Parameters: + + ULONG u + +Return value: + + void + +**/ +{ + g_GameData.sHeader.sPlayer[GetOpponentsColor()].uRating = u; +} + +void +TellGamelistThatIPlayColor(ULONG u) +/** + +Routine description: + + The gamelist needs to know what color the computer is playing. + This routine sets it. + +Parameters: + + ULONG u + +Return value: + + void + +**/ +{ + ULONG uOldColor = GetMyColor(); + GAME_PLAYER x; + + ASSERT(IS_VALID_COLOR(u)); + ASSERT(IS_VALID_COLOR(uOldColor)); + + if (u != uOldColor) + { + x = g_GameData.sHeader.sPlayer[uOldColor]; + g_GameData.sHeader.sPlayer[uOldColor] = + g_GameData.sHeader.sPlayer[u]; + g_GameData.sHeader.sPlayer[u] = x; + } +} + +ULONG +GetMoveNumber(ULONG uColor) +/** + +Routine description: + + What move number is it? + +Parameters: + + void + +Return value: + + ULONG + +**/ +{ + return(g_uMoveNumber[uColor]); +} + +void +MakeStatusLine(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + void + +**/ +{ + char buf[SMALL_STRING_LEN_CHAR]; + ASSERT(IS_VALID_COLOR(g_uToMove)); + + if (g_Options.fStatusLine) + { + strcpy(buf, "_\0"); + if (!g_Options.fRunningUnderXboard) + { + if ((TRUE == g_Options.fPondering) && + (g_Options.mvPonder.uMove != 0)) + { + snprintf(buf, SMALL_STRING_LEN_CHAR - 1, + "_[pondering %s] ", + MoveToSan(g_Options.mvPonder, &g_RootPosition)); + } + snprintf(buf, SMALL_STRING_LEN_CHAR - strlen(buf), + "%s%s(move %u)_", + buf, + (g_uToMove == WHITE) ? "white" : "black", + g_uMoveNumber[g_uToMove]); + Trace("%s\n", buf); + } + } +} + +static void +_ParsePgnHeaderLine(CHAR *p, CHAR **ppVar, CHAR **ppVal) +/** + +Routine description: + +Parameters: + + CHAR *p, + CHAR **ppVar, + CHAR **ppVal + +Return value: + + static void + +**/ +{ + *ppVar = NULL; + *ppVal = NULL; + if (*p != '[') return; + + p++; + *ppVar = p; + while(*p && !isspace(*p)) p++; + + p++; + *ppVal = p; + while(*p && *p != ']') p++; +} + +static void +_ParsePgnHeaderTag(CHAR *p) +/** + +Routine description: + + Parse PGN headers and extract people's names, ratings, game + result, etc... + +Parameters: + + CHAR *p + +Return value: + + static void + +**/ +{ + CHAR *pVar, *pVal; + + _ParsePgnHeaderLine(p, &pVar, &pVal); + if ((NULL == pVar) || (NULL == pVal)) + { + return; + } + + if (!STRNCMPI(pVar, "BLACK ", 6)) + { + p = pVal; + while(*p && *p != ']') p++; + if (*p) + { + *p = '\0'; + _FreeIfNotNull(g_GameData.sHeader.sPlayer[BLACK].szName); + g_GameData.sHeader.sPlayer[BLACK].szName = STRDUP(pVal); +#ifdef DEBUG + if (g_GameData.sHeader.sPlayer[BLACK].szName) + { + g_uAllocs++; + } +#endif + *p = ']'; + p++; + } + } + else if (!STRNCMPI(pVar, "WHITE ", 6)) + { + p = pVal; + while(*p && *p != ']') p++; + if (*p) + { + *p = '\0'; + _FreeIfNotNull(g_GameData.sHeader.sPlayer[WHITE].szName); + g_GameData.sHeader.sPlayer[WHITE].szName = STRDUP(pVal); +#ifdef DEBUG + if (g_GameData.sHeader.sPlayer[WHITE].szName) + { + g_uAllocs++; + } +#endif + *p = ']'; + p++; + } + } + else if (!STRNCMPI(pVar, "RESULT", 6)) + { + p = pVal; + if (*p == '"') p++; + if (!STRNCMPI(p, "1-0", 3)) + { + GAME_RESULT res; + res.eResult = RESULT_WHITE_WON; + strcpy(res.szDescription, "PGN game"); + SetGameResultAndDescription(res); + } + else if (!STRNCMPI(p, "0-1", 3)) + { + GAME_RESULT res; + res.eResult = RESULT_BLACK_WON; + strcpy(res.szDescription, "PGN game"); + SetGameResultAndDescription(res); + } + else if (!STRNCMPI(p, "1/2", 3)) + { + GAME_RESULT res; + res.eResult = RESULT_DRAW; + strcpy(res.szDescription, "PGN game"); + SetGameResultAndDescription(res); + } + while(*p && *p != ']') p++; + if (*p) p++; + } + // + // TODO: add others + // +} + +FLAG +LoadPgn(CHAR *szPgn) +/** + +Routine description: + + Load a PGN blob and create a move list from it. + +Parameters: + + CHAR *szPgn + +Return value: + + FLAG + +**/ +{ + POSITION *pos; + CHAR szMove[16]; + MOVE mv; + CHAR *p = szPgn; + ULONG uMoveCount = 0; + ULONG x; + FLAG fRet = FALSE; + FLAG fOldPost = g_Options.fShouldPost; + + g_Options.fShouldPost = FALSE; + ResetGameList(); + SetRootToInitialPosition(); + pos = GetRootPosition(); + + // + // Get rid of newlines, non-space spaces and .'s + // + while(*p) + { + if (isspace(*p)) *p = ' '; + if (*p == '.') *p = ' '; + p++; + } + + p = szPgn; + while(*p) + { + while(*p && isspace(*p)) p++; + while(*p && (isdigit(*p) || (*p == '.'))) p++; + if (*p == '[') + { + _ParsePgnHeaderTag(p); + while(*p && *p != ']') p++; + if (*p) p++; + } + else if (*p == '{') + { + while(*p && *p != '}') p++; + if (*p) p++; + } + else if (isalpha(*p)) + { + // + // Copy the thing we think is a move. + // + memset(szMove, 0, sizeof(szMove)); + x = 0; + while(*p && (!isspace(*p))) + { + if (x < (ARRAY_LENGTH(szMove) - 1)) + { + szMove[x] = *p; + } + x++; + p++; + } + + switch (LooksLikeMove(szMove)) + { + case MOVE_SAN: + mv = ParseMoveSan(szMove, pos); + break; + case MOVE_ICS: + mv = ParseMoveIcs(szMove, pos); + break; + default: + mv.uMove = 0; + break; + } + + //if (FALSE == SanityCheckMove(pos, mv)) + // { + // Trace("Error in PGN(?) Bad chunk \"%s\"\n", szMove); + // goto end; + // } + + if (FALSE == OfficiallyMakeMove(mv, 0, TRUE)) + { + Trace("Error in PGN(?) Can't play move \"%s\"\n", szMove); + goto end; + } + pos = GetRootPosition(); + uMoveCount++; + } + else + { + while(*p && !isspace(*p)) p++; + } + } + fRet = TRUE; + end: + g_Options.fShouldPost = fOldPost; + return(fRet); +} + + +char * +CleanupString(char *pIn) +/** + +Routine description: + + Ckeans up a PGN tag containing part of the opening line + name... gets rid of the quotes around the name and the newline. + +Parameters: + + char *pIn + +Return value: + + char + +**/ +{ + static char buf[256]; + char *p = pIn; + char *q = buf; + + // + // Skip leading whitespace in input + // + buf[0] = '\0'; + while(isspace(*p)) p++; + if (*p == '\0') return(buf); + + do + { + // + // Copy A-Z, 0-9, space, -, ., (, or ) + // + // Ignore others + // + if ((*p == ' ') || + (isalpha(*p)) || + (isdigit(*p)) || + (*p == '-') || + (*p == '.') || + (*p == ',') || + (*p == '(') || + (*p == ')')) + { + *q = *p; + q++; + if ((q - buf) > (sizeof(buf) - 1)) break; + } + p++; + } + while(*p); + + *q = '\0'; + buf[255] = 0; + return(buf); +} diff --git a/src/generate.c b/src/generate.c new file mode 100755 index 0000000..f1ebab8 --- /dev/null +++ b/src/generate.c @@ -0,0 +1,3270 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + generate.c + +Abstract: + + This module contains two move generators: a pseudo legal move + generator and a pseudo legal escaping move generator. The former + is called in positions where side on move is not in check and the + latter is called when the side on move is in check. Note: both of + these generators produce pseudo-legal moves. The normal move + generator is pretty bad: it does not bother to see if moves expose + their own king to check or if castles pass through check + etc... Instead it relies on MakeMove to throw out any illegal + moves it generates. The escape generator is better in that it + produces less illegal moves. But it is still possible to generate + some with it. An example: it will generate replies to check that + may include capturing moves that are illegal because the capturing + piece is pinned to the (already in check) king. Both generators + produce a set of moves that contains the true legal set of moves in + a position as a subset; if a move is legal it will be produced. + + This module also contains some code to flag moves as checking + moves and score moves after they are generated. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 11 May 2004 + +Revision History: + + $Id: generate.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" +#include "psqt.h" + +// +// Note: this order is important because of how EvalQueen works +// +const INT g_iQKDeltas[] = { + -17, -16, -15, -1, +1, +17, +15, +16, 0 }; + +static void +_FindUnblockedSquares(IN MOVE_STACK *pStack, + IN POSITION *pos) +/** + +Routine description: + + Given a position, find, count and mark all squares that are + unblocked for the king of the side not on move. For example: + + +---+---+---+---+- - - The squares marked with *'s in this + |***| K |***|*Q*| diagram are unblocked for the K. As + +---+---+---+---+- - - you can see, there are nine of them. + |*P*|***|***| | + +---+---+---+---+- - - Note the piece at the end of an unblocked + | |***| |*P*| ray from the king is on an unblocked + +---+---+---+---+- - - square (and its color doesn't matter) + | |*R*| | | + +---+---+---+---+- - - This stuff is used to flag checking moves + | | | | | as they are generated. + . . . . . + + Also note: this is one of the most called routines in the engine; + speed is of the essence here. + +Parameters: + + MOVE_STACK *pStack : move stack pointer + POSITION *pos : position pointer + +Return value: + + void + +**/ +{ + register ULONG u; + COOR cKing = pos->cNonPawns[FLIP(pos->uToMove)][0]; + COOR c; + ULONG uPly = pStack->uPly; +#ifdef DEBUG + PIECE pKing = pos->rgSquare[cKing].pPiece; + ULONG uCount = 0; + COOR cx; + + ASSERT(IS_ON_BOARD(cKing)); + ASSERT(IS_KING(pKing)); + ASSERT(GET_COLOR(pKing) != pos->uToMove); +#endif + + // + // Adjust the unblocked key value for this ply... + // + pStack->uUnblockedKeyValue[uPly]++; +#ifdef DEBUG + FOREACH_SQUARE(c) + { + if (!IS_ON_BOARD(c)) continue; + ASSERT(pStack->sUnblocked[uPly][c].uKey != + pStack->uUnblockedKeyValue[uPly]); + } +#endif + + u = 0; + ASSERT(g_iQKDeltas[u] != 0); + do + { + c = cKing + g_iQKDeltas[u]; + while(IS_ON_BOARD(c)) + { + pStack->sUnblocked[uPly][c].uKey = + pStack->uUnblockedKeyValue[uPly]; + pStack->sUnblocked[uPly][c].iPointer = -1 * g_iQKDeltas[u]; +#ifdef DEBUG + ASSERT(-g_iQKDeltas[u] == DIRECTION_BETWEEN_SQUARES(c,cKing)); + ASSERT(pStack->sUnblocked[uPly][c].iPointer != 0); + cx = c; + do + { + cx += pStack->sUnblocked[uPly][c].iPointer; + } + while(IS_ON_BOARD(cx) && (IS_EMPTY(pos->rgSquare[cx].pPiece))); + ASSERT(cx == cKing); + uCount++; +#endif + if (!IS_EMPTY(pos->rgSquare[c].pPiece)) + { + break; + } + c += g_iQKDeltas[u]; + } + u++; + } + while(g_iQKDeltas[u] != 0); + ASSERT(uCount > 2); + ASSERT(uCount < 28); +} + +#define SQUARE_IS_UNBLOCKED(c) (uUnblocked == kp[(c)].uKey) +#define DIR_FROM_SQ_TO_KING(c) (kp[(c)].iPointer) + +FLAG +WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv) +/** + +Routine description: + + Determine whether a move is a checking move or not. For this + function to work properly _FindUnblockedSquares must have been + called at the start of generation. + + Note: this is one of the most called codepaths in the engine, + speed is of the essence here. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board + MOVE mv : the move under consideration + +Return value: + + FLAG : TRUE if the move is checking, FALSE otherwise + +**/ +{ + // + // TODO: consider adding a hash table to see if sig+mv would + // give check. Is this worth it? + // + MOVE_STACK *pStack = &(ctx->sMoveStack); + POSITION *pos = &(ctx->sPosition); + COOR cTo = mv.cTo; + COOR cFrom = mv.cFrom; + PIECE pPiece = mv.pMoved; + COOR xKing = pos->cNonPawns[FLIP(GET_COLOR(pPiece))][0]; + KEY_POINTER *kp = &(pStack->sUnblocked[ctx->uPly][0]); + ULONG uUnblocked = pStack->uUnblockedKeyValue[ctx->uPly]; + COOR cEpSquare; + int iDelta; + + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + ASSERT(PositionsAreEquivalent(&(pStack->board[ctx->uPly]), pos)); + ASSERT(mv.uMove); + ASSERT(IS_KING(pos->rgSquare[xKing].pPiece)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(pPiece); + + // + // Phase 1: Does this move directly attack the king? + // + + // + // You can't attack one king directly with the other except by + // castling (in which case the rook is doing the attack). + // + if (IS_KING(pPiece)) + { + if (!IS_SPECIAL_MOVE(mv)) + { + goto exposes; + } + + ASSERT((mv.cFrom == E8) || (mv.cFrom == E1)); + pPiece &= ~4; + ASSERT(!IS_KING(pPiece)); + ASSERT(IS_ROOK(pPiece)); + ASSERT(pPiece == (BLACK_ROOK | GET_COLOR(pPiece))); + + switch(cTo) + { + case C1: + cTo = D1; + if (SQUARE_IS_UNBLOCKED(E1) && + (DIR_FROM_SQ_TO_KING(E1) == 1)) + { + ASSERT(RANK1(xKing)); + return(MOVE_FLAG_CHECKING); + } + break; + case G1: + cTo = F1; + if (SQUARE_IS_UNBLOCKED(E1) && + (DIR_FROM_SQ_TO_KING(E1) == -1)) + { + ASSERT(RANK1(xKing)); + return(MOVE_FLAG_CHECKING); + } + break; + case C8: + cTo = D8; + if (SQUARE_IS_UNBLOCKED(E8) && + (DIR_FROM_SQ_TO_KING(E8) == 1)) + { + ASSERT(RANK8(xKing)); + return(MOVE_FLAG_CHECKING); + } + break; + case G8: + cTo = F8; + if (SQUARE_IS_UNBLOCKED(E8) && + (DIR_FROM_SQ_TO_KING(E8) == -1)) + { + ASSERT(RANK8(xKing)); + return(MOVE_FLAG_CHECKING); + } + break; +#ifdef DEBUG + default: + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + break; +#endif + } + } + + // + // Ok, either its not a king or its a castle move and we are thinking + // about the rook now. + // + + // + // Check the attack vector table + // + ASSERT(!IS_KING(pPiece)); + iDelta = 0; + if (mv.pPromoted) + { + ASSERT(IS_PAWN(pPiece)); + ASSERT(GET_COLOR(pPiece) == GET_COLOR(mv.pPromoted)); + pPiece = mv.pPromoted; + ASSERT(!IS_PAWN(pPiece)); + iDelta = cFrom - cTo; + ASSERT(iDelta != 0); + } + + // + // Does pPiece attack xKing directly if there are not pieces in + // the way? + // + if (0 != (CHECK_VECTOR_WITH_INDEX((int)cTo - (int)xKing, + GET_COLOR(pPiece)) & + (1 << PIECE_TYPE(pPiece)))) + { + // + // We don't toggle knight squares as unblocked... so if the sq + // is unblocked then piece must not be a knight. Note: this + // logical OR replaced with bitwise equivalent for speed. + // + if ((SQUARE_IS_UNBLOCKED(cTo)) | (IS_KNIGHT(pPiece))) + { +#ifdef DEBUG + if (SQUARE_IS_UNBLOCKED(cTo)) + { + ASSERT(!IS_KNIGHT(pPiece)); + } + else + { + ASSERT(IS_KNIGHT(pPiece)); + } +#endif + return(MOVE_FLAG_CHECKING); + } + ASSERT(!IS_PAWN(pPiece)); + + // + // Special case: if this is a pawn that just promoted, and the + // from square was unblocked, this pawn in its new state can + // check the king. + // + if ((DIR_FROM_SQ_TO_KING(cFrom) == iDelta) && + (SQUARE_IS_UNBLOCKED(cFrom))) + { + return(MOVE_FLAG_CHECKING); + } + } + + exposes: + // + // We now know that the move itself does not directly attack the + // enemy king. We will now see if that move exposes check to the + // enemy king. + // + + // + // A move cannot expose check directly if its from square is not + // an unblocked square. But if it is unblocked, we will have to + // scan behind the piece to see if there is some attacker. + // + if (SQUARE_IS_UNBLOCKED(cFrom)) + { + // + // Piece moves towards the king on the same ray? Cannot be + // check. Piece moves away from the king on the same ray? + // Cannot be check. + // + if (DIRECTION_BETWEEN_SQUARES(cTo, xKing) != + DIR_FROM_SQ_TO_KING(cFrom)) + { + if (IS_ON_BOARD(FasterExposesCheck(pos, cFrom, xKing))) + { + ASSERT(IS_ON_BOARD(ExposesCheck(pos, cFrom, xKing))); + return(MOVE_FLAG_CHECKING); + } + } + } + + // + // There is one last special case. If this move was enpassant + // it's possible that the removal of the enemy pawn has exposed + // the enemy king to check. + // + // rnb2bnr/ppp3pp/4k3/1B1qPpB1/4p1Q1/8/PPP2PPP/RN2K1NR w - f6 0 0 + // rn5r/pp4pp/8/5qk1/1b2pP2/4K3/PPP3PP/RN4NR b - f3 0 0 + // + if (IS_ENPASSANT(mv)) + { + ASSERT(IS_PAWN(pPiece)); + ASSERT(VALID_EP_SQUARE(cTo)); + ASSERT(cTo == pos->cEpSquare); + cEpSquare = cTo + 16 * g_iBehind[(GET_COLOR(pPiece))]; +#ifdef DEBUG + if (GET_COLOR(pPiece)) + { + ASSERT(cEpSquare == (cTo + 16)); + } + else + { + ASSERT(cEpSquare == (cTo - 16)); + } +#endif + ASSERT(IS_PAWN(pos->rgSquare[cEpSquare].pPiece)); + ASSERT(OPPOSITE_COLORS(pPiece, pos->rgSquare[cEpSquare].pPiece)); + + // + // Logical OR replaced with bitwise for speed. + // + if (((SQUARE_IS_UNBLOCKED(cEpSquare)) | + (SQUARE_IS_UNBLOCKED(cFrom))) && + (IS_ON_BOARD(ExposesCheckEp(pos, cEpSquare, cFrom, cTo, xKing)))) + { + return(MOVE_FLAG_CHECKING); + } + } + + // + // No direct check + no exposed check = no check. + // + return(0); +} + + +static void FORCEINLINE +_AddNormalMove(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cFrom, + IN COOR cTo, + IN PIECE pCap) +/** + +Routine description: + + Adds a move from the generator functions to the stack of generated + moves. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cFrom : the move's from square + COOR cTo : the move's to square + PIECE pCap : what was captured (if anything) + +Return value: + + static void FORCEINLINE + +**/ +{ + PIECE pMoved = pos->rgSquare[cFrom].pPiece; + ULONG uPly = pStack->uPly; + MOVE_STACK_MOVE_VALUE_FLAGS *pMvf; + + ASSERT(pMoved); + ASSERT(GET_COLOR(pMoved) == pos->uToMove); + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + + pMvf = &(pStack->mvf[pStack->uEnd[uPly]]); + pMvf->mv.uMove = MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(cFrom, cTo, pMoved, pCap); + pStack->uEnd[uPly]++; + + ASSERT(pMvf->mv.uMove == MAKE_MOVE(cFrom, cTo, pMoved, pCap, 0, 0)); + ASSERT(SanityCheckMove(pos, pMvf->mv)); +} + + +static void FORCEINLINE +_AddEnPassant(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cFrom, + IN COOR cTo) +/** + +Routine description: + + Add an en passant pawn capture to the move stack. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cFrom : the from square + COOR cTo : the to square (and en passant square) + +Return value: + + static void + +**/ +{ + PIECE pMoved = BLACK_PAWN | pos->uToMove; + PIECE pCaptured = FLIP(pMoved); + ULONG uPly = pStack->uPly; + MOVE_STACK_MOVE_VALUE_FLAGS *pMvf; + + ASSERT(pCaptured == (BLACK_PAWN | (FLIP(pos->uToMove)))); + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(RANK4(cFrom) || RANK5(cFrom)); + ASSERT(VALID_EP_SQUARE(cTo)); + ASSERT(IS_PAWN(pos->rgSquare[cFrom].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cFrom].pPiece) == pos->uToMove); + + pMvf = &(pStack->mvf[pStack->uEnd[uPly]]); + pMvf->mv.uMove = + MAKE_MOVE(cFrom, cTo, pMoved, pCaptured, 0, MOVE_FLAG_SPECIAL); + pStack->uEnd[uPly]++; + + ASSERT(SanityCheckMove(pos, pMvf->mv)); +} + + +static void FORCEINLINE +_AddCastle(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cFrom, + IN COOR cTo) +/** + +Routine description: + + Add a castle move to the move stack. + +Parameters: + + MOVE_STACK *pStack, + POSITION *pos, + COOR cFrom, + COOR cTo + +Return value: + + static void FORCEINLINE + +**/ +{ + PIECE pMoved = BLACK_KING | pos->uToMove; + ULONG uPly = pStack->uPly; + MOVE_STACK_MOVE_VALUE_FLAGS *pMvf; + + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT((E1 == cFrom) || (E8 == cFrom)); + ASSERT(IS_KING(pos->rgSquare[cFrom].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cFrom].pPiece) == pos->uToMove); + + pMvf = &(pStack->mvf[pStack->uEnd[uPly]]); + pMvf->mv.uMove = MAKE_MOVE(cFrom, cTo, pMoved, 0, 0, MOVE_FLAG_SPECIAL); + pStack->uEnd[uPly]++; + + ASSERT(SanityCheckMove(pos, pMvf->mv)); +} + + +static void FORCEINLINE +_AddPromote(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cFrom, + IN COOR cTo) +/** + +Routine description: + + Adds a pawn promotion (set of) moves to the move stack. This can + be a capture-promotion or non-capture promotion. This function + pushes several moves onto the move stack, one for each possible + promotion target. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cFrom : the move's from square + COOR cTo : the move's to square + +Return value: + + static void + +**/ +{ + PIECE pMoved = BLACK_PAWN | pos->uToMove; + PIECE pCaptured = pos->rgSquare[cTo].pPiece; + ULONG uPly = pStack->uPly; + MOVE_STACK_MOVE_VALUE_FLAGS *pMvf; + ULONG u; + +#define ARRAY_LENGTH_TARG (4) + const static PIECE pTarg[ARRAY_LENGTH_TARG] = { BLACK_QUEEN, + BLACK_ROOK, + BLACK_BISHOP, + BLACK_KNIGHT }; + + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(RANK1(cTo) || RANK8(cTo)); + ASSERT(RANK7(cFrom) || RANK2(cFrom)); + ASSERT(ARRAY_LENGTH(pTarg) == ARRAY_LENGTH_TARG); + ASSERT(IS_PAWN(pos->rgSquare[cFrom].pPiece)); + + for (u = 0; u < ARRAY_LENGTH_TARG; u++) + { + pMvf = &(pStack->mvf[pStack->uEnd[uPly]]); + pMvf->mv.uMove = MAKE_MOVE(cFrom, cTo, pMoved, pCaptured, + pTarg[u] | pos->uToMove, MOVE_FLAG_SPECIAL); + pStack->uEnd[uPly]++; + ASSERT(SanityCheckMove(pos, pMvf->mv)); + } +#undef ARRAY_LENGTH_TARG +} + + +static void FORCEINLINE +_AddDoubleJump(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cFrom, + IN COOR cTo) +/** + +Routine description: + + This function adds a pawn double jump to the move stack. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cFrom : the move's from square + COOR cTo : the move's to square + +Return value: + + static void + +**/ +{ + PIECE pMoved = BLACK_PAWN | pos->uToMove; + ULONG uPly = pStack->uPly; + MOVE_STACK_MOVE_VALUE_FLAGS *pMvf; + + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(RANK2(cFrom) || RANK7(cFrom)); + ASSERT(RANK4(cTo) || RANK5(cTo)); + ASSERT(IS_PAWN(pos->rgSquare[cFrom].pPiece)); + + pMvf = &(pStack->mvf[pStack->uEnd[uPly]]); + pMvf->mv.uMove = MAKE_MOVE(cFrom, cTo, pMoved, 0, 0, MOVE_FLAG_SPECIAL); + pStack->uEnd[uPly]++; + + ASSERT(SanityCheckMove(pos, pMvf->mv)); +} + + +const INT g_iNDeltas[] = { + -33, -31, -18, -14, +14, +18, +31, +33, 0 }; + +void +GenerateKnight(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cKnight) +/** + +Routine description: + + This function is called by GenerateMoves' JumpTable. Its job + is to generate and push pseudo-legal knight moves for the + knight sitting on square cKnight. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cKnight : the knight's location + +Return value: + + void + +**/ +{ + COOR c; + ULONG u = 0; + PIECE p; + + ASSERT(IS_KNIGHT(pos->rgSquare[cKnight].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKnight].pPiece) == pos->uToMove); + ASSERT(g_iNDeltas[u] != 0); + + do + { + c = cKnight + g_iNDeltas[u]; + u++; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + + // + // This logical OR replaced with bitwise OR; the effect is + // the same the the bitwise is marginally faster. + // + if (IS_EMPTY(p) | (OPPOSITE_COLORS(p, pos->uToMove))) + { + _AddNormalMove(pStack, pos, cKnight, c, p); + } + } + } + while(0 != g_iNDeltas[u]); +} + +void +GenerateWhiteKnight(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cKnight) +{ + COOR c; + ULONG u = 0; + PIECE p; + + ASSERT(IS_KNIGHT(pos->rgSquare[cKnight].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKnight].pPiece) == pos->uToMove); + ASSERT(g_iNDeltas[u] != 0); + + do + { + c = cKnight + g_iNDeltas[u]; + u++; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + + // + // Note: this test covers empty squares also -- it is just + // testing that the low order bit (color bit) of p is zero + // which is true for black pieces and empty squares. This + // is done for speed over readability. + // + if (GET_COLOR(p) == BLACK) + { + ASSERT(IS_EMPTY(p) || (GET_COLOR(p) == BLACK)); + _AddNormalMove(pStack, pos, cKnight, c, p); + } + } + } + while(0 != g_iNDeltas[u]); +} + +// +// These logical AND/ORs replaced with bitwise AND/OR; the effect is +// the same the the bitwise is marginally faster. +// +#define BLOCKS_THE_CHECK(sq) \ + ((iAttackDelta != 0) & \ + (iAttackDelta == DIRECTION_BETWEEN_SQUARES(cAttacker, (sq))) & \ + (((cAttacker > cKing) & ((sq) > cKing)) | \ + ((cAttacker < cKing) & ((sq) < cKing)))) + +void +SaveMeKnight(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cKnight, + IN COOR cKing, + IN COOR cAttacker) +/** + +Routine description: + + This routine is called by GenerateEscapes' JumpTable. Its job is + to generate moves by the knight on square cKnight that alleviate + check to the king on square cKing. The (lone) piece attacking the + king is on square cAttacker. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cKnight : the location of the knight + COOR cKing : the location of the friendly king + COOR cAttacker : the location of the checking piece + +Return value: + + void + +**/ +{ + COOR c, cExposed; + int iAttackDelta = DIRECTION_BETWEEN_SQUARES(cAttacker, cKing); + ULONG u = 0; + PIECE p; + + ASSERT(InCheck(pos, pos->uToMove)); + ASSERT(IS_KNIGHT(pos->rgSquare[cKnight].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKnight].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cKnight].pPiece) == + GET_COLOR(pos->rgSquare[cKing].pPiece)); + ASSERT(OPPOSITE_COLORS(pos->rgSquare[cAttacker].pPiece, + pos->rgSquare[cKing].pPiece)); + ASSERT(g_iNDeltas[u] != 0); + + do + { + c = cKnight + g_iNDeltas[u]; + u++; + if (IS_ON_BOARD(c)) + { + if ((c == cAttacker) || BLOCKS_THE_CHECK(c)) + { + cExposed = ExposesCheck(pos, cKnight, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == c)) + { + p = pos->rgSquare[c].pPiece; + ASSERT(!p || + OPPOSITE_COLORS(p, pos->rgSquare[cKnight].pPiece)); + ASSERT(!p || (c == cAttacker)); + _AddNormalMove(pStack, pos, cKnight, c, p); + } + } + } + } + while(0 != g_iNDeltas[u]); +} + + +const INT g_iBDeltas[] = { + -17, -15, +15, +17, 0 }; + +void +GenerateBishop(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cBishop) +/** + +Routine description: + + This routine is called by GenerateMoves' JumpTable to generate + pseudo-legal bishop moves by the piece at cBishop. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cBishop : the bishop location + +Return value: + + void + +**/ +{ + COOR c; + PIECE p; + + ASSERT(IS_BISHOP(pos->rgSquare[cBishop].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cBishop].pPiece) == pos->uToMove); + + // + // Note: manually unrolled loop + // + c = cBishop - 17; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cBishop, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cBishop, c, p); + } + break; + } + c += -17; + } + + c = cBishop - 15; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cBishop, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cBishop, c, p); + } + break; + } + c += -15; + } + + c = cBishop + 15; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cBishop, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cBishop, c, p); + } + break; + } + c += 15; + } + + c = cBishop + 17; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cBishop, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cBishop, c, p); + } + break; + } + c += 17; + } +} + + +void +SaveMeBishop(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cBishop, + IN COOR cKing, + IN COOR cAttacker) +/** + +Routine description: + + This routine is called by GenerateEscapes' JumpTable in order to + generate moves by the bishop at cBishop to alleviate check on its + friendly king (at cKing) which is being checked by a piece at + cAttacker. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cBishop : the bishop's location + COOR cKing : the friendly king's location + COOR cAttacker : the checking piece's location + +Return value: + + void + +**/ +{ + int iAttackDelta = DIRECTION_BETWEEN_SQUARES(cAttacker, cKing); + COOR c; + COOR cExposed; + ULONG u = 0; + PIECE p; + + ASSERT(InCheck(pos, pos->uToMove)); + ASSERT(IS_BISHOP(pos->rgSquare[cBishop].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cBishop].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cBishop].pPiece) == + GET_COLOR(pos->rgSquare[cKing].pPiece)); + ASSERT(OPPOSITE_COLORS(pos->rgSquare[cAttacker].pPiece, + pos->rgSquare[cKing].pPiece)); + ASSERT(g_iBDeltas[u] != 0); + + do + { + c = cBishop + g_iBDeltas[u]; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if ((c == cAttacker) || BLOCKS_THE_CHECK(c)) + { + ASSERT(!p || + OPPOSITE_COLORS(p, pos->rgSquare[cBishop].pPiece)); + ASSERT(!p || (c == cAttacker)); + cExposed = ExposesCheck(pos, cBishop, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == c)) + { + _AddNormalMove(pStack, pos, cBishop, c, p); + break; + } + } + else if (!IS_EMPTY(p)) + { + break; + } + c += g_iBDeltas[u]; + } + u++; + } + while(0 != g_iBDeltas[u]); +} + + +const INT g_iRDeltas[] = { + -1, +1, +16, -16, 0 }; + + +void +GenerateRook(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cRook) +/** + +Routine description: + + This routine is called by GenerateMoves' JumpTable in order to + generate pseudo-legal moves for the rook at position cRook. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cRook : the rook's location + +Return value: + + void + +**/ +{ + COOR c; + PIECE p; + + ASSERT(IS_ROOK(pos->rgSquare[cRook].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cRook].pPiece) == pos->uToMove); + + // + // Note: manually unrolled loop + // + c = cRook - 1; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cRook, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cRook, c, p); + } + break; + } + c += -1; + } + + c = cRook + 1; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cRook, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cRook, c, p); + } + break; + } + c += 1; + } + + c = cRook + 16; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cRook, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cRook, c, p); + } + break; + } + c += 16; + } + + c = cRook - 16; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cRook, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cRook, c, p); + } + break; + } + c += -16; + } +} + +void +SaveMeRook(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cRook, + IN COOR cKing, + IN COOR cAttacker) +/** + +Routine description: + + This routine is called by GenerateEscapes' JumpTable in order to + generate moves by the rook at location cRook that alleviate check + to the king at cKing. The lone checking piece is at cAttacker. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cRook : the rook's location + COOR cKing : the king's location + COOR cAttacker : the checker's location + +Return value: + + void + +**/ +{ + int iAttackDelta = DIRECTION_BETWEEN_SQUARES(cAttacker, cKing); + COOR c; + COOR cExposed; + ULONG u = 0; + PIECE p; + + ASSERT(InCheck(pos, pos->uToMove)); + ASSERT(IS_ROOK(pos->rgSquare[cRook].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cRook].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cRook].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cRook].pPiece) == + GET_COLOR(pos->rgSquare[cKing].pPiece)); + ASSERT(OPPOSITE_COLORS(pos->rgSquare[cAttacker].pPiece, + pos->rgSquare[cKing].pPiece)); + ASSERT(g_iRDeltas[u] != 0); + + do + { + c = cRook + g_iRDeltas[u]; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if ((c == cAttacker) || BLOCKS_THE_CHECK(c)) + { + ASSERT(!p || + OPPOSITE_COLORS(p, pos->rgSquare[cRook].pPiece)); + ASSERT(!p || (c == cAttacker)); + cExposed = ExposesCheck(pos, cRook, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == c)) + { + _AddNormalMove(pStack, pos, cRook, c, p); + break; + } + } + else if (!IS_EMPTY(p)) + { + break; + } + c += g_iRDeltas[u]; + } + u++; + } + while(0 != g_iRDeltas[u]); +} + + +void +GenerateQueen(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cQueen) +/** + +Routine description: + + This routine is called by GenerateMoves' JumpTable in order to + generate pseudo-legal moves for the queen at position cQueen. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cQueen : the queen's location + +Return value: + + void + +**/ +{ + COOR c; + ULONG u = 0; + PIECE p; + + ASSERT(IS_QUEEN(pos->rgSquare[cQueen].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cQueen].pPiece) == pos->uToMove); + ASSERT(g_iQKDeltas[u] != 0); + + do + { + c = cQueen + g_iQKDeltas[u]; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (IS_EMPTY(p)) + { + _AddNormalMove(pStack, pos, cQueen, c, 0); + } + else + { + if (OPPOSITE_COLORS(p, pos->uToMove)) + { + _AddNormalMove(pStack, pos, cQueen, c, p); + } + break; + } + c += g_iQKDeltas[u]; + } + u++; + } + while(0 != g_iQKDeltas[u]); +} + + +void +SaveMeQueen(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cQueen, + IN COOR cKing, + IN COOR cAttacker) +/** + +Routine description: + + This routine is called by code in GenerateEscapes in order to + generate moves by the queen at square cQueen that alleviate check + on the friendly king at square cKing. The lone enemy piece that + is checking the king is sitting on square cAttacker. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cQueen : the queen's location + COOR cKing : the friendly king's location + COOR cAttacker : the attacker's location + +Return value: + + void + +**/ +{ + COOR c; + COOR cExposed; + int iAttackDelta = DIRECTION_BETWEEN_SQUARES(cAttacker, cKing); + ULONG u = 0; + PIECE p; + + ASSERT(InCheck(pos, pos->uToMove)); + ASSERT(IS_QUEEN(pos->rgSquare[cQueen].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cQueen].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cQueen].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cQueen].pPiece) == + GET_COLOR(pos->rgSquare[cKing].pPiece)); + ASSERT(OPPOSITE_COLORS(pos->rgSquare[cAttacker].pPiece, + pos->rgSquare[cKing].pPiece)); + ASSERT(g_iQKDeltas[u] != 0); + + do + { + c = cQueen + g_iQKDeltas[u]; + while(IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if ((c == cAttacker) || BLOCKS_THE_CHECK(c)) + { + ASSERT(!p || + OPPOSITE_COLORS(p, pos->rgSquare[cQueen].pPiece)); + ASSERT(!p || (c == cAttacker)); + cExposed = ExposesCheck(pos, cQueen, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == c)) + { + _AddNormalMove(pStack, pos, cQueen, c, p); + break; + } + } + else if (!IS_EMPTY(p)) + { + break; + } + c += g_iQKDeltas[u]; + } + u++; + } + while(0 != g_iQKDeltas[u]); +} + +void +GenerateBlackKing(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cKing) +/** + +Routine description: + + This function is called by GenerateMoves in order to generate + pseudo-legal moves for the black king at square cKing. Note: this + function often generates illegal castling moves and relies on the + MakeMove code to decide about the legality of the castle. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cKing : the king location + +Return value: + + void + +**/ +{ + COOR c; + ULONG u = 0; + PIECE p; + + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKing].pPiece) == pos->uToMove); + ASSERT(g_iQKDeltas[u] != 0); + + do + { + c = cKing + g_iQKDeltas[u]; + u++; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + + // + // This logical OR replaced with bitwise OR; the effect is + // the same the the bitwise is marginally faster. + // + if (IS_EMPTY(p) | (GET_COLOR(p))) + { + _AddNormalMove(pStack, pos, cKing, c, p); + } + } + } + while(0 != g_iQKDeltas[u]); + + if ((pos->bvCastleInfo & BLACK_CAN_CASTLE) == 0) return; +#ifdef DEBUG + p = pos->rgSquare[E8].pPiece; + ASSERT(IS_KING(p)); + ASSERT(cKing == E8); +#endif + + // + // Note: no castling through check is enforced at the time the + // move is played. This is a "pseudo-legal" move when generated. + // + if ((pos->bvCastleInfo & CASTLE_BLACK_SHORT) && + (IS_EMPTY(pos->rgSquare[G8].pPiece)) && + (IS_EMPTY(pos->rgSquare[F8].pPiece))) + { + ASSERT(pos->rgSquare[H8].pPiece == BLACK_ROOK); + _AddCastle(pStack, pos, E8, G8); + } + + if ((pos->bvCastleInfo & CASTLE_BLACK_LONG) && + (IS_EMPTY(pos->rgSquare[C8].pPiece)) && + (IS_EMPTY(pos->rgSquare[D8].pPiece)) && + (IS_EMPTY(pos->rgSquare[B8].pPiece))) + { + ASSERT(pos->rgSquare[A8].pPiece == BLACK_ROOK); + _AddCastle(pStack, pos, E8, C8); + } +} + +// +// N.B. There is no SaveYourselfBlackKing or SaveYourselfWhiteKing +// because this functionality is built into phase 1 of +// GenerateEscapes. +// + +void +GenerateWhiteKing(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cKing) +/** + +Routine description: + + This function is called by GenerateMoves in order to generate + pseudo-legal king moves by the white king at square cKing. Note: + it often generates illegal castling moves and relies on the code + in MakeMove to determine the legality of castles. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cKing : the king location + +Return value: + + void + +**/ +{ + COOR c; + ULONG u = 0; + PIECE p; + + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cKing].pPiece) == pos->uToMove); + ASSERT(g_iQKDeltas[u] != 0); + + do + { + c = cKing + g_iQKDeltas[u]; + u++; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + + // + // Note: this test covers empty squares also -- it is just + // testing that the low order bit (color bit) of p is zero + // which is true for black pieces and empty squares. This + // is done for speed over readability. + // + if (GET_COLOR(p) == BLACK) + { + ASSERT(IS_EMPTY(p) || (GET_COLOR(p) == BLACK)); + _AddNormalMove(pStack, pos, cKing, c, p); + } + } + } + while(0 != g_iQKDeltas[u]); + + if ((pos->bvCastleInfo & WHITE_CAN_CASTLE) == 0) return; +#ifdef DEBUG + p = pos->rgSquare[E1].pPiece; + ASSERT(IS_KING(p)); + ASSERT(cKing == E1); +#endif + + // + // Note: no castling through check is enforced at the time the + // move is played. This is a "pseudo-legal" move when generated. + // + if ((pos->bvCastleInfo & CASTLE_WHITE_SHORT) && + (IS_EMPTY(pos->rgSquare[G1].pPiece)) && + (IS_EMPTY(pos->rgSquare[F1].pPiece))) + { + ASSERT(pos->rgSquare[H1].pPiece == WHITE_ROOK); + _AddCastle(pStack, pos, E1, G1); + } + + if ((pos->bvCastleInfo & CASTLE_WHITE_LONG) && + (IS_EMPTY(pos->rgSquare[C1].pPiece)) && + (IS_EMPTY(pos->rgSquare[B1].pPiece)) && + (IS_EMPTY(pos->rgSquare[D1].pPiece))) + { + ASSERT(pos->rgSquare[A1].pPiece == WHITE_ROOK); + _AddCastle(pStack, pos, E1, C1); + } +} + + +void +GenerateWhitePawn(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cPawn) +/** + +Routine description: + + This function is called by GenerateMoves in order to generate + pseudo-legal pawn moves by the pawn at cPawn. It handles + en passant captures, double jumps, promotions, etc... + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cPawn : the pawn's location + +Return value: + + void + +**/ +{ + ULONG uRank = RANK(cPawn); + PIECE p; + COOR cTo; + + ASSERT(IS_PAWN(pos->rgSquare[cPawn].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == pos->uToMove); + ASSERT((RANK(cPawn) >= 2) && (RANK(cPawn) <= 7)); + + if (uRank != 7) + { + cTo = cPawn - 16; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddNormalMove(pStack, pos, cPawn, cTo, 0); + if (uRank == 2) + { + cTo = cPawn - 32; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddDoubleJump(pStack, pos, cPawn, cTo); + } + } + } + cTo = cPawn - 15; + if (IS_ON_BOARD(cTo)) + { + if (cTo == pos->cEpSquare) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p) == BLACK)) + { + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + cTo = cPawn - 17; + if (IS_ON_BOARD(cTo)) + { + if (cTo == pos->cEpSquare) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p) == BLACK)) + { + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + } + else + { + ASSERT(RANK7(cPawn)); + cTo = cPawn - 16; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + cTo = cPawn - 15; + if (IS_ON_BOARD(cTo)) + { + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p) == BLACK)) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + } + cTo = cPawn - 17; + if (IS_ON_BOARD(cTo)) + { + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p) == BLACK)) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + } + } +} + + +void +SaveMeWhitePawn(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cPawn, + IN COOR cKing, + IN COOR cAttacker) +/** + +Routine description: + + This function is called by the GenerateEscapes code in order to + ask for a pawn's help in alleviating check on the king at square + cKing. The lone attacker to said king is on square cAttacker. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cPawn : the pawn's location + COOR cKing : the friendly king's location + COOR cAttacker : the location of the lone checker to the king + +Return value: + + void + +**/ +{ + ULONG uRank = RANK(cPawn); + PIECE p; + COOR cTo; + COOR cExposed; + int iAttackDelta = DIRECTION_BETWEEN_SQUARES(cAttacker, cKing); + + ASSERT(InCheck(pos, pos->uToMove)); + ASSERT(IS_PAWN(pos->rgSquare[cPawn].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == WHITE); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == + GET_COLOR(pos->rgSquare[cKing].pPiece)); + ASSERT(OPPOSITE_COLORS(pos->rgSquare[cAttacker].pPiece, + pos->rgSquare[cKing].pPiece)); + ASSERT((RANK(cPawn) >= 2) && (RANK(cPawn) <= 7)); + + if (uRank != 7) + { + cTo = cPawn - 16; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + if (BLOCKS_THE_CHECK(cTo) && + !IS_ON_BOARD(ExposesCheck(pos, cPawn, cKing))) + { + _AddNormalMove(pStack, pos, cPawn, cTo, 0); + } + + if (uRank == 2) + { + cTo = cPawn - 32; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece) && + BLOCKS_THE_CHECK(cTo) && + !IS_ON_BOARD(ExposesCheck(pos, cPawn, cKing))) + { + _AddDoubleJump(pStack, pos, cPawn, cTo); + } + } + } + + cTo = cPawn - 15; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == BLACK); + ASSERT(IS_ON_BOARD(cTo)); + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + + // + // N.B. There is no possible way to block check with an + // en-passant capture because by definition the last move made + // by the other side was the pawn double jump. So only handle + // if the double jumping enemy pawn is the attacker and we can + // kill it en passant. + // + if ((cTo == pos->cEpSquare) && (cAttacker == cTo + 16)) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + + cTo = cPawn - 17; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == BLACK); + ASSERT(IS_ON_BOARD(cTo)); + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + if ((cTo == pos->cEpSquare) && (cAttacker == cTo + 16)) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + } + else + { + ASSERT(RANK7(cPawn)); + cTo = cPawn - 16; + if (BLOCKS_THE_CHECK(cTo) && IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + + cTo = cPawn - 15; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == BLACK); + ASSERT(IS_ON_BOARD(cTo)); + _AddPromote(pStack, pos, cPawn, cTo); + } + } + + cTo = cPawn - 17; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == BLACK); + ASSERT(IS_ON_BOARD(cTo)); + _AddPromote(pStack, pos, cPawn, cTo); + } + } + } +} + + +void +GenerateBlackPawn(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cPawn) +/** + +Routine description: + + This code is called by GenerateMoves in order to handle move + generation for the black pawn on square cPawn. It handles + en passant captures, double jumps, and promotion. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the position + COOR cPawn : the pawn location + +Return value: + + void + +**/ +{ + ULONG uRank = RANK(cPawn); + PIECE p; + COOR cTo; + + ASSERT(IS_PAWN(pos->rgSquare[cPawn].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == pos->uToMove); + ASSERT((RANK(cPawn) >= 2) && (RANK(cPawn) <= 7)); + + if (uRank != 2) + { + cTo = cPawn + 16; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddNormalMove(pStack, pos, cPawn, cTo, 0); + if (uRank == 7) + { + cTo = cPawn + 32; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddDoubleJump(pStack, pos, cPawn, cTo); + } + } + } + cTo = cPawn + 15; + if (IS_ON_BOARD(cTo)) + { + if (cTo == pos->cEpSquare) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p))) + { + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + cTo = cPawn + 17; + if (IS_ON_BOARD(cTo)) + { + if (cTo == pos->cEpSquare) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p))) + { + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + } + else + { + ASSERT(RANK2(cPawn)); + cTo = cPawn + 16; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + cTo = cPawn + 15; + if (IS_ON_BOARD(cTo)) + { + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p))) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + } + cTo = cPawn + 17; + if (IS_ON_BOARD(cTo)) + { + p = pos->rgSquare[cTo].pPiece; + + // + // This logical AND replaced with bitwise AND; the effect + // is the same the the bitwise is marginally faster. + // + if (!IS_EMPTY(p) & (GET_COLOR(p))) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + } + } +} + + +void +SaveMeBlackPawn(IN MOVE_STACK *pStack, + IN POSITION *pos, + IN COOR cPawn, + IN COOR cKing, + IN COOR cAttacker) +/** + +Routine description: + + This code is called to ask for a black pawn's help in alleviating + check to its king. The pawn is on square cPawn. The friendly + king is on square cKing. The lone enemy piece attacking it is on + square cAttacker. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + COOR cPawn : the pawn location + COOR cKing : the friendly king location + COOR cAttacker : the lone checker location + +Return value: + + void + +**/ +{ + ULONG uRank = RANK(cPawn); + PIECE p; + COOR cTo; + COOR cExposed; + int iAttackDelta = DIRECTION_BETWEEN_SQUARES(cAttacker, cKing); + + ASSERT(InCheck(pos, pos->uToMove)); + ASSERT(IS_PAWN(pos->rgSquare[cPawn].pPiece)); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == BLACK); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == pos->uToMove); + ASSERT(GET_COLOR(pos->rgSquare[cPawn].pPiece) == + GET_COLOR(pos->rgSquare[cKing].pPiece)); + ASSERT(OPPOSITE_COLORS(pos->rgSquare[cAttacker].pPiece, + pos->rgSquare[cKing].pPiece)); + ASSERT((RANK(cPawn) >= 2) && (RANK(cPawn) <= 7)); + + if (uRank != 2) + { + cTo = cPawn + 16; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + if (BLOCKS_THE_CHECK(cTo) && + !IS_ON_BOARD(ExposesCheck(pos, cPawn, cKing))) + { + _AddNormalMove(pStack, pos, cPawn, cTo, 0); + } + + if (uRank == 7) + { + cTo = cPawn + 32; + if (IS_EMPTY(pos->rgSquare[cTo].pPiece) && + BLOCKS_THE_CHECK(cTo) && + !IS_ON_BOARD(ExposesCheck(pos, cPawn, cKing))) + { + _AddDoubleJump(pStack, pos, cPawn, cTo); + } + } + } + + cTo = cPawn + 15; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == WHITE); + ASSERT(IS_ON_BOARD(cTo)); + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + + // + // N.B. There is no possible way to block check with an + // en-passant capture because by definition the last move made + // by the other side was the pawn double jump. So only handle + // if the double jumping enemy pawn is the attacker and we can + // kill it en passant. + // + if ((cTo == pos->cEpSquare) && + (cAttacker == cTo - 16)) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + + cTo = cPawn + 17; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == WHITE); + ASSERT(IS_ON_BOARD(cTo)); + _AddNormalMove(pStack, pos, cPawn, cTo, p); + } + } + if ((cTo == pos->cEpSquare) && + (cAttacker == cTo - 16)) + { + _AddEnPassant(pStack, pos, cPawn, cTo); + } + } + else + { + ASSERT(RANK2(cPawn)); + cTo = cPawn + 16; + if (BLOCKS_THE_CHECK(cTo) && + IS_EMPTY(pos->rgSquare[cTo].pPiece)) + { + _AddPromote(pStack, pos, cPawn, cTo); + } + + cTo = cPawn + 15; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == WHITE); + ASSERT(IS_ON_BOARD(cTo)); + _AddPromote(pStack, pos, cPawn, cTo); + } + } + + cTo = cPawn + 17; + if (cTo == cAttacker) + { + cExposed = ExposesCheck(pos, cPawn, cKing); + if (!IS_ON_BOARD(cExposed) || (cExposed == cAttacker)) + { + p = pos->rgSquare[cTo].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(GET_COLOR(p) == WHITE); + ASSERT(IS_ON_BOARD(cTo)); + _AddPromote(pStack, pos, cPawn, cTo); + } + } + } +} + + +void +InvalidGenerator(IN UNUSED MOVE_STACK *pStack, + IN UNUSED POSITION *pos, + IN UNUSED COOR cPawn) +/** + +Routine description: + + If you'd like to make a call, please hang up and try your call + again... + +Parameters: + + IN UNUSED MOVE_STACK *pStack, + IN UNUSED POSITION *pos, + IN UNUSED COOR cPawn + +Return value: + + void + +**/ +{ + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +} + + +void +InvalidSaveMe(IN UNUSED MOVE_STACK *pStack, + IN UNUSED POSITION *pos, + IN UNUSED COOR cPawn, + IN UNUSED COOR cKing, + IN UNUSED COOR cAttacker) +/** + +Routine description: + + ...if you need help, please dial the operator. + +Parameters: + + IN UNUSED MOVE_STACK *pStack, + IN UNUSED POSITION *pos, + IN UNUSED COOR cPawn, + IN UNUSED COOR cKing, + IN UNUSED COOR cAttacker + +Return value: + + void + +**/ +{ + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +} + + +static void +_GenerateAllMoves(IN MOVE_STACK *pStack, + IN POSITION *pos) +/** + +Routine description: + + This code generates all pseudo-legal moves in a position. Please + see notes at the top of this module for details. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board position + +Return value: + + static void + +**/ +{ + COOR c; + static void (*JumpTable[])(MOVE_STACK *, POSITION *, COOR) = + { + InvalidGenerator, // EMPTY + InvalidGenerator, // EMPTY | WHITE + InvalidGenerator, // 2 (BLACK_PAWN) + InvalidGenerator, // 3 (WHITE_PAWN) + GenerateKnight, // 4 (BLACK_KNIGHT) + GenerateWhiteKnight, // 5 (WHITE_KNIGHT) + GenerateBishop, // 6 (BLACK_BISHOP) + GenerateBishop, // 7 (WHITE_BISHOP) + GenerateRook, // 8 (BLACK_ROOK) + GenerateRook, // 9 (WHITE_ROOK) + GenerateQueen, // 10 (BLACK_QUEEN) + GenerateQueen, // 11 (WHITE_QUEEN) + GenerateBlackKing, // 12 (BLACK_KING) + GenerateWhiteKing // 13 (WHITE_KING) + }; + ULONG u; +#ifdef DEBUG + PIECE p; +#endif + + for(u = pos->uNonPawnCount[pos->uToMove][0] - 1; + u != (ULONG)-1; + u--) + { + c = pos->cNonPawns[pos->uToMove][u]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(!IS_PAWN(p)); + ASSERT(GET_COLOR(p) == pos->uToMove); +#endif + (JumpTable[pos->rgSquare[c].pPiece])(pStack, pos, c); + } + + if (pos->uToMove == BLACK) + { + for(u = 0; u < pos->uPawnCount[BLACK]; u++) + { + c = pos->cPawns[BLACK][u]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_PAWN(p)); + ASSERT(GET_COLOR(p) == pos->uToMove); +#endif + GenerateBlackPawn(pStack, pos, c); + } + } else { + ASSERT(pos->uToMove == WHITE); + for(u = 0; u < pos->uPawnCount[WHITE]; u++) + { + c = pos->cPawns[WHITE][u]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(c)); + p = pos->rgSquare[c].pPiece; + ASSERT(!IS_EMPTY(p)); + ASSERT(IS_PAWN(p)); + ASSERT(GET_COLOR(p) == pos->uToMove); +#endif + GenerateWhitePawn(pStack, pos, c); + } + } +} + + + +static ULONG +_GenerateEscapes(IN MOVE_STACK *pStack, + IN POSITION *pos) +/** + +Routine description: + + This function is called when side to move is in check in order to + generate pseudo-legal escapes from check. All legal escapes from + check are a subset of the moves returned by this function. In + general it's pretty good; the only bug I know about is that it + will generate a capture that alleviates check where the capturing + piece is pinned to the king (and thus the capture is illegal). + The purpose of this function is to allow the search to detect when + there is one legal reply to check and possibly extend. + +Parameters: + + MOVE_STACK *pStack : the move stack + POSITION *pos : the board + +Return value: + + ULONG : the number of pieces checking the king + +**/ +{ + ULONG u; + ULONG v; + COOR c; + COOR cDefender; + PIECE p; + PIECE pKing; + COOR cKing = pos->cNonPawns[pos->uToMove][0]; + int iIndex; + SEE_LIST rgCheckers; + int iDelta; + ULONG uReturn = 0; + static void (*JumpTable[]) + (MOVE_STACK *, POSITION *, COOR, COOR, COOR) = + { + InvalidSaveMe, // EMPTY + InvalidSaveMe, // EMPTY | WHITE + InvalidSaveMe, // 2 (BLACK_PAWN) + InvalidSaveMe, // 3 (WHITE_PAWN) + SaveMeKnight, // 4 (BLACK_KNIGHT) + SaveMeKnight, // 5 (WHITE_KNIGHT) + SaveMeBishop, // 6 (BLACK_BISHOP) + SaveMeBishop, // 7 (WHITE_BISHOP) + SaveMeRook, // 8 (BLACK_ROOK) + SaveMeRook, // 9 (WHITE_ROOK) + SaveMeQueen, // 10 (BLACK_QUEEN) + SaveMeQueen, // 11 (WHITE_QUEEN) + InvalidSaveMe, // kings already considered + InvalidSaveMe // kings already considered + }; + + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + ASSERT(TRUE == InCheck(pos, pos->uToMove)); + + // + // Use the SEE function GetAttacks to find out how many pieces are + // giving check and from whence. Note: we don't sort rgCheckers + // here; maybe it would be worth trying. In any event it + // shouldn't be affected by treating the list as a minheap + // vs. as a sorted list. + // + GetAttacks(&rgCheckers, pos, cKing, FLIP(pos->uToMove)); + ASSERT(rgCheckers.uCount > 0); + ASSERT(rgCheckers.uCount < 17); + uReturn = rgCheckers.uCount; + + // + // Phase I: See if the king can flee or take the checking piece. + // + pKing = pos->rgSquare[cKing].pPiece; + ASSERT(GET_COLOR(pKing) == pos->uToMove); + ASSERT(IS_KING(pKing)); + ASSERT(OPPOSITE_COLORS(pKing, rgCheckers.data[0].pPiece)); + u = 0; + while(0 != g_iQKDeltas[u]) + { + c = cKing + g_iQKDeltas[u]; + u++; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + + // + // This logical OR replaced with bitwise OR; the effect is + // the same the the bitwise is marginally faster. + // + if (IS_EMPTY(p) | (OPPOSITE_COLORS(p, pKing))) + { + if (FALSE == IsAttacked(c, pos, FLIP(pos->uToMove))) + { + // + // So we know the destination square is not under + // attack right now... but that could be because + // the present (pre-move) king position "blocks" + // the attack. Detect this. + // + for (v = 0; + v < rgCheckers.uCount; + v++) + { + ASSERT(OPPOSITE_COLORS(pKing, + rgCheckers.data[v].pPiece)); + if (!IS_PAWN(rgCheckers.data[v].pPiece) && + !IS_KNIGHT(rgCheckers.data[v].pPiece)) + { + iIndex = (int)rgCheckers.data[v].cLoc - + (int)cKing; + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + ASSERT(iDelta); + + iIndex = (int)rgCheckers.data[v].cLoc - + (int)c; + if (iDelta == CHECK_DELTA_WITH_INDEX(iIndex)) + { + goto loop; + } + } + } + ASSERT(v == rgCheckers.uCount); + + // + // If we get here the square is not under attack + // and it does not contain our own piece. It's + // either empty or contains an enemy piece. + // + ASSERT(!p || OPPOSITE_COLORS(pKing, p)); + _AddNormalMove(pStack, pos, cKing, c, p); + uReturn += 0x00010000; + } + } + } + loop: + ; + } + + // + // N.B. If there is more than one piece checking the king then + // there is no way to escape check by blocking check with another + // piece or capturing the offending piece. The two attackers + // cannot be on the same rank, file or diagonal because this would + // depend on the previous position being illegal. + // + if (rgCheckers.uCount > 1) + { +#ifdef DEBUG + // + // Note: the above comment is correct but this assertion fails + // on positions that we made up to run TestSearch. Disabled + // for now. + // +#if 0 + iDelta = DIRECTION_BETWEEN_SQUARES(rgCheckers.data[0].cLoc, cKing); + for (v = 1; v < rgCheckers.uCount; v++) + { + if (DIRECTION_BETWEEN_SQUARES(rgCheckers.data[v].cLoc, cKing) != + iDelta) + { + break; + } + } + ASSERT(v != rgCheckers.uCount); +#endif +#endif + return(uReturn); + } + + // + // Phase 2: If we get here there is a lone attacker causing check. + // See if the other pieces can block the check or take the + // checking piece. + // + c = rgCheckers.data[0].cLoc; + for (u = 1; // don't consider the king + u < pos->uNonPawnCount[pos->uToMove][0]; + u++) + { + cDefender = pos->cNonPawns[pos->uToMove][u]; + ASSERT(IS_ON_BOARD(cDefender)); + p = pos->rgSquare[cDefender].pPiece; + ASSERT(p && !IS_PAWN(p)); + ASSERT(GET_COLOR(p) == pos->uToMove); + + (JumpTable[p])(pStack, pos, cDefender, cKing, c); + } + + // Consider all pawns too + if (pos->uToMove == BLACK) + { + for (u = 0; u < pos->uPawnCount[BLACK]; u++) + { + cDefender = pos->cPawns[BLACK][u]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(cDefender)); + p = pos->rgSquare[cDefender].pPiece; + ASSERT(p && IS_PAWN(p)); + ASSERT(GET_COLOR(p) == pos->uToMove); +#endif + SaveMeBlackPawn(pStack, pos, cDefender, cKing, c); + } + } else { + ASSERT(pos->uToMove == WHITE); + for (u = 0; u < pos->uPawnCount[WHITE]; u++) + { + cDefender = pos->cPawns[WHITE][u]; +#ifdef DEBUG + ASSERT(IS_ON_BOARD(cDefender)); + p = pos->rgSquare[cDefender].pPiece; + ASSERT(p && IS_PAWN(p)); + ASSERT(GET_COLOR(p) == pos->uToMove); +#endif + SaveMeWhitePawn(pStack, pos, cDefender, cKing, c); + } + } + return(uReturn); +} + + +typedef struct _PRECOMP_KILLERS +{ + MOVE mv; + ULONG uBonus; +} +PRECOMP_KILLERS; + +static void +_ScoreAllMoves(IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mvHash) +/** + +Routine description: + + We have just generated all the moves, now score them. See comments + inline below about order. + +Parameters: + + IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mvHash, + +Return value: + + static void + +**/ +{ + ULONG uPly = ctx->uPly; + POSITION *pos = &ctx->sPosition; + ULONG u; + MOVE mv; + SCORE s; + MOVE_STACK_MOVE_VALUE_FLAGS mvf; + ULONG uHashMoveLoc = (ULONG)-1; + ULONG uColor = pos->uToMove; + PRECOMP_KILLERS sKillers[4]; + COOR cEnprise = GetEnprisePiece(pos, uColor); + + // + // We have generated all moves here. We also know that we are not + // escaping from check. There can be a hash move -- if there is + // then the search has already tried it and we should not generate + // it again. + // + // White has 218 legal moves in this position: + // 3Q4/1Q4Q1/4Q3/2Q4R/Q4Q2/3Q4/1Q4Rp/1K1BBNNk w - - 0 1 + // + + // + // Pre-populate killer/bonuses + // + sKillers[0].mv = ctx->mvKiller[uPly][0]; + sKillers[0].uBonus = FIRST_KILLER; + sKillers[1].mv.uMove = sKillers[3].mv.uMove = 0; + sKillers[2].mv = ctx->mvKiller[uPly][1]; + sKillers[2].uBonus = THIRD_KILLER; + if (uPly > 1) + { + sKillers[1].mv = ctx->mvKiller[uPly - 2][0]; + sKillers[1].uBonus = SECOND_KILLER; + sKillers[3].mv = ctx->mvKiller[uPly - 2][1]; + sKillers[3].uBonus = FOURTH_KILLER; + } + sKillers[0].uBonus |= + (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[0].mv) != 0)); + sKillers[1].uBonus |= + (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[1].mv) != 0)); + sKillers[2].uBonus |= + (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[2].mv) != 0)); + sKillers[3].uBonus |= + (SORT_THESE_FIRST * (IS_KILLERMATE_MOVE(sKillers[3].mv) != 0)); + + // + // Score moves + // + ASSERT(MOVE_COUNT(ctx, uPly) <= MAX_MOVES_PER_PLY); + for (u = pStack->uBegin[uPly]; + u < pStack->uEnd[uPly]; + u++) + { + mv = pStack->mvf[u].mv; + ASSERT(mv.uMove); + ASSERT(GET_COLOR(mv.pMoved) == uColor); + if (!IS_SAME_MOVE(mv, mvHash)) + { +#ifdef DEBUG + pStack->mvf[u].iValue = -MAX_INT; + pStack->mvf[u].bvFlags = 0; +#endif + // + // 1. Hash move (already handled by search, all we have to + // do here is not generate it) + // 2. Killer mate move, if one exists + // 3. Winning captures & promotions (MVV/LVA to tiebreak) + // 4. Even captures & promotions -- >= SORT_THESE_FIRST + // 5. Killer move 1-4 + // 6. "good" moves (moves away from danger etc...) + // 7. Other non capture moves (using dynamic move ordering scheme) + // 8. Losing captures -- <0 + // + + // + // Captures and promotions, use SEE + // + if (IS_CAPTURE_OR_PROMOTION(mv)) + { + ASSERT((mv.pCaptured) || (mv.pPromoted)); + s = PIECE_VALUE(mv.pCaptured) - + PIECE_VALUE(mv.pMoved); + if ((s <= 0) || mv.pPromoted) + { + s = SEE(pos, mv); + } + + if (s >= 0) + { + s += PIECE_VALUE_OVER_100(mv.pCaptured) + 120; + s += PIECE_VALUE_OVER_100(mv.pPromoted); + s -= PIECE_VALUE_OVER_100(mv.pMoved); + s += SORT_THESE_FIRST; + + // + // IDEA: bonus for capturing opponent's last moved + // piece to encourage quicker fail highs? + // + ASSERT(s >= SORT_THESE_FIRST); + ASSERT(s > 0); + ASSERT((s & STRIP_OFF_FLAGS) < VALUE_KING); + } +#ifdef DEBUG + else + { + ASSERT((s & STRIP_OFF_FLAGS) > -VALUE_KING); + s -= VALUE_KING; + ASSERT(s < 0); + } +#endif + } + + // + // Non-captures/promotes use history/killer + // + else + { + ASSERT((!mv.pCaptured) && (!mv.pPromoted)); + s = g_iPSQT[mv.pMoved][mv.cTo]; // 0..1000 + s |= (IS_SAME_MOVE(sKillers[0].mv, mv) * sKillers[0].uBonus); + s |= (IS_SAME_MOVE(sKillers[1].mv, mv) * sKillers[1].uBonus); + s |= (IS_SAME_MOVE(sKillers[2].mv, mv) * sKillers[2].uBonus); + s |= (IS_SAME_MOVE(sKillers[3].mv, mv) * sKillers[3].uBonus); + s |= ((GOOD_MOVE + PIECE_VALUE(mv.pMoved) / 2) * + (mv.cFrom == cEnprise)); + ASSERT(s >= 0); + } + pStack->mvf[u].iValue = s; + ASSERT(pStack->mvf[u].iValue != -MAX_INT); + } + else + { + ASSERT(uHashMoveLoc == (ULONG)-1); + uHashMoveLoc = u; +#ifdef DEBUG + ASSERT((mv.cFrom == mvHash.cFrom) && (mv.cTo == mvHash.cTo)); + pStack->mvf[u].bvFlags |= MVF_MOVE_SEARCHED; +#endif + } + + } // next move + + // + // If we generated the hash move, stick it at the end and pretend + // we didn't... it was already considered by the search and we + // should not generate it again. + // + if (uHashMoveLoc != (ULONG)-1) + { + ASSERT(MOVE_COUNT(ctx, uPly) >= 1); + ASSERT(uHashMoveLoc >= pStack->uBegin[uPly]); + ASSERT(uHashMoveLoc < pStack->uEnd[uPly]); + mvf = pStack->mvf[uHashMoveLoc]; + pStack->mvf[uHashMoveLoc] = pStack->mvf[pStack->uEnd[uPly] - 1]; +#ifdef DEBUG + pStack->mvf[pStack->uEnd[uPly] - 1] = mvf; +#endif + pStack->uEnd[uPly]--; + } +} + + + +static void +_ScoreAllEscapes(IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mvHash) +/** + +Routine description: + + We have just generated all the moves, now score them. See comments + inline below about order. + +Parameters: + + IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mvHash, + +Return value: + + static void + +**/ +{ + ULONG uPly = ctx->uPly; + POSITION *pos = &ctx->sPosition; + ULONG u; + MOVE mv; + SCORE s; + MOVE_STACK_MOVE_VALUE_FLAGS mvf; + ULONG uHashMoveLoc = (ULONG)-1; + COOR c; + ULONG v; + PIECE p; + static SCORE _bonus[2][7] = { + { 0, 2000, 1250, 1500, 1100, 850, 0 }, // friend + { 0, 1600, 100, 100, 50, -1, -1 }, // foe + }; + + // + // We have generated legal escapes from check here. There can be + // a hash move -- if there is then the search has already tried it + // and we should not generate it again. + // + + ASSERT(MOVE_COUNT(ctx, uPly) <= MAX_MOVES_PER_PLY); + for (u = pStack->uBegin[uPly]; + u < pStack->uEnd[uPly]; + u++) + { + mv = pStack->mvf[u].mv; + ASSERT(mv.uMove); + ASSERT(GET_COLOR(mv.pMoved) == pos->uToMove); + if (!IS_SAME_MOVE(mv, mvHash)) + { +#ifdef DEBUG + pStack->mvf[u].iValue = -MAX_INT; + pStack->mvf[u].bvFlags = 0; +#endif + pStack->mvf[u].mv.bvFlags |= MOVE_FLAG_ESCAPING_CHECK; + + // + // 1. Hash move (already handled by search, all we have to + // do here is not generate it) + // 2. Winning captures by pieces other than the checked king + // 3. Winning captures by the king + // 4. Even captures by pieces other than the king + // 5. Killer escapes + // 6. Moves that block the check and are even + // 7. King moves + // 8. Losing captures / blocks + // + + // + // Captures and promotions, use SEE + // + if (IS_CAPTURE_OR_PROMOTION(mv)) + { + ASSERT((mv.pCaptured) || (mv.pPromoted)); + s = PIECE_VALUE(mv.pCaptured) - + PIECE_VALUE(mv.pMoved); + if ((s <= 0) || mv.pPromoted) + { + s = SEE(pos, mv); + } + + if (s > 0) + { + // Winning captures: take with pieces before with king + s += PIECE_VALUE_OVER_100(mv.pPromoted); + s -= PIECE_VALUE_OVER_100(mv.pMoved); + s >>= IS_KING(mv.pMoved); + s |= SORT_THESE_FIRST; + ASSERT(s >= SORT_THESE_FIRST); + ASSERT(s > 0); + ASSERT((s & STRIP_OFF_FLAGS) < VALUE_KING); + } + else if (s == 0) + { + // Even capture -- can't be capturing w/ king + ASSERT(!IS_KING(mv.pMoved)); + s += PIECE_VALUE_OVER_100(mv.pPromoted) + 20; + s -= PIECE_VALUE_OVER_100(mv.pMoved); + s |= FIRST_KILLER; + ASSERT(s > 0); + } +#ifdef DEBUG + else + { + // Losing capture + ASSERT(!IS_KING(mv.pMoved)); + ASSERT((s & STRIP_OFF_FLAGS) > -VALUE_KING); + s -= VALUE_KING; + ASSERT(s < 0); + } +#endif + } + + // + // Non-captures/promotes + // + else + { + ASSERT((!mv.pCaptured) && (!mv.pPromoted)); + if (IS_SAME_MOVE(mv, ctx->mvKillerEscapes[uPly][0]) || + IS_SAME_MOVE(mv, ctx->mvKillerEscapes[uPly][1])) + { + s = SECOND_KILLER; + ASSERT(s >= 0); + } + else + { + s = g_iPSQT[mv.pMoved][mv.cTo]; // 0..1000 + if (!IS_KING(mv.pMoved)) + { + // 0..2400 + s += (VALUE_QUEEN - PIECE_VALUE(mv.pMoved)) * 4; + if (SEE(pos, mv) >= 0) + { + // Non-losing block of check + ASSERT(SEE(pos, mv) == 0); + s |= THIRD_KILLER; + ASSERT(s >= 0); + } + else + { + // Losing block of check + s -= VALUE_KING; + ASSERT(s < 0); + } + } + else + { + // If the king is fleeing, encourage a spot next + // to friendly pieces. + v = 0; + do { + c = mv.cTo + g_iQKDeltas[v++]; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + s += _bonus[OPPOSITE_COLORS(pos->uToMove, p)] + [PIECE_TYPE(p)]; + ASSERT(_bonus[OPPOSITE_COLORS(pos->uToMove, p)] + [PIECE_TYPE(p)] >= 0); + } + } + while(g_iQKDeltas[v] != 0); + } + } + } + pStack->mvf[u].iValue = s; + ASSERT(pStack->mvf[u].iValue != -MAX_INT); + } + else + { + ASSERT(uHashMoveLoc == (ULONG)-1); + uHashMoveLoc = u; +#ifdef DEBUG + ASSERT((mv.cFrom == mvHash.cFrom) && (mv.cTo == mvHash.cTo)); + pStack->mvf[u].bvFlags |= MVF_MOVE_SEARCHED; +#endif + } + } // next move + + // + // If we generated the hash move, stick it at the end and pretend + // we didn't... it was already considered by the search and we + // should not generate it again. + // + if (uHashMoveLoc != (ULONG)-1) + { + ASSERT(MOVE_COUNT(ctx, uPly) >= 1); + ASSERT(uHashMoveLoc >= pStack->uBegin[uPly]); + ASSERT(uHashMoveLoc < pStack->uEnd[uPly]); + mvf = pStack->mvf[uHashMoveLoc]; + pStack->mvf[uHashMoveLoc] = pStack->mvf[pStack->uEnd[uPly] - 1]; +#ifdef DEBUG + pStack->mvf[pStack->uEnd[uPly] - 1] = mvf; +#endif + pStack->uEnd[uPly]--; + } +} + + + +static void +_ScoreQSearchMovesInclChecks(IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + We have just generated all the moves. We were called from the + Qsearch so: + + 1. Unlike _ScoreAllMoves we don't have to think about a hash move + 2. QSearch only cares about winning/even captures/promotes and + checking moves. + + Like _ScoreSearchMoves, this function takes "hints" from the + searcher context about what squares are in danger and tries to + order moves away from those squares sooner. Unlike + _ScoreSearchMoves this function also attempts to capture enemies + that are in danger sooner. + +Parameters: + + IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + static void + +**/ +{ + register POSITION *pos = &ctx->sPosition; + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + ULONG uPly = ctx->uPly; + ULONG u, uColor = pos->uToMove; + MOVE mv; + MOVE mvLast = (pi-1)->mv; + SCORE s; + COOR cEnprise = GetEnprisePiece(pos, uColor); + + // + // We have generate all moves or just legal escapes from check + // here. There can be a hash move -- if there is then the search + // has already tried it and we should not generate it again. + // + // White has 218 legal moves in this position: + // 3Q4/1Q4Q1/4Q3/2Q4R/Q4Q2/3Q4/1Q4Rp/1K1BBNNk w - - 0 1 + // + ASSERT(MOVE_COUNT(ctx, uPly) <= MAX_MOVES_PER_PLY); + ASSERT(uPly >= 1); + + for (u = pStack->uBegin[uPly]; + u < pStack->uEnd[uPly]; + u++) + { + mv = pStack->mvf[u].mv; + ASSERT(GET_COLOR(mv.pMoved) == uColor); +#ifdef DEBUG + pStack->mvf[u].iValue = -MAX_INT; + pStack->mvf[u].bvFlags = 0; +#endif + pStack->mvf[u].mv.bvFlags |= WouldGiveCheck(ctx, mv); + + // + // 1. There can't be a hash move so don't worry about it + // 2. Winning captures & promotions + // 3. Even captures & promotions -- >= SORT_THESE_FIRST + // 4. Checking non-capture moves + // 5. Losing captures that check -- > 0 + // 6. Everything else is ignored -- <= 0 + // + + // + // Captures and promotions, use SEE + // + if (IS_CAPTURE_OR_PROMOTION(mv)) + { + ASSERT((mv.pCaptured) || (mv.pPromoted)); + s = PIECE_VALUE(mv.pCaptured) - + PIECE_VALUE(mv.pMoved); + if ((s <= 0) || mv.pPromoted) + { + s = SEE(pos, mv); + } + + if (s >= 0) + { + // + // Winning / even captures / promotes should be >= + // SORT_THESE_FIRST. + // + s += PIECE_VALUE_OVER_100(mv.pCaptured) + 120; + s += PIECE_VALUE_OVER_100(mv.pPromoted); + s -= PIECE_VALUE_OVER_100(mv.pMoved); + s += SORT_THESE_FIRST; + + // + // Bonus if it checks too + // + s += (pStack->mvf[u].mv.bvFlags & MOVE_FLAG_CHECKING) * 4; + + // + // Bonus for capturing last moved enemy piece. + // + s += (mv.cTo == mvLast.cTo) * 64; + ASSERT(s >= SORT_THESE_FIRST); + ASSERT(s > 0); + } + else + { + // + // Make losing captures into either zero scores or + // slightly positive if they check. Qsearch is going + // to bail as soon as it sees the first zero so no + // need to keep real SEE scores on these. + // + s = (pStack->mvf[u].mv.bvFlags & MOVE_FLAG_CHECKING); + ASSERT(s >= 0); + } + } + + // + // Non-captures/promotes -- we don't care unless they check + // + else + { + s = (pStack->mvf[u].mv.bvFlags & MOVE_FLAG_CHECKING) * 2; + ASSERT(s >= 0); + ASSERT(s < SORT_THESE_FIRST); + } + + // + // If this move moves a piece that was in danger, consider it + // sooner. + // + if (s > 0) + { + ASSERT(IS_CAPTURE_OR_PROMOTION(pStack->mvf[u].mv) || + IS_CHECKING_MOVE(pStack->mvf[u].mv)); + s += (mv.cFrom == cEnprise) * (PIECE_VALUE(mv.pMoved) / 4); + ASSERT(s > 0); + } + pStack->mvf[u].iValue = s; + ASSERT(pStack->mvf[u].iValue != -MAX_INT); + + } // next move +} + + +static void +_ScoreQSearchMovesNoChecks(IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + We have just generated all the moves. We were called from the + Qsearch so: + + 1. Unlike _ScoreAllMoves we don't have to think about a hash move + 2. QSearch only cares about winning/even captures/promotes. At + this point it is so deep that it doesn't even care about + checks. + + Like _ScoreSearchMoves, this function takes "hints" from the + searcher context about what squares are in danger and tries to + order moves away from those squares sooner. Unlike + _ScoreSearchMoves this function also attempts to capture enemies + that are in danger sooner. + +Parameters: + + IN MOVE_STACK *pStack, + IN SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + static void + +**/ +{ + register POSITION *pos = &(ctx->sPosition); + ULONG uPly = ctx->uPly; + ULONG u, uColor; + MOVE mv; + SCORE s; + + // + // We have generate all moves or just legal escapes from check + // here. There can be a hash move -- if there is then the search + // has already tried it and we should not generate it again. + // + // White has 218 legal moves in this position: + // 3Q4/1Q4Q1/4Q3/2Q4R/Q4Q2/3Q4/1Q4Rp/1K1BBNNk w - - 0 1 + // + ASSERT(MOVE_COUNT(ctx, uPly) <= MAX_MOVES_PER_PLY); + + uColor = pos->uToMove; + for (u = pStack->uBegin[uPly]; + u < pStack->uEnd[uPly]; + u++) + { + mv = pStack->mvf[u].mv; + ASSERT(GET_COLOR(mv.pMoved) == uColor); +#ifdef DEBUG + pStack->mvf[u].iValue = -MAX_INT; + pStack->mvf[u].bvFlags = 0; +#endif + // + // 1. There can't be a hash move so don't worry about it + // 2. Winning captures & promotions + // 3. Even captures & promotions -- >= SORT_THESE_FIRST + // 4. Everything else is ignored -- <= 0 + // + + // + // Captures and promotions, use SEE + // + s = 0; + if (IS_CAPTURE_OR_PROMOTION(mv)) + { + ASSERT((mv.pCaptured) || (mv.pPromoted)); + s = PIECE_VALUE(mv.pCaptured) - + PIECE_VALUE(mv.pMoved); + // + // TODO: how does this handle positions like K *p *k ? + // + if (s <= 0) + { + s = SEE(pos, mv); + } + + if (s >= 0) + { + // + // Winning / even captures / promotes should be >= + // SORT_THESE_FIRST. + // + s += PIECE_VALUE_OVER_100(mv.pCaptured) + 120; + s += PIECE_VALUE_OVER_100(mv.pPromoted); + s -= PIECE_VALUE_OVER_100(mv.pMoved); + s += SORT_THESE_FIRST; + + // + // IDEA: bonus for capturing an enprise enemy piece? + // + ASSERT(s >= SORT_THESE_FIRST); + ASSERT(s > 0); + } + } + pStack->mvf[u].iValue = s; + ASSERT(pStack->mvf[u].iValue != -MAX_INT); + + } // next move +} + + + +void +GenerateMoves(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mvHash, + IN ULONG uType) +/** + +Routine description: + + This is the entrypoint to the move generator. It invokes the + requested generation code which push moves onto the move stack in + ctx. Once the moves are generated this code optionally will score + the moves. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : a searcher thread's context + + IN: ctx->sPosition.uDangerCount and ctx->sPosition.cDanger + data is used to tweak move scoring. This data MUST be + consistent with the state of the current board. + + OUT: ctx->sMoveStack.uBegin[ctx->uPly] is set, + ctx->sMoveStack.uEnd[ctx->uPly] is set, + ctx->sMoveStack.mvf[begin..end] are populated + + MOVE mvHash : the hash move to not generate + + ULONG uType : what kind of moves to generate + + GENERATE_ALL_MOVES : pseudo-legal generation of all moves; + scored by _ScoreAllMoves. Return value is count of moves + generated. + + GENERATE_ESCAPE: called when stm in check, generate evasions + scored by _ScoreAllMoves. Return value is special code; + see inline comment below. + + GENERATE_CAPTURES_PROMS_CHECKS: caps, promotions, and checks + scored by _ScoreQSearchMoves. Return value is count of + moves generated. + + GENERATE_CAPTURES_PROMS: caps, promotions. Skip the checks. + + GENERATE_DONT_SCORE: pseudo-legal generation of all moves; + not scored to save time. Return value always zero. + +Return value: + + void + +**/ +{ + register ULONG uPly = ctx->uPly; + MOVE_STACK *pStack = &ctx->sMoveStack; + POSITION *pos = &ctx->sPosition; + ULONG uReturn; +#ifdef DEBUG + POSITION board; + ULONG u; + MOVE mv; + PIECE p; + + ASSERT((uPly >= 0) && (uPly < MAX_PLY_PER_SEARCH)); + memcpy(&board, pos, sizeof(POSITION)); + memcpy(&(pStack->board[uPly]), pos, sizeof(POSITION)); + + // + // Make sure the hash move makes sense (if provided) + // + if (mvHash.uMove) + { + p = pos->rgSquare[mvHash.cFrom].pPiece; + ASSERT(p); + ASSERT(GET_COLOR(p) == pos->uToMove); + p = pos->rgSquare[mvHash.cTo].pPiece; + ASSERT(!p || OPPOSITE_COLORS(p, pos->uToMove)); + } +#endif + pStack->uPly = uPly; + pStack->uEnd[uPly] = pStack->uBegin[uPly]; + pStack->sGenFlags[uPly].uAllGenFlags = 0; + + switch(uType) + { + case GENERATE_CAPTURES_PROMS_CHECKS: + ASSERT(!InCheck(pos, pos->uToMove)); + ASSERT(mvHash.uMove == 0); + _FindUnblockedSquares(pStack, pos); + _GenerateAllMoves(pStack, pos); + _ScoreQSearchMovesInclChecks(pStack, ctx); + break; + case GENERATE_CAPTURES_PROMS: + ASSERT(!InCheck(pos, pos->uToMove)); + ASSERT(mvHash.uMove == 0); + _FindUnblockedSquares(pStack, pos); + _GenerateAllMoves(pStack, pos); + _ScoreQSearchMovesNoChecks(pStack, ctx); + break; + case GENERATE_ALL_MOVES: + ASSERT(!InCheck(pos, pos->uToMove)); + _FindUnblockedSquares(pStack, pos); + _GenerateAllMoves(pStack, pos); + _ScoreAllMoves(pStack, ctx, mvHash); + uReturn = MOVE_COUNT(ctx, uPly); + break; + case GENERATE_ESCAPES: + ASSERT(InCheck(pos, pos->uToMove)); + _FindUnblockedSquares(pStack, pos); + uReturn = _GenerateEscapes(pStack, pos); + ASSERT(uReturn); + pStack->sGenFlags[uPly].uKingMoveCount = uReturn >> 16; + pStack->sGenFlags[uPly].uCheckingPieces = uReturn & 0xFF; + _ScoreAllEscapes(pStack, ctx, mvHash); + break; + + // Note: this is just for plytest / seetest. Just generate + // moves, do not score them. + case GENERATE_DONT_SCORE: + if (InCheck(pos, pos->uToMove)) + { + (void)_GenerateEscapes(pStack, pos); + for (uReturn = pStack->uBegin[uPly]; + uReturn < pStack->uEnd[uPly]; + uReturn++) + { + pStack->mvf[uReturn].mv.bvFlags |= + MOVE_FLAG_ESCAPING_CHECK; + } + } + else + { + (void)_GenerateAllMoves(pStack, pos); + } + goto end; +#ifdef DEBUG + default: + uReturn = 0; + ASSERT(FALSE); +#endif + } + +#ifdef DEBUG + // + // Sanity check the move list we just generated... + // + ASSERT(MOVE_COUNT(ctx, uPly) >= 0); + for (u = pStack->uBegin[uPly]; + u < pStack->uEnd[uPly]; + u++) + { + mv = pStack->mvf[u].mv; + ASSERT(!IS_SAME_MOVE(mv, mvHash)); + SanityCheckMove(pos, mv); + + if (WouldGiveCheck(ctx, mv)) + { + if (MakeMove(ctx, mv)) + { + ASSERT(ctx->uPly == (uPly + 1)); + ASSERT(InCheck(pos, pos->uToMove)); + UnmakeMove(ctx, mv); + + // + // Note: this is so that DEBUG and RELEASE builds search + // the same trees. Without this the MakeMove/UnmakeMove + // pair here can affect the order of the pieces in the + // POSITION piece lists which in turn affects the order + // in which moves are generated down the road. + // + memcpy(&ctx->sPosition, &board, sizeof(POSITION)); + } + } + else + { + if (MakeMove(ctx, mv)) + { + ASSERT(ctx->uPly == (uPly + 1)); + ASSERT(!InCheck(pos, pos->uToMove)); + UnmakeMove(ctx, mv); + + // + // Note: this is so that DEBUG and RELEASE builds search + // the same trees. Without this the MakeMove/UnmakeMove + // pair here can affect the order of the pieces in the + // POSITION piece lists which in turn affects the order + // in which moves are generated down the road. + // + memcpy(&ctx->sPosition, &board, sizeof(POSITION)); + } + } + } + ASSERT(PositionsAreEquivalent(&board, pos)); +#endif + end: + pStack->sGenFlags[uPly].uMoveCount = MOVE_COUNT(ctx, uPly); + pStack->uBegin[uPly + 1] = pStack->uEnd[uPly]; +} diff --git a/src/genetic/._main.cpp b/src/genetic/._main.cpp new file mode 100644 index 0000000..c78eae5 Binary files /dev/null and b/src/genetic/._main.cpp differ diff --git a/src/genetic/GeneticDriver.java b/src/genetic/GeneticDriver.java new file mode 100644 index 0000000..5c09b03 --- /dev/null +++ b/src/genetic/GeneticDriver.java @@ -0,0 +1,40 @@ +/* + Copyright 2007 Scott Gasch + + Licensed under the Apache License, Version 2.0 (the "License"); you + may not use this file except in compliance with the License. You may + obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. +*/ + +package org.guru.wannabe.genetic; + +public class GeneticDriver { + public static final int numGenerations = 5; + public static final int numPerGeneration = 32; + + public static void main(String[] args) { + System.out.println("---BEGIN: Genetic simulation."); + GeneticProcess process = new ParallelChessGeneticProcess(); + if (!process.mainInitialize(numGenerations, numPerGeneration)) { + throw new AssertionError("process.mainInitialize failed."); + } + for (int currentGeneration = 0; + currentGeneration < numGenerations; + currentGeneration++) { + System.out.println("---BEGIN: Generation " + currentGeneration); + process.generationInitialize(currentGeneration); + process.generationEvaluation(currentGeneration); + process.generationReproduction(currentGeneration); + System.out.println("---END: Generation " + currentGeneration); + } + System.out.println("---END: Genetic simulation."); + } +} diff --git a/src/genetic/GeneticProcess.java b/src/genetic/GeneticProcess.java new file mode 100644 index 0000000..091ce03 --- /dev/null +++ b/src/genetic/GeneticProcess.java @@ -0,0 +1,24 @@ +/* + Copyright 2007 Scott Gasch + + Licensed under the Apache License, Version 2.0 (the "License"); you + may not use this file except in compliance with the License. You may + obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. +*/ + +package org.guru.wannabe.genetic; + +public interface GeneticProcess { + boolean mainInitialize(int numGenerations, int numPerGeneration); + boolean generationInitialize(int currentGeneration); + boolean generationEvaluation(int currentGeneration); + boolean generationReproduction(int CurrentGeneration); +} diff --git a/src/genetic/Makefile b/src/genetic/Makefile new file mode 100755 index 0000000..f927946 --- /dev/null +++ b/src/genetic/Makefile @@ -0,0 +1,26 @@ +# Makefile + +# Gdata required activation.jar and mail.jar; make this where you put them +SHAREPATH= /usr/local/share/java/classes +CLASSPATH= ./ + +JFLAGS= -classpath $(CLASSPATH) -sourcepath ./ -d . +JAVAC= javac $(JFLAGS) $(JCFLAGS) -Xlint:unchecked +JAVA= java $(JFLAGS) $(JRFLAGS) + +JAVASRC= GeneticDriver.java GeneticProcess.java \ + ParallelChessGeneticProcess.java +CLASSES= $(JAVASRC:.java=.class) + +all : compile + +compile : $(JAVASRC) + $(JAVAC) $(JFLAGS) $(JAVASRC) + +doc : + mkdir -p doc + javadoc -d doc *.java + +clean : + rm -f $(CLASSES:.class='$$'*.class) $(CLASSES) + rm -fr doc diff --git a/src/genetic/ParallelChessGeneticProcess.java b/src/genetic/ParallelChessGeneticProcess.java new file mode 100644 index 0000000..75d9425 --- /dev/null +++ b/src/genetic/ParallelChessGeneticProcess.java @@ -0,0 +1,267 @@ +/* + Copyright 2007 Scott Gasch + + Licensed under the Apache License, Version 2.0 (the "License"); you + may not use this file except in compliance with the License. You may + obtain a copy of the License at + + http://www.apache.org/licenses/LICENSE-2.0 + + Unless required by applicable law or agreed to in writing, software + distributed under the License is distributed on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied. See the License for the specific language governing + permissions and limitations under the License. +*/ + +package org.guru.wannabe.genetic; + +import java.io.*; +import java.util.regex.*; + +import java.util.Map; +import java.util.TreeMap; +import java.util.List; +import java.util.ArrayList; +import java.util.Arrays; + +public class ParallelChessGeneticProcess implements GeneticProcess { + private static final int numProcessors = 4; + private static final String baselineDna = "./baseline.dna"; + private static final String baselineLog = "./baseline.log"; + private static final String scriptName = "./trial.ep_"; + + private int numGenerations; + private int numPerGeneration; + private int numSeeds; + + // Helper function to emulate system(3). + private static void system(String cmd[]) { + Runtime runtime = Runtime.getRuntime(); + try { + Process ps = runtime.exec(cmd); + InputStream stdin = ps.getInputStream(); + InputStreamReader isr = new InputStreamReader(stdin); + BufferedReader br = new BufferedReader(isr); + String line = null; + while((line = br.readLine()) != null) ; + ps.waitFor(); + } catch(Exception e) { + throw new AssertionError(e); + } + } + + // Private helpers to build filenames + private static String seedFilename(int generation, int which) { + return "./gen" + generation + "_seed" + which + ".dna"; + } + + private static String logFilename(int generation, int which) { + return "./gen" + generation + "_" + which + ".log"; + } + + private static String dnaFilename(int generation, int which) { + return "./gen" + generation + "_" + which + ".dna"; + } + + // Uses mutate.pl to cause dna mutations + private static void mutate(String from, String to) { + String cmd[] = new String[] { "./mutate.pl", from, to }; + system(cmd); + try { + BufferedWriter out = + new BufferedWriter(new FileWriter(to, true)); + out.write("# mutate " + from + " -> " + to + "\n"); + out.close(); + } catch(IOException e) { + throw new AssertionError(e); + } + } + + // Runs a chess trial event + private static void chessTrial(String dnaFile, String logFile) { + String cmd[] = new String[] { "./typhoon", + "--cpus", "1", + "--hash", "128m", + "--batch", + "--logfile", logFile, + "--dnafile", dnaFile, + "--command", "script ./trial.ep_" }; + system(cmd); + } + + // The mainInitialize method produces the 0th generation DNA from + // a seed file called "baseline.dna" using a helper script called + // mutate.pl (the generic DNA mutation routine). + public boolean mainInitialize(int numGenerations, + int numPerGeneration) { + + System.out.println("Performing pre-generation setup tasks."); + this.numGenerations = numGenerations; + this.numPerGeneration = numPerGeneration; + this.numSeeds = numPerGeneration / 5; + if ((numGenerations <= 0) || + (numPerGeneration <= 0) || + (numSeeds <= 0)) { + throw new IllegalArgumentException("Bad value"); + } + + // Create generation zero seeds based on mutations of baseline.dna + for (int x = 0; x < numSeeds; x++) { + String seedFile = seedFilename(0, x); + if (!new File(seedFile).exists()) { + mutate(baselineDna, seedFile); + } else { + System.out.println("Using existing " + seedFile); + } + } + + // Run baseline.dna trial to get a starting point. + if (!new File(baselineLog).exists()) { + chessTrial(baselineDna, baselineLog); + } else { + System.out.println("Using existing " + baselineLog); + } + return true; + } + + public boolean generationInitialize(int generationNumber) { + + // Using the seed dna of the previous generation, build the + // genes for the current generation. + System.out.println("Initializing generation " + generationNumber); + for (int x = 0; x < numPerGeneration; x++) { + String dnaFile = dnaFilename(generationNumber, x); + String seedFile = seedFilename(generationNumber, x % numSeeds); + mutate(seedFile, dnaFile); + } + return true; + } + + public boolean generationEvaluation(int generationNumber) { + class ChessGame implements Runnable { + public String dnaFile; + public String logFile; + public ChessGame(String dnaFile, String logFile) { + this.dnaFile = dnaFile; this.logFile = logFile; + } + public void run() { + if (!new File(logFile).exists()) { + System.out.println("Creating " + logFile); + chessTrial(dnaFile, logFile); + } else { + System.out.println("Using existing " + logFile); + } + } + } + + // Populate work queue + System.out.println("Evaluating generation " + generationNumber); + List workQueue = new ArrayList(); + for (int x = 0; x < numPerGeneration; x++) { + String dnaFile = dnaFilename(generationNumber, x); + String logFile = logFilename(generationNumber, x); + workQueue.add(new ChessGame(dnaFile, logFile)); + } + + // Depopulate the work queue in parallel + Thread threadPool[] = new Thread[numProcessors]; + while(!workQueue.isEmpty()) { + ChessGame next = workQueue.remove(0); + int x = 0; + do { + if ((threadPool[x] == null) || + (!threadPool[x].isAlive())) { + threadPool[x] = new Thread(next); + threadPool[x].setPriority(Thread.MAX_PRIORITY); + threadPool[x].start(); + break; + } + x++; + if (x >= numProcessors) { + x = 0; + try { + Thread.sleep(2000); + } catch(Exception e) { + ; + } + } + } + while(true); + } + + // Wait for all threads to become idle again + int x = 0; + do { + if (threadPool[x] != null && threadPool[x].isAlive()) { + x = 0; + } + x++; + try { + Thread.sleep(2000); + } catch(Exception e) { + ; + } + } while(x < numProcessors); + return true; + } + + public boolean generationReproduction(int generationNumber) { + + // Helper data class + class FileAndScore implements Comparable { + public final String file; + public final int score; + public final int number; + public FileAndScore(String file, int score, int number) { + this.file = file; this.score = score; this.number = number; + } + public int compareTo(FileAndScore other) { + return other.score - score; + } + } + + System.out.println("Seeding subsequent generation."); + List scores = new ArrayList(); + for (int x = 0; x < numPerGeneration; x++) { + String logFile = logFilename(generationNumber, x); + try { + BufferedReader log = new BufferedReader( + new FileReader(logFile)); + String line = null; + Pattern p = + Pattern.compile("\\s+correct solutions\\s+:\\s+(\\d+)"); + while ((line = log.readLine()) != null) { + Matcher m = p.matcher(line); + if (m.matches()) { + int score = Integer.parseInt(m.group(1)); + FileAndScore fas = + new FileAndScore(logFile, score, x); + scores.add(fas); + break; + } + } + log.close(); + } + catch (Exception e) { + throw new AssertionError(e); + } + } + java.util.Collections.sort(scores); + for (int x = 0; x < numSeeds; x++) { + FileAndScore breeder = scores.get(0); + scores.remove(0); + String dnaFile = dnaFilename(generationNumber, breeder.number); + String seedFile = seedFilename(generationNumber + 1, x); + if (!new File(seedFile).exists()) { + System.out.println("Number " + breeder.number + " got score " + + breeder.score + " and will propagate."); + String cmd[] = new String[] { "/bin/cp", "-f", dnaFile, seedFile }; + system(cmd); + } else { + System.out.println("Using existing " + seedFile); + } + } + return true; + } +} diff --git a/src/genetic/baseline.dna b/src/genetic/baseline.dna new file mode 100644 index 0000000..185d863 --- /dev/null +++ b/src/genetic/baseline.dna @@ -0,0 +1,129 @@ +# BEGIN MUTATION ALLOWED +# Trade pieces/pawns +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +# END MUTATION ALLOWED +# Reduced material down scaler +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +# Reduced material up scaler +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +# Passer material up scaler +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +# Pawn centrality bonus by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0,-10,0,0,0,0,0,0,0,0,-10,0,5,5,5,5,0,-10,0,0,0,0,0,0,0,0,-10,0,5,9,9,5,0,-10,0,0,0,0,0,0,0,0,-10,0,5,9,9,5,0,-10,0,0,0,0,0,0,0,0,-10,0,5,5,5,5,0,-10,0,0,0,0,0,0,0,0,-10,0,0,0,0,0,0,-10,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Backward shielded by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Backward exposed by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Doubled pawn penalty by count +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-48,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-14,-25,-39,-55,-73,-95,-121 +# Isolated pawn penalty by count +0,-3,-7,-9,-16,-35,-50,-85,-100 +# Isolated pawn penalty by board file +0,-8,-9,-10,-11,-11,-10,-9,-8 +# Isolated exposed base score +-6 +# Isolated doubled base score +-18 +# BEGIN MUTATION ALLOWED +# Passer pawn by rank/color (reduced if enemy controls sq ahead) +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +# Candidate passer pawn by rank/color +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +# Connected passer pawn by rank/color (x2, one for each pawn) +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +# Supported passer pawn by rank/color +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +# END MUTATION ALLOWED +# Outside passer pawn by how far outside +0,0,7,14,21,28,34,41,55 +# BEGIN MUTATION ALLOWED +# Passer bonus as material comes off +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# END MUTATION ALLOWED +# Unstoppable passer +800 +# Undeveloper minors in the opening +0,-6,-10,-16,-22 +# Bishop over knight in the endgame by how open is the board +33 +# Bishop pair value by number of pawns +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,58,56,55,54,53,52,51,50,49,48,47,46,45,44,43,42,41 +# BEGIN MUTATION ALLOWED +# Stationary pawns on bishop color +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-5,-7,-7,-7,-7,-7,-7,-5,0,0,0,0,0,0,0,0,-7,-7,-8,-8,-8,-8,-7,-7,0,0,0,0,0,0,0,0,-8,-9,-10,-12,-12,-10,-9,-8,0,0,0,0,0,0,0,0,-8,-9,-10,-12,-12,-10,-9,-8,0,0,0,0,0,0,0,0,-7,-7,-8,-8,-8,-8,-7,-7,0,0,0,0,0,0,0,0,-5,-7,-7,-7,-7,-7,-7,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Transient pawns on bishop color +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Bishop mobility by num squares +-22,-15,-13,-8,-3,0,2,4,7,11,15,17,18,19 +# Bishop mobility num-in-a-row bonus +-14,-6,1,4,6,7,9,11 +# END MUTATION ALLOWED +# Outposted bishop by distance from eking +0,38,30,18,8,4,0,-10,-16 +# Bishop in a closed position bonus +15,15,15,15,14,14,13,12,11,10,9,7,5,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# Knight centrality by location +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +# Knight-eking tropism bonus +0,15,12,9,5,0,0,0,0 +# Knight value as pawns come off +-30,-24,-18,-12,-6,0,6,12,18 +# Outposted knight by distance from eking +0,40,33,22,10,3,0,0,0 +# Knight on interesting square by rank/color +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +# BEGIN MUTATION ALLOWED +# Knight mobility +-17,-10,-6,0,3,6,8,9,10 +# Knight with N pawns supporting +0,7,11 +# END MUTATION ALLOWED +# Knight in a closed position +0,0,0,0,0,0,2,4,6,8,9,10,11,12,13,14,16,18,19,20,20,21,21,22,22,23,23,24,24,25,25,26,27 +# Rook on full open file by distance from eking +24,22,17,14,13,13,12,12 +# Rook on half open file with enemy pawn by distance from eking +12,11,9,9,8,8,8,7 +# Rook on half open file with friend pawn by distance from eking +13,12,11,11,9,9,9,8 +# Rook behind own passer by passer rank/color +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +# Rook leading own passer by passer rank/color +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +# King trapping friend rook +-40 +# Rook trapping eking +22 +# Rook value as pawns come off +55,44,33,22,11,0,-12,-24,-36 +# Rooks connected vertically (x2) +7 +# Rooks connected horizontally (x2) +4 +# BEGIN MUTATION ALLOWED +# Rook mobility by squares +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +# Rook mobility by n-in-a-row +-15,-6,0,4,8,8,8,8 +# Queen mobility by squares +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +# END MUTATION ALLOWED +# Queen out too early by num unmoved minors +0,-14,-22,-26,-33 +# Queen eking tropism +0,39,35,28,24,17,16,15 +# Queen attacking square next to eking (x #squares) +8 +# Initial king safety counter by location/color +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +# Bring king to center by location +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +# BEGIN MUTATION ALLOWED +# King pawn shield (x #pawns) +15 +# King safety by counter +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-140,-160,-180,-200,-225,-250,-275,-300,-333,-366,-399,-433,-466,-499,-533,-566,-599,-600,-600,-600,-600,-600,-600,-600,-600,-600,-600 +# END MUTATION ALLOWED +# King missing one castle option +-23 diff --git a/src/genetic/baseline.log b/src/genetic/baseline.log new file mode 100644 index 0000000..5c96888 --- /dev/null +++ b/src/genetic/baseline.log @@ -0,0 +1,370 @@ +Typhoon 1.00 (built on Jun 29 2008 15:18:00): + Copyright (C) 2000-2007, Scott Gasch (scott.gasch@gmail.com) + $Id: chess.h 353 2008-06-29 18:10:16Z scott $ + GCC 4.0.1 (Apple Inc. build 5465) + Make profile used: -std=gnu99 -D_X86_ -DOSX -DGENETIC -g -O3 -fexpensive-optimizations -ffast-math -finline-functions -m32 -DPERF_COUNTERS -DMP -DSMP + Multiprocessor enabled; 1 searcher thread + Performance counters + Hash sizes: 64 Mb (main), 10 Mb / thread (pawn), 48 Mb / thread (eval) + QCheckPlies: 1 + FutilityBase: 50 + Logging Eval DNA. +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-17,-10,-6,0,3,5,7,8,8 +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +24,22,17,14,13,13,12,12 +12,11,9,9,8,8,8,7 +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4 +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8 +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15 +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 + IID R-factor: 2 ply +INPUT SYSTEM INIT: Pushing "script ./trial.ep_ +" +_white(move 1)_ +SCRIPT> st 20 + +SCRIPT> easy + +SCRIPT> setboard 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - + +FEN: 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - 0 0 + + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 + +---------------------------------------+ + 8 | |::::| *q |::::| *r |::::| *k |::::| 0x00 + 7 |::::| *p |:*p:| *b |::::| |::::| | 0x10 + 6 | *r |::::| |:*p:| |:.P:| *p |::::| 0x20 + 5 |:*p:| |::::| |::::| *n |::::| *p | 0x30 + 4 | |::::| .P |::::| *n |::::| |::::| 0x40 + 3 |::::| |::::| |::::| .N |:.P:| .P | 0x50 + 2 | .P |:.P:| |::::| |:.Q:| |:.K:| 0x60 + 1 |::::| |:.B:| .R |:.R:| .B |::::| | 0x70 + +---------------------------------------+ + A B C D E F G H + + +SCRIPT> solution f7+ + +SCRIPT> id "ECM.001" + +SCRIPT> go + +The root position is: 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - 0 0 +SetMoveTimer: Soft time limit 00:20.000 seconds. +SetMoveTimer: Hard time limit 00:20.000 seconds. + 7 +2.98 00:00.365 184386 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Ba4 b3 + 8 +3.13 00:00.684 375962 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Ba4 Nf6+ Kg7 b3 Bxb3 axb3 Kxf6 + 9 +3.35 00:02.259 1314795 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg8 Nxe4 Ba4 Re1 Kh8 Bg5 +10 +3.58 00:04.394 2477084 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kf8 Nxe4 Ba4 Re1 Kg7 b3 Bc6 Bb2+ Kh7 +11 +3.64 00:08.367 4600580 f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg7 Nxe4 Bc6 Bd3 Qe8 Ng5 Qe5 Bf4 +SOFT TIMER (20.1 sec) --> stop searching now +move f7+ +--------------------------------------------- +Searched for 20.1 seconds, saw 10616832 nodes (8908964 qnodes) (527305 nps). +tellothers d11, +3.64, 20.1s, 527knps, PV=f7+ Kxf7 Rxe4 Rxe4 Ng5+ Kg7 Nxe4 Bc6 Bd3 Qe8 Ng5 Qe5 Bf4 +Hashing percentages: (37.045 total, 13.886 useful) +Pawn hash hitrate: 99.416 percent. +Null move cutoff rate: 77.853 percent. +First move beta cutoff rate was 93.652 percent. +Eval percentages: ( 8.46 hash, 69.90 lazy, 21.64 full) +Extensions: (303079 +, 137182 q+, 23377 1mv, 5339 !kmvs, 1374 mult+, 4112 pawn + 6087 threat, 0 zug, 1679 sing, 2 endg, 2644 bm, 8898 recap) +Problem "ECM.001" solved in 0.0 sec. +Current suite score: 1 correct of 1 problems. +SCRIPT> setboard 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - + +FEN: 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - 0 0 + + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 + +---------------------------------------+ + 8 | |::::| |::::| |::::| |:*r:| 0x00 + 7 |::::| *p |::::| |:*k:| |::::| | 0x10 + 6 | |::::| *b |:*p:| *p |::::| |::::| 0x20 + 5 |:*p:| |::::| |:*n:| *p |::::| | 0x30 + 4 | .P |::::| .P |:.R:| |::::| |::::| 0x40 + 3 |::::| |:.N:| |::::| .P |:.P:| | 0x50 + 2 | |:.P:| |::::| |::::| .K |::::| 0x60 + 1 |::::| |::::| .B |::::| |::::| | 0x70 + +---------------------------------------+ + A B C D E F G H + + +SCRIPT> solution Bxf3+ + +SCRIPT> id "ECM.002" + +SCRIPT> go + +The root position is: 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - 0 0 +SetMoveTimer: Soft time limit 00:20.000 seconds. +SetMoveTimer: Hard time limit 00:20.000 seconds. + 9 +2.48 00:00.164 117472 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kg2 Nxd4 g4 f4 g5 e5 +10 +2.25 00:00.348 262726 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 f4 g5 f3 g6 +11 +2.47 00:00.752 576332 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 f4 g5 e5 Kg4 Kf7 +12 +2.20 00:01.258 987310 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 f4 g5 e5 Ne4 Ke6 g6 +13 +2.47 00:03.330 2593758 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 f4 g5 e5 Kg4 Ke6 g6 Kf6 +14 +2.20 00:05.220 4166374 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 Kf6 gxf5 Kxf5 Kg2 e5 Kf2 e4 Ke3 +15 +2.28 00:12.333 9835420 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 Kf6 gxf5 Kxf5 Kg3 e5 Kf2 e4 Nd5 Ke5 +16 +2.30 00:19.914 16085480 Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 Kf6 gxf5 Kxf5 Kg2 Nb3 Nd1 Nc5 Nc3 Nd3 Nb5 +HARD TIMER (20.1 sec) --> stop searching now +move Bxf3+ +--------------------------------------------- +Searched for 20.1 seconds, saw 16252928 nodes (12457309 qnodes) (807319 nps). +tellothers d16, +2.30, 20.1s, 807knps, PV=Bxf3+ Bxf3 Rh2+ Kxh2 Nxf3+ Kh3 Nxd4 g4 Kf6 gxf5 Kxf5 Kg2 Nb3 Nd1 Nc5 Nc3 Nd3 Nb5 +Hashing percentages: (54.754 total, 26.571 useful) +Pawn hash hitrate: 98.837 percent. +Null move cutoff rate: 83.429 percent. +First move beta cutoff rate was 96.057 percent. +Eval percentages: (11.20 hash, 71.63 lazy, 17.16 full) +Extensions: (461475 +, 41902 q+, 2821 1mv, 401 !kmvs, 636 mult+, 4863 pawn + 699 threat, 18 zug, 290 sing, 21674 endg, 5357 bm, 10418 recap) +Problem "ECM.002" solved in 0.1 sec. +Current suite score: 2 correct of 2 problems. +SCRIPT> setboard 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - + +FEN: 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - 0 0 + + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 + +---------------------------------------+ + 8 | |::::| |::::| *k |::::| |::::| 0x00 + 7 |:*p:| |:.P:| |::::| |:*p:| | 0x10 + 6 | |::::| *q |::::| *n |:*p:| |:*p:| 0x20 + 5 |::::| |::::| .N |::::| |::::| | 0x30 + 4 | |::::| |::::| |::::| |::::| 0x40 + 3 |::::| .Q |::::| |::::| .P |:.P:| | 0x50 + 2 | |::::| |::::| |::::| .K |:.P:| 0x60 + 1 |::::| |::::| |::::| |::::| | 0x70 + +---------------------------------------+ + A B C D E F G H + + +SCRIPT> solution Qb5 + +SCRIPT> id "ECM.003" + +SCRIPT> go + +The root position is: 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - 0 0 +SetMoveTimer: Soft time limit 00:20.000 seconds. +SetMoveTimer: Hard time limit 00:20.000 seconds. + 5 +1.12 00:00.196 136405 Qb8+ Kd7 Qg8 g5 c8=Q+ Qxc8 Nxf6+ Kc7 Qf7+ Kb8 Nd7+ Kc7 Qxe6 Qxd7 Qxh6 + 5 +1.33 00:00.275 197327 Nb4 Qd7 Qd5 Nxc7 Qg8+ Ke7 Qxg7+ Kd8 Qxh6 + 5+ +2.92 00:00.334 242098 Qb5 ++ + 5 +2.76 00:00.335 242668 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 Nxb5 + 6 +2.76 00:00.338 245531 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 Nxb5 + 7 +2.76 00:00.490 369773 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 Nxb5 + 8 +2.72 00:00.936 734352 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 f4+ Ke4 Nxb5 + 9 +2.60 00:02.860 2302612 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 f4+ Ke4 Nxb5 a5 Nc3+ Kd4 +10 +2.60 00:05.762 4811455 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 f4+ Ke4 Nxb5 a5 Nc3+ Kd4 +11 +2.64 00:16.020 13521099 Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 Nxb5 a5 Kf2 g6 Nc3 Kd4 +HARD TIMER (20.2 sec) --> stop searching now +move Qb5 +--------------------------------------------- +Searched for 20.2 seconds, saw 16777218 nodes (13737368 qnodes) (831574 nps). +tellothers d11, +2.64, 20.2s, 832knps, PV=Qb5 Qxb5 c8=Q+ Kf7 Qxe6+ Kxe6 Nc7+ Ke5 Nxb5 a5 Kf2 g6 Nc3 Kd4 +Hashing percentages: (49.643 total, 23.838 useful) +Pawn hash hitrate: 99.845 percent. +Null move cutoff rate: 84.497 percent. +First move beta cutoff rate was 97.183 percent. +Eval percentages: ( 5.57 hash, 88.54 lazy, 5.89 full) +Extensions: (998642 +, 365387 q+, 40580 1mv, 2227 !kmvs, 773 mult+, 194 pawn + 4448 threat, 0 zug, 8001 sing, 15206 endg, 10689 bm, 3168 recap) +Problem "ECM.003" solved in 0.3 sec. +Current suite score: 3 correct of 3 problems. +SCRIPT> setboard 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - + +FEN: 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - 0 0 + + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 + +---------------------------------------+ + 8 | |::::| *r |::::| *b |::::| *k |::::| 0x00 + 7 |:.R:| |::::| |::::| *p |:*p:| | 0x10 + 6 | |::::| |::::| *p |:*b:| |:*p:| 0x20 + 5 |::::| *p |:.B:| *r |::::| |::::| | 0x30 + 4 | |:.P:| *q |::::| |:.P:| |::::| 0x40 + 3 |::::| |::::| .N |::::| |::::| | 0x50 + 2 | |::::| .P |:.Q:| |::::| .P |:.P:| 0x60 + 1 |::::| |::::| |::::| .R |:.K:| | 0x70 + +---------------------------------------+ + A B C D E F G H + + +SCRIPT> solution Rcxc5 + +SCRIPT> id "ECM.004" + +SCRIPT> go + +The root position is: 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - 0 0 +SetMoveTimer: Soft time limit 00:20.000 seconds. +SetMoveTimer: Hard time limit 00:20.000 seconds. + 7 +1.28 00:00.241 128871 Bd4+ Bxd4 Qxd4+ Qf2 Rxc2 Qxd4 Rxd4 Rd1 f6 + 7+ +1.90 00:00.406 230629 Bd4+ Bxd4 Qxd4+ Qf2 Rxc2 Qxd4 Rxd4 Rd1 f6 ++ + 7 +3.31 00:00.473 269299 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 c3 + 8 +3.54 00:00.762 457282 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 Rd1 Bc6 + 9 +3.45 00:01.279 775279 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 f5 e5 Re1 +10 +3.54 00:02.287 1455118 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 Rd1 Qf2 Rf1 Qc5 +11 +3.38 00:03.973 2655301 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 Qd6 g6 h3 Bd4 Rd1 +12 +3.54 00:07.504 5112945 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 Qe4 Bd4 Rd1 Bc3 h3 Qf2 +13 +3.58 00:14.106 9751497 Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 Qd6 Qa8 h3 Bc6 Rg1 Kh7 Qd3+ Be4 Qxb5 Bxc2 +SOFT TIMER (20.1 sec) --> stop searching now +move Rcxc5 +--------------------------------------------- +Searched for 20.1 seconds, saw 14286848 nodes (11078116 qnodes) (710896 nps). +tellothers d13, +3.58, 20.1s, 711knps, PV=Rcxc5 bxc5 Rxd3 Qxd3 Qxc5+ Kh1 Qxa7 Qd6 Qa8 h3 Bc6 Rg1 Kh7 Qd3+ Be4 Qxb5 Bxc2 +Hashing percentages: (54.802 total, 27.084 useful) +Pawn hash hitrate: 99.661 percent. +Null move cutoff rate: 80.447 percent. +First move beta cutoff rate was 94.013 percent. +Eval percentages: ( 7.93 hash, 81.56 lazy, 10.50 full) +Extensions: (242731 +, 147017 q+, 10540 1mv, 11362 !kmvs, 273 mult+, 1569 pawn + 4886 threat, 25 zug, 3489 sing, 19 endg, 12049 bm, 5871 recap) +Problem "ECM.004" solved in 0.5 sec. +Current suite score: 4 correct of 4 problems. +SCRIPT> setboard 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - + +FEN: 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - 0 0 + + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 + +---------------------------------------+ + 8 | |::::| |::::| |::::| *k |::::| 0x00 + 7 |:*p:| |:*q:| *b |::::| *p |::::| *p | 0x10 + 6 | |:*p:| |::::| |:*n:| *p |::::| 0x20 + 5 |::::| |:*b:| |::::| *p |::::| | 0x30 + 4 | |::::| .B |::::| |::::| |::::| 0x40 + 3 |::::| |:.P:| |::::| |:.N:| | 0x50 + 2 | .P |:.P:| |::::| .Q |:.P:| .P |:.P:| 0x60 + 1 |::::| |::::| |:.N:| |:.K:| | 0x70 + +---------------------------------------+ + A B C D E F G H + + +SCRIPT> solution Bxf2+ + +SCRIPT> id "ECM.005" + +SCRIPT> go + +The root position is: 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - 0 0 +SetMoveTimer: Soft time limit 00:20.000 seconds. +SetMoveTimer: Hard time limit 00:20.000 seconds. + 7 +0.99 00:00.173 97919 Bxf2+ Qxf2 Qxc4 Qd4 Qc6 Nf3 h6 c4 + 8 +1.07 00:00.357 216878 Bxf2+ Qxf2 Qxc4 Qd4 Qe6 Nf3 Nd5 Qe5 Qxe5 Nxe5 + 9 +1.07 00:00.646 411939 Bxf2+ Qxf2 Qxc4 Qd4 Qe6 Nf3 Nd5 Qe5 Qxe5 Nxe5 +10 +1.01 00:01.439 944061 Bxf2+ Qxf2 Qxc4 Qd4 Qe6 Nf3 Nd5 c4 Qe3+ Qxe3 Nxe3 Ne5 +11 +1.02 00:02.977 2004691 Bxf2+ Qxf2 Qxc4 Qd4 Qe6 Nf3 Nd5 c4 Qe3+ Qxe3 Nxe3 Ne5 Ba4 +12 +0.98 00:06.061 4098991 Bxf2+ Qxf2 Qxc4 Qd4 Qe6 Nf3 Ne8 b3 f6 c4 g5 Kh1 f4 +SOFT TIMER (20.0 sec) --> stop searching now +move Bxf2+ +--------------------------------------------- +Searched for 20.0 seconds, saw 13631488 nodes (11086938 qnodes) (680902 nps). +tellothers d12, +0.98, 20.0s, 681knps, PV=Bxf2+ Qxf2 Qxc4 Qd4 Qe6 Nf3 Ne8 b3 f6 c4 g5 Kh1 f4 +Hashing percentages: (31.320 total, 14.951 useful) +Pawn hash hitrate: 98.692 percent. +Null move cutoff rate: 75.182 percent. +First move beta cutoff rate was 94.965 percent. +Eval percentages: ( 6.34 hash, 78.69 lazy, 14.97 full) +Extensions: (404449 +, 155342 q+, 9621 1mv, 17129 !kmvs, 998 mult+, 3515 pawn + 6103 threat, 15 zug, 5503 sing, 6067 endg, 12601 bm, 8911 recap) +Problem "ECM.005" solved in 0.1 sec. +Current suite score: 5 correct of 5 problems. +SCRIPT> setboard 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - + +FEN: 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - 0 0 + + + 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 + +---------------------------------------+ + 8 | |::::| |:*q:| |::::| |::::| 0x00 + 7 |:*p:| *p |::::| |::::| *p |:*k:| *p | 0x10 + 6 | |::::| |::::| |:*n:| *p |:.N:| 0x20 + 5 |::::| |:*b:| *p |:*r:| |:.B:| | 0x30 + 4 | |::::| |::::| *r |::::| |::::| 0x40 + 3 |::::| |:.P:| |::::| .Q |::::| | 0x50 + 2 | .P |:.P:| |::::| |:.P:| .P |:.P:| 0x60 + 1 |:.R:| |::::| |::::| .R |:.K:| | 0x70 + +---------------------------------------+ + A B C D E F G H + + +SCRIPT> solution Bxf6+ + +SCRIPT> id "ECM.006" + +SCRIPT> go + +The root position is: 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - 0 0 +SetMoveTimer: Soft time limit 00:20.000 seconds. +SetMoveTimer: Hard time limit 00:20.000 seconds. + 7 +0.99 00:00.284 179093 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 dxe4 + 8 +1.25 00:00.553 377491 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 Rad1 + 9 +1.05 00:01.062 761451 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 Rad1 Re2 +10 +1.21 00:01.884 1386628 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 b4 Bb6 Rad1 +11 +0.97 00:03.816 2860869 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 b4 Bb6 Rad1 Re2 +12 +1.12 00:08.716 6383777 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 b4 Bb6 Kg2 Re2 Kf3 +13 +1.10 00:15.549 11572369 Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 Kg2 Re2 b4 Bb6 Rad1 +HARD TIMER (20.0 sec) --> stop searching now +move Bxf6+ +--------------------------------------------- +Searched for 20.0 seconds, saw 14680066 nodes (11319222 qnodes) (732823 nps). +tellothers d13, +1.10, 20.0s, 733knps, PV=Bxf6+ Qxf6 Ng4 Qxf3 gxf3 Rg5 fxe4 Rxg4+ Kh1 Rxe4 Kg2 Re2 b4 Bb6 Rad1 +Hashing percentages: (53.520 total, 26.213 useful) +Pawn hash hitrate: 98.553 percent. +Null move cutoff rate: 84.810 percent. +First move beta cutoff rate was 96.523 percent. +Eval percentages: ( 6.98 hash, 83.44 lazy, 9.58 full) +Extensions: (375467 +, 183351 q+, 44761 1mv, 9029 !kmvs, 1761 mult+, 580 pawn + 3970 threat, 2 zug, 5124 sing, 5803 endg, 9894 bm, 7604 recap) diff --git a/src/genetic/gen0_0.dna b/src/genetic/gen0_0.dna new file mode 100644 index 0000000..17f913b --- /dev/null +++ b/src/genetic/gen0_0.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8, +7,7,7,7,7,7,7,7,7,6,6,6,6,5,5,4,3,2,2,2,1,1,1,0,0,0,0,0,0,0,0,0, +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-9,0,0,0,0,0,0,-9,0,0,0,0,0,0,0,0,-9,0,5,5,5,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,10,10,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,10,10,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,5,5,5,0,-9,0,0,0,0,0,0,0,0,-9,0,0,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-2,-6,-7,-14,-30,-44,-74,-88, +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5, +-11 +0,0,190,130,72,42,21,15,0,0,0,15,21,42,72,130,190,0, +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-9,-9,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-9,-9,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9, +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +8,8,8,7,7,6,6,5,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-17,-10,-6,0,3,5,7,8,8 +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +24,22,17,14,13,13,12,12 +13,12,10,10,9,9,9,7, +10,9,9,9,7,7,7,6, +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-23,-17,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-17,-23,0, +-36, +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4, +-30,-25,-21,-15,-7,-2,0,4,8,12,16,18,20,22,23, +-15,-6,0,4,8,8,8,8 +-26,-23,-19,-15,-9,-7,-3,-1,0,1,3,6,8,10,12,13,14,15,16,16,17,17,18,18,19,19,20,20, +0,-14,-22,-26,-33 +0,40,33,25,22,20,18,17, +7, +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,5,5,4,2,0,0,0,0,0,0,0,0,0,2,4,11,12,12,11,4,2,0,0,0,0,0,0,0,0,4,5,14,19,19,14,5,4,0,0,0,0,0,0,0,0,4,5,14,19,19,14,5,4,0,0,0,0,0,0,0,0,2,4,11,12,12,11,4,2,0,0,0,0,0,0,0,0,0,2,4,5,5,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-19, +# mutate ./baseline.dna -> ./gen0_seed0.dna diff --git a/src/genetic/gen0_seed0.dna b/src/genetic/gen0_seed0.dna new file mode 100644 index 0000000..393454c --- /dev/null +++ b/src/genetic/gen0_seed0.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +7,7,7,7,7,7,7,7,7,6,6,6,6,5,5,4,3,2,2,2,1,1,1,0,0,0,0,0,0,0,0,0, +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-9,0,0,0,0,0,0,-9,0,0,0,0,0,0,0,0,-9,0,5,5,5,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,10,10,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,10,10,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,5,5,5,0,-9,0,0,0,0,0,0,0,0,-9,0,0,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-2,-6,-7,-14,-30,-44,-74,-88, +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5, +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9, +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +9,9,9,8,8,7,7,6,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-17,-10,-6,0,3,5,7,8,8 +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +24,22,17,14,13,13,12,12 +12,11,9,9,8,8,8,7 +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-23,-17,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-17,-23,0, +-36, +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4 +-30,-25,-21,-15,-7,-2,0,4,8,12,16,18,20,22,23, +-15,-6,0,4,8,8,8,8 +-26,-23,-19,-15,-9,-7,-3,-1,0,1,3,6,8,10,12,13,14,15,16,16,17,17,18,18,19,19,20,20, +0,-14,-22,-26,-33 +0,40,33,25,22,20,18,17, +7, +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,5,5,4,2,0,0,0,0,0,0,0,0,0,2,4,11,12,12,11,4,2,0,0,0,0,0,0,0,0,4,5,14,19,19,14,5,4,0,0,0,0,0,0,0,0,4,5,14,19,19,14,5,4,0,0,0,0,0,0,0,0,2,4,11,12,12,11,4,2,0,0,0,0,0,0,0,0,0,2,4,5,5,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed0.dna diff --git a/src/genetic/gen0_seed1.dna b/src/genetic/gen0_seed1.dna new file mode 100644 index 0000000..ec279f8 --- /dev/null +++ b/src/genetic/gen0_seed1.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,0,0,0,0,0,0,-7,0,0,0,0,0,0,0,0,-7,0,4,4,4,4,0,-7,0,0,0,0,0,0,0,0,-7,0,4,8,8,4,0,-7,0,0,0,0,0,0,0,0,-7,0,4,8,8,4,0,-7,0,0,0,0,0,0,0,0,-7,0,4,4,4,4,0,-7,0,0,0,0,0,0,0,0,-7,0,0,0,0,0,0,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,64,43,13,6,3,1,0,0,0,1,3,6,13,43,64,0, +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +706, +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12, +-17,-10,-6,0,3,5,7,8,8 +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +24,22,17,14,13,13,12,12, +10,9,8,8,7,7,7,6, +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7, +4 +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8 +-32,-28,-23,-18,-11,-8,-4,-2,-1,2,4,7,10,12,15,16,17,18,19,20,21,21,22,22,23,23,24,24, +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15 +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-22, +# mutate ./baseline.dna -> ./gen0_seed1.dna diff --git a/src/genetic/gen0_seed2.dna b/src/genetic/gen0_seed2.dna new file mode 100644 index 0000000..e9efe52 --- /dev/null +++ b/src/genetic/gen0_seed2.dna @@ -0,0 +1,57 @@ +0,78,70,63,58,53,49,45,43,43,43,43,43,43,43,43,0,0,108,101,94,86,78,72,67,61,57,57,57,57,57,57,57,0,0,130,114,107,100,94,88,81,75,66,66,66,66,66,66,66,0, +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36, +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,156,107,59,34,17,12,0,0,0,12,17,34,59,107,156,0, +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +51,0,0,32,0,37,16,0,12,7,17,3,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +682, +0,-6,-10,-16,-22 +34, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,-2,-3,-3,-3,-3,-3,-3,-2,0,0,0,0,0,0,0,0,-3,-4,-6,-7,-7,-6,-4,-3,0,0,0,0,0,0,0,0,-3,-4,-6,-7,-7,-6,-4,-3,0,0,0,0,0,0,0,0,-2,-3,-3,-3,-3,-3,-3,-2,0,0,0,0,0,0,0,0,0,0,-1,-1,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,22,17,12,5,0,0,0,0, +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-17,-10,-6,0,3,5,7,8,8 +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +25,23,17,14,13,13,12,12, +12,11,9,9,8,8,8,7 +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +6, +4 +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8 +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15 +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23, +# mutate ./baseline.dna -> ./gen0_seed2.dna diff --git a/src/genetic/gen0_seed3.dna b/src/genetic/gen0_seed3.dna new file mode 100644 index 0000000..dfe3e08 --- /dev/null +++ b/src/genetic/gen0_seed3.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-11,-8,-8,-10,-10,-8,-8,-11,0,0,0,0,0,0,0,0,-8,-6,-6,-8,-8,-6,-6,-8,0,0,0,0,0,0,0,0,-6,-5,-5,-6,-6,-5,-5,-6,0,0,0,0,0,0,0,0,-6,-5,-5,-6,-6,-5,-5,-6,0,0,0,0,0,0,0,0,-8,-6,-6,-8,-8,-6,-6,-8,0,0,0,0,0,0,0,0,-11,-8,-8,-10,-10,-8,-8,-11,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,-27,-55,-84,-114,-145,-177,-210,-248,0,-19,-40,-65,-92,-123,-157,-198,-248,0,-7,-16,-26,-39,-54,-73,-95,-122,0,-6,-11,-21,-33,-47,-62,-81,-103, +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,69,46,15,6,3,1,0,0,0,1,3,6,15,46,69,0, +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-5,-9,-15,-20, +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-25,-16,-11,-5,-1,0,1,3,4,5,7,8,9,10, +-10,-4,1,3,4,5,5,5 +0,35,30,19,8,4,0,-10,-17, +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,13,12,10,6,3,0,0,0,0,0,0,0,3,6,10,12,13, +-17,-10,-6,0,3,5,7,8,8 +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,10,12,13,15,17,19,22,24,24,25,25,26,26,27,27,28,28,30,31, +24,22,17,14,13,13,12,12 +12,11,9,9,8,8,8,7 +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-26,-18,-15,-10,-5,-3,0,0,0,-3,-5,-10,-15,-18,-26,0, +-33, +18, +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +6, +4, +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8, +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15, +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed3.dna diff --git a/src/genetic/gen0_seed4.dna b/src/genetic/gen0_seed4.dna new file mode 100644 index 0000000..4b6a92e --- /dev/null +++ b/src/genetic/gen0_seed4.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-36,-12,0,2,5,8,12,17,23,-52,-20,0,3,7,11,15,20,26,-8,0,0,5,12,16,20,24,30, +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +7,7,7,7,7,7,6,6,6,5,6,4,3,4,3,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-3,-2,-2,-3,-3,-2,-2,-3,0,0,0,0,0,0,0,0,-3,-2,-2,-3,-3,-2,-2,-3,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-31,-63,-97,-131,-167,-203,-241,-285,0,-22,-46,-74,-106,-141,-181,-228,-285,0,-8,-18,-30,-45,-62,-84,-109,-140,0,-6,-12,-24,-38,-54,-71,-93,-119, +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11, +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,55,54,53,52,51,50,49,47,45,42,41,41,41,41,41,41,41, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12, +-17,-10,-6,0,3,5,7,8,8 +0,4,8, +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,28, +24,22,17,14,13,13,12,12 +9,9,7,7,6,6,6,5, +13,12,11,11,9,9,9,8 +0,0,24,16,11,5,0,0,0,0,0,0,0,5,11,16,24,0, +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4 +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8 +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-23,-27,-35, +0,34,28,22,19,17,16,15 +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed4.dna diff --git a/src/genetic/gen0_seed5.dna b/src/genetic/gen0_seed5.dna new file mode 100644 index 0000000..81b587b --- /dev/null +++ b/src/genetic/gen0_seed5.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,2,3,4,5,5,6,6,6,6,6,6,6,6,6,6,6,6, +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +63,-1,-1,39,-1,45,20,-1,14,9,21,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,38,32,20,9,4,0,-11,-18, +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-9,-6,-6,-6,-6,-6,-6,-9,0,0,0,0,0,0,0,0,-6,-1,-1,0,0,-1,-1,-6,0,0,0,0,0,0,0,0,-6,-1,3,4,4,3,-1,-6,0,0,0,0,0,0,0,0,-6,-1,4,6,6,4,-1,-6,0,0,0,0,0,0,0,0,-6,-1,4,6,6,4,-1,-6,0,0,0,0,0,0,0,0,-6,-1,3,4,4,3,-1,-6,0,0,0,0,0,0,0,0,-6,-1,-1,0,0,-1,-1,-6,0,0,0,0,0,0,0,0,-9,-6,-6,-6,-6,-6,-6,-9,0,0,0,0,0,0,0,0, +0,13,10,8,3,0,0,0,0, +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-16,-9,-5,0,2,4,6,7,7, +0,4,8 +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +24,22,17,14,13,13,12,12 +12,11,9,9,8,8,8,7 +13,12,11,11,9,9,9,8 +0,0,24,16,11,5,0,0,0,0,0,0,0,5,11,16,24,0, +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +22 +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4 +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8 +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-11,-17,-21,-26, +0,34,28,22,19,17,16,15 +7, +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,4,6,6,4,2,0,0,0,0,0,0,0,0,0,2,4,12,14,14,12,4,2,0,0,0,0,0,0,0,0,4,6,16,21,21,16,6,4,0,0,0,0,0,0,0,0,4,6,16,21,21,16,6,4,0,0,0,0,0,0,0,0,2,4,12,14,14,12,4,2,0,0,0,0,0,0,0,0,0,2,4,6,6,4,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed5.dna diff --git a/src/genetic/gen0_seed6.dna b/src/genetic/gen0_seed6.dna new file mode 100644 index 0000000..0250961 --- /dev/null +++ b/src/genetic/gen0_seed6.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +7,7,7,7,7,7,6,6,6,5,6,4,3,4,3,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-10,-18,-39,-56,-96,-113, +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,79,61,39,17,8,4,0,0,0,4,8,17,39,61,79,0, +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +29, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,56,55,54,53,52,51,50,48,46,43,42,42,42,42,42,42,42, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-17,-10,-6,0,3,5,7,8,8, +0,4,8, +0,0,0,0,0,0,0,0,0,0,1,2,4,6,9,11,12,13,15,17,19,21,21,22,22,23,23,24,24,25,25,26,27 +24,22,17,14,13,13,12,12 +11,10,8,8,7,7,7,6, +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-21,-15,-12,-8,-4,-2,0,0,0,-2,-4,-8,-12,-15,-21,0, +-40 +23, +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4 +-22,-19,-16,-11,-5,-1,0,3,6,9,12,13,15,17,18, +-15,-6,0,4,8,8,8,8, +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15 +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,16,16,13,5,3,0,0,0,0,0,0,0,0,5,7,18,24,24,18,7,5,0,0,0,0,0,0,0,0,5,7,18,24,24,18,7,5,0,0,0,0,0,0,0,0,3,5,13,16,16,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed6.dna diff --git a/src/genetic/gen0_seed7.dna b/src/genetic/gen0_seed7.dna new file mode 100644 index 0000000..c442968 --- /dev/null +++ b/src/genetic/gen0_seed7.dna @@ -0,0 +1,57 @@ +0,76,68,62,57,52,48,44,42,42,42,42,42,42,42,42,0,0,106,99,92,85,77,71,66,60,56,56,56,56,56,56,56,0,0,127,112,105,98,92,86,80,74,65,65,65,65,65,65,65,0, +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-9,0,0,0,0,0,0,-9,0,0,0,0,0,0,0,0,-9,0,5,5,5,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,10,10,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,10,10,5,0,-9,0,0,0,0,0,0,0,0,-9,0,5,5,5,5,0,-9,0,0,0,0,0,0,0,0,-9,0,0,0,0,0,0,-9,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-5 +-11 +0,0,152,104,58,33,16,12,0,0,0,12,16,33,58,104,152,0, +0,0,0,48,34,22,13,9,0,0,0,9,13,22,34,48,0,0 +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,51,34,11,5,2,0,0,0,0,0,2,5,11,34,51,0, +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-18,-11,-8,-4,0,0,0,2,3,4,4,5,6,7, +-8,-3,0,2,3,4,4,4, +0,31,26,17,7,3,0,-9,-15, +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0 +0,12,10,7,3,0,0,0,0, +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-19,-11,-6,0,3,5,8,9,9, +0,4,8 +0,0,0,0,0,0,0,0,0,0,0,1,3,5,8,10,11,12,14,16,18,20,20,21,21,22,22,23,23,24,24,25,25, +24,22,17,14,13,13,12,12 +11,10,8,8,7,7,7,6, +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +25, +55,51,44,38,33,27,22,16,7,1,-3,-6,-9,-12,-18,-22,-25 +7 +4 +-28,-24,-20,-14,-7,-2,0,4,8,12,15,17,19,21,22 +-15,-6,0,4,8,8,8,8 +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15 +8 +1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,4,4,4,4,4,4,4,4,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,1,1,1,1,1,1,1,1,0,0,0,0,0,0,0,0,1,0,0,0,1,0,0,1,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed7.dna diff --git a/src/genetic/gen0_seed8.dna b/src/genetic/gen0_seed8.dna new file mode 100644 index 0000000..de77bb3 --- /dev/null +++ b/src/genetic/gen0_seed8.dna @@ -0,0 +1,57 @@ +-1,90,81,73,67,62,57,52,50,50,50,50,50,50,50,50,-1,-1,125,117,109,100,91,84,78,71,66,66,66,66,66,66,66,-1,-1,150,132,124,116,109,102,94,87,77,77,77,77,77,77,77,-1 +-43,-15,0,3,6,10,15,21,28,-63,-25,0,4,9,14,19,25,32,-10,0,0,7,15,20,24,29,36 +0,0,0,0,0,0,0,0,0,1,1,1,1,1,2,3,4,5,6,6,7,7,7,7,8,8,8,8,8,8,8,8 +8,8,8,8,8,8,8,8,8,7,7,7,7,6,6,5,4,3,3,3,2,2,2,1,1,1,0,0,0,0,0,0 +8,8,8,8,8,8,7,7,7,6,7,5,4,5,4,3,2,2,1,1,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,9,9,5,0,-8,0,0,0,0,0,0,0,0,-8,0,5,5,5,5,0,-8,0,0,0,0,0,0,0,0,-8,0,0,0,0,0,0,-8,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-4,-3,-3,-4,-4,-3,-3,-4,0,0,0,0,0,0,0,0,-5,-4,-4,-5,-5,-4,-4,-5,0,0,0,0,0,0,0,0,-7,-5,-5,-7,-7,-5,-5,-7,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-7,-6,-6,-7,-7,-6,-6,-7,0,0,0,0,0,0,0,0,-9,-7,-7,-9,-9,-7,-7,-9,0,0,0,0,0,0,0,0,-12,-9,-9,-11,-11,-9,-9,-12,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-32,-65,-99,-134,-170,-207,-245,-290,0,-23,-47,-76,-108,-144,-184,-232,-290,0,-9,-19,-31,-46,-64,-86,-111,-143,0,-7,-13,-25,-39,-55,-73,-95,-121 +0,-3,-7,-9,-16,-35,-50,-85,-100 +0,-7,-8,-9,-10,-10,-9,-8,-7 +-4, +-11 +0,0,162,111,62,36,18,13,0,0,0,13,18,36,62,111,162,0 +0,0,0,50,35,23,13,9,0,0,0,9,13,23,35,50,0,0, +0,0,96,74,48,21,10,5,0,0,0,5,10,21,48,74,96,0 +0,0,60,40,13,6,3,1,0,0,0,1,3,6,13,40,60,0 +0,0,7,14,21,28,34,41,55 +60,-1,-1,37,-1,43,19,-1,14,9,20,4,3,3,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +800 +0,-6,-10,-16,-22 +33 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,53,52,51,50,49,48,47,45,43,41,40,40,40,40,40,40,40 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-7,-8,-10,-11,-11,-10,-8,-7,0,0,0,0,0,0,0,0,-6,-7,-9,-8,-8,-9,-7,-6,0,0,0,0,0,0,0,0,-4,-6,-7,-7,-7,-7,-6,-4,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-4,-5,-7,-8,-8,-7,-5,-4,0,0,0,0,0,0,0,0,-3,-4,-4,-4,-4,-4,-4,-3,0,0,0,0,0,0,0,0,-1,-1,-2,-2,-2,-2,-1,-1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +-22,-14,-10,-5,-1,0,1,3,4,5,6,7,8,9 +-10,-4,1,3,4,5,5,5 +0,33,28,18,8,4,0,-10,-16 +10,10,10,9,9,8,8,7,7,6,5,4,3,2,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,5,8,8,5,-2,-8,0,0,0,0,0,0,0,0,-8,-2,4,5,5,4,-2,-8,0,0,0,0,0,0,0,0,-8,-2,-2,0,0,-2,-2,-8,0,0,0,0,0,0,0,0,-12,-8,-8,-8,-8,-8,-8,-12,0,0,0,0,0,0,0,0, +0,15,12,9,4,0,0,0,0 +0,25,19,14,6,0,0,0,0 +0,12,11,9,6,3,0,0,0,0,0,0,0,3,6,9,11,12 +-17,-10,-6,0,3,5,7,8,8 +0,4,8, +0,0,0,0,0,0,0,0,0,0,1,2,4,6,10,12,13,14,16,19,21,23,23,24,24,25,25,26,26,28,28,29,30, +24,22,17,14,13,13,12,12 +12,11,9,9,8,8,8,7 +13,12,11,11,9,9,9,8 +0,0,25,17,12,6,1,0,0,0,0,0,1,6,12,17,25,0 +0,0,-22,-16,-13,-9,-5,-3,0,0,0,-3,-5,-9,-13,-16,-22,0 +-40 +22 +62,58,50,43,37,30,25,18,8,1,-3,-6,-10,-13,-20,-25,-28, +7 +4 +-31,-26,-22,-15,-7,-2,0,4,8,13,16,19,21,23,24, +-15,-6,0,4,8,8,8,8 +-30,-26,-22,-17,-11,-8,-4,-2,-1,2,4,7,10,12,14,15,16,17,18,19,20,20,21,21,22,22,23,23 +0,-14,-22,-26,-33 +0,34,28,22,19,17,16,15 +8 +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,3,3,3,3,3,3,3,3,0,0,0,0,0,0,0,0,2,2,2,2,2,2,2,2,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0, +0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,5,7,17,23,23,17,7,5,0,0,0,0,0,0,0,0,3,5,13,15,15,13,5,3,0,0,0,0,0,0,0,0,1,3,5,7,7,5,3,1,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0 +0,-4,-8,-12,-16,-20,-25,-31,-38,-50,-63,-76,-90,-105,-120,-135,-150,-165,-180,-195,-210,-225,-240,-255,-270,-290,-310,-330,-350,-370,-390,-410,-440,-470,-500,-500,-500,-500,-500,-500,-500,-500 +-23 +# mutate ./baseline.dna -> ./gen0_seed8.dna diff --git a/src/genetic/main.cpp b/src/genetic/main.cpp new file mode 100644 index 0000000..aa7ec73 --- /dev/null +++ b/src/genetic/main.cpp @@ -0,0 +1,918 @@ +/* + * INCLUDES + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +/* + * GLOBALS + */ + +int start_time; +bool pipe_logging = false; +int only_opening = -1; +FILE *pgn_log = NULL; +FILE *match_log = NULL; + + + + +/* + * Misc + */ + +void strip_newline(char *s) +{ + int i; + + for (i = 0;; ++i) + { + if (!s[i] || s[i] == '\r' || s[i] == '\n') + { + s[i] = 0; + return; + } + } +} + +void copy_result(char *to, char *from) +{ + int i; + + for (i = 0; i < strlen(from); ++i) + if (from[i] == '0' || from[i] == '1') + break; + strcpy(to, &from[i]); + for (i = 0; i < strlen(to); ++i) + if (to[i] == '}') + break; + to[i + 1] = 0; +} + + + + +/* + * MyLock + */ + +#include +#include + +class MyLock +{ +public: + MyLock(); + void get(); + void release(); + +private: + pthread_mutex_t the_lock; +}; + +MyLock::MyLock() +{ + pthread_mutex_init(&the_lock, NULL); +} + +void MyLock::get() +{ + for (;;) + { + if (pthread_mutex_lock(&the_lock) == 0) // EBUSY?? + break; + usleep(1); + } +} + +void MyLock::release() +{ + pthread_mutex_unlock(&the_lock); +} + +MyLock glock; + + + + +/* + * Settings + */ + +class Settings +{ +public: + Settings() { count = 0; }; + bool read(char *filename); + char * get(char *name); + +private: + char map[20][2][1000]; + int count; +}; + +Settings settings; + +bool Settings::read(char *filename) +{ + FILE *f; + char line[1000]; + char var[1000]; + + printf("Reading settings file: %s\n", filename); + count = 0; + f = fopen(filename, "r"); + if (!f) + { + printf("Couldn't open file.\n"); + return false; + } + for (;;) + { + line[0] = 0; + fgets(line, 1000, f); + if (!line[0]) + break; + strip_newline(line); + sscanf(line, "%s", var); + strcpy(map[count][0], var); + strcpy(map[count][1], line + strlen(var) + 1); + count++; + } + fclose(f); + return true; +} + +char * Settings::get(char *name) +{ + int i; + + for (i = 0; i < count; ++i) + if (!strcmp(map[i][0], name)) + return map[i][1]; + printf("Setting not found: %s\n", name); + exit(1); +} + + + + +/* + * ChildProc + */ + +class ChildProc +{ +public: + ChildProc(); + virtual ~ChildProc(); + + virtual void start(char *cmd_line); + virtual void stop(); + void send(char *line); + void receive(char *line, int size); + bool poll(); + void flush(); + char * get_cmd() { return cmd; } + +private: + void init(); + + char cmd[100]; + bool running; + + int pid; + int to_prog[2]; + int from_prog[2]; + FILE *to; + FILE *from; +}; + +ChildProc::ChildProc() +{ + init(); +} + +ChildProc::~ChildProc() +{ + stop(); +} + +void ChildProc::init() +{ + strcpy(cmd, ""); + pid = 0; + to = NULL; + from = NULL; + running = false; +} + +void ChildProc::start(char *cmd_line) +{ + char *argv[100]; + char arg_buff[100][100]; + int args = 0, i = 0, j = 0; + + argv[0] = arg_buff[0]; + for (;;) + { + argv[args][i] = cmd_line[j]; + if (!argv[args][i] || argv[args][i] == ' ') + { + argv[args][i] = 0; + args++; + argv[args] = arg_buff[args]; + i = -1; // will get incremented to 0 + } + if (!cmd_line[j]) + break; + i++; + j++; + } + argv[args] = NULL; + + stop(); + glock.get(); + pipe(to_prog); + pipe(from_prog); + if ((pid = fork()) == 0) // what to do with glock here? + { + dup2(to_prog[0], 0); + dup2(from_prog[1], 1); + close(to_prog[0]); + close(to_prog[1]); + close(from_prog[0]); + close(from_prog[1]); + dup2(1, fileno(stderr)); // force stderr to the pipe + execvp(argv[0], argv); + perror(argv[0]); + exit(1); + } + if (pid == -1) + { + printf("fork() failed, command line: %s\n", cmd_line); + exit(1); + } + close(to_prog[0]); + close(from_prog[1]); + from = fdopen(from_prog[0], "r"); + to = fdopen(to_prog[1], "w"); + setbuf(from, NULL); + setbuf(to, NULL); + glock.release(); + + running = true; + strcpy(cmd, argv[0]); +} + +void ChildProc::stop() +{ + int x; + + if (!running) + return; + glock.get(); + fclose(to); + fclose(from); + close(to_prog[1]); + close(from_prog[0]); + glock.release(); + kill(pid, SIGTERM); + waitpid(pid, &x, 0); + init(); +} + +void ChildProc::send(char *line) +{ + char temp[1000]; + int i; + + if (!running) + return; + strcpy(temp, line); + strip_newline(temp); + glock.get(); + fprintf(to, "%s\n", temp); + glock.release(); + if (pipe_logging) + printf("%s send: %s\n", cmd, temp); +} + +void ChildProc::receive(char *line, int size) +{ + int i; + + line[0] = 0; + if (!running) + return; + if (!poll()) + return; + glock.get(); + fgets(line, size, from); + glock.release(); + strip_newline(line); + if (pipe_logging) + printf("%s recv: %s\n", cmd, line); +} + +bool ChildProc::poll() +{ + fd_set myset; + timeval mytime; + int r; + + FD_ZERO(&myset); + FD_SET(from_prog[0], &myset); + mytime.tv_sec = 0; + mytime.tv_usec = 0; + glock.get(); + r = select(from_prog[0] + 1, &myset, NULL, NULL, &mytime); + glock.release(); + return (r > 0) ? true : false; +} + +void ChildProc::flush() +{ + char line[1000]; + + while (poll()) + { + receive(line, 1000); + if (!line[0]) + break; + } +} + + + + +/* + * ChessEngine + */ + +class ChessEngine : private ChildProc +{ +public: + void start(char *cmd_line, char *init_str_arg); + void stop(); + void new_game(); + void send_move(char *move); + void get_move(char *move); + bool is_game_over() { return game_over; } + char * get_result() { return result; } + +private: + bool game_over; + char result[100]; + char init_str[1000]; +}; + +void ChessEngine::start(char *cmd_line, char *init_str_arg) +{ + ChildProc::start(cmd_line); + send("xboard\n"); + strcpy(init_str, init_str_arg); +} + +void ChessEngine::stop() +{ + send("quit\n"); + ChildProc::stop(); +} + +void ChessEngine::new_game() +{ + char temp[1000]; + + // stop the engine and flush leftover output + // only necessary when reusing the engine + /*send("?\n"); + usleep(100000); + flush();*/ + + send("new\n"); + send("easy\n"); + sprintf(temp, "%s\n", init_str); + send(temp); + send("force\n"); + + game_over = false; +} + +void ChessEngine::send_move(char *move) +{ + char s[100]; + + if (game_over) + return; + sprintf(s, "%s\n", move); + send(s); +} + +void ChessEngine::get_move(char *move) +{ + char line[1000]; + char tok[1000]; + + move[0] = 0; + while (poll()) // does the engine think the game is over? + { + receive(line, 1000); + if (strchr(line, '{')) + { + game_over = true; + copy_result(result, line); + } + } + if (game_over) + return; + send("go\n"); + for (;;) + { + receive(line, 1000); + if (!line[0]) + { + usleep(1000); + continue; + } + if (strchr(line, '{')) + { + game_over = true; + copy_result(result, line); + break; + } + sscanf(line, "%s", tok); + if (!strcmp(tok, "move")) + { + sscanf(line, "move %s", move); + break; + } + } + if (!game_over) + send("force\n"); +} + + + + +/* + * WorkItems + */ + +const int max_work_items = 5000; +const int max_game_ply = 400; + +struct WorkItem +{ + volatile int status; + bool printed; + + int white_engine; + int opening_id; + char opening[200]; + char move[max_game_ply + 2][10]; + int moves; + char result[100]; +}; + +WorkItem *work_item[max_work_items]; +int work_items; + +bool make_work_items(char *filename) +{ + FILE *f; + char line[1000]; + int openings = 0; + WorkItem *w; + + printf("Creating work items from file: %s\n", filename); + work_items = 0; + f = fopen(filename, "r"); + if (!f) + { + printf("Couldn't open file.\n"); + return false; + } + for (;;) + { + line[0] = 0; + fgets(line, 1000, f); + if (!line[0]) + break; + strip_newline(line); + openings++; + + if (only_opening != -1 && openings != only_opening) + continue; + + w = new WorkItem; + w->status = 0; + w->opening_id = openings; + strcpy(w->opening, line); + w->white_engine = 1; + work_item[work_items++] = w; + + w = new WorkItem; + w->status = 0; + w->opening_id = openings; + strcpy(w->opening, line); + w->white_engine = 2; + work_item[work_items++] = w; + } + fclose(f); + printf("%d work items created.\n", work_items); + return true; +} + +void print_game(WorkItem *w) +{ + char white_name[100]; + char black_name[100]; + char line[1000]; + char short_result[100]; + char *temp; + int m, i, line_break; + + if (w->white_engine == 1) + { + strcpy(white_name, settings.get("engine1")); + strcpy(black_name, settings.get("engine2")); + } + else + { + strcpy(white_name, settings.get("engine2")); + strcpy(black_name, settings.get("engine1")); + } + sprintf(line, "Opening: %d, %s vs. %s, result: %s\n", + w->opening_id, + white_name, + black_name, + w->result); + printf(line); + fprintf(match_log, line); + fflush(match_log); + + strcpy(short_result, w->result); + temp = strchr(short_result, ' '); + if (temp) + *temp = 0; + fprintf(pgn_log, "[Round \"%d.%d\"]\n", w->opening_id, w->white_engine); + fprintf(pgn_log, "[White \"%s\"]\n", white_name); + fprintf(pgn_log, "[Black \"%s\"]\n", black_name); + fprintf(pgn_log, "[Result \"%s\"]\n", short_result); + fprintf(pgn_log, "\n"); + m = 0; + line_break = 0; + for (i = 1;; ++i) + { + if (m == w->moves) + { + fprintf(pgn_log, "%s\n", w->result); + break; + } + fprintf(pgn_log, "%d. %s ", i, w->move[m++]); + if (m < w->moves) + fprintf(pgn_log, "%s ", w->move[m++]); + if (m > line_break + 8) + { + fprintf(pgn_log, "\n"); + line_break = m; + } + } + fprintf(pgn_log, "\n"); + fflush(pgn_log); + + w->printed = true; +} + +void print_stats(int items) +{ + int i; + int win = 0, lose = 0, draw = 0; + int games = 0; + double percent; + double elo; + char elo_sign = '+'; + int elapsed_time; + int min, sec; + double spg = 10.0; + double percent_done; + double eta; + int eta_min, eta_sec; + + for (i = 0; i < items; ++i) + { + if (work_item[i]->status != 2) // shouldn't happen + break; + if (strstr(work_item[i]->result, "1-0")) + { + if (work_item[i]->white_engine == 1) + win++; + else + lose++; + } + if (strstr(work_item[i]->result, "0-1")) + { + if (work_item[i]->white_engine == 1) + lose++; + else + win++; + } + if (strstr(work_item[i]->result, "1/2-1/2")) + draw++; + } + games = win + lose + draw; + + percent = (double)win + (0.5 * (double)draw); + percent /= (double)games; + if (percent > 0.99999) + elo = 400.0; + else if (percent < 0.00001) + elo = -400.0; + else + elo = -400.0 * log(1.0 / percent - 1.0) / log(10.0); + if (elo < 0.0) + { + elo_sign = '-'; + elo = -elo; + } + elapsed_time = time(NULL) - start_time; + sec = elapsed_time; + min = sec / 60; + sec -= min * 60; + if (elapsed_time) + spg = (double)(time(NULL) - start_time) / (double)games; + percent_done = (double)games / (double)work_items; + eta = (double)work_items - (double)games; + eta *= spg; + eta_sec = (int)eta; + eta_min = eta_sec / 60; + eta_sec -= eta_min * 60; + + printf("%s vs. %s: +%d -%d =%d, %.2f%c, ELO: %c%d\n", + settings.get("engine1"), + settings.get("engine2"), + win, lose, draw, + (float)(percent * 100.0), '%', + elo_sign, (int)elo); + printf("%d games in %d:%02d, %.2f seconds/game, %.1f%c done, ETA: %d:%02d\n", + games, min, sec, (float)spg, + (float)(percent_done * 100.0), '%', + eta_min, eta_sec); + printf("\n"); +} + + + +/* + * WorkerThread + */ + +class WorkerThread +{ +public: + void do_work(int id_arg); + void do_item(WorkItem *w); + +private: + void do_opening(WorkItem *w); + void add_move(WorkItem *w, char *move); + + int id; + ChessEngine engine1, engine2; +}; + +void WorkerThread::do_work(int id_arg) +{ + int i; + + id = id_arg; + for (;;) + { + glock.get(); + for (i = 0; i < work_items; ++i) + if (work_item[i]->status == 0) + break; + if (i != work_items) + work_item[i]->status = 1; + glock.release(); + + if (i == work_items) + break; + do_item(work_item[i]); + } +} + +void WorkerThread::do_item(WorkItem *w) +{ + char move[100]; + ChessEngine *etm; // engine to move + ChessEngine *etw; // engine to wait + ChessEngine *temp; + + w->printed = false; + w->moves = 0; + + engine1.start(settings.get("cmd1"), settings.get("init1")); + engine2.start(settings.get("cmd2"), settings.get("init2")); + engine1.new_game(); + engine2.new_game(); + do_opening(w); + + etm = &engine1; + etw = &engine2; + if ((w->moves & 1) == 1 && w->white_engine == 1) + { + etm = &engine2; + etw = &engine1; + } + if ((w->moves & 1) == 0 && w->white_engine == 2) + { + etm = &engine2; + etw = &engine1; + } + for (;;) + { + etm->get_move(move); + if (etm->is_game_over()) + { + strcpy(w->result, etm->get_result()); + break; + } + etw->send_move(move); + add_move(w, move); + if (w->moves >= max_game_ply) + { + strcpy(w->result, "1/2-1/2 {Game too long}"); + break; + } + temp = etm; + etm = etw; + etw = temp; + } + + engine1.stop(); + engine2.stop(); + w->status = 2; +} + +void WorkerThread::do_opening(WorkItem *w) +{ + char move[100]; + int i = 0, j = 0; + + for (;;) + { + move[i] = w->opening[j]; + if (!move[i] || move[i] == ' ') + { + move[i] = 0; + engine1.send_move(move); + engine2.send_move(move); + add_move(w, move); + i = -1; + } + if (!w->opening[j]) + break; + i++; + j++; + } +} + +void WorkerThread::add_move(WorkItem *w, char *move) +{ + strcpy(w->move[w->moves++], move); +} + + + + +/* + * threads + */ + +WorkerThread *worker[100]; +pthread_t *mythread[100]; +volatile int thread_count = 0; + +void * thread_proc(void *arg) +{ + int id; + + glock.get(); + id = thread_count++; + glock.release(); + worker[id] = new WorkerThread; + worker[id]->do_work(id); + delete worker[id]; + pthread_exit(&mythread[id]); + delete mythread[id]; // ? +} + +void start_threads(int count) +{ + int i; + int x = 0; + + printf("Starting threads...\n"); + for (i = 0; i < count; ++i) + { + mythread[i] = new pthread_t; + pthread_create(mythread[i], NULL, thread_proc, (void *)&x); + } + printf("Started %d threads.\n", i); +} + + + + +/* + * main + */ + +main(int argc, char *argv[]) +{ + int i; + char settings_filename[100]; + int threads = 1; + + start_time = time(NULL); + strcpy(settings_filename, "settings.txt"); + + for (i = 1;;) + { + if (i >= argc) + break; + if (!strcmp(argv[i], "-l")) + { + pipe_logging = true; + } + else if (!strcmp(argv[i], "-o")) + { + only_opening = atoi(argv[++i]); + } + else if (!strcmp(argv[i], "-t")) + { + threads = atoi(argv[++i]); + } + else if (argv[i][0] == '-') + { + printf("Usage: shiai [options] [settings file]\n"); + printf("\n"); + printf(" -h : Display this screen\n"); + printf(" -l : Display I/O with engines (\"log\")\n"); + printf(" -o # : Run opening number #\n"); + printf(" -t # : Run with # threads\n"); + printf("\n"); + exit(0); + } + else + { + strcpy(settings_filename, argv[i]); + } + i++; + } + + if (!settings.read(settings_filename)) + exit(1); + if (!make_work_items(settings.get("openings"))) + exit(1); + + pgn_log = fopen(settings.get("pgnlog"), "w"); + if (!pgn_log) + { + printf("Couldn't open %s for writing.\n", settings.get("pgnlog")); + exit(1); + } + match_log = fopen(settings.get("matchlog"), "w"); + if (!match_log) + { + printf("Couldn't open %s for writing.\n", settings.get("matchlog")); + exit(1); + } + + if (threads <= 0 || threads > 16) + threads = 1; + start_threads(threads); + for (i = 0; i < work_items; ++i) + { + while (work_item[i]->status != 2) + sleep(1); + print_game(work_item[i]); + print_stats(i + 1); + } + + fclose(pgn_log); + fclose(match_log); + return 0; +} diff --git a/src/genetic/mutate.pl b/src/genetic/mutate.pl new file mode 100755 index 0000000..ea4f38e --- /dev/null +++ b/src/genetic/mutate.pl @@ -0,0 +1,31 @@ +#!/usr/bin/perl + +open(FILE, $ARGV[0]) || die $!; +open(OUT, ">$ARGV[1]") || die $!; +$mutation_chance = 0.20; +$mutation_allowed = 1; + +while() { + next if (/^\s*$/); + if (/^\s*#/) { + $mutation_allowed = 1 if (/^#\s*BEGIN MUTATION ALLOWED/); + $mutation_allowed = 0 if (/^#\s*END MUTATION ALLOWED/); + print OUT; + next; + } + $should_mutate = rand() < $mutation_chance; + $mutation_amount = (rand() - 0.5) / 2.7; + if (($should_mutate) && ($mutation_allowed)) { + @arr = split(/,/); + for $a (@arr) { + $x = ($a * $mutation_amount); + $x += $a; + $x = int($x); + print OUT "$x,"; + } + print OUT "\n"; + } else { + print OUT; + } +} +exit 0; diff --git a/src/genetic/org/guru/wannabe/genetic/GeneticDriver.class b/src/genetic/org/guru/wannabe/genetic/GeneticDriver.class new file mode 100644 index 0000000..4845848 Binary files /dev/null and b/src/genetic/org/guru/wannabe/genetic/GeneticDriver.class differ diff --git a/src/genetic/org/guru/wannabe/genetic/GeneticProcess.class b/src/genetic/org/guru/wannabe/genetic/GeneticProcess.class new file mode 100644 index 0000000..3db2b55 Binary files /dev/null and b/src/genetic/org/guru/wannabe/genetic/GeneticProcess.class differ diff --git a/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$1ChessGame.class b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$1ChessGame.class new file mode 100644 index 0000000..2a23c9b Binary files /dev/null and b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$1ChessGame.class differ diff --git a/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$1FileAndScore.class b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$1FileAndScore.class new file mode 100644 index 0000000..c73b2a7 Binary files /dev/null and b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$1FileAndScore.class differ diff --git a/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$2FileAndScore.class b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$2FileAndScore.class new file mode 100644 index 0000000..8223691 Binary files /dev/null and b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess$2FileAndScore.class differ diff --git a/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess.class b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess.class new file mode 100644 index 0000000..83e165a Binary files /dev/null and b/src/genetic/org/guru/wannabe/genetic/ParallelChessGeneticProcess.class differ diff --git a/src/genetic/position.bin b/src/genetic/position.bin new file mode 100644 index 0000000..1f52dce Binary files /dev/null and b/src/genetic/position.bin differ diff --git a/src/genetic/position.lrn b/src/genetic/position.lrn new file mode 100644 index 0000000..aed44ce --- /dev/null +++ b/src/genetic/position.lrn @@ -0,0 +1,11 @@ +position +[White "unknown"] +[Black "Crafty 19.13"] +[Date "2007.06.18"] +setboard 1r1r/1b2kpp/2pRp2p/p3P/2B/2PR2P/P1P2P1P/2K/ b +{-140 6314 780} +[White "unknown"] +[Black "Crafty 19.13"] +[Date "2007.06.19"] +setboard /4k/1n1p1p1p/n2Pp1pP/2p1P1P/N1P2P/1P1KB// b +{-280 15604 1020} diff --git a/src/genetic/score_histogram.pl b/src/genetic/score_histogram.pl new file mode 100755 index 0000000..facc71a --- /dev/null +++ b/src/genetic/score_histogram.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl + +$gen = $ARGV[0]; +opendir(DIR, "."); +@files = readdir(DIR); +closedir(DIR); + +$min_score = 999999999; $max_score = 0; +$total = 0; +$best = ""; +for $file(@files) { + if ($file =~ m/gen(\d+)_\d+\.log/) { + $score = 0; + next if $1 != $gen; + open(FILE, $file) || die $!; + $total++; + while() { + chop; + if (m/ correct solutions\s+\:\s+(\d+)/) { + $score = $1; + last; + } + } + $score = int($score); + $scores[$score] += 1; + $names{$score} .= "$file "; + if ($score > $max_score) { + $max_score = $score; + $best = $file; + } + $min_score = $score if ($score < $min_score); + close(FILE); + } +} + +for ($x = $min_score; $x <= $max_score; $x++) { + next if $scores[$x] == 0; + printf "%4u : ", $x; + print "*" x int($scores[$x] / $total * 60); + print " ($scores[$x], $names{$x})\n"; +} +print "Best was $best\n"; +system "tail -22 $best"; diff --git a/src/genetic/trial.ep_ b/src/genetic/trial.ep_ new file mode 100644 index 0000000..a98e32f --- /dev/null +++ b/src/genetic/trial.ep_ @@ -0,0 +1,3520 @@ +st 20 +easy +setboard 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - +solution f7+ +id "ECM.001" +go +setboard 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - +solution Bxf3+ +id "ECM.002" +go +setboard 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - +solution Qb5 +id "ECM.003" +go +setboard 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - +solution Rcxc5 +id "ECM.004" +go +setboard 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - +solution Bxf2+ +id "ECM.005" +go +setboard 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - +solution Bxf6+ +id "ECM.006" +go +setboard 3rr1k1/pb3pp1/1p1q1b1p/1P2NQ2/3P4/P1NB4/3K1P1P/2R3R1 w - - +solution Rxg7+ +id "ECM.007" +go +setboard r1b1r1k1/p1p3pp/2p2n2/2bp4/5P2/3BBQPq/PPPK3P/R4N1R b - - +solution Bg4 +id "ECM.008" +go +setboard 3r4/1b2k3/1pq1pp2/p3n1pr/2P5/5PPN/PP1N1QP1/R2R2K1 b - - +solution Rxh3 +id "ECM.009" +go +setboard 2r4k/pB4bp/6p1/6q1/1P1n4/2N5/P4PPP/2R1Q1K1 b - - +solution Qxc1 +id "ECM.010" +go +setboard 1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - +solution Nxg4 +id "ECM.011" +go +setboard 5rk1/7p/p1N5/3pNp2/2bPnqpQ/P7/1P3PPP/4R1K1 w - - +solution Ne7+ +id "ECM.012" +go +setboard rnb2rk1/pp2np1p/2p2q1b/8/2BPPN2/2P2Q2/PP4PP/R1B2RK1 w - - +solution Nd5 +id "ECM.013" +go +setboard 2k4r/1pp2ppp/p1p1bn2/4N3/1q1rP3/2N1Q3/PPP2PPP/R4RK1 w - - +solution Nd5 +id "ECM.014" +go +setboard r3kb1r/pp2pppp/3q4/3Pn3/6b1/2N1BN2/PP3PPP/R2QKB1R w KQkq - +solution Nxe5 +id "ECM.015" +go +setboard 2rr2k1/1b3p1p/p4qpb/2R1n3/3p4/BP2P3/P3QPPP/3R1BKN b - - +solution Rxc5 +id "ECM.016" +go +setboard r1b1k3/5p1p/p1p5/3np3/1b2N3/4B3/PPP1BPrP/2KR3R w q - +solution Rxd5 +id "ECM.017" +go +setboard r3rbk1/1pq2ppp/2ppbnn1/p3p3/P1PPN3/BP1BPN1P/2Q2PP1/R2R2K1 w - - +solution Nxd6 +id "ECM.018" +go +setboard b7/2q2kp1/p3pbr1/1pPpP2Q/1P1N3P/6P1/P7/5RK1 w - - +solution Rxf6+ +id "ECM.019" +go +setboard 1rr1nbk1/5ppp/3p4/1q1PpN2/np2P3/5Q1P/P1BB1PP1/2R1R1K1 w - - +solution Bxa4 +id "ECM.020" +go +setboard r7/5kp1/2p1p2p/1p1n3P/2rP4/2P3R1/PK2RPP1/2B5 b - - +solution Rxc3 +id "ECM.021" +go +setboard r1r3k1/p3qpp1/b1P4p/3p4/3Nn3/4P3/P1Q2PPP/1BR1K2R b K - +solution Qb4+ +id "ECM.022" +go +setboard rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - +solution Bxd5 +id "ECM.023" +go +setboard 6rk/1p1br2p/pqp5/3pNP2/3Pp3/P5PR/5PKR/Q7 w - - +solution Rxh7+ +id "ECM.024" +go +setboard 2b3k1/5p1p/7b/p2B3p/3P4/P2Q1N1P/1q3PP1/6K1 w - - +solution Bxf7+ +id "ECM.025" +go +setboard r1b5/4k3/p7/3p1n2/3Bp3/2P2r1P/PPBK1P2/4R2R w - - +solution Bc5+ +id "ECM.026" +go +setboard r4rk1/1b3Npp/p7/1p3Q2/3P4/1B2q3/P5PP/3n1R1K b - - +solution Bxg2+ +id "ECM.027" +go +setboard r1b2rk1/2q2ppp/2pbp3/p7/4Nn2/3B4/PPPBQ1PP/R4R1K w - - +solution Rxf4 +id "ECM.028" +go +setboard 3r2k1/1q1P1ppp/r2R2n1/p4Q2/1ppB2R1/6P1/PP3PP1/6K1 w - - +solution Rgxg6 +id "ECM.029" +go +setboard r2q1rk1/p3b1pp/2p5/1pn5/1n1Bp1b1/1P6/PQ1PPP2/2RNKBNR b K - +solution Bxe2 +id "ECM.030" +go +setboard 3r2k1/p2r1p1p/1p2p1p1/q4n2/3P4/PQ1R3P/1P2NPP1/3R2K1 b - - +solution Nxd4 +id "ECM.031" +go +setboard 2bnr1k1/2q2ppp/p7/2p1b3/2N1B3/R7/1P2QPPP/2B3K1 w - - +solution Nxe5 +id "ECM.032" +go +setboard r1b2r1k/3nN2p/p2Q1p2/8/4PP2/1R6/q1PK2PP/4R3 w - - +solution Qd5 +id "ECM.033" +go +setboard 1nk1r1r1/pp2n1pp/4p3/q2pPp1N/b1pP1P2/B1P2R2/2P1B1PP/R2Q2K1 w - - +solution Nf6 +id "ECM.034" +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +solution Rxc8 +id "ECM.035" +go +setboard br1r2k1/1q4p1/p2ppb1p/2p2p2/2P1n3/Pn2P2P/QPR2PPB/2NRNBK1 b - - +solution Nxc1 +id "ECM.036" +go +setboard 2k4r/ppp1n1p1/2n2qb1/2N5/Q1P3p1/P2r3P/1P3PB1/R1B2RK1 w - - +solution Qb5 +id "ECM.037" +go +setboard 8/6bk/1B1R4/6p1/2bNP3/4KP2/1r6/8 b - - +solution Be5 +id "ECM.038" +go +setboard r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - +solution Rxa1 +id "ECM.039" +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +solution Nxc6 +id "ECM.040" +go +setboard 5rk1/1b3ppp/p3p3/1p1q2N1/4n3/6P1/PP2PPBP/2Q2RK1 b - - +solution Nxg3 +id "ECM.041" +go +setboard 2kr3r/pppq2p1/1bn1R3/6N1/1P6/1QN1B1p1/P4PP1/R5K1 b - - +solution gxf2+ +id "ECM.042" +go +setboard 2rr4/5pk1/p1q3p1/3bpP1p/1p4nR/1N4Q1/PPP3PP/3NR2K b - - +solution Bxg2+ +id "ECM.043" +go +setboard r4rk1/pp4pp/2nqb3/3p4/8/2NB4/PP1Q1PPP/4RRK1 w - - +solution Bxh7+ +id "ECM.044" +go +setboard 3rk1r1/3b1p1p/p2BpQ2/8/2q5/2P5/PP3PPP/3R2K1 b - - +solution Rxg2+ +id "ECM.045" +go +setboard 3r1rk1/4pp1p/p1Q1b1p1/3N4/3b4/5B2/Pq3PPP/R4RK1 b - - +solution Bxd5 +id "ECM.046" +go +setboard 5bk1/1bqn1r1p/p3Q1p1/4p3/1PN1Pp2/P1N4P/5PP1/R1BR2K1 w - - +solution Qxf7+ +id "ECM.047" +go +setboard 3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - +solution d3 +id "ECM.048" +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +solution Qxf7+ +id "ECM.049" +go +setboard 2kr1b1R/1b3pp1/p2pp3/1pq3P1/2nQPP2/P1N5/1PP1BB2/1K6 w - - +solution Rxf8 +id "ECM.050" +go +setboard 1k1r1b1r/p1p1q3/2p1p3/4Ppp1/4nP2/P2BQ3/1PP3PB/2KR3R b - - +solution Rxh2 +id "ECM.051" +go +setboard r3nb1Q/p1q2kr1/2p3p1/2ppnpP1/1P3N2/4P3/PB1P4/1R2KB1R w K - +solution Qxf8+ +id "ECM.052" +go +setboard r1bq1rk1/pp3pbp/2pp1np1/2n3B1/2PNP3/2N2P2/PP1QB1PP/R4RK1 b - - +solution Nfxe4 +id "ECM.053" +go +setboard 1rb1qn2/1p2nrbk/p2p2p1/P2Pp1Pp/NP2P2P/2RNB3/2QKB3/1R6 w - - +solution Ba7 +id "ECM.054" +go +setboard 5r2/1b2k2p/3bp3/5PP1/Bn1Q3P/1N6/1Pr5/1K3R2 b - - +solution Rxb2+ +id "ECM.055" +go +setboard r1b1r1k1/pp4bp/5np1/2qPB3/8/6NP/PPP1Q1B1/R4R1K w - - +solution Rxf6 +id "ECM.056" +go +setboard r1b2r1k/1pq3bp/8/3Qp2n/1P1n1pp1/2NP2P1/3BPPBP/1R2NRK1 b - - +solution Qxc3 +id "ECM.057" +go +setboard 4qk2/pp3pp1/1nbr3p/2p5/5N2/2P1Q3/PPB2PPP/2K1R3 w - - +solution Ng6+ +id "ECM.058" +go +setboard 3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - +solution Rd5 +id "ECM.059" +go +setboard r4rk1/pp1b2pp/3bpq2/3p1p2/2PPn3/PP1B4/1BQN1PPP/R4RK1 b - - +solution Bxh2+ +id "ECM.060" +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +solution Nxf7 +id "ECM.061" +go +setboard 2rq1r2/pp3pnk/2n1b1pp/3pQ3/3P1N2/P1N5/1P3PPP/1BR2RK1 w - - +solution Bxg6+ +id "ECM.062" +go +setboard 4nk2/r1r1bppp/pN2p3/2np4/8/BPN3PP/P3PPK1/2RR4 w - - +solution Ncxd5 +id "ECM.063" +go +setboard r4r1k/2pqn1b1/p1bp2pp/1p2pn2/4N3/2PP1PPQ/PPB4P/R1B1RNK1 b - - +solution Nd4 +id "ECM.064" +go +setboard r1bQ1nk1/bp3ppp/p7/3B4/1P6/P3P1P1/2P4P/q1B2RK1 b - - +solution Bxe3+ +id "ECM.065" +go +setboard 3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - +solution Rxd4 +id "ECM.066" +go +setboard 2nq2k1/2r3pp/p1p1rp2/PpQ1N3/1P1PR3/8/5PPP/2R3K1 w - - +solution Nf7 +id "ECM.067" +go +setboard r1b2rk1/1p2bppp/p3pn2/4B3/1qBR4/2N5/P3QPPP/R5K1 w - - +solution Bd3 +id "ECM.068" +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +solution g6 +id "ECM.069" +go +setboard 5r1k/p6p/1p1p1qp1/2pQpr2/8/2PP2P1/PP2RPKP/5R2 b - - +solution e4 +id "ECM.070" +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +solution Qh6 +id "ECM.071" +go +setboard 2r2rk1/5pbp/p5p1/3P2q1/1QbN4/5P2/P4BPP/2RR2K1 b - - +solution Bf1 +id "ECM.072" +go +setboard r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - +solution Nh7 +id "ECM.073" +go +setboard 3nk3/3q1p2/1B3pr1/4p3/bP2P2p/r2B4/2Q2RPP/3R2K1 w - - +solution Bb5 +id "ECM.074" +go +setboard 3rnr1k/pp3ppp/4b3/2p1qNP1/P2pPR2/1P1P2Q1/2P3BP/5RK1 w - - +solution Nh6 +id "ECM.075" +go +setboard r1b2kr1/1p1p1pNp/p1n1p1p1/5P2/3QP3/2N5/PqP1B1PP/R4RK1 w - - +solution fxg6 +id "ECM.076" +go +setboard 5rk1/3r1p1p/3b2pQ/8/4q3/4B2P/3R1PP1/4R1K1 w - - +solution Rxd6 +id "ECM.077" +go +setboard 4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - +solution Nxc5 +id "ECM.078" +go +setboard 2rnrbnk/3q1ppp/p1p5/3p1P2/1p1PPN2/4BQ1R/PP1N2PP/3R2K1 w - - +solution Ng6+ +id "ECM.079" +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +solution Rd4 +id "ECM.080" +go +setboard Q7/p1r1ppk1/1qP4p/2Rb2p1/8/3N2P1/4PP1P/6K1 b - - +solution Qb1+ +id "ECM.081" +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +solution exf6 +id "ECM.082" +go +setboard r2qr1k1/pp3pbp/3p1np1/2pP1bB1/2P1N3/3Q1PN1/PP4PP/R4RK1 b - - +solution Nxe4 +id "ECM.083" +go +setboard 4r1k1/1b4pp/p7/1prP3q/2P1B3/5P2/P3Q2P/3RR2K w - - +solution Bg6 +id "ECM.084" +go +setboard r1br2k1/ppb1qpp1/2P4p/2n1p3/4B3/P1N2N2/1P3PPP/2RQ1RK1 w - - +solution Nd5 +id "ECM.085" +go +setboard 2r3k1/1nqbrp2/p5pp/1p1Pp1N1/8/1P5P/P1B2PP1/2RQR1K1 w - - +solution Nxf7 +id "ECM.086" +go +setboard 2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - +solution Nh6+ +id "ECM.087" +go +setboard r1b1rk2/3n1pbQ/2qp2p1/p2N2P1/2Bp3N/4P3/PP3PP1/2KR3R w - - +solution Nxg6+ +id "ECM.088" +go +setboard r1r2qkb/4pp1p/pBbp3P/3Nn1P1/4Q3/1B6/PPP5/1K1R2R1 w - - +solution g6 +id "ECM.089" +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +solution Re7 +id "ECM.090" +go +setboard rn1q1r2/4bpk1/p3p3/1pN1N1np/2pP4/4PpBb/PPQ4P/1B1RK1R1 w - - +solution Nc6 +id "ECM.091" +go +setboard 5rk1/6pp/8/2Q4q/N2pP3/4b1Pb/4PP1K/1R3R2 b - - +solution Bxf1+ +id "ECM.092" +go +setboard 2r4k/pp2Q1pp/5r2/P2P4/3Pb1P1/4Ppq1/1P1R3N/3R3K b - - +solution Qe1+ +id "ECM.093" +go +setboard 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - +solution Qxh7+ +id "ECM.094" +go +setboard r1b4k/p2n1Bpp/1p1Q1n2/5p2/3P4/P3BqP1/1P3P1P/R4RK1 b - - +solution Bb7 +id "ECM.095" +go +setboard rn1r2k1/p4ppp/2p3b1/3PQ3/1B2Np1q/1B3P2/P1P3PP/4R1K1 w - - +solution Nf6+ +solution Qe8+ +id "ECM.096" +go +setboard 4r2k/5R1p/pp1Bq1pN/2p1P3/1n1b3Q/3P4/1P4KP/8 w - - +solution Rxh7+ +id "ECM.097" +go +setboard r2nk1r1/pb3q1p/4p3/3p2pQ/8/BP6/P4PPP/2R1R1K1 w q - +solution Rc7 +id "ECM.098" +go +setboard 6k1/1pqb1p2/5bpB/r2n4/4N1P1/1P3P2/1P1Q4/1K5R w - - +solution Qxd5 +id "ECM.099" +go +setboard rr4k1/2p1ppb1/3pbnpp/q1pP4/4P3/1PNNBP1P/P1KR2P1/2Q4R b - - +solution Qxc3+ +id "ECM.100" +go +setboard 1r3rk1/3Q2pp/p3p3/6B1/3np3/6R1/PqP1B2P/3K2R1 w - - +solution Qxg7+ +id "ECM.101" +go +setboard 2r5/p4Q2/k1bBp3/4P3/p1nq4/5B2/2Pr2P1/1R1RK3 w - - +solution Qb7+ +id "ECM.102" +go +setboard 5rk1/p1pb2pp/2p5/3p3q/2P3n1/1Q4BN/PP1Np1KP/R3R3 b - - +solution Qxh3+ +id "ECM.103" +go +setboard 2r1nk2/4qpbQ/4b3/1p2RpP1/4P3/p7/PBP5/1K5R w - - +solution Qxg7+ +id "ECM.104" +go +setboard 2kr4/1bpr3p/4R3/1pQ5/8/6B1/3q2PP/2R4K w - - +solution Qxc7+ +id "ECM.105" +go +setboard r4rk1/1pbb2pp/p1p1p2q/2Pp4/1P1Pn3/P3B2P/2Q1BPP1/R4RNK b - - +solution Qxe3 +id "ECM.106" +go +setboard r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - +solution Qxf5+ +id "ECM.107" +go +setboard 6r1/p4rkp/3RQ1n1/1pp1p1B1/2p1P3/2P3R1/P4qPK/8 w - - +solution Qxe5+ +id "ECM.108" +go +setboard 2kr1r2/1pp3pp/1n2p1b1/pN2B3/P1q5/1Q1p3P/5PP1/R4R1K w - - +solution Rac1 +id "ECM.109" +go +setboard 2kr1bnr/1ppq4/p3bp2/6pp/4p3/2N2NBP/PP3PP1/2RQ1RK1 w - - +solution Na4 +id "ECM.110" +go +setboard r2q2rk/p3bp1p/4b1p1/3pP2R/1p1B4/3BQ3/PPP3PP/5R1K w - - +solution Rxf7 +id "ECM.111" +go +setboard r1b1Q3/6pk/p6p/1pq1n3/4N3/8/PPP3PP/R6K b - - +solution Qc6 +id "ECM.112" +go +setboard q6r/pp3pkp/5np1/4Q3/4P3/6N1/P4PPP/5RK1 w - - +solution Nh5+ +id "ECM.113" +go +setboard r1b1rk2/pp3ppQ/1np5/4q3/2B4N/4P3/PP3PP1/2R2K1R w - - +solution Qg8+ +id "ECM.114" +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +solution Nxh7 +id "ECM.115" +go +setboard r3r1k1/p2N1pp1/1pn1p3/q1n5/2PQ4/P3B3/4PPKP/R5R1 w - - +solution Nf6+ +id "ECM.116" +go +setboard 4qbk1/1R5n/p2pr1p1/2pQpNPp/P1P1P3/2P2P2/3B4/5K2 w - - +solution Ne7+ +id "ECM.117" +go +setboard 3qr1k1/1p1bppbp/p2p2p1/2rPn3/P2N4/4BP2/1PPQ2PP/R2R1BK1 w - - +solution Ne6 +id "ECM.118" +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +solution Rxf6 +id "ECM.119" +go +setboard 8/R5p1/6k1/pr2p1b1/4K3/7P/5P2/6R1 w - - +solution h4 +id "ECM.120" +go +setboard 5rk1/1b1r1p2/p1q1pQp1/1p2P2p/8/1BP1NR2/PP1n2PP/5R1K w - - +solution Bxe6 +id "ECM.121" +go +setboard 6k1/p1p2r2/1p1p1P1Q/3P4/2P5/5qr1/PP4RP/6RK w - - +solution Qh3 +id "ECM.122" +go +setboard 2b1rr1k/1p5p/1Ppp2q1/p3bN2/2P1n3/5R2/PBQ3BP/3R2K1 w - - +solution Nxd6 +id "ECM.123" +go +setboard 3b2rk/7p/p7/2pbqNrn/Pp1p1R2/1P1Q2P1/1BPN1R1P/6K1 w - - +solution Rxd4 +id "ECM.124" +go +setboard 1rbr2k1/1pq1bp1p/p1pNn1p1/2n1p3/2B1P2P/1NQ1BP2/PP4P1/1K1R3R w - - +solution Nxf7 +id "ECM.125" +go +setboard r4rk1/1pp1b1pp/p1q5/3pPp2/3Pn3/P3N3/1P3PPP/R1BQR1K1 w - - +solution Qb3 +id "ECM.126" +go +setboard rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - +solution Nf6+ +id "ECM.127" +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +solution Nxh5 +id "ECM.128" +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +solution Re6 +id "ECM.129" +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +solution Rxe7 +id "ECM.130" +go +setboard 2rq1rk1/pp2bppp/1npp1n2/3PpN1b/2P5/2N3PP/PP2PPB1/R1BQ1RK1 w - - +solution c5 +id "ECM.131" +go +setboard rnbq1rk1/pp2b1pp/5n2/2pPp3/2P1N3/3B1N2/PP4PP/R1BQK2R w KQ - +solution d6 +id "ECM.132" +go +setboard 2n1rbk1/5pp1/7p/qP1pp3/4b1Q1/1B5P/1P1N1PP1/2B1R1K1 w - - +solution Rxe4 +id "ECM.133" +go +setboard 4k3/2R2p2/5p1p/8/rb6/1N6/5PPP/5K2 w - - +solution Rc4 +id "ECM.134" +go +setboard 2k3r1/pp2rp2/1np5/2Np1p2/P2P3p/1R2P1Pq/2Q2P1P/1R4K1 w - - +solution Nxb7 +id "ECM.135" +go +setboard 2r1k3/p3nrR1/1p1p4/2p1p1p1/2P1B3/2PP1P2/P5K1/7R w - - +solution Rh8+ +id "ECM.136" +go +setboard 8/1Qp3pk/7p/5p2/5Pqn/1P1r4/P5PP/2B2RK1 b - - +solution c6 +id "ECM.137" +go +setboard 2rr1bk1/5p1p/pPN2np1/3Bp3/2Q1n3/1P2B1Pq/P3PP2/R2R2K1 b - - +solution Rxd5 +id "ECM.138" +go +setboard 3r2k1/1p4pp/p1q1p3/3p1B2/bP1B2P1/P4Q2/5PKP/2b2R2 w - - +solution Rxc1 +id "ECM.139" +go +setboard rnb1r1k1/pp5p/2pp2p1/4b3/2P1P2q/1NN1BPp1/PP1QB1P1/3RR1K1 b - - +solution Bf4 +id "ECM.140" +go +setboard 5n1r/1p2kp2/rB1Nb3/4p1Pp/4p2P/1PP5/8/1K1R1R2 w - - +solution Rxf7+ +id "ECM.141" +go +setboard b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - +solution d3+ +id "ECM.142" +go +setboard 4r1k1/3R1ppp/p2p4/5PP1/2q2P2/2n2B2/P1P3QP/1r3R1K w - - +solution Rxb1 +id "ECM.143" +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +solution Bd5+ +id "ECM.144" +go +setboard 6k1/4ppbp/p5p1/1B1Q4/2P2Pn1/8/qr4PP/2B2RK1 b - - +solution Bd4+ +id "ECM.145" +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +solution Ba3 +id "ECM.146" +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +solution g6 +id "ECM.147" +go +setboard 5r2/1b3pk1/pqrpp1p1/4n1Nn/1p2PP1P/8/PPPQB3/1NKR2R1 b - - +solution Rfc8 +id "ECM.148" +go +setboard 1r2k2r/p5bp/4p1p1/q2pn3/1p2N1P1/6QP/PPP5/1KBR3R w k - +solution Bh6 +id "ECM.149" +go +setboard rn1q1rk1/pp3p1p/2p5/3p4/5Q1P/2NP3R/PPP3P1/4RK2 w - - +solution Rg3+ +id "ECM.150" +go +setboard 7r/kppQP1pp/p7/2qp1R2/4n3/1P2b2P/P1P3PK/R7 b - - +solution Re8 +id "ECM.151" +go +setboard r1b1kb1Q/qp2pp2/p3n1p1/2nN2Pp/2B4P/7N/PPP5/2KRR3 w q - +solution Nc7+ +id "ECM.152" +go +setboard 8/1bq3kp/p5p1/1pb1p3/4P2P/2PQ2P1/1P5B/5N1K b - - +solution Qd8 +id "ECM.153" +go +setboard 2r1q1r1/6bk/p2pN1pp/1p1N4/4P3/3R3Q/PnP4P/1K4R1 w - - +solution Nf6+ +id "ECM.154" +go +setboard 4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - +solution Ra8 +id "ECM.155" +go +setboard 6k1/p1q2pp1/2n2b2/3B2Pp/2P2P2/5N1P/Pr1Q2K1/4R3 w - - +solution Re8+ +id "ECM.156" +go +setboard r1r3k1/p4n2/3p4/5NpR/8/2q2P2/P1PQ4/2K4R w - - +solution Rh8+ +id "ECM.157" +go +setboard 8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - +solution g4+ +id "ECM.158" +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +solution Nd6 +id "ECM.159" +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +solution Ba4 +id "ECM.160" +go +setboard r1bq3k/ppp2Qp1/2n1p2p/6N1/2BPN3/2P1n3/PP4PP/R5K1 w - - +solution Nf6 +id "ECM.161" +go +setboard 3R4/1p2kp2/p1b1nN2/6p1/8/6BP/2r1qPPK/Q7 w - - +solution Rd7+ +id "ECM.162" +go +setboard 6k1/p5p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - +solution Rh8+ +id "ECM.163" +go +setboard 8/5P2/4K1kP/4R3/8/8/8/5r2 w - - +solution Rg5+ +id "ECM.164" +go +setboard 3r1rk1/p1p1qp1p/2p1b1p1/8/P2PRP2/2P1NQ2/6PP/R5K1 w - - +solution f5 +id "ECM.165" +go +setboard 6k1/pr3ppp/1p3qn1/5NQ1/2p5/8/P4PPP/4R1K1 w - - +solution Re8+ +id "ECM.166" +go +setboard Q7/1pq2kpp/4bp2/3r4/2B5/P3P3/1r3PPP/2R1K2R b K - +solution Rd1+ +id "ECM.167" +go +setboard 4r1k1/p4ppp/4q2r/1Q6/4p3/4P1P1/P4P1P/2RR2K1 w - - +solution Rd6 +id "ECM.168" +go +setboard 8/5p1k/4p1p1/3p2K1/3P1Q1P/P4P2/7q/8 b - - +solution f6+ +id "ECM.169" +go +setboard r4r2/6k1/3p4/2pPp2p/4Pqp1/3P1P2/1R2Q1KP/5R2 b - - +solution Ra1 +id "ECM.170" +go +setboard 4r1k1/1np1r1pp/1ppp1q2/6N1/1P3P2/4RQP1/7P/4R1K1 w - - +solution Qh5 +id "ECM.171" +go +setboard r4rk1/pp3p1p/3pq1p1/2nNp3/3R1P2/7Q/PP4PP/5RK1 w - - +solution f5 +id "ECM.172" +go +setboard 3qn2k/1p3Bp1/rbn4p/2p5/p1P2p2/P2b2PP/1BQNRP2/1R4K1 w - - +solution Qxd3 +id "ECM.173" +go +setboard 3r1rk1/1pp4p/1q3bp1/p3p3/P2n1P2/2BB3P/1PP2QP1/R4RK1 b - - +solution Bh4 +id "ECM.174" +go +setboard 4rrk1/2p2ppp/p2b4/1p1P4/3P2nq/2P4P/PPQ1RPP1/RNB3K1 b - - +solution Qxf2+ +id "ECM.175" +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +solution Nxf7 +id "ECM.176" +go +setboard r3kb1r/2q2p2/3p4/ppp1n1B1/P6P/1B3pQ1/1PP3b1/2KRR3 w kq - +solution Bd5 +id "ECM.177" +go +setboard r1b2rk1/1p4pp/p1n3q1/4ppN1/7Q/2P1B3/P1P2PPP/R2R2K1 w - - +solution Rd6 +id "ECM.178" +go +setboard 1rb2r2/1pR1N2p/p2R2pk/5p2/4pP2/1P1nP3/P4P1P/5BK1 w - - +solution Rf6 +id "ECM.179" +go +setboard r1b3k1/ppp2r2/6p1/3n3p/6qP/3BQ3/PBP5/2KR3R w - - +solution Bd4 +id "ECM.180" +go +setboard 3r2k1/p2q1r1p/1p1N2p1/1PpP4/3b1Bn1/1Q4Pb/1P2RP1P/R5KB b - - +solution Qxd6 +id "ECM.181" +go +setboard 4r1k1/1pbb3p/2pp2q1/p1n5/2P2R2/1PN1n1P1/PB2Q1B1/5RK1 w - - +solution Qxe3 +id "ECM.182" +go +setboard 3r2k1/p2r1p1p/1pR1p1qP/3P1pP1/3R4/1P2Q3/P4K2/8 w - - +solution dxe6 +id "ECM.183" +go +setboard 3r3k/p1Q3bp/2p3p1/8/2P1BRn1/1P4Pb/P1N1q2P/6BK b - - +solution Nf2+ +id "ECM.184" +go +setboard r4k2/p1pr1ppp/2q5/3PR2P/3Q4/8/6P1/5RK1 w - - +solution Re7 +id "ECM.185" +go +setboard 1R3b2/3r3k/2p1bp1p/r1q1pNpQ/2PpP2P/6B1/P4PP1/1R4K1 w - - +solution Nxh6 +id "ECM.186" +go +setboard r1b4r/pp2ppk1/2np1np1/3N3p/2B1P3/q3BP2/P1PQ2PP/1R3RK1 w - - +solution Nxe7 +id "ECM.187" +go +setboard r3k2r/pb1n1pbp/4p1p1/q1n1P3/Bp1N1N2/4B3/PP3PPP/R2Q1RK1 w kq - +solution Ndxe6 +id "ECM.188" +go +setboard 5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - +solution Ne4 +id "ECM.189" +go +setboard 5rk1/5pbp/b5p1/p1nNN3/1p2n3/1P4PP/P4PB1/2BR2K1 w - - +solution Nd7 +id "ECM.190" +go +setboard 2k1r1r1/ppb2p2/6b1/2qP4/2P2P2/4pP1p/P3Q2P/2RBRN1K b - - +solution Bd3 +id "ECM.191" +go +setboard 5r1k/pp1n1p1p/1b1qpP2/8/1PrN4/P1N1Q1P1/7P/3R1R1K w - - +solution Qh6 +id "ECM.192" +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +solution Nb6 +id "ECM.193" +go +setboard 1r3rk1/p4pbp/q1p2pp1/3p1b2/1n1P1P1B/PB3N2/1PPQR1PP/2KR4 b - - +solution Bxc2 +id "ECM.194" +go +setboard 1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - +solution Bxc5 +id "ECM.195" +go +setboard 2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - +solution Rxd5 +id "ECM.196" +go +setboard rn3rk1/pp2ppbp/6p1/2R3N1/2B3b1/q3B3/P1P1Q1PP/5RK1 w - - +solution Rxf7 +id "ECM.197" +go +setboard r1k3r1/pppnb1p1/4N3/3QP2p/3P3q/4B3/PPP2P2/R3KB2 w Q - +solution Ba6 +id "ECM.198" +go +setboard r1nqr2k/1p1b1Q1p/p5p1/P1pPb3/5B2/2N5/BP4PP/R4RK1 w - - +solution Qf8+ +id "ECM.199" +go +setboard 8/k3r1b1/Pp2rpp1/1qpQ4/4nB2/2P2NP1/7P/R4RK1 w - - +solution Bb8+ +id "ECM.200" +go +setboard 1k1r4/ppq2p2/8/2pPb1r1/2P1Q1B1/6P1/PP3PK1/R4R2 b - - +solution f5 +id "ECM.201" +go +setboard r1b2nk1/2qn1p1p/1ppR2p1/8/1PP1NP2/4r1PP/1Q2N1B1/3R2K1 w - - +solution b5 +id "ECM.202" +go +setboard 8/5pk1/3q2p1/8/7P/5Q1K/6B1/6b1 b - - +solution Qh2+ +id "ECM.203" +go +setboard 6r1/ppp4k/3p2rp/3Pb3/PPP1Np1q/5P1b/3QRRBP/6K1 b - - +solution Bd4 +id "ECM.204" +go +setboard 4br1k/pR4bp/2r1B1pN/4npB1/3p4/P7/5PPP/4R1K1 w - - +solution Rxg7 +id "ECM.205" +go +setboard r1bq1rk1/pppn2bp/3p2p1/3N1p2/8/BP1BRQ1P/P1PP1PP1/4R1K1 w - - +solution Nxc7 +id "ECM.206" +go +setboard r6r/1p2kp2/3p1b2/pPpPpQ1P/1nP1P2P/6R1/1P2K3/1B6 w - - +solution Rg6 +id "ECM.207" +go +setboard 2q1r1k1/1b3pbp/3p2p1/1Ppn3n/5P2/5B2/1P1B2PP/R2NNQ1K b - - +solution Ndxf4 +id "ECM.208" +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +solution Rb3 +id "ECM.209" +go +setboard r2qr1n1/p4pk1/1p1p2p1/4p3/4PQ2/1PN2P2/1PP3P1/2KR3R w - - +solution Rh7+ +id "ECM.210" +go +setboard r4rk1/ppp3b1/3p1qp1/3Pp3/2P1Bn2/4BP2/PP1Q4/2K3RR w - - +solution Rxg6 +id "ECM.211" +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +solution Bf4 +id "ECM.212" +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +solution Re7 +id "ECM.213" +go +setboard 1q3rk1/r5b1/pNp1bn1p/2Pp1n2/1P2p3/1N2P2P/PBQKB3/3R3R b - - +solution Nxe3 +id "ECM.214" +go +setboard r4n1r/ppq1nk2/1bpRpN2/4PpQ1/8/2B4P/PPP2PP1/2KR4 w - - +solution Rd7 +id "ECM.215" +go +setboard 3r2k1/p5pp/bpP1p3/3n1p2/2NQpP1q/P3P3/1B1R1R2/4KBr1 b - - +solution Rxf1+ +id "ECM.216" +go +setboard 1rq1r2k/5Rbp/p2p1p1B/2p1p3/2P1P2Q/1P6/P5PP/3b3K w - - +solution Bxg7+ +id "ECM.217" +go +setboard 5Q2/5p1p/3p2p1/4p1k1/4P1P1/3R1P1K/r6P/4q3 w - - +solution f4+ +id "ECM.218" +go +setboard 2b2r1k/ppq3pp/3b3r/n3NpN1/Q2PpP1B/2P1R3/PP5P/4R1K1 w - - +solution Ngf7+ +id "ECM.219" +go +setboard 2r1r1k1/1R4bp/p5p1/2pqn3/8/2B5/1PQ1B1PP/5RK1 w - - +solution Bc4 +id "ECM.220" +go +setboard 7k/pp1q2pp/3Nr1n1/3B2Q1/2pP4/B3P1Pb/P6P/6K1 w - - +solution Qd8+ +id "ECM.221" +go +setboard r5k1/5p1p/bq1p2p1/r2Pp3/1p2N1P1/1P3P2/1KPQ3P/3R3R b - - +solution Ra2+ +id "ECM.222" +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +solution Bg7 +id "ECM.223" +go +setboard 5nk1/2b1q1p1/2p5/3pP1pQ/1r1P2P1/3B1R2/5PP1/6K1 w - - +solution Rxf8+ +id "ECM.224" +go +setboard 1k1r3r/1pp2p2/p2b4/4n1p1/N3q1P1/1B2B3/PP3RP1/4RQK1 b - - +solution Rh1+ +id "ECM.225" +go +setboard rnb1kr2/p4pQ1/8/1ppPpP2/2p1P3/N6P/Pq4B1/3R1RK1 w q - +solution Nxb5 +id "ECM.226" +go +setboard 5r1k/2p3pp/3pQ3/3P1rN1/pp5q/5PR1/P4PKP/B7 w - - +solution Bxg7+ +id "ECM.227" +go +setboard 8/pR3Bk1/3p2p1/5b1p/2P4P/6P1/P4bQK/4q3 b - - +solution Bg1+ +id "ECM.228" +go +setboard r1b1Rnk1/6pp/p4q2/1pp2P2/3r4/2NB4/PP1Q2PP/4R1K1 w - - +solution Nd5 +id "ECM.229" +go +setboard 1Q6/pb3pk1/1p3qp1/1N3p1p/2Pr3P/3BR1PK/r7/6R1 b - - +solution Rh2+ +id "ECM.230" +go +setboard rq3r1k/p2n1p2/1pbb1np1/2p2BB1/8/2N2N2/PP3QPP/3R1RK1 w - - +solution Rxd6 +id "ECM.231" +go +setboard 2kr3r/Qpp1n1p1/2b2pp1/4b3/8/6N1/PPP2P2/R1B2RK1 b - - +solution Rh1+ +id "ECM.232" +go +setboard 8/2p2Q1p/1rp5/p3q1kp/P7/2P2RP1/5PK1/8 w - - +solution Rf5+ +id "ECM.233" +go +setboard 1r2b3/1p2q1bk/p1p1p1p1/P1PpP2r/1P1KpPQP/4P2N/6R1/4B2R b - - +solution Rxe5 +id "ECM.234" +go +setboard 6k1/3b1p1p/6p1/2BPR3/8/4Q2P/1q3rPK/8 w - - +solution Re8+ +id "ECM.235" +go +setboard 2R5/4ppkp/6p1/p2P4/4P2P/p3B1P1/qbR2PK1/8 w - - +solution Rg8+ +id "ECM.236" +go +setboard 3rr1k1/1b5p/p6p/1p3N2/6Pb/P1Q1p3/1PP4P/R5K1 b - - +solution Bf2+ +id "ECM.237" +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +solution Qc1 +id "ECM.238" +go +setboard 3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - +solution Bf3 +solution Rxc5 +id "ECM.239" +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +solution Rxd6 +id "ECM.240" +go +setboard 6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - +solution Rh4+ +id "ECM.241" +go +setboard 3r4/1pQ4R/p1b2kp1/P6p/2q5/7P/2P3P1/6K1 b - - +solution Rd1+ +id "ECM.242" +go +setboard 6rr/1b3k1p/pbqppPn1/1p5Q/4PN2/P6R/1PP3BP/2B2R1K w - - +solution Qxh7+ +id "ECM.243" +go +setboard 4rrk1/3b1ppp/pb6/1pqP4/P1p1PP2/1P2NK2/3QB2P/R2R4 b - - +solution Rxe4 +id "ECM.244" +go +setboard 2r1r1k1/1p4bp/p2p1qp1/1n1P4/2P1B2P/1N1Q4/PP2R3/1K5R b - - +solution Rxc4 +id "ECM.245" +go +setboard 6rr/ppqb1pkp/2pb1pn1/3p3Q/3P1P1N/3B1RN1/PPP3PP/5RK1 w - - +solution Qh6+ +id "ECM.246" +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +solution Bh7+ +id "ECM.247" +go +setboard r2q1rk1/1b1nbpp1/p1p1p2p/1pPpN3/3P1N2/P2BP3/1PQ2PPP/R4RK1 w - - +solution Bh7+ +id "ECM.248" +go +setboard 2r2rk1/pb4pp/1p2p3/4Npq1/3P1n2/5P2/PP1R2PP/RB2Q1K1 b - - +solution Rc1 +id "ECM.249" +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +solution Bxf7+ +id "ECM.250" +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +solution Bb7 +id "ECM.251" +go +setboard r5k1/pp2ppb1/4qn2/r3B1p1/3P4/3QNP1R/PP2K1P1/7R w - - +solution Bxf6 +id "ECM.252" +go +setboard 1R2br1k/5r1p/p2p1P2/6RQ/3p1P2/4p2B/q6P/5N1K w - - +solution Rxe8 +id "ECM.253" +go +setboard kr1r4/7p/2bqp1p1/p7/1Pp1PP1P/K1B1nNPB/PP5R/RN2Q3 b - - +solution Qxb4+ +id "ECM.254" +go +setboard 5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - +solution Rxd7+ +id "ECM.255" +go +setboard kn5r/p2r2p1/1pqBp1np/1Q1pPp2/R2P4/1N6/2P2PPP/R5K1 w - - +solution Rxa7+ +id "ECM.256" +go +setboard 4Rnk1/2p2pp1/3r3p/p2P4/P5Q1/1B5P/5PK1/q7 w - - +solution Rxf8+ +id "ECM.257" +go +setboard 4r3/2k1p2q/pp1nR1p1/2pP1pP1/2P2P2/1P6/P1K3B1/4Q3 w - - +solution Rxd6 +id "ECM.258" +go +setboard 2b3k1/p4ppp/7q/2Q5/8/P3r1P1/1r4BP/R3R1K1 b - - +solution Rxg2+ +id "ECM.259" +go +setboard r1b1rbk1/7p/2p1pBp1/p2pP1P1/5P2/1PqB4/P1P1Q3/1K4RR w - - +solution Rxh7 +id "ECM.260" +go +setboard 2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - +solution Bxh6 +id "ECM.261" +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +solution Rxh8+ +id "ECM.262" +go +setboard 3r2k1/p4rPp/1b1q3Q/n1p1pP2/1p6/3B1NR1/P4P1P/6RK w - - +solution Qxh7+ +id "ECM.263" +go +setboard r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - +solution Bh7+ +id "ECM.264" +go +setboard r2rn1k1/1bqn1ppp/p7/2bpP1P1/1p1N1Q2/1P3B2/PBP1NR1P/3R2K1 w - - +solution Qxf7+ +id "ECM.265" +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +solution Nxf7 +id "ECM.266" +go +setboard r1b1r1k1/1p1n1p2/p1nBp1p1/q2pP1Np/P7/R2B3Q/2P2PPP/5RK1 w - - +solution Nxf7 +id "ECM.267" +go +setboard r1b1k2r/ppp3pp/1qp5/2b1Pp2/3Qn3/5N2/PPPBNPPP/2KR3R w kq - +solution Qd8+ +id "ECM.268" +go +setboard 1k6/1p4p1/P1p5/5Q2/2q2r2/P7/8/4R2K w - - +solution Re8+ +id "ECM.269" +go +setboard 6k1/1p3p2/4r1p1/1PPrbq1p/2QN4/P2R1P1P/R4KP1/8 b - - +solution Bg3+ +id "ECM.270" +go +setboard 4n1q1/1k1b4/2p4R/2Pp4/1p1N1rpQ/3B4/PPP2P2/2K5 w - - +solution Nxc6 +id "ECM.271" +go +setboard r2qk2r/1pp2ppp/p3pnn1/6N1/1B1P2P1/1Q2P2P/PP3PK1/R6R b kq - +solution Nh4+ +id "ECM.272" +go +setboard 2kr2r1/R2p3p/2n2p2/1R3P2/2P1p3/4BQ2/1Pq4P/4K3 w - - +solution Ra8+ +id "ECM.273" +go +setboard r3r1k1/pp3pp1/2bb1q2/3p4/4n1Pp/2P1BB1P/PP2NPK1/R1Q4R b - - +solution Qxf3+ +id "ECM.274" +go +setboard r1br4/ppq2pk1/3bpN2/8/2P5/3n2B1/PP2QPPP/R4K1R w - - +solution Qg4+ +id "ECM.275" +go +setboard 6kb/B1p2p2/5r2/1r1p2pR/6q1/3P2P1/P1P2PP1/2KR3Q b - - +solution Rb1+ +id "ECM.276" +go +setboard rn4k1/pp2p1b1/4b3/q2p2Q1/2B2P2/8/P1P1K1P1/R6R w - - +solution Rh8+ +id "ECM.277" +go +setboard 3k2r1/pp1b3Q/1b2pP1p/3pN2q/5B2/7B/PP2nP1K/2R5 b - - +solution Rg2+ +id "ECM.278" +go +setboard 2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - +solution Rxc3 +id "ECM.279" +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +solution Nxg7 +id "ECM.280" +go +setboard 4k2r/1bqnbppp/p3p3/1p2P1N1/2r2BB1/8/PPP3PP/R2Q1R1K w k - +solution Nxf7 +id "ECM.281" +go +setboard 5r1k/1pqb3p/2n5/p1pB4/2Pp1r1P/1P5P/R2N2K1/3Q1R2 b - - +solution Bxh3+ +id "ECM.282" +go +setboard r4r2/pp2qk2/4pnp1/3pQ3/2p2P2/3B4/PPP2P2/2KR3R w - - +solution Bxg6+ +id "ECM.283" +go +setboard 3bq3/p1n2rk1/1pp1p1p1/3pPnPp/1P1P1N1P/2PN3K/P2BQR2/8 w - - +solution Nxg6 +id "ECM.284" +go +setboard b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - +solution Bxg6+ +id "ECM.285" +go +setboard r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - +solution Qh6+ +id "ECM.286" +go +setboard 4k3/p4ppp/nb1P4/4p3/1P6/P4BP1/3q1r1P/2R2QKR w - - +solution Qb5+ +id "ECM.287" +go +setboard r2q1rk1/pp2pp2/3pb3/3Qb2R/4P1p1/1BN1Bn2/PPP2P2/2K4R w - - +solution Rh8+ +id "ECM.288" +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +solution Nxg7 +id "ECM.289" +go +setboard 1rbk2nr/p1pp2b1/7p/2qP1pp1/2Bn4/2NKBP2/PP2N1PP/R2Q3R b - - +solution Qxc4+ +id "ECM.290" +go +setboard 1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - +solution Rxb2 +id "ECM.291" +go +setboard 5rk1/ppp1q2p/1n1p1np1/3P2N1/1P1R2P1/2Q4P/P3r1B1/5RK1 b - - +solution Rxg2+ +id "ECM.292" +go +setboard 6k1/pp2p2p/3p2p1/4b1r1/2Pn1r1q/2B1N3/PP4B1/R3QRK1 b - - +solution Qh2+ +id "ECM.293" +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +solution Qxg6+ +id "ECM.294" +go +setboard r2k3r/2pb1ppp/p1p1q3/2Q5/5B2/2N5/PPP2PPP/3R2K1 w - - +solution Bxc7+ +id "ECM.295" +go +setboard 2r2r2/2N2pkp/2Q5/1N2p1b1/1p6/3P1qPb/PPR2P1P/4R1K1 b - - +solution e4 +id "ECM.296" +go +setboard 2r1qrk1/pp1b1ppp/4pn2/n1b5/8/2NQ1NP1/PP1BPPBP/R2R2K1 w - - +solution b4 +id "ECM.297" +go +setboard 2b1qr1k/7p/p1pR2p1/1pP1p1Q1/4P3/1B6/PP4PP/6K1 w - - +solution Re6 +id "ECM.298" +go +setboard 1r2k2r/2p2p1b/q1Pppb1N/p2p2P1/Q2P4/P3B3/1P5P/2KRR3 b k - +solution Rb4 +id "ECM.299" +go +setboard 8/2b2k1p/2N2pp1/P2p4/3KnP2/6BP/P5P1/8 w - - +solution Kxd5 +id "ECM.300" +go +setboard 4b1r1/1p3ppk/3r3p/p1p1qP1B/3pPN2/3P3R/nPPQ3P/6RK w - - +solution Ne6 +id "ECM.301" +go +setboard 4b2k/7p/3q3P/1p1pRpr1/1P1B4/2P2Q2/7K/8 w - - +solution Qg3 +id "ECM.302" +go +setboard 2kr2r1/pbp4p/1p4p1/1NqpNp2/4nQ2/8/PPPR1PPP/2K1R3 w - - +solution Nc6 +id "ECM.303" +go +setboard 1rr3k1/1p1bqpbp/1R1p2p1/pN1P4/P3P1n1/1Q6/3NB1PP/2B1R1K1 b - - +solution Rc3 +id "ECM.304" +go +setboard r1br4/1p3k2/p2q1p2/3N1Pp1/3Q4/8/PP4P1/4RR1K w - - +solution Re6 +id "ECM.305" +go +setboard r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - +solution Bd5 +id "ECM.306" +go +setboard 3r1rk1/2p1qp1p/pnP3p1/4n3/PP1NpR2/1BQ4P/6P1/5RK1 w - - +solution Ne6 +id "ECM.307" +go +setboard r1bq1k2/5pb1/p2p1n2/2pPrP2/2p4B/3B2R1/PP1Q2PP/R5K1 w - - +solution Qg5 +id "ECM.308" +go +setboard 2bq1rk1/p4pbp/p2p2p1/3P4/2p1QP2/2Pr3P/PP1N2P1/R1B2RK1 b - - +solution Bd4+ +id "ECM.309" +go +setboard r5rk/1p1bqpnp/3p1b1B/pBnPp2P/4P3/2N2Q2/PP3P2/R3KNR1 b Q - +solution Nf5 +id "ECM.310" +go +setboard r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - +solution Re7 +id "ECM.311" +go +setboard r3r1k1/p1q2pp1/2p4p/7n/BPPP2N1/3Q1N2/P3n1P1/R1B4K b - - +solution Nhg3+ +id "ECM.312" +go +setboard r2qrbk1/1p4pb/2n2p1p/pNpn4/2N5/PP1PPQPB/1B5P/2R2RK1 w - - +solution Nbd6 +id "ECM.313" +go +setboard 5r1k/1p1b1p1p/p2ppb2/5P1B/1q6/1Pr3R1/2PQ2PP/5R1K w - - +solution Qh6 +id "ECM.314" +go +setboard r1b2rk1/p3bppp/2q5/8/2p1NR2/PnB1P3/1PB1Q1PP/3R2K1 w - - +solution Rd6 +id "ECM.315" +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +solution R1b4 +id "ECM.316" +go +setboard 4r3/pp1b3k/2p2qpp/2Pp4/1P6/PBbP1N1P/2R3P1/3Q3K b - - +solution Re1+ +id "ECM.317" +go +setboard 1rb2rk1/p1p2ppp/2q5/3R4/2P1N3/bP4B1/P1Q2P1P/1K5R w - - +solution Bd6 +id "ECM.318" +go +setboard 8/5k1p/5PpB/3PR3/2r4P/1p3K2/2b5/8 b - - +solution Re4 +id "ECM.319" +go +setboard 4r2k/3b3p/p2p4/2pP1p2/q1B2Q1P/2PK1P2/Pr1R4/7R b - - +solution Re4 +id "ECM.320" +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +solution Rd5 +id "ECM.321" +go +setboard 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - +solution Rxh7+ +id "ECM.322" +go +setboard r1b1r1kb/p1qn1pnp/2p1p1p1/4P1N1/2p1NPP1/4B3/PPPQ3P/3RK2R w K - +solution Qxd7 +id "ECM.323" +go +setboard 5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - +solution Rxe7 +id "ECM.324" +go +setboard 5rk1/5p1p/8/3pNp2/RPrqn3/1Q5P/1P3PP1/4R1K1 w - - +solution Rxe4 +id "ECM.325" +go +setboard 2rr2k1/4qppp/bn6/p1bB4/4N3/6P1/PB2PP1P/2RQ1RK1 w - - +solution Rxc5 +id "ECM.326" +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +solution Rxd7 +id "ECM.327" +go +setboard 5rk1/r2nqpp1/p3p3/1p2P3/4N1pP/8/PPP3Q1/1K1R3R w - - +solution Rxd7 +id "ECM.328" +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +solution Qh6 +id "ECM.329" +go +setboard 2r2r1k/1pq1b1p1/p1b1Qn1p/8/3B4/2NB4/PPP3PP/3R1R1K w - - +solution Rxf6 +id "ECM.330" +go +setboard 3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - +solution Rxe6 +id "ECM.331" +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +solution Rxc8+ +id "ECM.332" +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +solution Rxe4 +id "ECM.333" +go +setboard r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - +solution Rxe5 +id "ECM.334" +go +setboard 8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - +solution Rxd4 +id "ECM.335" +go +setboard r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - +solution Rxe5 +id "ECM.336" +go +setboard r3r1k1/pbqn1ppp/1p3n2/1Pb5/2p5/5N1P/PBQ1BPP1/1N1R1RK1 b - - +solution Rxe2 +id "ECM.337" +go +setboard 2r2rbk/6bp/5qp1/1N1p1n2/4p3/1p5P/1P3PP1/RBBQ1RK1 b - - +solution Ng3 +id "ECM.338" +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +solution Rxc5 +id "ECM.339" +go +setboard 1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - +solution Rxe7 +id "ECM.340" +go +setboard r1k2n1r/2pb4/1p1p1qpp/p2P1p2/3N1P1P/2Q3P1/PPP1R3/2K1RB2 w - - +solution Re8+ +id "ECM.341" +go +setboard r1b2r1R/1p2bpk1/4p1p1/4P1N1/p2p4/5Q2/qPP2PP1/1NKR4 w - - +solution Qf6+ +id "ECM.342" +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +solution Nxe6 +id "ECM.343" +go +setboard 4q1r1/5kpp/2p1nb2/2PpQp2/r4P2/1N3P2/1BP1R2P/6RK w - - +solution Rxg7+ +id "ECM.344" +go +setboard 2r1k2r/1pq1bppp/p3bn2/4N3/2pPN3/2P5/P3QPPP/R1B1R1K1 w k - +solution Nxf6+ +id "ECM.345" +go +setboard 1r3k1r/4Rn1p/pb1p1P2/1p1q2P1/5p2/7Q/PPP1B1RP/2K5 w - - +solution Rxf7+ +id "ECM.346" +go +setboard 4rrk1/ppn3pp/2pb1n1q/3p4/1P1P4/P3BNP1/2P1BPKP/R2Q1R2 b - - +solution Rxe3 +id "ECM.347" +go +setboard 2b1r2k/2Q4p/4q3/1pp5/3b4/4NP2/1P3BP1/3R2K1 w - - +solution Rxd4 +id "ECM.348" +go +setboard r3r1k1/pp3ppp/1qp5/2bbNQ2/5B2/2P5/PP3PPP/3RR1K1 w - - +solution Rxd5 +id "ECM.349" +go +setboard 7r/3qbk1r/3p1n2/p1pPp1p1/Pp1nPpP1/1P1Q1P1B/1NP3K1/R3B2R b - - +solution Nxg4 +id "ECM.350" +go +setboard r2qn1k1/1p1b3p/2pp1b2/6pQ/p1P1P3/P1N3PB/1P6/3R1R1K w - - +solution Rxf6 +id "ECM.351" +go +setboard 2rq3r/5p2/p3pkbQ/3p4/3N4/2P4R/P4PP1/4R1K1 w - - +solution Rf3+ +id "ECM.352" +go +setboard r4k1r/pp2pp2/3p1b2/q2PnQpp/3N4/1BP3P1/PP3PP1/3RR1K1 w - - +solution Rxe5 +id "ECM.353" +go +setboard 5rk1/2p3pp/p1p4r/2P1p3/3pPnq1/1P3R1P/PN1Q3K/R5N1 b - - +solution Qxf3 +id "ECM.354" +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +solution Rxd7 +id "ECM.355" +go +setboard 2r2rk1/p3p1bp/3qP1p1/1Q1p4/P4P2/3R4/1P4PP/2B2RK1 b - - +solution Rxc1 +id "ECM.356" +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +solution Rxd4 +id "ECM.357" +go +setboard 1r6/3b1pk1/pr1p1q1p/2pPb1p1/2B1P1P1/2N2PP1/1PQ3K1/RR6 b - - +solution Rxb2 +id "ECM.358" +go +setboard 2r2rk1/5ppp/1p2p3/p7/1n1R4/P1NnPN2/1P3PPP/1R4K1 b - - +solution Nxb2 +id "ECM.359" +go +setboard 2r3k1/p1r1ppb1/2bp1np1/q5N1/1p1BP2Q/3P4/PP2N1PP/2R2R1K w - - +solution Bxf6 +id "ECM.360" +go +setboard r3r1k1/p4ppp/2pp1b2/8/q2n1P2/2BQ3P/PPP3P1/1K1R2NR b - - +solution Re3 +id "ECM.361" +go +setboard rn1kr3/pppb4/3p1q2/3P1pNn/2P2P1p/1P2Q2P/P2NR1B1/4R1K1 w - - +solution Qxe8+ +id "ECM.362" +go +setboard r2q1rk1/ppp1b1pp/1nn1p3/4P3/2PP4/2N1B2P/PP1Q4/2KR1B1R b - - +solution Rxf1 +id "ECM.363" +go +setboard r3k3/1pqb1p2/p3p3/4n2r/3N1Q2/2P5/PP4B1/4RRK1 w q - +solution Rxe5 +id "ECM.364" +go +setboard 1rb2bk1/q4r2/pB1p1nn1/3Pp3/N3PpP1/8/1PQ1BNP1/R1R3K1 b - - +solution Rxb6 +id "ECM.365" +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +solution Rxd8 +id "ECM.366" +go +setboard r4rk1/5p2/p1b1pQpq/8/1B2P3/2NR4/PPP3PP/1K6 w - - +solution Rd5 +id "ECM.367" +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +solution Rxg6+ +id "ECM.368" +go +setboard 2rr2k1/5ppp/p1b1pn2/q1p5/P1B1PQ2/R1PN1P2/6PP/1R4K1 b - - +solution Rxd3 +id "ECM.369" +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +solution Bd8 +id "ECM.370" +go +setboard 1k2rb1r/pbp1q1pp/2pp4/2PnpP2/Q7/1P3NP1/PB5P/2KR1B1R w - - +solution Rxd5 +id "ECM.371" +go +setboard 7k/p1p1r2p/1p1pnr1q/5pp1/2PPPp2/2PB1P1P/P2Q1PRK/7R b - - +solution g4 +id "ECM.372" +go +setboard 5qk1/p4p2/1p3Pp1/2p4Q/3rr3/7R/PP6/6RK b - - +solution Rh4 +id "ECM.373" +go +setboard 5r1k/5Bb1/3p2Pp/p1pP4/1p2Q3/4P1P1/q7/3K3R w - - +solution Rxh6+ +id "ECM.374" +go +setboard 2b4B/1pp2k2/1p6/3P3n/5p1P/1P4p1/P2r2P1/R5KR b - - +solution f3 +id "ECM.375" +go +setboard r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b q - +solution Bh2 +id "ECM.376" +go +setboard r2q1r2/p1pbppbk/1p3npp/n2P2B1/7Q/2NB1N2/PPP3PP/4RRK1 w - - +solution d6 +id "ECM.377" +go +setboard 5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - +solution Nf7+ +id "ECM.378" +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +solution Bxe5+ +id "ECM.379" +go +setboard r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - +solution Bc3 +id "ECM.380" +go +setboard 2r1k2r/3b1pb1/p2ppp2/2q2P2/2p1P2p/P1N2N2/1PP1Q1PP/3R1R1K w k - +solution e5 +id "ECM.381" +go +setboard 3r1rk1/1pq1bppp/p7/n2RN3/P7/1P6/1B2QPPP/R5K1 w - - +solution Nd7 +id "ECM.382" +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +solution Rxc4 +id "ECM.383" +go +setboard r3bknr/1p4pp/p3Q3/q4pb1/P1Bn4/8/1PP2PPP/R1B1R1K1 w - - +solution Qd6+ +id "ECM.384" +go +setboard r1b1nrk1/p2n3p/2pp4/8/2P2q1N/1PB4P/P4PB1/R2QR1K1 w - - +solution Bd5+ +id "ECM.385" +go +setboard 7k/5rp1/p1bQB2p/1p4nN/4P3/1Pq5/P5PP/3R3K b - - +solution Bxe4 +id "ECM.386" +go +setboard r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - +solution d4 +id "ECM.387" +go +setboard r2r2k1/1bq2pb1/6pp/2P1p3/1nBpN2N/6PP/2Q2P2/3RR1K1 w - - +solution Nf6+ +id "ECM.388" +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +solution Nf6+ +id "ECM.389" +go +setboard 2k1r3/Qp3pb1/2p4p/6q1/8/1P4PN/PBPn1P2/K2R4 b - - +solution Qe5 +id "ECM.390" +go +setboard r3r1k1/1pp2p1b/7p/2Q5/2PP2p1/2P1NpPq/P2R1P1P/6RK b - - +solution Rxe3 +id "ECM.391" +go +setboard 5bk1/5p1p/Q5p1/1B4n1/8/2q1p3/6PP/3R2K1 b - - +solution e2 +id "ECM.392" +go +setboard r5k1/1p3pp1/1p3q1p/1P1bQ3/P2P3n/8/3B1PPP/R3R1K1 b - - +solution Nf3+ +id "ECM.393" +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +solution Rxa6 +id "ECM.394" +go +setboard r5kr/p3PR1p/1p1p2pq/4n3/8/3B4/P4QPP/4R1K1 w - - +solution Rxe5 +id "ECM.395" +go +setboard 2bq1b2/1p3k2/1r1p1p1p/pNpP1PpP/P1P3P1/6B1/1P5Q/2K1R3 w - - +solution Re6 +id "ECM.396" +go +setboard 2kr3r/pp3p1p/2b1p3/q3Q3/5P2/2P1B3/P1P3PP/1R3RK1 b - - +solution Rhg8 +id "ECM.397" +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +solution Rxd3 +id "ECM.398" +go +setboard 2r2nk1/6pp/p1rPqp2/1pP1p3/1P6/2B3R1/1P2Q1PP/5RK1 w - - +solution Rxf6 +id "ECM.399" +go +setboard 3r2k1/pb3p1p/1q4p1/2b1P3/1Pp5/2P1p1P1/P3Q1BP/R1B4K b - - +solution Qc6 +id "ECM.400" +go +setboard r2rnbk1/pp3ppp/1q4n1/3p1N2/5P2/1PQB4/PBP3PP/4RR1K w - - +solution Nh6+ +id "ECM.401" +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +solution e5 +id "ECM.402" +go +setboard r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - +solution Rxh5 +id "ECM.403" +go +setboard 5rr1/pp1kq1bp/2bppn2/2p3B1/4N3/2NP2P1/PPP4P/R3QRK1 b - - +solution Nxe4 +id "ECM.404" +go +setboard 1r1q1k2/R4pp1/5p1r/1p1p1n1p/3Pb2N/1BP5/2P1Q1PP/4R1K1 w - - +solution Qxe4 +id "ECM.405" +go +setboard R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - +solution Nxe5 +id "ECM.406" +go +setboard r1b3kr/bp3ppp/p1nNp3/4P3/P1Q2P2/BBP5/5qPP/R2R3K w - - +solution Nxc8 +id "ECM.407" +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +solution Rxc4 +id "ECM.408" +go +setboard 4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - +solution Rxf6 +id "ECM.409" +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +solution e6 +id "ECM.410" +go +setboard r4rk1/1b4bp/p1npq1P1/R3p3/8/1N2BP2/1PPQ2P1/4KB1R w K - +solution Qxd6 +id "ECM.411" +go +setboard 6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - +solution Bd2 +id "ECM.412" +go +setboard 6k1/2p3p1/2b4p/p4P2/2pR2PK/2P1r2P/1B6/8 b - - +solution Bg2 +id "ECM.413" +go +setboard r1b2rk1/pp2ppbp/2np1np1/q7/4P3/2N1BN2/PPPQBPPP/2KR3R b - - +solution Nxe4 +id "ECM.414" +go +setboard 3r1rk1/p1q4p/1p3bp1/3bnp2/3B4/1NPB3P/P1PQ2P1/1R2R2K b - - +solution Nf3 +id "ECM.415" +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +solution Ng5 +id "ECM.416" +go +setboard 1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - +solution bxc6 +id "ECM.417" +go +setboard r3kbnr/1ppb3p/p1q1pp2/3p4/3P4/2N2N2/PPP2PPP/R1BQ1RK1 w kq - +solution Ne5 +id "ECM.418" +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +solution Rxf6 +id "ECM.419" +go +setboard 3rr1k1/1p1qb2p/pP4p1/2p2p2/4RQ2/3P4/1PPB2PP/4R1K1 w - - +solution Bc3 +id "ECM.420" +go +setboard 2b2r2/rpp2pkp/3pq3/2pR2P1/2n1P1N1/2P2B2/1P3Q1P/1K5R b - - +solution Qxd5 +id "ECM.421" +go +setboard 6k1/rnqb3p/5ppQ/2pPp3/p1N1P3/2PB3P/5PP1/1R4K1 w - - +solution f4 +id "ECM.422" +go +setboard 7r/pp4k1/3pn1p1/q1pB1b2/2P5/5NR1/1P3PP1/2Q3K1 w - - +solution b4 +id "ECM.423" +go +setboard 5r2/4prkp/3q2p1/2pP1n2/N1Q2R2/1P4PP/P5K1/4R3 b - - +solution g5 +id "ECM.424" +go +setboard B1b1rbk1/5ppp/pq6/1p2n3/2p2P2/6PP/PPQ4K/R1BR4 b - - +solution Ng4+ +id "ECM.425" +go +setboard 8/2R4p/2R3bk/8/5N1P/1p3PP1/2pqP1K1/8 w - - +solution g4 +id "ECM.426" +go +setboard 6k1/p4p1p/3pqp2/2p1r3/2Pnr1N1/P6P/1P1Q1PP1/3R1RK1 b - - +solution Ne2+ +id "ECM.427" +go +setboard 1kqr3r/p1p4p/RpQP4/2P1p3/4B3/4Bp2/P4P1P/6K1 b - - +solution Rdg8+ +id "ECM.428" +go +setboard 6k1/3Q1pp1/4p2p/p2pP3/1p1P2P1/nP1R1N2/q1r2PKP/8 w - - +solution Qe8+ +id "ECM.429" +go +setboard 6k1/5pp1/p5r1/3Np2q/4P2p/1r3P1Q/n4P1P/3R2RK w - - +solution Rxg6 +id "ECM.430" +go +setboard nr2rb2/3q1kpp/3p4/pnpPpNBP/2N1P3/3Q4/PP3P2/2K3RR w - - +solution Nh6+ +id "ECM.431" +go +setboard r3k1r1/1pp2ppp/pb1p1qn1/4p2b/2B1P3/N1PP1NPP/PP2QPK1/R4R2 b q - +solution Nh4+ +id "ECM.432" +go +setboard 1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - +solution Bxh6 +id "ECM.433" +go +setboard r2b4/pb2q1k1/np1p2r1/1N1Pp2Q/PPN1Pp2/8/2R2BPp/2R4K w - - +solution Ncxd6 +id "ECM.434" +go +setboard r7/2qnb1kp/p2p1nP1/1p1Pp1p1/6N1/3BB2Q/PPP4P/5RK1 w - - +solution Qxh7+ +id "ECM.435" +go +setboard n1rqk3/1p2p3/1n1pP1p1/pP1P1p1r/3B3P/1BN3p1/3Q4/R3K2R w KQ - +solution Qg5 +id "ECM.436" +go +setboard rn2kr2/pp1b1pQp/3Pp3/qB1n4/3N4/P7/1PP2PPP/2KR3R w q - +solution Nxe6 +id "ECM.437" +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +solution Bh4 +id "ECM.438" +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +solution Bf8 +id "ECM.439" +go +setboard 4rr1k/pbp3bp/3p4/1p5q/3n4/1B1Q2B1/PP1N1N1P/4RRK1 b - - +solution Rf3 +id "ECM.440" +go +setboard r3k2r/pp2ppbp/1qp5/2n2b2/2P5/4BN2/PP1QBP1P/2KR3R b kq - +solution Nb3+ +id "ECM.441" +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +solution Ng6+ +id "ECM.442" +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +solution Qb2 +id "ECM.443" +go +setboard 2r3k1/n3qppp/1B1r1n2/N7/N4P2/1Q4PP/P5B1/R1b4K b - - +solution Qe1+ +id "ECM.444" +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +solution Qxg5+ +id "ECM.445" +go +setboard rnb2k2/ppbp2p1/2p2pB1/8/1PN5/2P5/P4PPP/R1B3K1 w - - +solution Bf4 +id "ECM.446" +go +setboard 2k5/1p1b4/2n1p1r1/7q/4RP2/3BQN2/2P2K1P/8 w - - +solution f5 +id "ECM.447" +go +setboard 2k3r1/1ppr3p/p1pB2q1/6n1/N3Pp2/8/PPP1Q1PP/3R1RK1 b - - +solution f3 +id "ECM.448" +go +setboard r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - +solution Rxh2+ +id "ECM.449" +go +setboard 6r1/6rk/3p3p/p2Rp3/R1PqPp1b/2N2Q2/6PP/7K b - - +solution Rxg2 +id "ECM.450" +go +setboard 4r1k1/1p2rq1p/2bQpp2/p1Pp4/3P4/P3RN2/5PPP/4R1K1 w - - +solution Ne5 +id "ECM.451" +go +setboard b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1KP/8 w - - +solution g6 +id "ECM.452" +go +setboard 1k4q1/1p2Rprp/p1p5/2Pp4/1P1Q3P/6P1/P5K1/8 w - - +solution Qe5+ +id "ECM.453" +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +solution Ng6+ +id "ECM.454" +go +setboard r4r1k/p2bN2p/1p1p1p2/2q4P/3Q4/1P6/1PP3P1/1K2R2R w - - +solution Ng6+ +id "ECM.455" +go +setboard 2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - +solution h4 +id "ECM.456" +go +setboard r1b2k1r/1p2qp2/pN1p1n2/2pP2pp/P2bP1P1/2N5/1P2BPP1/R2Q1RK1 b - - +solution hxg4 +id "ECM.457" +go +setboard 6nk/p4rrp/1p1p1p2/1q1Pp2R/4B1P1/1PP2Q1R/P6P/7K w - - +solution g5 +id "ECM.458" +go +setboard r1b1k2r/6pp/p1p1p3/3np1B1/1b2N3/8/q1PQB1PP/3RK2R w Kkq - +solution Qxb4 +id "ECM.459" +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +solution Bxh5 +id "ECM.460" +go +setboard 2r3k1/4qpp1/2p1r3/pbQpN1Pp/3P1P1P/4P3/PP6/1KR3R1 w - - +solution Qxb5 +id "ECM.461" +go +setboard 4r2k/p2Q3p/2p1r1p1/4NpR1/3P4/2P1PP1b/P4q1P/6RK w - - +solution Nxg6+ +id "ECM.462" +go +setboard 4r1kb/p2r4/1np1p1p1/3nP1Bp/1p3P1R/1B2qP2/PPPN3Q/2K4R w - - +solution Rxh5 +id "ECM.463" +go +setboard 2rq2k1/pp1bpp1p/3p1np1/8/3NPPnQ/1BP5/P1P3P1/1K1R3R w - - +solution e5 +id "ECM.464" +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +solution Rxd5 +id "ECM.465" +go +setboard 2r1kr2/p1qbbp1Q/3pp3/5p2/1p1N1PB1/6P1/PPP4P/K2RR3 w - - +solution Bxf5 +id "ECM.466" +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +solution Rf6 +id "ECM.467" +go +setboard 2rr2k1/5pn1/1b2q1pp/pP1pP3/2pP1PP1/2R1B2P/2Q3B1/3R3K w - - +solution f5 +id "ECM.468" +go +setboard 2Q2bkr/5p2/1rb5/1pN1n1qB/1P1pPN2/6P1/5P2/R1R3K1 w - - +solution Nce6 +id "ECM.469" +go +setboard 2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - +solution Nc3+ +id "ECM.470" +go +setboard 2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - +solution Nxf5+ +id "ECM.471" +go +setboard 1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - +solution Ne6 +id "ECM.472" +go +setboard r7/pp4pk/2n3qp/5p2/3p4/P4QB1/1PP1RPPP/6K1 b - - +solution d3 +id "ECM.473" +go +setboard 2r2r1k/1p3p1p/p2p1Pp1/3Pp3/1q2Bn1Q/8/1PP3PP/4RR1K w - - +solution Rxf4 +id "ECM.474" +go +setboard r4rk1/5ppp/p7/4PR2/P1qnp2Q/4B3/1P4PP/5RK1 w - - +solution Rh5 +id "ECM.475" +go +setboard 4r3/pb3pk1/6p1/8/6P1/1PNrB2K/P4P1P/2R5 b - - +solution Rexe3+ +id "ECM.476" +go +setboard 1r3kr1/p3q1b1/3p2Q1/2p2p2/2P2N2/4Pn2/PB6/K2R3R w - - +solution Ne6+ +id "ECM.477" +go +setboard 5r1k/6bp/3p1q2/3Q1nP1/8/6P1/PP3BKP/R2N4 b - - +solution Ne3+ +id "ECM.478" +go +setboard 1r1q1k1r/Q4ppp/2B2n2/8/Pbbp4/1P4P1/2PP1P1P/R1B1K2R b KQ - +solution Qe8+ +id "ECM.479" +go +setboard 5rk1/p1p1R1p1/1p5p/8/2pP1P2/3n2P1/PP2Q2P/5KNq b - - +solution Nxf4 +id "ECM.480" +go +setboard r5k1/1N3ppp/4b3/1Nq5/Pn3pn1/5B2/1PPQ3P/R6K b - - +solution Qxb5 +id "ECM.481" +go +setboard 1r2k2r/1bq2pp1/pn2p2p/1p2P1b1/3N4/2N3Q1/PPP3PP/1K1R1BR1 w k - +solution Bxb5+ +id "ECM.482" +go +setboard r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - +solution Nxh6 +id "ECM.483" +go +setboard 2r2r2/p4p1k/1p2pBpn/2p5/6N1/8/P4P2/R3R1K1 w - - +solution Kg2 +id "ECM.484" +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +solution Bg5 +id "ECM.485" +go +setboard 3rn1k1/pp3ppp/6b1/2p1Q3/2P1P3/P4P2/1B1qBP1P/1R5K w - - +solution Rd1 +id "ECM.486" +go +setboard 4r1k1/5ppp/p1q3b1/1ppNr3/2P1P3/1P4QP/P4PP1/4RRK1 w - - +solution f4 +id "ECM.487" +go +setboard 2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - +solution Bh3 +id "ECM.488" +go +setboard 2b3k1/5qp1/p2r1n1p/3p4/3B4/1RP3QP/P2Nr1P1/3R2K1 b - - +solution Ne4 +id "ECM.489" +go +setboard 6k1/5rp1/4Nb1p/2p5/4Q3/1r5P/q5P1/3R1R1K w - - +solution Rxf6 +id "ECM.490" +go +setboard 1r2r1k1/p4ppb/q1pbnn1p/4p3/N1P1P3/pPB2NP1/2Q1RPBP/R5K1 b - - +solution Nxe4 +id "ECM.491" +go +setboard r4r2/1pnqb2k/3p1p1p/p1pPpPpP/2P1N1P1/4BP2/PP1Q4/R2R2K1 w - - +solution Bxc5 +id "ECM.492" +go +setboard rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - +solution Nf6+ +id "ECM.493" +go +setboard 6kr/1p1r1p1p/p2pnPpQ/3Np2R/2q1P3/5P2/PPP5/2KR4 w - - +solution Rxe5 +id "ECM.494" +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +solution Nd6 +id "ECM.495" +go +setboard r2q1rk1/pp1n2pp/2pb4/1P1p3n/P1PPpP2/4P2b/1BNNBP1P/R2QR1K1 b - - +solution Nxf4 +id "ECM.496" +go +setboard rq1r2k1/3nbp1p/p2p2p1/1p1Pp1P1/3B1P2/3B3Q/PPP4P/2KR2R1 w - - +solution f5 +id "ECM.497" +go +setboard r4rk1/1bq1bppp/8/p2pPR2/3B4/1NnP3Q/1P4PP/4R1K1 w - - +solution Rh5 +id "ECM.498" +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +solution Nxh5 +id "ECM.499" +go +setboard r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - +solution f3 +id "ECM.500" +go +setboard 4rqk1/p5b1/3p3p/3Pn1p1/1pP1NrP1/4NP2/P3Q1P1/1K1RR3 b - - +solution Nxf3 +id "ECM.501" +go +setboard r2qkr2/1p3pQp/2p1b3/1B1pN3/1p6/8/1P1K1PPP/2B1R3 w q - +solution Nxc6 +id "ECM.502" +go +setboard r3rk2/pb2bpp1/1n5p/q1pP1B2/1p3B2/5N2/PPQ2PPP/R2R2K1 w - - +solution Bc8 +id "ECM.503" +go +setboard r1bqr2k/ppp2p1p/5b2/3Pn1p1/1PP1Bp2/8/PB2N1PP/R2Q1RK1 w - - +solution Nxf4 +id "ECM.504" +go +setboard 1q4k1/p3rppp/3b1n2/8/5P2/4P3/PP1B3P/RNQ3K1 b - - +solution Bxf4 +id "ECM.505" +go +setboard r3k2r/1p1b1p2/p3p3/2b3p1/4N1n1/1B5P/PPP3P1/R1B2R1K b kq - +solution Bc6 +id "ECM.506" +go +setboard r3kb1r/npqbpp1p/p3n1p1/P3P3/6N1/3B1NB1/1PP3PP/R3QRK1 w kq - +solution Ng5 +id "ECM.507" +go +setboard 7k/p6p/4bppb/1N6/P2p1p2/1PrP2P1/2r1P2P/1R1Q2K1 b - - +solution f3 +id "ECM.508" +go +setboard 2kr4/pp1r1pp1/4n1p1/4R3/2Pp1qP1/3P2QP/5PB1/1R4K1 w - - +solution Rc5+ +id "ECM.509" +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +solution Rxe6 +id "ECM.510" +go +setboard r2qkn1r/pb2bp2/1pp1p3/5p1p/2BPN3/5NQ1/PPP2PPP/1K1RR3 w kq - +solution d5 +id "ECM.511" +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +solution Nxf5 +id "ECM.512" +go +setboard 3r3k/p4npp/1p2qpb1/4P3/5P2/P3N3/1B2QP1P/6RK w - - +solution exf6 +id "ECM.513" +go +setboard 6rk/1b2bp1p/ppq1p3/2p1Pp2/P1Br1P2/1PNR2P1/2P1QK1P/6R1 b - - +solution Rxf4+ +id "ECM.514" +go +setboard r3r1k1/p1q2pp1/b1pb3p/n7/B3n3/2P1BN2/PP1N1PPP/R2QK2R b KQ - +solution Nxc3 +id "ECM.515" +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +solution Bxf6 +id "ECM.516" +go +setboard r5n1/pppb1B2/2k1pb2/3p2B1/5P2/2N5/PPP3P1/2KR4 w - - +solution Nxd5 +id "ECM.517" +go +setboard 2b2q2/r2n2kp/1n1p1pp1/p1pP4/1pP1NPN1/1P1B4/P5PP/Q3R1K1 w - - +solution Nexf6 +id "ECM.518" +go +setboard 1k1r2r1/p1p3q1/2p2p2/3pn3/1P1b2bB/1QN5/P4PPP/1R2RBK1 b - - +solution Nf3+ +id "ECM.519" +go +setboard r3k2r/1bq1bp1p/p2p1np1/1p2p3/3NP3/P1N2QB1/1PP2PPP/3RR1K1 w kq - +solution Ndxb5 +id "ECM.520" +go +setboard r2q4/5p1P/2p1bR2/ppk1p1P1/3pB2Q/8/PPP5/6K1 w - - +solution g6 +id "ECM.521" +go +setboard r3kb1r/pp1b1pp1/4p3/2q3Qp/5B2/2PB4/P4PPP/R3R1K1 w kq - +solution Rxe6+ +id "ECM.522" +go +setboard 1rbr2k1/p4pp1/5b1p/2p1p3/3qPP2/1PNB2PP/PKP2Q2/5R1R b - - +solution c4 +id "ECM.523" +go +setboard r3r1k1/p6p/bp4p1/2bPN3/6n1/6P1/PB2RPB1/3R2K1 w - - +solution d6 +id "ECM.524" +go +setboard 2bk3r/3r2pp/p2nQ3/q2R2P1/1p6/8/PPP2P1P/1K3B1R b - - +solution Qxd5 +id "ECM.525" +go +setboard 3r1k2/1q1r1pp1/3p2bp/p2N4/8/2P1RQ1P/P4PP1/4R1K1 w - - +solution Nf6 +id "ECM.526" +go +setboard 3q3r/p2r1pkp/bp1N1np1/n2p4/5Q2/B1P5/P4PPP/R3R1K1 w - - +solution Nf5+ +id "ECM.527" +go +setboard r4Nk1/1p2pp1p/p1np2p1/3N4/P3PPn1/8/1bPKBqPP/R2Q1R2 b - - +solution Qd4+ +id "ECM.528" +go +setboard 1kb3rr/1p2n2q/1Np2p2/1p6/1P1N1P1p/8/2P1RQPP/R6K w - - +solution Nxb5 +id "ECM.529" +go +setboard r3r1k1/p3Rp1p/1qp1bQ2/8/1p1P4/3R4/PP3PPP/6K1 w - - +solution Rg3+ +id "ECM.530" +go +setboard rn4k1/pp2rpb1/2pNb1pp/4p3/P3Pq2/2P2N1P/1PB1QPP1/R3R1K1 w - - +solution Nf5 +id "ECM.531" +go +setboard 3r1rk1/pp3ppp/8/2p5/4PB1n/P1P2qPP/Q3RP1K/6R1 b - - +solution Qg2+ +id "ECM.532" +go +setboard r4rn1/ppp1q3/2bp2kp/6P1/3QpP2/2N5/PPP1B3/2KR3R w - - +solution f5+ +id "ECM.533" +go +setboard 3qr2r/1p1bppk1/3p2p1/p1nP1PQp/3N3R/1P4PP/P1P3BK/4R3 w - - +solution Ne6+ +id "ECM.534" +go +setboard 2rq1rk1/1b1nbpp1/1p5p/p2pNB2/3p1N2/4P3/PPQ2PPP/2RR2K1 w - - +solution Bh7+ +id "ECM.535" +go +setboard 8/5pkp/2pp2p1/4P3/1P2P3/2QBq2P/2PnNnPK/8 b - - +solution Nf1+ +id "ECM.536" +go +setboard r3r2k/pb2q1p1/1p2Nn1p/2b5/2B5/2P2P2/PPQ3PP/4RR1K w - - +solution Nf4 +id "ECM.537" +go +setboard r1b2nk1/ppq2ppp/8/1BP1p1NQ/5p2/8/PP3PPP/3R2K1 w - - +solution Rd7 +id "ECM.538" +go +setboard 6k1/5qp1/pN5p/3pRp2/3QnP2/2r4P/r5P1/6RK b - - +solution Qh5 +id "ECM.539" +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +solution Nf5+ +id "ECM.540" +go +setboard 6rk/p2b4/3p1Nqp/2pPpn2/P1P4p/5P1P/Q2B1NP1/6RK b - - +solution Ng3+ +id "ECM.541" +go +setboard r4r1k/pppb2pp/8/3q4/2N5/P1P2nQ1/BP2R2P/R6K b - - +solution Ne1+ +id "ECM.542" +go +setboard r5rk/1pp1n1pp/p1n1b1q1/3p1p2/7R/2QB1N2/PB3PPP/4R1K1 w - - +solution Rxe6 +id "ECM.543" +go +setboard 8/4Ppk1/6p1/1p6/1Pb1Q3/6pq/8/6K1 w - - +solution Qe5+ +id "ECM.544" +go +setboard 3R4/4Qpk1/4p1p1/7p/7K/5rP1/5P2/2q5 w - - +solution Qf8+ +id "ECM.545" +go +setboard 8/5pk1/p6p/2R5/3q2p1/6P1/2Q3PK/4r3 w - - +solution Rg5+ +id "ECM.546" +go +setboard 1Q4R1/8/P1b2p2/2p2k2/2P5/5p2/1r5P/4R1K1 b - - +solution f2+ +id "ECM.547" +go +setboard 5r1k/1q2R3/8/6Q1/8/8/6P1/7K b - - +solution Rf1+ +id "ECM.548" +go +setboard 8/4p3/8/3P3p/P2pK3/6P1/7b/3k4 w - - +solution d6 +id "ECM.549" +go +setboard 3Q4/k3K3/q7/2N1P3/1P6/5r2/8/8 b - - +solution Rf7+ +id "ECM.550" +go +setboard 3k4/p1p5/8/2p1p3/4P3/PpPP2K1/1P6/8 b - - +solution c4 +id "ECM.551" +go +setboard 6r1/5p1k/4p3/3pQp2/1p1P1P1q/1P3RR1/7r/5K2 w - - +solution Rxg8 +id "ECM.552" +go +setboard r1b2rk1/ppp2ppp/2n3q1/b2N2N1/2BP4/4p2P/PPP3P1/R2Q1RK1 w - - +solution Nxf7 +id "ECM.553" +go +setboard 1r4k1/3qb2p/pr1pppn1/2p2N2/2P2PQ1/1P4P1/P2R2BP/R5K1 w - - +solution Bd5 +id "ECM.554" +go +setboard r6r/pR1nqkpp/2p1p3/3p4/6Q1/2b4P/P1PP1PP1/2B1R1K1 w - - +solution Rxe6 +id "ECM.555" +go +setboard 1k1r3r/ppq2pnp/1npbb1p1/3p4/3P1NP1/2NBP2P/PPQ2P1B/1KR4R w - - +solution Nb5 +id "ECM.556" +go +setboard 5rk1/p1p1br2/1p1p2qp/4p3/2PPn1pP/3Q2P1/PPN1P1K1/2RR2B1 b - - +solution Bxh4 +id "ECM.557" +go +setboard r5r1/4q2k/p2p3p/5p2/4p3/P2QR3/1PP2PPP/4R1K1 w - - +solution Rxe4 +id "ECM.558" +go +setboard r1b2rk1/4bnpp/2p5/pp2q3/4N3/PQ2B1P1/1PP3BP/4RRK1 w - - +solution Ng5 +id "ECM.559" +go +setboard 2rr2k1/1p3p2/p2n2p1/P2PnNq1/3QP1p1/1RN5/6PP/5RK1 b - - +solution Nf3+ +id "ECM.560" +go +setboard r3k1r1/pb1qpp1p/1pnp1n1B/2p2R2/3PP3/2P3PN/P1P3BP/R2Q3K b q - +solution Nxe4 +id "ECM.561" +go +setboard 2r2rk1/pp2bppp/3q1n2/3nNRB1/3P4/1B5Q/PP4PP/3R2K1 w - - +solution Nxf7 +id "ECM.562" +go +setboard r1bq1rk1/1pp2ppn/1pnp3p/3N4/2B1PN2/3P4/PPP3PP/R2Q1RK1 w - - +solution Ng6 +id "ECM.563" +go +setboard r1b2rk1/pp3p1p/2pq2pn/2nNN3/2B1QP2/8/P1PP2PP/R1B1K2R w KQ - +solution Nxf7 +id "ECM.564" +go +setboard 1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - +solution Nxf7 +id "ECM.565" +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +solution Rxc5 +id "ECM.566" +go +setboard r1b3k1/2pq2pp/p4p2/1p1Nr3/2n2R2/1B6/PPQ2PPP/R5K1 w - - +solution Rxc4 +id "ECM.567" +go +setboard 2rq1rk1/3bbppp/p3pn2/1p1pN3/2nP1B2/P1NBP2Q/1P3PPP/2R2RK1 w - - +solution Nxd5 +id "ECM.568" +go +setboard 2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - +solution Nxc1 +id "ECM.569" +go +setboard 1r4nk/3b2bp/3p4/3P3p/2pNPq2/P1N2p1P/1P3Q2/1R4KR b - - +solution Rxb2 +id "ECM.570" +go +setboard 2r5/p3kpp1/P2p4/1P2pP1p/1P2PqnP/6R1/r2N2P1/3RQ1K1 b - - +solution Rxd2 +id "ECM.571" +go +setboard 2br2k1/1p2qppp/r1n1p3/pQ1nN3/P2P4/2B3P1/1P3PBP/2RR2K1 w - - +solution Qxa6 +id "ECM.572" +go +setboard 5rk1/3q2bp/3pb2r/1p1n1p2/3p1P2/P2B1QN1/1P1B2PP/2R1R1K1 w - - +solution Nxf5 +id "ECM.573" +go +setboard 4r1k1/1ppQr1p1/1p1p1pP1/3P3p/7P/1P3q2/P1P5/1KRR4 w - - +solution Re1 +id "ECM.574" +go +setboard 2Rr2k1/7p/4pqp1/p4p2/1p1P1Q1P/8/PP3PP1/6K1 w - - +solution Qe5 +id "ECM.575" +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +solution Rc1 +id "ECM.576" +go +setboard 5rk1/bp4p1/p2rp2p/8/8/2PN4/PP1R1PPP/3R2K1 b - - +solution e5 +id "ECM.577" +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +solution Bh3 +id "ECM.578" +go +setboard n1bq3k/pp4bp/6p1/5pP1/3p1P2/1B1P4/PB3Q1P/4R1K1 w - - +solution Bxd4 +id "ECM.579" +go +setboard r3r1k1/p2n4/3p1pp1/qnp3B1/1p2P1P1/1P3P2/PP2N2Q/1K1R1B2 w - - +solution Nf4 +id "ECM.580" +go +setboard 6k1/pb3ppp/1p2p3/4P3/5P2/P1r5/1q4PP/1B2Q1RK b - - +solution Rc1 +id "ECM.581" +go +setboard 2rq1kbR/4R1p1/3p3r/pp1P1Pp1/6P1/3B4/PPP1Q3/6K1 w - - +solution f6 +id "ECM.582" +go +setboard 2r5/5kb1/4ppp1/pp1qB3/2rP4/1RP2R1Q/P4PP1/6K1 b - - +solution Rh8 +id "ECM.583" +go +setboard 4k3/4Bp2/1p2nP1P/2p5/2K1b1B1/8/P7/8 w - - +solution Bf3 +id "ECM.584" +go +setboard 3rr1k1/ppp1qp1p/3b2p1/4np1P/1P1N1Pn1/P1P4R/1B1NB3/R2Q1K2 b - - +solution Nf3 +id "ECM.585" +go +setboard 1k1r3r/ppqb4/5Ppp/3p4/P2np3/3BR1Q1/2PB1PPP/R5K1 w - - +solution Rxe4 +id "ECM.586" +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +solution Nxc6 +id "ECM.587" +go +setboard 8/2R2pbk/6pp/1p2pq2/1P2Qn2/3P3P/3B1PP1/r3N1K1 b - - +solution Nxd3 +id "ECM.588" +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +solution h3 +id "ECM.589" +go +setboard r2b1rnk/1p4qp/p1p1b1p1/2PpNp2/PP1PnP1Q/3BB2R/4N1PP/R6K w - - +solution Qxh7+ +id "ECM.590" +go +setboard r1b2rk1/1p3pbp/2p3p1/p1q5/1P6/1Q4P1/1P2PPBP/R1B1R1K1 b - - +solution Be6 +id "ECM.591" +go +setboard 4r1k1/r1q2p1p/p5pB/1pbBpN1n/1n2P3/5Q2/PP3PPP/R1R3K1 w - - +solution Rxc5 +id "ECM.592" +go +setboard r1r3k1/ppnbb1pp/2ppp1q1/1P3p2/P1PPn3/2N2NP1/2Q1PPBP/1RB2RK1 w - - +solution Nxe4 +id "ECM.593" +go +setboard r1b1k2r/2q1bppp/p3p3/1p1nP1B1/3Q4/2N5/PPP1B1PP/2KR3R w kq - +solution Bxe7 +id "ECM.594" +go +setboard 1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - +solution Nxh2 +id "ECM.595" +go +setboard 2rqk1nr/pp3ppp/2n1p3/2b5/3N4/2NQB1P1/PP2PPKP/R4R2 w k - +solution Nxe6 +id "ECM.596" +go +setboard rnb2rk1/pp4pp/2pb1n2/3N1p1q/2P5/3N2P1/P1Q1PPBP/R1B2RK1 w - - +solution Bf4 +id "ECM.597" +go +setboard 8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - +solution f4 +id "ECM.598" +go +setboard 8/5pp1/7p/5P1P/2p3P1/2k5/5P2/2K5 w - - +solution f6 +id "ECM.599" +go +setboard 7k/8/1p1ppp1p/1Pp5/2P2P2/8/3P2PP/6K1 w - - +solution f5 +id "ECM.600" +go +setboard 8/p5k1/2p2p2/4p1p1/1p2P3/1P4PP/1PP5/5K2 b - - +solution g4 +id "ECM.601" +go +setboard 8/5K2/kp6/p1p5/P2p4/1P3P2/2P5/8 b - - +solution b5 +id "ECM.602" +go +setboard 8/2k3p1/2p4p/5P2/2K3PP/8/8/8 w - - +solution g5 +id "ECM.603" +go +setboard 8/1kp1b3/1p4K1/4P2p/P1P3p1/5pP1/P4P2/4B3 b - - +solution h4 +id "ECM.604" +go +setboard 8/8/4b1p1/2Bp3p/5P1P/1pK1Pk2/8/8 b - - +solution g5 +id "ECM.605" +go +setboard 8/8/3K1k2/5p1p/4p1p1/4P1P1/5PP1/8 b - - +solution f4 +id "ECM.606" +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +solution Bxg6 +id "ECM.607" +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +solution Rxc6 +id "ECM.608" +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +solution f6 +id "ECM.609" +go +setboard 2kr3r/ppp1qpp1/2p5/2b2b2/2P1pPP1/1P2P1p1/PBQPB3/RN2K1R1 b Q - +solution Rh1 +id "ECM.610" +go +setboard 1r3qk1/pb3p1p/1pn2PpQ/2pN4/3r4/5B2/PPP4P/4RRK1 w - - +solution Ne7+ +id "ECM.611" +go +setboard 4r1k1/5p1p/3q2p1/1p1P4/1P6/2p4P/2Q1nPB1/4RK2 b - - +solution Ng3+ +id "ECM.612" +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +solution e5 +id "ECM.613" +go +setboard 5r2/pp1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +id "ECM.614" +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +solution b5 +id "ECM.615" +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +solution Rxa6 +id "ECM.616" +go +setboard 3r2k1/p6p/b2r2p1/2qPQp2/2P2P2/8/6BP/R4R1K w - - +solution Rxa6 +id "ECM.617" +go +setboard 8/p3q1k1/6p1/1p3nP1/2pp1QBr/P2P4/1PP2K2/R7 b - - +solution Qe3+ +id "ECM.618" +go +setboard 7k/4b2p/5p1P/5PP1/1pNp1P2/1P1B4/2P2K2/r7 w - - +solution g6 +id "ECM.619" +go +setboard 5r1k/1p1b2rP/p2p4/3P3B/P2P4/5pP1/1P2pP2/R3R1K1 b - - +solution Rxg3+ +id "ECM.620" +go +setboard 6B1/2p2pp1/2p5/p3K3/1k6/nP4P1/5P1P/8 b - - +solution Nc4+ +id "ECM.621" +go +setboard 3q1k2/5p2/p5pN/1b2Q2P/8/8/5PPK/8 w - - +solution Qh8+ +id "ECM.622" +go +setboard 6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - +solution Rc4 +id "ECM.623" +go +setboard 4r2k/3n1Qpp/1pRP1p2/p4P2/1p1P2P1/6rP/P3q1B1/6RK w - - +solution Qe6 +id "ECM.624" +go +setboard 2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - +solution Nxe6 +id "ECM.625" +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +solution Ba6 +id "ECM.626" +go +setboard 3rr1k1/pppRn1pp/4Pp2/1P5q/1QB5/4P3/P4P1P/4K1R1 w - - +solution Qxe7 +id "ECM.627" +go +setboard rn1q2k1/pp3pb1/3p2pp/2pP2N1/3r1P2/7Q/PP4PP/R1B2RK1 w - - +solution Nxf7 +id "ECM.628" +go +setboard 8/6Bp/6p1/2k1p3/4PPP1/1pb4P/8/2K5 b - - +solution b2+ +id "ECM.629" +go +setboard 5bk1/r4ppp/1r1P1n2/2p2N2/b7/2B3P1/5PBP/R3R1K1 w - - +solution Bxf6 +id "ECM.630" +go +setboard 8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - +solution a6 +id "ECM.631" +go +setboard 3qr1k1/p4ppp/1p1P4/2r1nN2/4P2n/P7/1B4P1/3QRRK1 w - - +solution d7 +id "ECM.632" +go +setboard 6k1/5pbp/6p1/2p1r3/1pPr4/3n2NP/1PB2PP1/1R1R2K1 b - - +solution Nxb2 +id "ECM.633" +go +setboard 4r3/p4pk1/6p1/P1pB2Pp/2P3b1/2p1N1P1/Qb1r1P2/6K1 b - - +solution Rxe3 +id "ECM.634" +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +solution Nxa7 +id "ECM.635" +go +setboard r4rk1/ppq3pp/2p1Pn2/4p1Q1/8/2N5/PP4PP/2KR1R2 w - - +solution Rxf6 +id "ECM.636" +go +setboard r3qr1k/1b4pp/p2RQ3/Bp2p3/4p3/6P1/PPP2P1P/3R2K1 b - - +solution Qh5 +id "ECM.637" +go +setboard 8/6kP/6p1/1p1pP3/pP6/P1n2K2/2N5/8 w - - +solution e6 +id "ECM.638" +go +setboard 8/Pb6/8/8/7K/5k1p/6pB/8 b - - +solution g1=Q +id "ECM.639" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "ECM.640" +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +solution cxb6 +id "ECM.641" +go +setboard 6k1/p4pbp/Bp2p1p1/n2P4/q3P3/B1rQP3/P5PP/5RK1 w - - +solution dxe6 +id "ECM.642" +go +setboard 5r2/R4p2/5P1k/4PK2/1p6/8/8/8 w - - +solution Rxf7 +id "ECM.643" +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +solution f5 +id "ECM.644" +go +setboard 1r6/3r1Pk1/p2p1np1/5q2/1p3P2/1B5R/PPP4Q/1K1R4 w - - +solution Rh8 +id "ECM.645" +go +setboard 8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - +solution Bxb3 +id "ECM.646" +go +setboard 2r5/1r5k/1P3p2/PR2pP1p/4P2p/2p1BP2/1p2n3/4R2K b - - +solution Nd4 +id "ECM.647" +go +setboard 4r2k/p2qr1pp/1pp2p2/2p1nP1N/4R3/1P1P2RP/1PP2QP1/7K w - - +solution Rxg7 +id "ECM.648" +go +setboard 6k1/p4p2/5Ppp/3RP3/Pr4P1/2p2K2/7P/8 w - - +solution Rd8+ +id "ECM.649" +go +setboard 8/1R2P3/6k1/3B4/2P2P2/1p2r3/1Kb4p/8 w - - +solution Be6 +id "ECM.650" +go +setboard 2kr2r1/pp2bQ1p/2b1P3/2qN4/8/1B2p2P/PPP3P1/3R1R1K b - - +solution e2 +id "ECM.651" +go +setboard r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - +solution Bxh7+ +id "ECM.652" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Bb5 +id "ECM.653" +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +solution Bxh7+ +id "ECM.654" +go +setboard 6rk/3nrpbp/p1bq1npB/1p2p1N1/4P1PQ/P2B3R/1PP1N2P/5R1K w - - +solution Nxh7 +id "ECM.655" +go +setboard 1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - +solution Bxh7+ +id "ECM.656" +go +setboard 2k5/ppp3pp/8/NQ2n2q/2Pp1n2/R4bP1/1P3P1P/4R1K1 b - - +solution Qxh2+ +id "ECM.657" +go +setboard 5rrk/1p3qpp/p3pn2/2PpBp2/3P1P1Q/P1P1R2R/2b1B1PP/6K1 w - - +solution Qxh7+ +id "ECM.658" +go +setboard r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - +solution Bxh7+ +id "ECM.659" +go +setboard r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/1P3PPP/2R3K1 w - - +solution Bxh7+ +id "ECM.660" +go +setboard r5rk/1p1q1p1p/5pn1/p2p1N1Q/3P2P1/PP2R3/5P1P/5RK1 w - - +solution Qxh7+ +id "ECM.661" +go +setboard 2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - +solution Rxh7+ +id "ECM.662" +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +solution Rxh7 +id "ECM.663" +go +setboard 4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - +solution Bxh7+ +id "ECM.664" +go +setboard r1b2rk1/2q1bppp/p1n1p3/1p1np1P1/5P2/1NNBBQ2/PPP4P/R4RK1 w - - +solution Bxh7+ +id "ECM.665" +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +solution Nxh7 +id "ECM.666" +go +setboard r4rk1/pp2q1p1/4b2p/2ppb3/6n1/2P3N1/PPQBBPPP/R4RK1 b - - +solution Nxh2 +id "ECM.667" +go +setboard b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - +solution Bxh7+ +id "ECM.668" +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +solution Qxh7+ +id "ECM.669" +go +setboard r1b1rnk1/pp1nb1pp/2p1pp2/q3N3/2PP1P2/3BP1N1/PBQ3PP/R4RK1 w - - +solution Bxh7+ +id "ECM.670" +go +setboard 4r1k1/2q2r1p/p3bQ2/1p4Bp/2np4/8/PPB2PP1/3RR1K1 w - - +solution Bxh7+ +id "ECM.671" +go +setboard 5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - +solution Bxh7+ +id "ECM.672" +go +setboard 2rqr1k1/1p1bbppp/p3p3/n7/3P2Q1/2PB1N2/P4PPP/R1B1R1K1 w - - +solution Bxh7+ +id "ECM.673" +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +solution Nxh7 +id "ECM.674" +go +setboard rn1q1rk1/pb1p1ppp/4p3/2pnP3/1bp5/2N2N2/PP3PPP/RBBQK2R w KQ - +solution Bxh7+ +id "ECM.675" +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +solution Rxh7 +id "ECM.676" +go +setboard r1b2rk1/1pq2ppp/p1p1p3/2n1P3/2N2P2/3B4/PPP3PP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.677" +go +setboard rnq3rk/4bp1p/p1p3pQ/1p1pP3/1P1N1B2/2P3R1/1P3PPP/R5K1 w - - +solution e6 +id "ECM.678" +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +solution Nxh7 +id "ECM.679" +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +solution Bxh7+ +id "ECM.680" +go +setboard 1r2nrkb/2n2p1p/p2p1Pp1/P1pPp1P1/1pP1P1q1/1P1BB1N1/3Q4/2KR3R w - - +solution Rxh7 +id "ECM.681" +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +solution Bxh7+ +id "ECM.682" +go +setboard r2q3r/2pkb1p1/p2p1n2/4p1p1/Pp2P1P1/1QP5/1P1P2PP/RNB2RK1 b - - +solution Rxh2 +id "ECM.683" +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +solution Nxh7 +id "ECM.684" +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +solution Rxh7 +id "ECM.685" +go +setboard r2qn1k1/pb4Pp/1pn5/2p5/2P2p2/P1PB4/5PPP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.686" +go +setboard r4rk1/pp1n1ppp/3qp3/3nN1P1/b2P4/P2B1Q2/3B1P1P/1R2R1K1 w - - +solution Bxh7+ +id "ECM.687" +go +setboard r2r2k1/ppqbbppp/4pn2/6N1/n1P4P/3B1N2/PP2QPP1/1KBR3R w - - +solution Nxh7 +id "ECM.688" +go +setboard r5k1/6bp/2q1p1p1/p2pP3/3P4/1rP2QP1/3B1PK1/2R4R w - - +solution Rxh7 +id "ECM.689" +go +setboard r6r/4ppk1/p2p1bp1/B2p4/3P2p1/QP2P3/P1R1qPPP/2R3K1 b - - +solution Rxh2 +id "ECM.690" +go +setboard 4nrk1/r4p1p/p2p2pQ/2pPpNPP/qpn1P3/5P1R/PPP1N3/2K3R1 w - - +solution Qxh7+ +id "ECM.691" +go +setboard r3k2r/1b1n1p2/pq1p1bp1/1p4p1/P3P3/1NN5/1PP3PP/R2QRB1K b kq - +solution Rxh2+ +id "ECM.692" +go +setboard r2qrnk1/4bppp/b1p5/1p1p2P1/p2P1N1P/2NBP3/PPQ2P2/2K3RR w - - +solution Bxh7+ +id "ECM.693" +go +setboard rn1q1rk1/pppbb1pp/4p3/3pP1p1/3P3P/2NB4/PPP2PP1/R2QK2R w KQ - +solution Bxh7+ +id "ECM.694" +go +setboard 1r2nr1k/6pp/pp1p1p2/2pPnN2/q1P1PB2/5PR1/4K1P1/2Q4R w - - +solution Bxe5 +id "ECM.695" +go +setboard 3r1rk1/4qp1p/p1bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxh2+ +id "ECM.696" +go +setboard r2q1rk1/3n1ppp/8/1pbP2P1/p1N4P/PnBBPQ2/5P2/R3K2R w KQ - +solution Bxh7+ +id "ECM.697" +go +setboard 2k3r1/ppq2p1p/n1Pb1p2/8/6r1/4BN1b/PPQ2PPP/R3RBK1 b - - +solution Bxh2+ +id "ECM.698" +go +setboard 3qr1k1/1br2ppp/p2b4/8/PpNp4/3P4/1PP2PPP/R1BQ1RK1 b - - +solution Bxh2+ +id "ECM.699" +go +setboard 3r2k1/p1R2p2/4pQp1/1q5p/5P1P/1PR5/2Pr2P1/6K1 b - - +solution Rxg2+ +id "ECM.700" +go +setboard r1b4r/3p1kp1/pp3q1p/4RP2/8/B7/P5PP/4QRK1 w - - +solution Qe4 +id "ECM.701" +go +setboard 1r2rnk1/2R2bpp/p2q4/1p1N2R1/5P2/1Q1B3P/PP4P1/7K w - - +solution Rxg7+ +id "ECM.702" +go +setboard 3r2k1/pb5p/1p2qpp1/8/2p5/1P1nP3/P1N2PPP/1Q1R1R1K b - - +solution Bxg2+ +id "ECM.703" +go +setboard 4rrk1/2qb2pp/p5P1/1p2p3/1b2P3/2N5/PPPQ4/1K1R2R1 w - - +solution gxh7+ +id "ECM.704" +go +setboard 3q1k2/pp3ppn/2p1n2p/4pN1N/P3P2P/5Q2/1PP2PP1/6K1 w - - +solution Nhxg7 +id "ECM.705" +go +setboard 2r2r1k/3b1pb1/p3pp1p/q2p1P1B/8/2N2RR1/P1PQ2PP/7K w - - +solution Rxg7 +id "ECM.706" +go +setboard 5bk1/1p4p1/4N1R1/3p4/p1r2P1q/Pr1QP2P/1P6/1K4R1 w - - +solution Rxg7+ +id "ECM.707" +go +setboard 2r1r1k1/5ppp/p3pn2/1pb1N3/2P5/1PQ3R1/PB2qPPP/3R2K1 w - - +solution Rxg7+ +id "ECM.708" +go +setboard 7k/1bp1P1p1/3p2rp/1pb2p1q/5P2/1BP2N1P/1P4P1/R1B2R1K b - - +solution Rxg2 +id "ECM.709" +go +setboard r1q1bk1r/1p3pp1/4pn1p/p3Q3/P1P2N2/1B4R1/1P3PPP/4R1K1 w - - +solution Rxg7 +id "ECM.710" +go +setboard r4rk1/p2n2p1/1q1Qpn1p/1P6/P6B/2p5/2B1KP1P/R5R1 w - - +solution Rxg7+ +id "ECM.711" +go +setboard r2qr1k1/1p3ppp/2pb4/2Np4/1P1P2bn/3BP3/2QN1PPP/1RR3K1 b - - +solution Nxg2 +id "ECM.712" +go +setboard r3r1k1/pp3pp1/3p4/2q4p/2P5/1PB2Q1P/n4PP1/3R1RK1 w - - +solution Bxg7 +id "ECM.713" +go +setboard r5k1/pn1q1rpp/2pp4/5R1N/bP6/4BQ2/P4PPP/2R3K1 w - - +solution Nxg7 +id "ECM.714" +go +setboard 3r1rk1/5pp1/pq1n1n1p/2pPR3/2B2P2/1PBQ2RP/P5P1/6K1 w - - +solution Rxg7+ +id "ECM.715" +go +setboard rn3rk1/ppq2ppp/2pb1nb1/5N2/2BP4/8/PPP1N1P1/R1B1QR1K w - - +solution Nxg7 +id "ECM.716" +go +setboard r1qb1r1k/2p3pp/p1n1bp2/1p1Np2Q/P3P3/1BP3R1/1P3PPP/R1B3K1 w - - +solution Rxg7 +id "ECM.717" +go +setboard r4rk1/5ppp/p2pbb2/3B3Q/qp2p3/4B3/PPP2P1P/2KR2R1 w - - +solution Rxg7+ +id "ECM.718" +go +setboard 4q1k1/1b3r1p/p4pp1/1p6/2P2n2/1P3N2/1B3PPP/R2Q3K b - - +solution Nxg2 +id "ECM.719" +go +setboard r2r3k/5bp1/2p2N2/5P1p/3q3Q/3B2R1/n5PP/3R3K w - - +solution Rxg7 +id "ECM.720" +go +setboard 4rrk1/2pn2pb/p1p1qp2/1pb1pN2/P3P1PN/1P1P4/1BP2PK1/R2Q3R w - - +solution Nxg7 +id "ECM.721" +go +setboard r3r1k1/p3bppp/q1b2n2/5Q2/1p1B4/1BNR4/PPP3PP/2K2R2 w - - +solution Rg3 +id "ECM.722" +go +setboard r4rk1/1p1q1ppp/p1b4B/8/2R3R1/P2P4/1b1N1QPP/6K1 w - - +solution Bxg7 +id "ECM.723" +go +setboard rq3rk1/3b1ppp/p2bp3/3pB2Q/8/1B5P/PP3PP1/2RR2K1 w - - +solution Bxg7 +id "ECM.724" +go +setboard 4kbr1/pp1bpp1p/3p1p2/3N4/1PBQP3/q7/P1r2PPP/R4RK1 b - - +solution Rxg2+ +id "ECM.725" +go +setboard 2r3k1/1p2R1p1/p3n2p/2pq4/7P/1P1P2P1/PB1Q3K/8 w - - +solution Bxg7 +id "ECM.726" +go +setboard 2rr2k1/4bppp/p1n1p3/3q4/1p1P2N1/2P3R1/P3QPPP/2B2RK1 w - - +solution Nh6+ +id "ECM.727" +go +setboard rq1r1bk1/1b3pp1/3pn2p/1n2BN1P/1P2P3/3R1NP1/3Q1PB1/2R3K1 w - - +solution Bxg7 +id "ECM.728" +go +setboard r1b5/ppqn2bk/3R2pp/2p2p2/2P1rN2/4BN2/PPQ2PPP/4R1K1 w - - +solution Rxg6 +id "ECM.729" +go +setboard 3q1r2/1p1b1pk1/pn5p/3pN1pQ/3P3P/2r3B1/P4PP1/3RR1K1 w - - +solution Nxf7 +id "ECM.730" +go +setboard r1bqkbnr/pp2ppp1/2p4p/3n2N1/2BP4/5N2/PPP2PPP/R1BQK2R w KQkq - +solution Nxf7 +id "ECM.731" +go +setboard r2qr1k1/1ppb1p1p/p1np2p1/7Q/3PP2b/1B2N2P/PP3PP1/R1B2RK1 w - - +solution Bxf7+ +id "ECM.732" +go +setboard 2r3k1/pbq1np1p/1p1b1Bp1/8/6QP/2P2N2/B4PP1/4R1K1 w - - +solution Bxf7+ +id "ECM.733" +go +setboard r3r1k1/1bqn1ppp/1pp2p2/8/3P4/1B4N1/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.734" +go +setboard r3r1k1/pp3ppp/8/1Nbp3q/3NnBn1/2P5/PPQ2PPP/3R1RK1 b - - +solution Ngxf2 +id "ECM.735" +go +setboard r2r2k1/1b2qpp1/1p2n3/p1b1p2p/4P1n1/PP1B2PP/1B1NQP2/R3NRK1 b - - +solution Nxf2 +id "ECM.736" +go +setboard r2qr1k1/1b2bp1p/p3p1p1/1p2N1Bn/3P4/P6Q/1P3PPP/RB2R1K1 w - - +solution Nxf7 +id "ECM.737" +go +setboard r5k1/1pp3pp/1b1p1r2/pN1P1n2/P1P3nq/6N1/1P1B1PQP/4RRK1 b - - +solution Nxf2 +id "ECM.738" +go +setboard 2rqnk1r/pp2bpp1/2p1pn1p/2P1N2P/3P1BP1/3BQ3/PP6/2K2R1R w - - +solution Nxf7 +id "ECM.739" +go +setboard 2rq1rk1/1b2bppp/p1n5/1p1BN3/5B2/P7/1P3PPP/R2Q1RK1 w - - +solution Nd7 +id "ECM.740" +go +setboard 3r1qrk/p1p5/bbp3pp/4p3/4Pp1N/2Pn3P/PPQN1PPB/R4RK1 b - - +solution Nxf2 +id "ECM.741" +go +setboard r2qr1k1/pb2bp1p/1pn1p1pB/8/2BP4/P1P2N2/4QPPP/3R1RK1 w - - +solution d5 +id "ECM.742" +go +setboard r3r1k1/1bq1nppp/p1np4/1ppBpN2/4P3/2PP1N2/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.743" +go +setboard r5k1/p4ppp/3qpb2/1P2N3/1nBP4/1P5P/4QPP1/4R1K1 w - - +solution Nxf7 +id "ECM.744" +go +setboard r2qr1k1/1b1nbp1p/p3pp2/1p2N3/3P4/3B1N2/PP2QPPP/R2R2K1 w - - +solution Nxf7 +id "ECM.745" +go +setboard r3k2r/p1qb1p2/1p2p2p/3pPpN1/P1nP3Q/8/2P2PPP/R1B1R1K1 w kq - +solution Nxf7 +id "ECM.746" +go +setboard 3qNk2/5p1p/1r3p2/2p5/Q1pb4/3b2P1/P4PBP/4R1K1 b - - +solution Bxf2+ +id "ECM.747" +go +setboard 2r1r1k1/1pq1bp1p/p3pnp1/P2n2N1/7R/2P4P/1PB1QPP1/2B1R1K1 w - - +solution Nxf7 +id "ECM.748" +go +setboard r1bq2k1/pp1n1ppp/3b1n2/PQ1B3r/3N1P2/2N5/1PP3PP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.749" +go +setboard 2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - +solution Bxf7+ +id "ECM.750" +go +setboard r4rk1/ppRn1p2/6pb/2P1pq1p/3N4/P1QPn1Pb/1B1NPP1P/4R1KB b - - +solution Qxf2+ +id "ECM.751" +go +setboard r3kr2/1b2qp2/pp2p2N/4p2Q/8/2n5/P3B1PP/3R1R1K w q - +solution Nxf7 +id "ECM.752" +go +setboard b2r1rk1/pq2bpp1/1p2p2p/4N2n/2P2R2/1PB2N2/1P2QPPP/4R1K1 w - - +solution Rxf7 +id "ECM.753" +go +setboard rqb1k2r/1p1nbp1p/p4pp1/8/1PBN1P2/P1N1P3/7P/2RQ1RK1 w kq - +solution Bxf7+ +id "ECM.754" +go +setboard r2r2k1/4ppbp/5np1/p1q5/QnB1P3/5N2/1P3PPP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.755" +go +setboard 1r2q1k1/p3pp2/3p1bp1/2pP2N1/8/P5PB/2Q2PK1/1rBR4 w - - +solution Nxf7 +id "ECM.756" +go +setboard 2rqrbk1/pb1n1p1p/1p2pnp1/4N3/2BP1N2/1P2Q3/PB3PPP/3R1RK1 w - - +solution Nxf7 +id "ECM.757" +go +setboard 1r4k1/p4pp1/bqnrpn1p/2ppN3/2P2P1B/P3P3/1P2B1PP/1Q1R1RK1 w - - +solution Bxf6 +id "ECM.758" +go +setboard r1bqrbk1/5p1p/2pp2nB/pp5Q/4P3/PBNPR2P/1P4P1/R5K1 w - - +solution Bxf7+ +id "ECM.759" +go +setboard r1bqkb1r/1p3ppp/pn1P1n2/4p3/2B5/2N2N2/PP3PPP/R1BQ1RK1 w kq - +solution Bxf7+ +id "ECM.760" +go +setboard 2rqr1k1/pp2nppp/3p2b1/6B1/2BNn1Q1/P7/1PP2PPP/2KRR3 w - - +solution Bxf7+ +id "ECM.761" +go +setboard r3r1k1/pbq1ppbp/1pp2np1/4N3/3P4/2P5/PPB1QPPP/R1B1R1K1 w - - +solution Nxf7 +id "ECM.762" +go +setboard r1b2rk1/p6p/2p3Pb/3pp1q1/8/2PB4/PP3PP1/RN1Q1K1R b - - +solution Rxf2+ +id "ECM.763" +go +setboard r2rn3/1p3pk1/p1pNn1pp/q3P3/P7/1PN4P/2QR1PP1/3R2K1 w - - +solution Nxf7 +id "ECM.764" +go +setboard r1bqr1k1/1p1nnpb1/p5pp/2P1p1B1/B3N3/5N2/P4PPP/2RQR1K1 w - - +solution Nd6 +id "ECM.765" +go +setboard r1b1r1k1/pp2qpbp/2p3p1/2P5/3NnB2/7P/PPQ1PPB1/2RR2K1 b - - +solution Nxf2 +id "ECM.766" +go +setboard rn2r1k1/pp3p1p/3P2p1/2p1bbB1/2B5/2N5/Pq4PP/R2Q1RK1 w - - +solution Bxf7+ +id "ECM.767" +go +setboard 5rk1/r2qnppp/p1nN4/2Q5/3PB3/4P3/6PP/R4RK1 w - - +solution Nxf7 +id "ECM.768" +go +setboard 1bq2k2/1b1n1pp1/pp5p/2pBpN2/P3P2B/3Q1P2/1PP3PP/4K3 w - - +solution Bxf7 +id "ECM.769" +go +setboard rnb2rk1/pp3pbp/2p3pB/2q5/4P3/1BN5/PPP3PP/R2Q1R1K w - - +solution Rxf7 +id "ECM.770" +go +setboard 3qr1k1/1br1bp1p/p3p1pB/1p1nN3/3PB3/7Q/PP3PPP/3RR1K1 w - - +solution Nxf7 +id "ECM.771" +go +setboard 1qr1b1k1/4bpp1/pn2p2p/1p1nN3/3P4/P2BBN1Q/1P3PPP/4R1K1 w - - +solution Bxh6 +id "ECM.772" +go +setboard rr1q2k1/1p2bpp1/2p1p2p/P1Pn4/2NP4/3Q1RP1/5PKP/2B1R3 w - - +solution Bxh6 +id "ECM.773" +go +setboard r2r2k1/pb1nbpp1/1qp1pn1p/1p2N3/3P1B2/P1N1P3/BPQ2PPP/2R2RK1 w - - +solution Bxh6 +id "ECM.774" +go +setboard 2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - +solution Rxh6+ +id "ECM.775" +go +setboard r1b1r3/pp2Npbk/3pp2p/q5p1/2QNPP2/6P1/PPP3P1/2KR3R w - - +solution Ndf5 +id "ECM.776" +go +setboard r1q3r1/1ppQ2pk/3bNp1p/p3pP2/P3P3/7R/1PP3PP/3R2K1 w - - +solution Rxh6+ +id "ECM.777" +go +setboard 4r1k1/p1pq1pp1/2p5/3p1b2/Q7/2P1B2P/P1P1rPP1/2R2RK1 b - - +solution Bxh3 +id "ECM.778" +go +setboard 1rbqnr2/5p1k/p1np3p/1p1Np3/4P2P/1Q2B3/PPP1BP2/2KR3R w - - +solution Bxh6 +id "ECM.779" +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.780" +go +setboard 3r1r1k/p5p1/n1p2p1p/1qp2b2/N1R4R/1PB1P1P1/P2P3P/3Q2K1 w - - +solution Rxh6+ +id "ECM.781" +go +setboard r4rk1/2q1b1p1/p4p1p/n3pP2/1p2Q1N1/4B3/PPP3PP/4RR1K w - - +solution Nxh6+ +id "ECM.782" +go +setboard 6rk/3b1n1p/1p1q3b/1PpNp3/2P1Pp2/2Q2NrP/5RP1/2R2B1K b - - +solution Bxh3 +id "ECM.783" +go +setboard r2q1rk1/ppp2pp1/1b2b2p/3n3Q/2Bp4/3P1N2/PPP2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.784" +go +setboard r3rbk1/1bp1qpp1/p6p/np2p2Q/4P2N/1BP4P/PP3PP1/R1B1R1K1 w - - +solution Bg5 +id "ECM.785" +go +setboard 4q3/p2r1ppk/R6p/3n4/3B1Q2/4P2P/5PP1/6K1 w - - +solution Rxh6+ +id "ECM.786" +go +setboard 7r/1p2qk2/pQ1p2p1/3Ppp2/P4b2/2P2PrP/1P2R1B1/4R2K b - - +solution Rhxh3+ +id "ECM.787" +go +setboard 5rk1/Qp5p/3pp1p1/4n3/2P1P2q/5r1P/P3NPP1/3R1RK1 b - - +solution Rxh3 +id "ECM.788" +go +setboard 2r1r1k1/pb1n1pp1/1p1qpn1p/4N1B1/2PP4/3B4/P2Q1PPP/3RR1K1 w - - +solution Bxh6 +id "ECM.789" +go +setboard 3q1rk1/p2bbpp1/1rn4p/1pp2P2/3pBBP1/3P3P/PPPQ3N/R4RK1 w - - +solution Bxh6 +id "ECM.790" +go +setboard 2br2k1/4qppp/p5r1/2pBp3/2P1Pn2/4Q2P/RP3PPK/1N4R1 b - - +solution Bxh3 +id "ECM.791" +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +solution Bxh6 +id "ECM.792" +go +setboard r5r1/pbn4k/1p1p1Ppp/2pPn3/4BQq1/1PN3P1/PB3PK1/3R1R2 w - - +solution Qxh6+ +id "ECM.793" +go +setboard r1b2rk1/pp2bpp1/4p2p/2q4Q/5nNB/2PB4/PP3PPP/2KR3R w - - +solution Nxh6+ +id "ECM.794" +go +setboard 6k1/p4ppp/1pn1b1rr/8/PBpPp2q/2P1P1NP/5PP1/RR3QK1 b - - +solution Bxh3 +id "ECM.795" +go +setboard r1b2rk1/1p3pp1/p5Pp/2bpPp1Q/3N4/1Pq1B1R1/2P4P/3R2K1 w - - +solution Bxh6 +id "ECM.796" +go +setboard r2r2k1/pp1n1bp1/2p2p1p/b4N2/q2BR3/2QB2PP/1PP5/2KR4 w - - +solution Nxh6+ +id "ECM.797" +go +setboard 3r2bk/1q4p1/p2P1N1p/2p1rP2/pb5R/7P/1P4P1/2Q2RK1 w - - +solution Rxh6+ +id "ECM.798" +go +setboard 2b1rk2/r6p/1pP1p1p1/p2pNnR1/5Q2/P1B4q/1PP2P1P/1K4R1 w - - +solution Nxg6+ +id "ECM.799" +go +setboard 6R1/6Q1/3q2p1/5p1p/P3p1k1/1P1r2P1/5PK1/8 b - - +solution Rxg3+ +id "ECM.800" +go +setboard r6r/ppnqpk2/3pbpp1/5N2/1PP1P3/5RR1/P2QB1PP/6K1 w - - +solution Nh6+ +id "ECM.801" +go +setboard 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - +solution Rfxg6+ +id "ECM.802" +go +setboard 2b2r1k/2p3pp/2Nb4/pP5q/2PP4/P4pP1/5P1P/R1BQ2K1 b - - +solution Bxg3 +id "ECM.803" +go +setboard r1bq2k1/pp3r1p/2n1p1p1/3pP3/6Q1/2PB2P1/P4PK1/R1B4R w - - +solution Bxg6 +id "ECM.804" +go +setboard 3q1rk1/2r4p/n1p1n1pQ/p2pP3/Np1P2R1/5PN1/PP3KP1/2R5 w - - +solution Rxg6+ +id "ECM.805" +go +setboard 2Nq1rk1/6pp/b1p2b2/p6Q/np1p4/6P1/PB3PBP/R3R1K1 w - - +solution Be4 +id "ECM.806" +go +setboard r2r4/p4pk1/2p3p1/1p1nPR2/5p1Q/2N5/PPPq4/1K4R1 w - - +solution e6 +id "ECM.807" +go +setboard 2kr3r/pbq3p1/1p2pp2/2b4n/2P1B3/1P1N2Pp/PB2QP1P/R4RK1 b - - +solution Nxg3 +id "ECM.808" +go +setboard r5k1/1p2Rpb1/3p1np1/2nP2B1/1qP5/1pN1Q2P/P5P1/1B4K1 w - - +solution Bxg6 +id "ECM.809" +go +setboard 2rqr1k1/pb2bp1p/1pn1pnpB/4N3/3P4/P1N3R1/1P3PPP/RB1Q2K1 w - - +solution Rxg6+ +id "ECM.810" +go +setboard 2r5/pp2qr1k/1nb3pp/2ppBp2/2P4P/3B2R1/P3QPP1/1R4K1 w - - +solution Rxg6 +id "ECM.811" +go +setboard 3rr3/3q1p1k/p2P2pp/1bp1b3/5N2/6QP/P1B3P1/3RR1K1 w - - +solution Bxg6+ +id "ECM.812" +go +setboard r2q1rk1/pp2ppb1/3pn1pQ/3R4/2P3B1/4BR2/PP4PP/6K1 w - - +solution Qxg6 +id "ECM.813" +go +setboard 1n1b1rk1/r4p1p/p1p2qpQ/P3Np2/2BP4/2P1R3/5PPP/R5K1 w - - +solution Rb1 +id "ECM.814" +go +setboard 6rk/pb3p1p/3bpPq1/3P4/1p1B3r/1B4P1/PPRQ1R1P/6K1 b - - +solution Bxg3 +id "ECM.815" +go +setboard 3rr1k1/pb2bp1p/3qp1pB/1p2N3/3P2Q1/2P1R3/P4PPP/4R1K1 w - - +solution Nxg6 +id "ECM.816" +go +setboard r2q1rk1/pb1nbp1p/1p2p1p1/4N1BQ/2PP4/P7/5PPP/RB2R1K1 w - - +solution Nxg6 +id "ECM.817" +go +setboard 1Q4R1/r2qbp2/3p1kp1/3Bp2p/8/3PP1P1/5PKP/8 w - - +solution Rxg6+ +id "ECM.818" +go +setboard r3r1k1/b1p2pn1/p2q1Bp1/1p1bN1Qp/3P4/2P4P/PPB2PP1/R3R1K1 w - - +solution Nxg6 +id "ECM.819" +go +setboard 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - +solution Nxe6 +id "ECM.820" +go +setboard k2r3r/ppq2p1p/n1pb1Pp1/4p3/2Q5/1R2B1P1/PPP2PBP/R5K1 w - - +solution Rxb7 +id "ECM.821" +go +setboard 1rb2rk1/p1p1qppp/2p2n2/3P4/1b3P2/2NB4/PPPBQ1PP/2KR3R b - - +solution Ba3 +id "ECM.822" +go +setboard k7/pp1N4/4P3/5P2/8/5p2/1R6/B4Knq w - - +solution Nb6+ +id "ECM.823" +go +setboard 4rrk1/p5pp/1p4q1/3p2n1/2pP2P1/P1P1PP2/3B2K1/1R2QR2 b - - +solution Nxf3 +id "ECM.824" +go +setboard 1q1r3k/3P1pp1/ppBR1n1p/4Q2P/P4P2/8/5PK1/8 w - - +solution Rxf6 +id "ECM.825" +go +setboard 1rbq2k1/b1p3pp/p1Pp4/3Ppr2/8/5N2/PPQ2PPP/R1B2RK1 b - - +solution Rxf3 +id "ECM.826" +go +setboard 1r1q1r1k/2p3pp/1p1bQ3/p7/1PP5/Pn3B2/1B3PPP/R4RK1 b - - +solution Rxf3 +id "ECM.827" +go +setboard r4rk1/2p1qpp1/p1p5/2Ppn2b/2PQ1N1p/4P3/PB3PPP/R4RK1 b - - +solution Nf3+ +id "ECM.828" +go +setboard r1bq1rk1/1p2bppp/p3p3/n3P3/4N3/1P1P1N2/PB4PP/R3QR1K w - - +solution Nf6+ +id "ECM.829" +go +setboard 1n2r3/p1pq1kp1/1b1pNpp1/3P4/5RP1/3Q3P/1B3P2/6K1 w - - +solution Bxf6 +id "ECM.830" +go +setboard r1bq1rk1/ppp3p1/7p/3P2n1/2PQ1p2/1N5P/PPP2PPK/R1B2R2 b - - +solution Nf3+ +id "ECM.831" +go +setboard 3r1b2/p4bkp/1p1P1p2/r3p1p1/2q1N3/2N2P2/1P1R2PP/2QR3K w - - +solution Nxf6 +id "ECM.832" +go +setboard rqbn1rk1/1p3ppp/p3p3/8/4NP2/8/PPP1BQPP/1K1R3R w - - +solution Nf6+ +id "ECM.833" +go +setboard r1b1kb1r/1p4pp/p2ppn2/8/2qNP3/2N1B3/PPP3PP/R2Q1RK1 w kq - +solution Rxf6 +id "ECM.834" +go +setboard 1rn5/p3Bk1p/1pq1bpp1/P3p3/1Q2P2P/2P3P1/5PB1/1R4K1 w - - +solution Bxf6 +id "ECM.835" +go +setboard 2nr2k1/1pq1bppp/p1p5/2p1P1PQ/2P1NP2/1PNR4/P6P/6K1 w - - +solution Nf6+ +id "ECM.836" +go +setboard 6nk/pn2qr1r/1pbp1p1p/2p1pPpN/P1P1P1PP/2PP3R/7Q/2BBK2R w K - +solution Nxf6 +id "ECM.837" +go +setboard 7r/4p1k1/p3Pppp/1p6/3N1R2/3PQ2P/qr4b1/5RK1 w - - +solution Rxf6 +id "ECM.838" +go +setboard r3k2r/1bq1bp2/p3p1pp/1p2P3/3NpP2/4B1Q1/PPP3PP/1K1R3R w kq - +solution Nxe6 +id "ECM.839" +go +setboard rnbqkb1r/pp1n1p2/4p1p1/1N1pP2p/1P4Q1/3B1N2/P1PB1PPP/R3K2R w KQkq - +solution Qxe6+ +id "ECM.840" +go +setboard r1b1kb1r/1p1n1ppp/p2ppn2/6BB/2qNP3/2N5/PPP2PPP/R2Q1RK1 w kq - +solution Nxe6 +id "ECM.841" +go +setboard r1b1k1nr/3n1p1p/1qpBp1p1/pp2b3/4PN2/PBN2Q2/1PP2PPP/2KR3R w kq - +solution Nxe6 +id "ECM.842" +go +setboard 2r2rk1/1b3ppp/pq2p3/1pbn2N1/3B3P/1B4P1/P1P1QP2/2KRR3 w - - +solution Qh5 +id "ECM.843" +go +setboard r3k2r/pp1n1pb1/1qn1p1p1/2p3Pp/4R2P/2NP2QB/PPPB1P2/2K1R3 w kq - +solution Rxe6+ +id "ECM.844" +go +setboard r3k2r/1q3ppp/p3p3/2b1P3/p2N1Q2/P7/1PP3PP/3R1R1K w kq - +solution Nxe6 +id "ECM.845" +go +setboard 3qr1k1/rp3pbp/2p3p1/3p1b2/N1nP4/P2NP3/1PQ2PPP/1BRR2K1 b - - +solution Rxe3 +id "ECM.846" +go +setboard rnbqkb1r/1p1n1pp1/p3p2p/3pP3/3p1NQP/2N5/P1PB1PP1/R3KB1R w KQkq - +solution Nxe6 +id "ECM.847" +go +setboard 3r1b1R/3bkpp1/1p1np3/1BqpPPP1/PQ1N4/8/1PP5/1K6 w - - +solution f6+ +id "ECM.848" +go +setboard 4r1k1/pp2n2p/1r1n1bp1/q2p1pB1/3P3N/P1NQ1P1P/1PP3R1/1K5R b - - +solution Rxb2+ +id "ECM.849" +go +setboard 3r2k1/2p1bppp/4b3/p2pP3/qr1N1B1P/8/1PPQ2P1/1K1RR3 b - - +solution Rxb2+ +id "ECM.850" +go +setboard 1k1r3r/ppR2ppp/1q2b3/1N6/4Q3/8/PP3PPP/4R1K1 w - - +solution Rxb7+ +id "ECM.851" +go +setboard 1r3rk1/5pbp/p2Pp1p1/q1n3P1/2p2P1P/2N1Q2R/PP6/1BKR4 b - - +solution Rxb2 +id "ECM.852" +go +setboard rr4k1/5p1p/n2p1npQ/q1pP4/6P1/2N2P1N/PP1R3P/2K4R b - - +solution Rxb2 +id "ECM.853" +go +setboard 1k2bb1r/1p3p1p/p2qpP1p/3pN3/3P1Q2/2RB2P1/PP3P1P/6K1 w - - +solution Qc1 +id "ECM.854" +go +setboard 1r4k1/1r3p2/p1p1b1pQ/q3P3/P7/bPN1R1P1/2P4P/1K1R1B2 b - - +solution Bxb3 +id "ECM.855" +go +setboard 5rk1/5rp1/p2qb3/R2Np2Q/3bP2B/7P/P5PK/1R6 b - - +solution Rf1 +id "ECM.856" +go +setboard 6k1/5p2/R3p1p1/1pq1PpB1/4nP2/5Q1P/P2r2PK/8 w - - +solution Ra8+ +id "ECM.857" +go +setboard 3r1rk1/p3q1pp/2Rb4/3P4/8/1P2Qp2/PB3PPP/3R2K1 b - - +solution Bxh2+ +id "ECM.858" +go +setboard 1r6/5pk1/p1b2qpp/P1P1n3/1N6/Q5NP/5PP1/3R2K1 b - - +solution Bxg2 +id "ECM.859" +go +setboard 1r4k1/1q3pb1/r1b3p1/pp1Qp3/P3P3/1B2BP2/1PP3P1/1K1R3R w - - +solution Qd8+ +id "ECM.860" +go +setboard 2R5/p3q1kp/6p1/3p4/b2P2p1/Pr4N1/5Q2/3K3R w - - +solution Nf5+ +id "ECM.861" +go +setboard 3r4/kb6/pp6/4R1pr/PPpq4/2N3Q1/2P3PP/3R3K b - - +solution Rf8 +id "ECM.862" +go +setboard 4r1k1/5p1p/4q1p1/8/Q5n1/3B2P1/P4P1P/2R3K1 b - - +solution Nxf2 +id "ECM.863" +go +setboard 8/2q1np1k/6p1/1PPn3p/8/P2Q3P/6P1/2R4K b - - +solution Nf5 +id "ECM.864" +go +setboard r1bq1rk1/ppp1n1bn/3p2p1/3Pp1Pp/1PP1Pp1P/2NN1P2/P3B3/R1BQ1RK1 b - - +solution Nxg5 +id "ECM.865" +go +setboard 7R/1p1r4/2b2p2/2Pp1qk1/3P1bp1/3N4/2Q2PB1/6K1 w - - +solution Rg8+ +id "ECM.866" +go +setboard r6r/1pn1b1k1/2p1pq2/2Pp3p/p2P1Pp1/P2BP1P1/1P2QB2/3R2KR w - - +solution Rxh5 +id "ECM.867" +go +setboard 1r4k1/pp4pp/2n1b3/1Rq1p3/2P2r2/P1B2P2/2Q1B1PP/3R1K2 b - - +solution Rxf3+ +id "ECM.868" +go +setboard 7k/1p4p1/2p4r/5p2/p1QP1q2/2P2PR1/r4P1P/4R2K b - - +solution Rxh2+ +id "ECM.869" +go +setboard 1r3r2/6kp/3p1pp1/qnp1pP2/1p2P2N/3P4/PPPQ1P1P/1K1R2R1 w - - +solution fxg6 +id "ECM.870" +go +setboard 5rk1/1rP3pp/p4n2/3Pp3/1P2Pq2/2Q4P/P5P1/R3R1K1 b - - +solution Rxc7 +id "ECM.871" +go +setboard 2rq1rk1/5ppp/2b1pb2/np6/6N1/2NBB3/PP3PPP/R2Q2K1 w - - +solution Bb6 +id "ECM.872" +go +setboard 5r2/p2p2kp/3PnNp1/1qr1Pp2/2p5/P1R5/6PP/2Q1R1K1 w - - +solution Qh6+ +id "ECM.873" +go +setboard 2Qbq1k1/6p1/1p4Np/4p2P/3rP3/8/3p2PK/3R4 w - - +solution Rf1 +id "ECM.874" +go +setboard 2kr1br1/ppp2p1p/2n1p1q1/2Nn4/3P4/1Q2PB2/PP1B1P1P/2R1K2R b K - +solution Qg1+ +id "ECM.875" +go +setboard 2K5/6p1/kp2P3/1p6/1P6/2P1P2p/8/1r6 w - - +solution e7 +id "ECM.876" +go +setboard 2kr3r/1Rp1bpp1/p6q/Q3P3/2P5/3p1NP1/P3P2P/1R4K1 b - - +solution Qe3+ +id "ECM.877" +go +setboard 6k1/1R4pp/2p5/8/P1rNp3/6Pb/4PK2/8 w - - +solution a5 +id "ECM.878" +go +setboard r2r2k1/pp3ppp/2q5/2p5/2P1P1n1/P4P1b/1BQ1BP1P/R3R2K b - - +solution Rd2 +id "ECM.879" +go diff --git a/src/genetic/typhoon b/src/genetic/typhoon new file mode 100755 index 0000000..de5f56d Binary files /dev/null and b/src/genetic/typhoon differ diff --git a/src/hash.c b/src/hash.c new file mode 100755 index 0000000..4b0cc0a --- /dev/null +++ b/src/hash.c @@ -0,0 +1,971 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + hash.c + +Abstract: + + The main transposition table code. The table is a large range of + memory organized into lines (64 bytes). Each line contains four + entries that are 16 bytes each (index 0..3). + + After a search, data about the position's score and the depth we + searched to determine this score can be stored in the hash table. + When information is stored a hash replacement scheme is used to + overwrite one of the four entries on a line. + + Later, before embarking on a deep recursive search, we can check + the hash table to see if information relevant to this position + has been stored already (and can be reused). If so, we can avoid + repeating the same search and save time. + + A hash entry is 16 bytes long and looks like this: + + typedef struct _HASH_ENTRY + { + MOVE mv; // 0 1 2 3 + UCHAR uDepth; // 4 + UCHAR bvFlags; // 5 ==> d i r t | thr up low exact + signed short iValue; // 6 7 + UINT64 u64Sig; // 8 9 A B C D E F == 16 bytes + } HASH_ENTRY; + + The mv is the best move in a position. Even if we do not have a + deep enough uDepth recorded to cut off, mv is searched first. + uDepth is the depth searched to determine iValue. iValue is + either the exact score or a bound score -- depending on the + value of bvFlag's low order 4 bits. The high order 4 bits + in bvFlags holds "dirty" information to aide the hash replacement + scheme. Finally the u64Sig value is used to absolutely identify + the position to which the hash entry's information refers. + + When screwing around with the hash code, turn on PERF_COUNTERS and + watch the hash hit rate (and usable hash hit rate). Also here is + Fine position #70 which is a great sanity check for hash code: + + 8/k7/3p4/p2P1p2/P2P1P2/8/8/K7/ w - - 0 0 bm 1. Ka1-b1 Ka7-b7 2. Kb1-c1 + +Author: + + Scott Gasch (scott.gasch@gmail.com) 12 Jun 2004 + +Revision History: + + $Id: hash.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +// +// Hash entries are 16 bytes each and hash lines are 4 entries = 64 +// bytes. This is done on purpose so that a hash line fits in a cpu +// cache line. My Athlons have 64 byte cache lines. To adjust this +// for other processors, change the constant below. +// +#define CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(x) \ + ASSERT(IS_VALID_DEPTH(x)); \ + (x) >>= 4; \ + ASSERT(((x) & 0xffffff00) == 0); + +#define HASH_ENTRY_IS_DIRTY(x) \ + (((x).bvFlags & 0xF0) != g_cDirty) + +#undef ADJUST_MATE_IN_N + +#ifdef MP +// +// On MP builds we lock ranges of the hash table in order to mitigate +// against two searcher threads colliding on the same entry at once. +// I did not have a free bit to use in the hash entry so I lock every +// 256th hash table entry at once. +// +#define NUM_HASH_LOCKS 256 +volatile static ULONG g_uHashLocks[NUM_HASH_LOCKS]; +#define HASH_IS_LOCKED(x) ((g_uHashLocks[(x)]) != 0) +#define LOCK_HASH(x) \ + AcquireSpinLock(&(g_uHashLocks[(x)])); \ + ASSERT(HASH_IS_LOCKED(x)); +#define UNLOCK_HASH(x) \ + ASSERT(HASH_IS_LOCKED(x)); \ + ReleaseSpinLock(&(g_uHashLocks[(x)])); +#else // no MP +#define HASH_IS_LOCKED(x) +#define LOCK_HASH(x) +#define UNLOCK_HASH(x) +#endif + +ULONG g_uHashTableSizeEntries = 0; +ULONG g_uHashTableSizeBytes = 0; +HASH_ENTRY *g_pHashTable = NULL; +UCHAR g_cDirty = 0; + +void +DirtyHashTable(void) +/** + +Routine description: + + The dirty pattern is bitwise ored onto the bvFlags part of a + hash table entry. Since the low nibble is used to hold flags + like upper bound, lower bound, exact score, and threat the + dirty indicator is limited to operating in the upper nibble + of bvFlags (giving it a range of 16 values) + +Parameters: + + void + +Return value: + + void + +**/ +{ + ASSERT((g_cDirty & 0x0F) == 0); + g_cDirty += 0x10; + ASSERT((g_cDirty & 0x0F) == 0); +#ifdef TEST + if (g_Options.fShouldPost) + { + Trace("Hash table dirty char: 0x%02x\n", g_cDirty); + } +#endif +} + + +void +CleanupHashSystem(void) +/** + +Routine description: + + Cleanup the hash table by freeing the memory and zeroing some + variables. This is called before building an opening book in + order to free some virtual address space up. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (NULL != g_pHashTable) + { + ASSERT(g_uHashTableSizeBytes > 0); + SystemFreeMemory(g_pHashTable); + g_pHashTable = NULL; + g_uHashTableSizeBytes = 0; + g_uHashTableSizeEntries = 0; + } +} + +FLAG +InitializeHashSystem(void) +/** + +Routine description: + + Initialize the hash system... allocate the table and get everything + ready to go. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + ULONG uBytesToAlloc; + + if (!IS_A_POWER_OF_2(g_Options.uNumHashTableEntries)) + { + return(FALSE); + } + g_uHashTableSizeEntries = g_Options.uNumHashTableEntries; + if (g_uHashTableSizeEntries != 0) + { + ASSERT(g_pHashTable == NULL); + uBytesToAlloc = (sizeof(HASH_ENTRY) * g_uHashTableSizeEntries); + g_pHashTable = SystemAllocateMemory(uBytesToAlloc); + g_uHashTableSizeBytes = uBytesToAlloc; + ClearHashTable(); +#ifdef MP + memset((BYTE *)g_uHashLocks, 0, sizeof(g_uHashLocks)); +#endif + } + return(TRUE); +} + + +void +ClearHashTable (void) +/** + +Routine description: + + Zero out the entire hash table. This function is called when a new + position is loaded into the root board. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (NULL != g_pHashTable) + { + g_cDirty = 0; + ASSERT(0 != g_uHashTableSizeBytes); + ASSERT(0 != g_uHashTableSizeEntries); + memset(g_pHashTable, 0, g_uHashTableSizeBytes); + } +} + + +// +// (g_uHashTableSizeEntries) => 1000 0000 ... 0000 +// NUM_HASH_ENTRIES_PER_LINE => - 0100 +// ------------------------------------------------ +// 1111 1111 ... 1100 => Start of a hash line +// +#define KEY_TO_HASH_LINE_START(x) \ + ((x) & (g_uHashTableSizeEntries - NUM_HASH_ENTRIES_PER_LINE)) + +static HASH_ENTRY * +_SelectHashLine(UINT64 u64Key) +/** + +Routine description: + + On an MP system, this routine locks part of the hash table, the + caller should do its thing and then unlock the locked portion of + the hash table by calling _DeselectHashLine(u64Key). + +Parameters: + + UINT64 u64Key + +Return value: + + static HASH_ENTRY + +**/ +{ + ULONG uLow = (ULONG)(u64Key >> 32); + ULONG uLine = KEY_TO_HASH_LINE_START(uLow); +#ifdef MP + ULONG uLock = (uLine >> 2) & (NUM_HASH_LOCKS - 1); + LOCK_HASH(uLock); + ASSERT(IS_A_POWER_OF_2(NUM_HASH_LOCKS)); +#endif + ASSERT(g_uHashTableSizeBytes != 0); + ASSERT(g_uHashTableSizeEntries != 0); + ASSERT(g_pHashTable != NULL); + ASSERT(IS_A_POWER_OF_2(g_uHashTableSizeEntries)); + ASSERT(((g_uHashTableSizeEntries - NUM_HASH_ENTRIES_PER_LINE) & + (NUM_HASH_ENTRIES_PER_LINE - 1)) == 0); + return(&(g_pHashTable[uLine])); +} + +#ifdef MP +static void +_DeselectHashLine(UINT64 u64Key) +/** + +Routine description: + + This releases the lock taken by _SelectHashLine + +Parameters: + + UINT64 u64Key + +Return value: + + static void + +**/ +{ + ULONG uLow = (ULONG)(u64Key >> 32); + ULONG uLine = KEY_TO_HASH_LINE_START(uLow); + ULONG uLock = (uLine >> 2) & (NUM_HASH_LOCKS - 1); + + ASSERT(IS_A_POWER_OF_2(NUM_HASH_LOCKS)); + ASSERT(MP); + UNLOCK_HASH(uLock); +} +#endif + + +static HASH_ENTRY * +_SelectHashEntry(UINT64 u64Key, + ULONG uDepth, + ULONG uType, + SCORE iValue) +/** + +Routine description: + + This routine takes a lock. The caller should do its thing and then + release the lock by calling _DeselectHashEntry. + +Parameters: + + UINT64 u64Key, + ULONG uDepth + +Return value: + + static HASH_ENTRY + +**/ +{ + HASH_ENTRY *pEntry; + HASH_ENTRY *pStore; + + ASSERT(g_uHashTableSizeBytes != 0); + ASSERT(g_uHashTableSizeEntries != 0); + ASSERT(g_pHashTable != NULL); + ASSERT(IS_A_POWER_OF_2(g_uHashTableSizeEntries)); + + // + // _SelectHashLine takes a lock on MP builds. + // + pEntry = _SelectHashLine(u64Key); + ASSERT(pEntry != NULL); +#ifdef DEBUG + pStore = NULL; +#endif + + // + // Note: Hash lines consist of four entries currently: + // + // 1. The first is a depth-priority hash entry (store here if you + // can beat the depth of what's already in there). + // + // 2. The second is an always-store hash entry (store here if you + // can't store in the depth-priority entry). + // + // 3. and 4. The last two entries are where we bump the data from + // the depth- priority table and always-store table when they are + // going to be overwritten by newer data. + // + + // + // Replace the 0th entry on the line if: + // + // ...the new entry has greater depth + // ...the current entry is stale (from an old search) + // + if ((pEntry[0].uDepth <= uDepth) || + HASH_ENTRY_IS_DIRTY(pEntry[0])) + { + // + // Do we need to back up the entry we will overwrite? + // + if ((pEntry[0].u64Sig != u64Key) || + ((pEntry[0].bvFlags & HASH_FLAG_VALID_BOUNDS) != uType)) + { + pEntry[2] = pEntry[0]; + } + pStore = &(pEntry[0]); + goto end; + } + + // + // We could not replace the depth priority 0th entry; instead, + // replace the "always replace" 1st entry on the line unless it + // contains mate information and is not stale. + // + if (((abs(pEntry[1].iValue >= +NMATE)) && + (abs(iValue) < +NMATE)) && + (!HASH_ENTRY_IS_DIRTY(pEntry[1]))) + { + pStore = &(pEntry[3]); + goto end; + } + if ((pEntry[1].u64Sig != u64Key) || + ((pEntry[1].bvFlags & HASH_FLAG_VALID_BOUNDS) != uType)) + { + pEntry[3] = pEntry[1]; + } + pStore = &(pEntry[1]); + + end: + ASSERT(pStore != NULL); + return(pStore); +} + + +#ifdef MP +static void +_DeselectHashEntry(UINT64 u64Key) +/** + +Routine description: + + Releases the lock taken by _SelectHashEntry. + +Parameters: + + UINT64 u64Key + +Return value: + + static void + +**/ +{ + _DeselectHashLine(u64Key); // this releases a lock +} +#endif + + +void +StoreUpperBound(//MOVE mvBest, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat) +/** + +Routine description: + + Store an upper bound in the hash table. + +Parameters: + + MOVE mvBest : singular move from the node, if any + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat + +Return value: + + void + +**/ +{ + UINT64 u64Key; + HASH_ENTRY *pHash; + + ASSERT(IS_VALID_SCORE(iValue)); + ASSERT(IS_VALID_DEPTH(uDepth)); + + // + // It does not make sense to store hash positions that are worth + // at best ~INFINITY. Every position is and this is a waste of + // hash space. Ignore these. + // + if (iValue >= +NMATE) return; + if (NULL == g_pHashTable) return; + + CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(uDepth); + u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig; + + // + // _SelectHashEntry takes a lock on MP builds + // + pHash = _SelectHashEntry(u64Key, uDepth, HASH_FLAG_UPPER, iValue); + ASSERT(pHash != NULL); + pHash->uDepth = (UCHAR)uDepth; + if (pHash->u64Sig != u64Key) + { + // + // Note: don't overwrite a good hash move with "none" if we + // are replacing a hash entry for the same position. Also + // if we are klobbering data about the same position save + // a memory write to update the (same) sig. + // + pHash->mv.uMove = 0; + pHash->u64Sig = u64Key; + } + ASSERT((g_cDirty & HASH_FLAG_UPPER) == 0); + pHash->bvFlags = g_cDirty | HASH_FLAG_UPPER; + ASSERT((pHash->bvFlags & 0xF0) == g_cDirty); + if (TRUE == fThreat) + { + ASSERT((pHash->bvFlags & HASH_FLAG_THREAT) == 0); + pHash->bvFlags |= HASH_FLAG_THREAT; + } + + if (iValue <= -NMATE) + { + // + // If this is an upper bound near -INFINITY + // (i.e. ~-INFINITY at best) convert it into -NMATE at + // best (at best mate in N). + // + pHash->iValue = -NMATE; + } + else + { + // + // Otherwise hash the exact value. + // + ASSERT(iValue > -NMATE); + ASSERT(iValue < +NMATE); + pHash->iValue = (signed short)iValue; + } +#ifdef MP + // + // Release the lock on MP builds + // + _DeselectHashEntry(u64Key); +#endif +} + + +void +StoreExactScore(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat, + ULONG uPly) +/** + +Routine description: + + Store a best move and its exact score in the hash table. + +Parameters: + + MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat, + ULONG uPly + +Return value: + + void + +**/ +{ + HASH_ENTRY *pHash; + UINT64 u64Key; + + ASSERT(IS_VALID_SCORE(iValue)); + ASSERT(IS_VALID_DEPTH(uDepth)); + if (NULL == g_pHashTable) return; + + CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(uDepth); + u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig; + + // + // _SelectHashEntry takes a lock on MP builds. + // + pHash = _SelectHashEntry(u64Key, uDepth, HASH_FLAG_EXACT, iValue); + ASSERT(pHash != NULL); + + // + // Populate the hash entry + // + pHash->uDepth = (UCHAR)uDepth; + ASSERT(mvBestMove.uMove); + pHash->mv.uMove = mvBestMove.uMove; + ASSERT((g_cDirty & HASH_FLAG_EXACT) == 0); + pHash->bvFlags = g_cDirty | HASH_FLAG_EXACT; + ASSERT((pHash->bvFlags & 0xF0) == g_cDirty); + if (TRUE == fThreat) + { + ASSERT((pHash->bvFlags & HASH_FLAG_THREAT) == 0); + pHash->bvFlags |= HASH_FLAG_THREAT; + } + pHash->u64Sig = u64Key; + + if (iValue >= +NMATE) + { +#ifdef ADJUST_MATE_IN_N + ASSERT((iValue + (int)uPly) < +INFINITY); + ASSERT((iValue + (int)uPly) > -INFINITY); + pHash->iValue = (signed short)(iValue + (int)uPly); +#else + pHash->bvFlags = g_cDirty | HASH_FLAG_LOWER; + ASSERT((pHash->bvFlags & 0xF0) == g_cDirty); + pHash->iValue = +NMATE; +#endif + } + else if (iValue <= -NMATE) + { +#ifdef ADJUST_MATE_IN_N + ASSERT((iValue + (int)uPly) < +INFINITY); + ASSERT((iValue - (int)uPly) > -INFINITY); + pHash->iValue = (signed short)(iValue - (int)uPly); +#else + pHash->bvFlags = g_cDirty | HASH_FLAG_UPPER; + ASSERT((pHash->bvFlags & 0xF0) == g_cDirty); + pHash->iValue = +NMATE; +#endif + } + else + { + ASSERT(iValue > -NMATE); + ASSERT(iValue < +NMATE); + pHash->iValue = (short signed)iValue; + } +#ifdef MP + // + // Release the lock on MP builds + // + _DeselectHashEntry(u64Key); // Release the lock +#endif +} + + +void +StoreLowerBound(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat) +/** + +Routine description: + + Store a lower bound score and move in the hash table. + +Parameters: + + MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat + +Return value: + + void + +**/ +{ + HASH_ENTRY *pHash; + UINT64 u64Key; + + ASSERT(IS_VALID_SCORE(iValue)); + ASSERT(IS_VALID_DEPTH(uDepth)); + + // + // Do not bother to hash this node if it is telling us that the + // value of this position is worth at least ~-INFINITY. This is + // useless information and a waste of hash space. + // + if (iValue <= -NMATE) return; + if (NULL == g_pHashTable) return; + + CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(uDepth); + u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig; + + // + // _SelectHashEntry takes a lock on MP builds + // + pHash = _SelectHashEntry(u64Key, uDepth, HASH_FLAG_LOWER, iValue); + ASSERT(pHash != NULL); + + // + // Populate the entry + // + pHash->uDepth = (UCHAR)uDepth; + if ((mvBestMove.uMove) || (pHash->u64Sig != u64Key)) + { + // + // Note: only overwrite the existing hash move if either we + // have a move (i.e. not null move) or the entry we are + // overwriting is for a different position. + // + pHash->mv.uMove = mvBestMove.uMove; + } + pHash->u64Sig = u64Key; + ASSERT((g_cDirty & HASH_FLAG_LOWER) == 0); + pHash->bvFlags = g_cDirty | HASH_FLAG_LOWER; + ASSERT((pHash->bvFlags & 0xF0) == g_cDirty); + pHash->bvFlags |= (HASH_FLAG_THREAT * (fThreat == TRUE)); + if (iValue < +NMATE) + { + ASSERT(iValue < +NMATE); + ASSERT(iValue > -NMATE); + pHash->iValue = (signed short)iValue; + } + else + { + // + // If the value is greater than mate in N don't store how many + // moves N is because this depends on where in the search we + // have found this position. Just say that this position is + // worth at least mate in N. + // + pHash->iValue = +NMATE; + } +#ifdef MP + // + // Release the lock on MP builds + // + _DeselectHashEntry(u64Key); +#endif +} + + +MOVE +GetPonderMove(POSITION *pos) +/** + +Routine description: + + Get a move to ponder. + +Parameters: + + POSITION *pos + +Return value: + + MOVE + +**/ +{ + HASH_ENTRY *pHash; + ULONG x; + UINT64 u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig; + MOVE mv; + + mv.uMove = 0; + if (NULL == g_pHashTable) return(mv); + + // + // _SelectHashLine takes a lock on MP builds + // + pHash = _SelectHashLine(u64Key); + for (x = 0; + x < NUM_HASH_ENTRIES_PER_LINE; + x++) + { + if (u64Key == pHash->u64Sig) + { + mv = pHash->mv; + if ((pHash->bvFlags & HASH_FLAG_VALID_BOUNDS) == + HASH_FLAG_EXACT) + { + goto end; + } + } + } + + end: +#ifdef MP + // + // Release the lock. + // + _DeselectHashLine(u64Key); +#endif + return(mv); +} + + +HASH_ENTRY * +HashLookup(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + ULONG uNextDepth, + SCORE iAlpha, + SCORE iBeta, + FLAG *pfThreat, + FLAG *pfAvoidNull, + MOVE *pHashMove, + SCORE *piScore) +/** + +Routine description: + + Lookup any information we have about the current position in the + hash table. Cutoff if we can. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + ULONG uNextDepth, + SCORE iAlpha, + SCORE iBeta, + FLAG *pfThreat, + FLAG *pfAvoidNull, + MOVE *pHashMove, + SCORE *piScore + +Return value: + + HASH_ENTRY + +**/ +{ + HASH_ENTRY *pHash; + ULONG x; + POSITION *pos = &(ctx->sPosition); + UINT64 u64Key = pos->u64NonPawnSig ^ pos->u64PawnSig; + ULONG uMoveScore = 0; + ULONG uThisScore; + +#define COMPUTE_MOVE_SCORE(mv, depth) \ + ((depth) * 8 + PIECE_VALUE_OVER_100((mv).pCaptured) + 1) + + ASSERT(IS_VALID_DEPTH(uDepth)); + ASSERT(IS_VALID_DEPTH(uNextDepth)); + ASSERT(uNextDepth <= uDepth); + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(pHashMove->uMove == 0); + ASSERT(NULL != g_pHashTable); + INC(ctx->sCounters.hash.u64Probes); + + // + // These are out parameters for the caller, initialize them + // saying we don't know anything. + // + *pfAvoidNull = FALSE; + *pfThreat = FALSE; + + CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(uDepth); + CONVERT_SEARCH_DEPTH_TO_HASH_DEPTH(uNextDepth); + + // + // _SelectHashLine takes a lock on MP builds. + // + pHash = _SelectHashLine(u64Key); + for (x = 0; + x < NUM_HASH_ENTRIES_PER_LINE; + x++) + { + if (u64Key == pHash->u64Sig) + { + // + // This entry hit, make it "clean" so it is harder to replace + // later on. + // + pHash->bvFlags &= 0x0F; + ASSERT((g_cDirty & 0x0F) == 0); + pHash->bvFlags |= g_cDirty; + ASSERT((pHash->bvFlags & 0xF0) == g_cDirty); + + // + // Parse the matching entry + // + *pfThreat |= ((pHash->bvFlags & HASH_FLAG_THREAT) > 0); + + // + // If we have an exact match and sufficient depth to + // satisfy the depth to which we will later search after a + // nullmove, see if the known value of this node is less + // than beta. If so, doing nothing in this position will + // probably not be better than doing something therefore + // its not wise to perform the nullmove search. It's just + // a waste of nodes and time. + // + if ((pHash->uDepth >= uNextDepth) && + ((pHash->bvFlags & HASH_FLAG_UPPER) || + (pHash->bvFlags & HASH_FLAG_EXACT)) && + (pHash->iValue < iBeta)) + { + *pfAvoidNull = TRUE; + } + + // Because we can encounter several moves while looking for + // a hash cutoff, have a semantic about which one we return + // to the search. + INC(ctx->sCounters.hash.u64OverallHits); + if (pHash->mv.uMove) { + uThisScore = COMPUTE_MOVE_SCORE(pHash->mv, uDepth); + ASSERT(uThisScore != 0); + if (uThisScore > uMoveScore) { + uMoveScore = uThisScore; + *pHashMove = pHash->mv; + ASSERT(SanityCheckMove(pos, pHash->mv)); + } + } + + // + // We have a hit, but is it useful? + // + if (pHash->uDepth >= uDepth) + { + switch (pHash->bvFlags & HASH_FLAG_VALID_BOUNDS) + { + case HASH_FLAG_EXACT: + *piScore = pHash->iValue; + INC(ctx->sCounters.hash.u64UsefulHits); + INC(ctx->sCounters.hash.u64ExactScoreHits); +#ifdef ADJUST_MATE_IN_N + // + // Readjust mate in N scores. + // + if (pHash->iValue >= +NMATE) + { + *piScore -= (int)uPly; + } + else if (pHash->iValue <= -NMATE) + { + *piScore += (int)uPly; + } +#endif + ASSERT(IS_VALID_SCORE(*piScore)); + goto end; + break; + + case HASH_FLAG_LOWER: + if (pHash->iValue >= iBeta) + { + INC(ctx->sCounters.hash.u64UsefulHits); + INC(ctx->sCounters.hash.u64LowerBoundHits); + *piScore = pHash->iValue; + ASSERT(IS_VALID_SCORE(*piScore)); + goto end; + } + break; + + case HASH_FLAG_UPPER: + if (pHash->iValue <= iAlpha) + { + INC(ctx->sCounters.hash.u64UsefulHits); + INC(ctx->sCounters.hash.u64UpperBoundHits); + *piScore = pHash->iValue; + ASSERT(IS_VALID_SCORE(*piScore)); + goto end; + } + break; +#ifdef DEBUG + default: + ASSERT(FALSE); + break; +#endif + } + } + } + pHash++; + } + pHash = NULL; + + end: +#ifdef MP + // + // Release the lock. + // + _DeselectHashLine(u64Key); +#endif + return(pHash); +} diff --git a/src/ics.c b/src/ics.c new file mode 100755 index 0000000..5a8d2cd --- /dev/null +++ b/src/ics.c @@ -0,0 +1,272 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + ics.c + +Abstract: + + Routines to convert internal move structs into ICS (d2d4 style) + move strings and vice versa. + + See also san.c. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 16 May 2004 + +Revision History: + + $Id: ics.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + + +CHAR * +MoveToIcs(MOVE mv) +/** + +Routine description: + + Convert a MOVE into an ICS ("d2d4" style) string. Note: not + thread safe. + +Parameters: + + MOVE mv : the move to convert + +Return value: + + CHAR * + +**/ +{ + static char szTextMove[10]; + char *p = szTextMove; + + if (0 == mv.uMove) + { + return(NULL); + } + memset(szTextMove, 0, sizeof(szTextMove)); + + ASSERT(IS_ON_BOARD(mv.cFrom)); + ASSERT(IS_ON_BOARD(mv.cTo)); + *p++ = FILE(mv.cFrom) + 'a'; + *p++ = RANK(mv.cFrom) + '0'; + *p++ = FILE(mv.cTo) + 'a'; + *p++ = RANK(mv.cTo) + '0'; + + if (mv.pPromoted) + { + if (IS_QUEEN(mv.pPromoted)) + { + *p++ = 'Q'; + } + else if (IS_ROOK(mv.pPromoted)) + { + *p++ = 'R'; + } + else if (IS_BISHOP(mv.pPromoted)) + { + *p++ = 'B'; + } + else if (IS_KNIGHT(mv.pPromoted)) + { + *p++ = 'N'; + } + else + { + ASSERT(FALSE); + return(NULL); + } + } + *p = 0; + return(szTextMove); +} + + +MOVE +ParseMoveIcs(CHAR *szInput, POSITION *pos) +/** + +Routine description: + + Parse a move in ICS format (i.e. "d2d4") and create a MOVE struct. + +Parameters: + + CHAR *szInput, + POSITION *pos + +Return value: + + MOVE + +**/ +{ + MOVE mv; + COOR cFrom, cTo; + PIECE pMoved, pCaptured, pProm; + CHAR *szMoveText = StripMove(szInput); + static CHAR *szPieces = "nbrq"; + CHAR *p; + + mv.uMove = 0; + if (InCheck(pos, pos->uToMove)) + { + mv.bvFlags |= MOVE_FLAG_ESCAPING_CHECK; + } + + cFrom = FILE_RANK_TO_COOR((tolower(szMoveText[0]) - 'a'), + (tolower(szMoveText[1]) - '0')); + cTo = FILE_RANK_TO_COOR((tolower(szMoveText[2]) - 'a'), + (tolower(szMoveText[3]) - '0')); + + // + // check for castling moves in o-o style notation. + // + if ((!STRCMPI(szMoveText, "OO")) || + (!STRCMPI(szMoveText, "00")) || + (((E1 == cFrom) && (G1 == cTo)) && + (pos->rgSquare[E1].pPiece == WHITE_KING)) || + (((E8 == cFrom) && (G8 == cTo)) && + (pos->rgSquare[E8].pPiece == BLACK_KING))) + { + if (pos->uToMove == WHITE) + { + if (pos->bvCastleInfo & CASTLE_WHITE_SHORT) + { + ASSERT(pos->rgSquare[E1].pPiece == WHITE_KING); + mv.uMove = + MAKE_MOVE(E1, G1, WHITE_KING, 0, 0, MOVE_FLAG_SPECIAL); + } + } + else // black to move + { + if (pos->bvCastleInfo & CASTLE_BLACK_SHORT) + { + ASSERT(pos->rgSquare[E8].pPiece == BLACK_KING); + mv.uMove = + MAKE_MOVE(E8, G8, BLACK_KING, 0, 0, MOVE_FLAG_SPECIAL); + } + } + goto done; + } + else if ((!STRCMPI(szMoveText, "OOO")) || + (!STRCMPI(szMoveText, "000")) || + (((E1 == cFrom) && (C1 == cTo)) && + (pos->rgSquare[E1].pPiece == WHITE_KING)) || + (((E8 == cFrom) && (C8 == cTo)) && + (pos->rgSquare[E8].pPiece == BLACK_KING))) + { + if (pos->uToMove == WHITE) + { + if (pos->bvCastleInfo & CASTLE_WHITE_LONG) + { + ASSERT(pos->rgSquare[E1].pPiece == WHITE_KING); + mv.uMove = + MAKE_MOVE(E1, C1, WHITE_KING, 0, 0, MOVE_FLAG_SPECIAL); + } + } + else // black to move + { + if (pos->bvCastleInfo & CASTLE_BLACK_LONG) + { + ASSERT(pos->rgSquare[E8].pPiece == BLACK_KING); + mv.uMove = + MAKE_MOVE(E8, C8, BLACK_KING, 0, 0, MOVE_FLAG_SPECIAL); + } + } + goto done; + } + + if ((!IS_ON_BOARD(cFrom)) || + (!IS_ON_BOARD(cTo))) + { + goto illegal; + } + + pMoved = pos->rgSquare[cFrom].pPiece; + if ((IS_EMPTY(pMoved)) || (GET_COLOR(pMoved) != pos->uToMove)) + { + goto illegal; + } + + pCaptured = pos->rgSquare[cTo].pPiece; + if ((pCaptured != 0) && (GET_COLOR(pCaptured) == pos->uToMove)) + { + goto illegal; + } + + mv.cFrom = cFrom; + mv.cTo = cTo; + mv.pMoved = pMoved; + mv.pCaptured = pCaptured; + + if (IS_PAWN(pMoved)) + { + // + // Promotion + // + if ((szMoveText[4] != 0) && (szMoveText[4] != '\n')) + { + if (IS_PAWN(mv.pMoved)) + { + if (((BLACK == GET_COLOR(mv.pMoved)) && (RANK(cTo) != 1)) || + ((WHITE == GET_COLOR(mv.pMoved)) && (RANK(cTo) != 8))) + { + goto illegal; + } + } + p = strchr(szPieces, tolower(szMoveText[4])); + if (NULL == p) + { + goto illegal; + } + pProm = (PIECE)((BYTE *)p - (BYTE *)szPieces); + pProm += 2; + pProm <<= 1; + pProm |= pos->uToMove; + mv.pPromoted = pProm; + mv.bvFlags = MOVE_FLAG_SPECIAL; + } + + // + // Handle en passant captures. + // + if (cTo == pos->cEpSquare) + { + mv.bvFlags = MOVE_FLAG_SPECIAL; + if (WHITE == pos->uToMove) + { + mv.pCaptured = pos->rgSquare[cTo + 0x10].pPiece; + ASSERT(mv.pCaptured == BLACK_PAWN); + } + else + { + mv.pCaptured = pos->rgSquare[cTo - 0x10].pPiece; + ASSERT(mv.pCaptured == WHITE_PAWN); + } + } + + // + // Handle double jumps. + // + if (abs(RANK(cTo) - RANK(cFrom)) > 1) + { + mv.bvFlags = MOVE_FLAG_SPECIAL; + } + } + + done: + return(mv); + + illegal: + mv.uMove = 0; + return(mv); +} diff --git a/src/input.c b/src/input.c new file mode 100755 index 0000000..9f829f7 --- /dev/null +++ b/src/input.c @@ -0,0 +1,515 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + input.c + +Abstract: + + This module implements an input thread dedicated to watching for + user input on stdin and maintaining a queue of input events for + consumption by the main engine thread. Currently only the main + engine thread (and not helper threads) may consume user input + because: 1. I see no performance reason to make all threads able + to consume input and 2. it makes the locking assumptions easier. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 14 May 2004 + +Revision History: + + $Id: input.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +DLIST_ENTRY g_InputEventList; +volatile static ULONG g_uInputLock; +extern CHAR g_szInitialCommand[SMALL_STRING_LEN_CHAR]; + +#define INPUT_IS_LOCKED (g_uInputLock != 0) +#define LOCK_INPUT \ + AcquireSpinLock(&g_uInputLock); \ + ASSERT(INPUT_IS_LOCKED); +#define UNLOCK_INPUT \ + ASSERT(INPUT_IS_LOCKED); \ + ReleaseSpinLock(&g_uInputLock); +volatile FLAG g_fExitProgram = FALSE; +volatile ULONG g_uNumInputEvents; + +typedef struct _INPUT_EVENT +{ + DLIST_ENTRY links; + CHAR *szInput; +} +INPUT_EVENT; + +ULONG g_uBlockingInputLock = 0; + +static void +_WaitUntilTheresInputToRead(void) +{ + if (g_uBlockingInputLock != (ULONG)-1) + { + SystemObtainSemaphoreResource(g_uBlockingInputLock); + SystemReleaseSemaphoreResource(g_uBlockingInputLock); + } + else + { + SystemDeferExecution(100); + } +} + + +static void +_UnblockBlockedReaders(void) +{ + if (g_uBlockingInputLock != (ULONG)-1) + { + SystemReleaseSemaphoreResource(g_uBlockingInputLock); + } +} + + +static void +_BlockBlockingReaders(void) +{ + if (g_uBlockingInputLock != (ULONG)-1) + { + SystemObtainSemaphoreResource(g_uBlockingInputLock); + } +} + + +void +PushNewInput(CHAR *buf) +/** + +Routine description: + + Allocate a new input event for some user input and push it onto + the queue. + +Parameters: + + CHAR *buf + +Return value: + + void + +**/ +{ + INPUT_EVENT *pEvent; + FLAG fDone = FALSE; + FLAG fInQuote, fSemi; + CHAR *p; + CHAR *q; + + do + { + pEvent = (INPUT_EVENT *)SystemAllocateMemory(sizeof(INPUT_EVENT)); + + // + // Note: you can specify more than one command per line using + // a semi-colon to separate them. If the semi-colon is quoted, + // though, ignore it. + // + fInQuote = FALSE; + fSemi = FALSE; + p = buf; + do + { + switch(*p) + { + case ';': + if (FALSE == fInQuote) + { + *p = '\0'; + fSemi = TRUE; + } + else + { + p++; + } + break; + case '"': + fInQuote = FLIP(fInQuote); + p++; + break; + case '\0': + fDone = TRUE; + break; + default: + p++; + break; + } + } + while((FALSE == fDone) && (FALSE == fSemi)); + pEvent->szInput = STRDUP(buf); + + // + // Push it onto the queue + // + LOCK_INPUT; + InsertTailList(&g_InputEventList, &(pEvent->links)); + g_uNumInputEvents++; + if (g_uNumInputEvents == 1) + { + _UnblockBlockedReaders(); + } + q = pEvent->szInput; + ASSERT(q); + while(*q && isspace(*q)) q++; +#ifdef DEBUG + Trace("INPUT THREAD SAW (event %u): %s", + g_uNumInputEvents, + pEvent->szInput); +#endif + if (!STRNCMPI("quit", q, 4)) + { + g_fExitProgram = TRUE; + UNLOCK_INPUT; + return; + } + UNLOCK_INPUT; + + buf = (p + 1); + } + while(FALSE == fDone); +} + + +static void +_InitInputSystemCommonCode(void) +/** + +Routine description: + + Common code for initializing the input system (called whether we + are spawing an input thread or running in batch mode with no input + thread). + +Parameters: + + void + +Return value: + + void + +**/ +{ + setbuf(stdout, NULL); + setbuf(stdin, NULL); + setbuf(stderr, NULL); + + g_uBlockingInputLock = SystemCreateSemaphore(1); + if (g_uBlockingInputLock == (ULONG)-1) + { + Bug("_InitInputSystemCommonCode: Failed to create input semaphore.\n"); + } + g_uNumInputEvents = 0; + _BlockBlockingReaders(); + InitializeListHead(&g_InputEventList); + g_uInputLock = 0; + if (g_szInitialCommand[0] != '\0') + { + Trace("INPUT SYSTEM INIT: Pushing \"%s\"\n", g_szInitialCommand); + PushNewInput(g_szInitialCommand); + g_szInitialCommand[0] = '\0'; + } +} + + + +void +InitInputSystemInBatchMode(void) +/** + +Routine description: + + User specified --batch on the cmdline... so don't spawn an input + thread. Just process the initial command. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (g_szInitialCommand[0] == '\0') + { + UtilPanic(INCONSISTENT_STATE, + NULL, "Batch mode specified with no initial command", + NULL, NULL, + __FILE__, __LINE__); + } + _InitInputSystemCommonCode(); +} + + +#ifdef USE_READLINE +char *readline(const char *prompt); +void add_history(const char *line); +#endif + +ULONG +InputThreadEntry(ULONG uUnused) +/** + +Routine description: + + The entry point of the input thread. + +Parameters: + + ULONG uUnused + +Return value: + + ULONG + +**/ +{ + static CHAR buf[SMALL_STRING_LEN_CHAR]; + INPUT_EVENT *pEvent; + DLIST_ENTRY *p; + FLAG fFailure; +#ifdef USE_READLINE + CHAR *pReadline = NULL; +#endif + + while(TRUE != g_fExitProgram) + { + // + // Get another input + // + fFailure = FALSE; +#ifdef USE_READLINE + memset(buf, 0, sizeof(buf)); + pReadline = readline(NULL); + if (pReadline != NULL) + { + strncpy(buf, pReadline, sizeof(buf) - 1); + add_history(pReadline); + free(pReadline); + } + else + { + fFailure = TRUE; + } +#else + if (NULL == fgets(buf, sizeof(buf), stdin)) + { + fFailure = TRUE; + } +#endif + if (fFailure == TRUE) + { + Trace("INPUT THREAD: got end-of-file on stdin, exiting.\n"); + break; + } + + // + // And push it onto the queue + // + PushNewInput(buf); + } + Trace("INPUT THREAD: thread terminating.\n"); + + // + // Free the queue + // + while(!IsListEmpty(&g_InputEventList)) + { + p = RemoveHeadList(&g_InputEventList); + pEvent = CONTAINING_STRUCT(p, INPUT_EVENT, links); + SystemFreeMemory(pEvent->szInput); + SystemFreeMemory(pEvent); + } + g_uNumInputEvents = (ULONG)-1; + return(0); +} + + +ULONG +InitInputSystemWithDedicatedThread(void) +/** + +Routine description: + + Initialize the input system with a dedicated input thread. + +Parameters: + + void + +Return value: + + ULONG + +**/ +{ + ULONG uHandle = -1; + + _InitInputSystemCommonCode(); + if (FALSE == SystemCreateThread(InputThreadEntry, + 0, + &uHandle)) + { + Bug("Failed to start input thread!\n"); + uHandle = -1; + } + return(uHandle); +} + + +CHAR * +PeekNextInput(void) +/** + +Routine description: + + Peek at what the next input event will be without consuming it. + Because only one thread can be consuming events from the queue at + a time (presumably the same thread that called this Peek function) + it should be safe to do this without a lock. But the overhead is + low so I lock here anyway. + +Parameters: + + void + +Return value: + + CHAR * + +**/ +{ + INPUT_EVENT *p; + char *q = NULL; + + LOCK_INPUT; + if (!IsListEmpty(&g_InputEventList)) + { + p = CONTAINING_STRUCT(g_InputEventList.pFlink, INPUT_EVENT, links); + q = p->szInput; + } + UNLOCK_INPUT; + return(q); +} + + +CHAR * +ReadNextInput(void) +/** + +Routine description: + + Read the next input (and dequeue it). + +Parameters: + + void + +Return value: + + CHAR * + +**/ +{ + CHAR *pRet = NULL; + INPUT_EVENT *p; + DLIST_ENTRY *q; + + LOCK_INPUT; + if (!IsListEmpty(&g_InputEventList)) + { + q = RemoveHeadList(&g_InputEventList); + p = CONTAINING_STRUCT(q, INPUT_EVENT, links); + g_uNumInputEvents--; + if (g_uNumInputEvents == 0) + { + _BlockBlockingReaders(); + } + pRet = p->szInput; + SystemFreeMemory(p); + } + UNLOCK_INPUT; + return(pRet); +} + + +CHAR * +BlockingReadInput(void) +/** + +Routine description: + + Block waiting on the next input read. + +Parameters: + + void + +Return value: + + CHAR + +**/ +{ + CHAR *pCh = NULL; + + do + { + _WaitUntilTheresInputToRead(); + if (TRUE == g_fExitProgram) + { + if (-1 != g_uBlockingInputLock) + { + SystemDeleteSemaphore(g_uBlockingInputLock); + } + return(NULL); + } + pCh = ReadNextInput(); + if (NULL != pCh) + { + if (strlen(pCh) > 0) break; + SystemFreeMemory(pCh); + } + } + while(1); + return(pCh); +} + +ULONG +NumberOfPendingInputEvents(void) +/** + +Routine description: + + How many input events are pending on the queue. Note: the value + returned is obviously potentially out of date the instant it gets + sent back to the caller... + +Parameters: + + void + +Return value: + + ULONG + +**/ +{ + return(g_uNumInputEvents); +} diff --git a/src/large.bin b/src/large.bin new file mode 100755 index 0000000..3212478 Binary files /dev/null and b/src/large.bin differ diff --git a/src/layout.pl b/src/layout.pl new file mode 100755 index 0000000..c4fe0f2 --- /dev/null +++ b/src/layout.pl @@ -0,0 +1,62 @@ +#!/usr/bin/perl + +@data = ( " main.o root.o search.o draw.o hash.o dynamic.o ", + " generate.o see.o move.o movesup.o ", + " eval.o pawnhash.o bitboard.o ", + " command.o script.o input.o vars.o util.o list.o fbsd.o gamelist.o ", + " board.o ics.o san.o fen.o book.o bench.o mersenne.o ", + " piece.o sig.o data.o probe.o egtb.o" ); + +$num_permutations = factorial(scalar @data); +for ($i = 0; $i < $num_permutations; $i++) +{ + open(OBJS, ">_object_files.$i") || die $!; + print OBJS "OBJS=\t\t"; + my @permutation = @data[n2perm($i, $#data)]; + print OBJS "@permutation\n"; + close(OBJS); + system("cp _object_files.$i _objs_"); + system("make"); + system("cp typhoon typhoon.$i"); +} + +# Utility function: factorial with memoizing +BEGIN { + my @fact = (1); +sub factorial($) { + my $n = shift; + return $fact[$n] if defined $fact[$n]; + $fact[$n] = $n * factorial($n - 1); +} +} + +# n2pat($N, $len) : produce the $N-th pattern of length $len +sub n2pat +{ + my $i = 1; + my $N = shift; + my $len = shift; + my @pat; + while ($i <= $len + 1) { # Should really be just while ($N) { ... + push @pat, $N % $i; + $N = int($N/$i); + $i++; + } + return @pat; +} + +# pat2perm(@pat) : turn pattern returned by n2pat() into +# permutation of integers. XXX: splice is already O(N) +sub pat2perm +{ + my @pat = @_; + my @source = (0 .. $#pat); + my @perm; + push @perm, splice(@source, (pop @pat), 1) while @pat; + return @perm; +} + +# n2perm($N, $len) : generate the Nth permutation of $len objects +sub n2perm { + pat2perm(n2pat(@_)); +} diff --git a/src/layout_parse.pl b/src/layout_parse.pl new file mode 100755 index 0000000..f0d055a --- /dev/null +++ b/src/layout_parse.pl @@ -0,0 +1,43 @@ +#!/usr/bin/perl + +opendir(DIR, ".") || die; +@files = readdir(DIR); +closedir(DIR); + +$max = 0; +$maxpos = -1; +$sum = 0; +$min = 99999999; +$minpos = -1; +$count = 0; + +for $file(@files) +{ + if ($file =~ /(\d+)typhoon\.log/) + { + $num = $1; + open(FILE, $file); + while() + { + if (/\((\d+) nps\)\./) + { + $count++; + $speed = $1; + $sum += $speed; + if ($speed > $max) + { + $maxpos = $num; + $max = $speed; + } + if ($speed < $min) + { + $minpos = $num; + $min = $speed; + } + } + } + close(FILE); + } +} + +printf "max $max at $maxpos, min $min at $minpos, avg %f\n", ($sum/$count); diff --git a/src/list.c b/src/list.c new file mode 100644 index 0000000..dd3a199 --- /dev/null +++ b/src/list.c @@ -0,0 +1,100 @@ +/*++ + +Copyright (c) Scott Gasch + +Module Name: + + list.c + +Abstract: + + Random doubly linked list helper routines. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 29 Nov 2007 + +Revision History: + +--*/ + +#include "chess.h" + +INLINE void +InitializeListHead(IN DLIST_ENTRY *pListHead) +{ + pListHead->pFlink = pListHead->pBlink = pListHead; +} + +INLINE FLAG +IsListEmpty(IN DLIST_ENTRY *pListHead) +{ + return (FLAG)(pListHead->pFlink == pListHead); +} + +INLINE FLAG +RemoveEntryList(IN DLIST_ENTRY *pEntry) +{ + DLIST_ENTRY *pBlink; + DLIST_ENTRY *pFlink; + + pFlink = pEntry->pFlink; + pBlink = pEntry->pBlink; + pBlink->pFlink = pFlink; + pFlink->pBlink = pBlink; + return (FLAG)(pFlink == pBlink); +} + +INLINE DLIST_ENTRY * +RemoveHeadList(IN DLIST_ENTRY *pListHead) +{ + DLIST_ENTRY *pFlink; + DLIST_ENTRY *pEntry; + + pEntry = pListHead->pFlink; + pFlink = pEntry->pFlink; + pListHead->pFlink = pFlink; + pFlink->pBlink = pListHead; + + return(pEntry); +} + +INLINE DLIST_ENTRY * +RemoveTailList(IN DLIST_ENTRY *pListHead) +{ + DLIST_ENTRY *pBlink; + DLIST_ENTRY *pEntry; + + pEntry = pListHead->pBlink; + pBlink = pEntry->pBlink; + pListHead->pBlink = pBlink; + pBlink->pFlink = pListHead; + + return(pEntry); +} + +INLINE void +InsertTailList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry) +{ + DLIST_ENTRY *pBlink; + + pBlink = pListHead->pBlink; + pEntry->pFlink = pListHead; + pEntry->pBlink = pBlink; + pBlink->pFlink = pEntry; + pListHead->pBlink = pEntry; +} + +INLINE void +InsertHeadList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry) +{ + DLIST_ENTRY *pFlink; + + pFlink = pListHead->pFlink; + pEntry->pFlink = pFlink; + pEntry->pBlink = pListHead; + pFlink->pBlink = pEntry; + pListHead->pFlink = pEntry; +} diff --git a/src/lock.h b/src/lock.h new file mode 100644 index 0000000..49504e0 --- /dev/null +++ b/src/lock.h @@ -0,0 +1,128 @@ +#if defined(SMP) + +# undef Pause +# define Pause() + +/* + ******************************************************************************* + * * + * this is a Microsoft windows-based operating system. * + * * + ******************************************************************************* + */ +# if defined(_WIN32) || defined(_WIN64) + +# define pthread_attr_t HANDLE +# define pthread_t HANDLE +# define thread_t HANDLE + +extern pthread_t NumaStartThread(void *func, void *args); + +# if ((defined (_M_IA64) || defined (_M_AMD64)) && !defined(NT_INTEREX)) + +# include + +# pragma intrinsic (_InterlockedExchange) + +typedef volatile LONG lock_t[1]; + +# define LockInit(v) ((v)[0] = 0) +# define LockFree(v) ((v)[0] = 0) +# define Unlock(v) ((v)[0] = 0) + +__forceinline void Lock(volatile LONG * hPtr) +{ + int iValue; + + for (;;) { + iValue = _InterlockedExchange((LPLONG) hPtr, 1); + if (0 == iValue) + return; + while (*hPtr); + } +} + +# else /* NT non-Alpha/Intel, without assembler Lock() */ + +# define lock_t volatile int +# define LockInit(v) ((v) = 0) +# define LockFree(v) ((v) = 0) +# define Lock(v) do { \ + while(InterlockedExchange((LPLONG)&(v),1) != 0); \ + } while (0) +# define Unlock(v) ((v) = 0) + +# endif /* architecture check */ + +# else +/* + ******************************************************************************* + * * + * this is a Unix-based operating system. define the spinlock code as needed * + * for SMP synchronization. * + * * + ******************************************************************************* + */ + +# if defined(ALPHA) + +# include + +# define lock_t volatile long +# define LockInit(v) ((v) = 0) +# define LockFree(v) ((v) = 0) +# define Lock(v) __LOCK_LONG(&(v)) +# define Unlock(v) __UNLOCK_LONG(&(v)) + +# elif defined(POWERPC) + /* OS X */ + +# include + +# define lock_t OSSpinLock +# define LockInit(v) ((v) = 0) +# define LockFree(v) ((v) = 0) +# define Lock(v) OSSpinLockLock(&(v)) +# define Unlock(v) OSSpinLockUnlock(&(v)) + +# else /* X86 */ + +# undef Pause +# define Pause() ({asm volatile ("pause");}) + +static void __inline__ LockX86(volatile int *lock) +{ + int dummy; + asm __volatile__("1: movl $1, %0" "\n\t" + " xchgl (%1), %0" "\n\t" " testl %0, %0" "\n\t" + " jz 3f" "\n\t" "2: pause" "\n\t" + " movl (%1), %0" "\n\t" " testl %0, %0" "\n\t" + " jnz 2b" "\n\t" " jmp 1b" "\n\t" "3:" + "\n\t":"=&q"(dummy) + :"q"(lock) + :"cc"); +} + +static void __inline__ UnlockX86(volatile int *lock) +{ + int dummy; + asm __volatile__("movl $0, (%1)":"=&q"(dummy) + :"q"(lock)); +} + +# define LockInit(p) (p=0) +# define LockFree(p) (p=0) +# define Unlock(p) (UnlockX86(&p)) +# define Lock(p) (LockX86(&p)) +# define lock_t volatile int + +# endif + +# endif /* windows or unix */ + +#else +# define LockInit(p) +# define LockFree(p) +# define Lock(p) +# define Unlock(p) +#endif /* SMP code */ diff --git a/src/main.c b/src/main.c new file mode 100755 index 0000000..e1399c6 --- /dev/null +++ b/src/main.c @@ -0,0 +1,749 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + main.c + +Abstract: + + Program entry point and setup code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: main.c 355 2008-07-01 15:46:43Z scott $ + +**/ + +#include "chess.h" + +FILE *g_pfLogfile = NULL; +GAME_OPTIONS g_Options; +CHAR g_szInitialCommand[SMALL_STRING_LEN_CHAR]; +ULONG g_uInputThreadHandle = (ULONG)-1; + +void +Banner(void) +/** + +Routine description: + + Describe the compile/build options and program version. + +Parameters: + + void + +Return value: + + void + +**/ +{ + char *p; + + Trace("Typhoon %s (built on %s %s):\n", VERSION, __DATE__, __TIME__); + Trace(" Copyright (C) 2000-2007, Scott Gasch (scott.gasch@gmail.com)\n"); + Trace(" " REVISION); + Trace(" " COMPILER_STRING); + Trace(" Make profile used: %s\n", PROFILE); +#ifdef MP + Trace(" Multiprocessor enabled; %u searcher thread%s\n", + g_Options.uNumProcessors, (g_Options.uNumProcessors > 1) ? "s" : ""); +#else + Trace(" Single processor version\n"); +#endif +#ifdef DEBUG + Trace(" DEBUG build\n"); +#endif +#ifdef TEST + Trace(" Testcode compiled in\n"); +#endif +#ifdef EVAL_DUMP + Trace(" Evaluation terms\n"); +#endif +#ifdef EVAL_TIME + Trace(" Evaluation timing\n"); +#endif +#ifdef PERF_COUNTERS + Trace(" Performance counters\n"); +#ifdef TEST_NULL + Trace(" Testing nullmove prediction algorithms\n"); +#endif +#endif +#ifdef DUMP_TREE + Trace(" Search tree dumpfile generation enabled\n"); +#endif + Trace(" Hash sizes: %u Mb (main), %u Mb / thread (pawn), %u Mb / thread (eval)\n", + (g_uHashTableSizeEntries * sizeof(HASH_ENTRY)) / MB, + PAWN_HASH_TABLE_SIZE * sizeof(PAWN_HASH_ENTRY) / MB, + EVAL_HASH_TABLE_SIZE * sizeof(EVAL_HASH_ENTRY) / MB); + Trace(" QCheckPlies: %u\n", QPLIES_OF_NON_CAPTURE_CHECKS); + Trace(" FutilityBase: %u\n", FUTILITY_BASE_MARGIN); + p = ExportEvalDNA(); + Trace(" Logging Eval DNA.\n"); + Log(p); + free(p); +#ifdef DO_IID + Trace(" IID R-factor: %u ply\n", IID_R_FACTOR / ONE_PLY); +#endif +} + + +void +EndLogging(void) +/** + +Routine description: + + Close the main logfile. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (NULL != g_pfLogfile) { + fflush(g_pfLogfile); + fflush(stdout); + fclose(g_pfLogfile); + g_pfLogfile = NULL; + } +} + + +FLAG +BeginLogging(void) +/** + +Routine description: + + Open the main logfile. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (NULL != g_pfLogfile) { + EndLogging(); + } + if (!strlen(g_Options.szLogfile) || + !strcmp(g_Options.szLogfile, "-")) { + return(FALSE); + } + + // If the logfile we want to write already exists, back it up. + if (TRUE == SystemDoesFileExist(g_Options.szLogfile)) { + VERIFY(BackupFile(g_Options.szLogfile)); + } + ASSERT(FALSE == SystemDoesFileExist(g_Options.szLogfile)); + + g_pfLogfile = fopen(g_Options.szLogfile, "wb+"); + if (NULL == g_pfLogfile) { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Can't open logfile", + (void *)&(g_Options.szLogfile), + (void *)"write", + NULL, + __FILE__, __LINE__); + } + return(TRUE); +} + + +FLAG +PreGameReset(FLAG fResetBoard) +/** + +Routine description: + + Reset internal state between games. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (TRUE == fResetBoard) + { + SetRootToInitialPosition(); + } + SetMyName(); + ClearDynamicMoveOrdering(); + ClearHashTable(); + ResetOpeningBook(); + return(TRUE); +} + + +static ULONG +_ParseHashOption(char *p, + ULONG uEntrySize) +{ + ULONG u, v; + CHAR c; + + if ((!STRCMPI(p, "none")) || (!STRCMPI(p, "no"))) return(0); + if (2 == sscanf(p, "%u%1c", &u, &c)) + { + v = u; + switch(c) + { + case 'K': + case 'k': + u *= 1024; + break; + case 'M': + case 'm': + u *= 1024 * 1024; + break; + case 'G': + case 'g': + u *= 1024 * 1024 * 1024; + break; + default: + Trace("Error (unrecognized size): \"%s\"\n", p); + break; + } + if (u < v) + { + Trace("Error (size too large): \"%s\"\n", p); + u = v; + } + u /= uEntrySize; + } + else + { + u = (ULONG)atoi(p); + } + + while(!IS_A_POWER_OF_2(u)) + { + u &= (u - 1); + } + return(u); +} + + + +void +InitializeOptions(int argc, char *argv[]) +/** + +Routine description: + + Set global options to their initial state. This code also is + responsible for parsing the commandline in order to override the + default state of global options. + +Parameters: + + int argc, + char *argv[] + +Return value: + + void + +**/ +{ + int i; + + // + // Defaults + // + memset(&g_Options, 0, sizeof(g_Options)); + g_szInitialCommand[0] = '\0'; + g_Options.uMyClock = g_Options.uOpponentsClock = 600; + g_Options.fGameIsRated = FALSE; + g_Options.fOpponentIsComputer = FALSE; + g_Options.uSecPerMove = 0; + g_Options.uMaxDepth = MAX_PLY_PER_SEARCH - 1; + g_Options.fShouldPonder = TRUE; + g_Options.fPondering = g_Options.fThinking = FALSE; + g_Options.mvPonder.uMove = 0; + g_Options.fShouldPost = TRUE; + g_Options.fForceDrawWorthZero = FALSE; + g_Options.uMyIncrement = 0; + g_Options.uMovesPerTimePeriod = 0; + g_Options.szAnalyzeProgressReport[0] = '\0'; + g_Options.fShouldAnnounceOpening = TRUE; + g_Options.eClock = CLOCK_NONE; + g_Options.eGameType = GAME_UNKNOWN; + g_Options.ePlayMode = FORCE_MODE; + g_Options.fNoInputThread = FALSE; + g_Options.fVerbosePosting = TRUE; + strcpy(g_Options.szEGTBPath, "/egtb/three;/etc/four;/egtb/five"); + strcpy(g_Options.szLogfile, "typhoon.log"); + strcpy(g_Options.szBookName, "book.bin"); + g_Options.uNumHashTableEntries = 0x10000; + g_Options.uNumProcessors = 1; + g_Options.fStatusLine = TRUE; + g_Options.iResignThreshold = 0; + g_Options.u64MaxNodeCount = 0ULL; + + i = 1; + while(i < argc) + { +#ifdef MP + if ((!STRCMPI(argv[i], "--cpus")) && (argc > i)) + { + g_Options.uNumProcessors = (ULONG)atoi(argv[i+1]); + if ((g_Options.uNumProcessors == 0) || + (g_Options.uNumProcessors > 64)) + { + g_Options.uNumProcessors = 2; + } + i++; + } + else +#endif + if ((!STRCMPI(argv[i], "--command")) && (argc > i)) + { + strncpy(g_szInitialCommand, + argv[i+1], + SMALL_STRING_LEN_CHAR - 2); + strcat(g_szInitialCommand, "\r\n"); + i++; + } + else if ((!STRCMPI(argv[i], "--hash")) && (argc > i)) + { + g_Options.uNumHashTableEntries = + _ParseHashOption(argv[i+1], + sizeof(HASH_ENTRY)); + i++; + } + else if ((!STRCMPI(argv[i], "--egtbpath")) && (argc > i)) + { + if (!strcmp(argv[i+1], "-")) { + g_Options.szEGTBPath[0] = '\0'; + } else { + strncpy(g_Options.szEGTBPath, argv[i+1], SMALL_STRING_LEN_CHAR); + } + i++; + } + else if (!STRCMPI(argv[i], "--book") && argc > i) + { + if (!strcmp(argv[i+1], "-")) { + g_Options.szBookName[0] = '\0'; + } else { + strncpy(g_Options.szBookName, argv[i+1], SMALL_STRING_LEN_CHAR); + } + i++; + } + else if (!STRCMPI(argv[i], "--batch")) + { + g_Options.fNoInputThread = TRUE; + } + else if ((!STRCMPI(argv[i], "--dnafile")) && (argc > i)) + { + if (!ReadEvalDNA(argv[i+1])) + { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Bad DNA file", + (void *)&(argv[i+1]), + (void *)"read", + NULL, + __FILE__, __LINE__); + } + i++; + } + else if ((!STRCMPI(argv[i], "--logfile")) && (argc > i)) + { + strncpy(g_Options.szLogfile, argv[i+1], + SMALL_STRING_LEN_CHAR); + i++; + } + else if (!STRCMPI(argv[i], "--help")) { + Trace("Usage: %s [--batch] [--command arg] [--logfile arg] [--egtbpath arg]\n" + " [--dnafile arg] [--cpus arg] [--hash arg]\n\n" + " --batch : operate the engine without an input thread\n" + " --book : specify the opening book to use or '-' for none\n" + " --command : specify initial command(s) (requires arg)\n" + " --cpus : indicate the number of cpus to use (1..64)\n" + " --hash : indicate desired hash size (e.g. 16m, 1g)\n" + " --egtbpath : supplies the egtb path or '-' for none\n" + " --logfile : indicate desired output logfile name or '-' for none\n" + " --dnafile : indicate desired eval profile input (requres arg)\n\n" + "Example: %s --hash 256m --cpus 2\n" + " %s --logfile test.out --batch --command \"test\" --dnafile test.in\n", argv[0], argv[0], argv[0]); + exit(-1); + } + else + { + Trace("Error (unknown argument): \"%s\"; try --help\n", argv[i]); + } + + // + // TODO: parse other commandline options and override above + // + + i++; + } +} + + +void +CleanupOptions(void) +/** + +Routine description: + + Cleanup options... + +Parameters: + + void + +Return value: + + void + +**/ +{ + NOTHING; +} + + +FLAG +MainProgramInitialization(int argc, char *argv[]) +/** + +Routine description: + + Perform main program initialization. This includes stuff like: + precomputing some data structures, resetting the global options, + parsing the commandline to override said options, and calling out + to other modules to tell them to initialize themselves. + +Parameters: + + int argc, + char *argv[] + +Return value: + + FLAG + +**/ +{ + srand((unsigned int)time(0)); + InitializeOptions(argc, argv); + InitializeTreeDump(); + InitializeEGTB(); + InitializeSigSystem(); + InitializeInteriorNodeRecognizers(); + InitializeSearchDepthArray(); + InitializeWhiteSquaresTable(); + InitializeVectorDeltaTable(); + InitializeSwapTable(); + InitializeDistanceTable(); + InitializeOpeningBook(); + InitializeDynamicMoveOrdering(); + InitializeHashSystem(); + InitializePositionHashSystem(); +#ifdef MP + InitializeParallelSearch(); +#endif + VERIFY(PreGameReset(TRUE)); + (void)BeginLogging(); + return TRUE; +} + + +FLAG +MainProgramCleanup(void) +/** + +Routine description: + + Perform main program cleanup. Tear down the stuff we set up in + MainProgramInitialization. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + CleanupOpeningBook(); + CleanupEGTB(); + CleanupDynamicMoveOrdering(); +#ifdef MP + CleanupParallelSearch(); +#endif + CleanupPositionHashSystem(); + CleanupHashSystem(); + CleanupTreeDump(); + CleanupOptions(); + EndLogging(); + return(TRUE); +} + + +#ifdef TEST +FLAG +RunStartupProgramTest(void) +/** + +Routine description: + + If we built this version with -DTEST then this code is the start + of the self-test that runs at program startup time. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + ULONG u, x, y; + +#ifdef _X86_ + Trace("Testing CPP macros...\n"); + for (u = 0; u < 1000000; u++) + { + x = rand() * rand(); + y = rand() * rand(); + x = x & ~(0x80000000); + y = y & ~(0x80000000); + + if (MAX(x, y) != MAXU(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "max maxu", NULL, NULL, __FILE__, __LINE__); + } + + if (MAXU(x, y) != MAXU(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "maxu assoc", NULL, NULL, __FILE__, __LINE__); + } + + if (MIN(x, y) != MINU(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "min minu", NULL, NULL, __FILE__, __LINE__); + } + + if (MINU(x, y) != MINU(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "minu assoc", NULL, NULL, __FILE__, __LINE__); + } + + if (abs(x - y) != ABS_DIFF(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "abs_diff", NULL, NULL, __FILE__, __LINE__); + } + + if (ABS_DIFF(x, y) != ABS_DIFF(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "abs_diff assoc", NULL, NULL, __FILE__, __LINE__); + } + } +#endif + + TestDraw(); +#ifdef EVAL_DUMP + TestEval(); +#endif + TestBitboards(); + TestSan(); + TestIcs(); + TestGetAttacks(); + TestMoveGenerator(); + TestLegalMoveGenerator(); + TestFenCode(); + TestLiftPlaceSlidePiece(); + TestExposesCheck(); + TestIsAttacked(); + TestMakeUnmakeMove(); + TestSearch(); + + return(TRUE); +} +#endif // TEST + + + +void DeclareTerminalStates(GAME_RESULT result) { + switch(result.eResult) { + case RESULT_IN_PROGRESS: + return; + case RESULT_BLACK_WON: + Trace("0-1 {%s}\n", result.szDescription); + SetGameResultAndDescription(result); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_WHITE_WON: + Trace("1-0 {%s}\n", result.szDescription); + SetGameResultAndDescription(result); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_DRAW: + Trace("1/2-1/2 {%s}\n", result.szDescription); + Trace("tellics draw\n"); + SetGameResultAndDescription(result); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_ABANDONED: + case RESULT_UNKNOWN: + ASSERT(FALSE); + SetGameResultAndDescription(result); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + } +} + + +// Main work loop +void MainProgramLoop() { + POSITION pos; + GAME_RESULT result; + FLAG fThink; + FLAG fPonder; + + while (!g_fExitProgram) { + + // Prepare to search or ponder + memcpy(&pos, GetRootPosition(), sizeof(POSITION)); + fThink = fPonder = FALSE; + result.eResult = RESULT_IN_PROGRESS; + result.szDescription[0] = '\0'; + + // What should we do? + switch(g_Options.ePlayMode) { + case I_PLAY_WHITE: + fThink = (pos.uToMove == WHITE); + fPonder = (pos.uToMove == BLACK); + break; + case I_PLAY_BLACK: + fThink = (pos.uToMove == BLACK); + fPonder = (pos.uToMove == WHITE); + break; + case FORCE_MODE: + default: + fThink = fPonder = FALSE; + break; + } + + if (fThink) { + result = Think(&pos); + if ((NumberOfPendingInputEvents() != 0) && + (FALSE == g_fExitProgram)) + { + MakeStatusLine(); + ParseUserInput(FALSE); + } + DeclareTerminalStates(result); + } else if (fPonder) { + if (g_Options.fShouldPonder) { + result = Ponder(&pos); + } + if (FALSE == g_fExitProgram) + { + MakeStatusLine(); + ParseUserInput(FALSE); + } + DeclareTerminalStates(result); + } else { + MakeStatusLine(); + ParseUserInput(FALSE); + } + } +} + + +int CDECL +main(int argc, char *argv[]) +/** + +Routine description: + + Chess engine entry point and main loop. + +Parameters: + + int argc, + char *argv[] + +Return value: + + int CDECL + +**/ +{ + // Initial setup work... + Trace("Setting up, please wait...\n"); + if (FALSE == SystemDependentInitialization()) + { + Trace("main: Operating system dependent init code failed, " + "aborting.\n"); + exit(-1); + } + if (FALSE == MainProgramInitialization(argc, argv)) + { + Trace("main: Main program init code failed, aborting.\n"); + exit(-1); + } + Banner(); +#ifdef TEST + (void)RunStartupProgramTest(); +#endif + if (TRUE == g_Options.fNoInputThread) + { + InitInputSystemInBatchMode(); + } + else + { + g_uInputThreadHandle = InitInputSystemWithDedicatedThread(); + } + + // Enter the main work loop code... + MainProgramLoop(); + + // If we get here g_fExitProgram is set -- clean up. + Trace("MAIN THREAD: thread terminating.\n"); + if (FALSE == MainProgramCleanup()) + { + Trace("main: Main program cleanup code failed, aborting.\n"); + exit(-1); + } + exit(0); +} diff --git a/src/mersenne.c b/src/mersenne.c new file mode 100644 index 0000000..68eef94 --- /dev/null +++ b/src/mersenne.c @@ -0,0 +1,168 @@ +// +// This is the ``Mersenne Twister'' random number generator MT19937, which +// generates pseudorandom integers uniformly distributed in 0..(2^32 - 1) +// starting from any odd seed in 0..(2^32 - 1). This version is a recode +// by Shawn Cokus (Cokus@math.washington.edu) on March 8, 1998 of a version by +// Takuji Nishimura (who had suggestions from Topher Cooper and Marc Rieffel in +// July-August 1997). +// +// Effectiveness of the recoding (on Goedel2.math.washington.edu, a DEC Alpha +// running OSF/1) using GCC -O3 as a compiler: before recoding: 51.6 sec. to +// generate 300 million random numbers; after recoding: 24.0 sec. for the same +// (i.e., 46.5% of original time), so speed is now about 12.5 million random +// number generations per second on this machine. +// +// According to the URL +// (and paraphrasing a bit in places), the Mersenne Twister is ``designed +// with consideration of the flaws of various existing generators,'' has +// a period of 2^19937 - 1, gives a sequence that is 623-dimensionally +// equidistributed, and ``has passed many stringent tests, including the +// die-hard test of G. Marsaglia and the load test of P. Hellekalek and +// S. Wegenkittl.'' It is efficient in memory usage (typically using 2506 +// to 5012 bytes of static data, depending on data type sizes, and the code +// is quite short as well). It generates random numbers in batches of 624 +// at a time, so the caching and pipelining of modern systems is exploited. +// It is also divide- and mod-free. +// +// This library is free software; you can redistribute it and/or modify it +// under the terms of the GNU Library General Public License as published by +// the Free Software Foundation (either version 2 of the License or, at your +// option, any later version). This library is distributed in the hope that +// it will be useful, but WITHOUT ANY WARRANTY, without even the implied +// warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See +// the GNU Library General Public License for more details. You should have +// received a copy of the GNU Library General Public License along with this +// library; if not, write to the Free Software Foundation, Inc., 59 Temple +// Place, Suite 330, Boston, MA 02111-1307, USA. +// +// The code as Shawn received it included the following notice: +// +// Copyright (C) 1997 Makoto Matsumoto and Takuji Nishimura. When +// you use this, send an e-mail to with +// an appropriate reference to your work. +// +// It would be nice to CC: when you write. +// + +// +// Note: This code is used with permission +// +// $Id: mersenne.c 7 2004-07-01 15:46:42Z scott $ +// + +#include +#include + +// +// uint32 must be an unsigned integer type capable of holding at least 32 +// bits; exactly 32 should be fastest, but 64 is better on an Alpha with +// GCC at -O3 optimization so try your options and see what's best for you +// + +#define N (624) // length of state vector +#define M (397) // a period parameter +#define K (0x9908B0DFU) // a magic constant +#define hiBit(u) ((u) & 0x80000000U) // mask all but highest bit of u +#define loBit(u) ((u) & 0x00000001U) // mask all but lowest bit of u +#define loBits(u) ((u) & 0x7FFFFFFFU) // mask the highest bit of u +#define mixBits(u, v) (hiBit(u)|loBits(v)) // move hi bit of u to hi bit of v + +static unsigned int state[N+1]; // state vector + 1 extra to not violate ANSI C +static unsigned int *next; // next random value is computed from here +static int left = -1; // can *next++ this many times before reloading + + +void seedMT(unsigned int seed) +{ + // + // We initialize state[0..(N-1)] via the generator + // + // x_new = (69069 * x_old) mod 2^32 + // + // from Line 15 of Table 1, p. 106, Sec. 3.3.4 of Knuth's + // _The Art of Computer Programming_, Volume 2, 3rd ed. + // + // Notes (SJC): I do not know what the initial state requirements + // of the Mersenne Twister are, but it seems this seeding generator + // could be better. It achieves the maximum period for its modulus + // (2^30) iff x_initial is odd (p. 20-21, Sec. 3.2.1.2, Knuth); if + // x_initial can be even, you have sequences like 0, 0, 0, ...; + // 2^31, 2^31, 2^31, ...; 2^30, 2^30, 2^30, ...; 2^29, 2^29 + 2^31, + // 2^29, 2^29 + 2^31, ..., etc. so I force seed to be odd below. + // + // Even if x_initial is odd, if x_initial is 1 mod 4 then + // + // the lowest bit of x is always 1, + // the next-to-lowest bit of x is always 0, + // the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... , + // the 3rd-from-lowest bit of x 4-cycles ... 0 1 1 0 0 1 1 0 ... , + // the 4th-from-lowest bit of x has the 8-cycle ... 0 0 0 1 1 1 1 0 ... , + // ... + // + // and if x_initial is 3 mod 4 then + // + // the lowest bit of x is always 1, + // the next-to-lowest bit of x is always 1, + // the 2nd-from-lowest bit of x alternates ... 0 1 0 1 0 1 0 1 ... , + // the 3rd-from-lowest bit of x 4-cycles ... 0 0 1 1 0 0 1 1 ... , + // the 4th-from-lowest bit of x has the 8-cycle ... 0 0 1 1 1 1 0 0 ... , + // ... + // + // The generator's potency (min. s>=0 with (69069-1)^s = 0 mod 2^32) is + // 16, which seems to be alright by p. 25, Sec. 3.2.1.3 of Knuth. It + // also does well in the dimension 2..5 spectral tests, but it could be + // better in dimension 6 (Line 15, Table 1, p. 106, Sec. 3.3.4, Knuth). + // + // Note that the random number user does not see the values generated + // here directly since reloadMT() will always munge them first, so maybe + // none of all of this matters. In fact, the seed values made here could + // even be extra-special desirable if the Mersenne Twister theory says + // so-- that's why the only change I made is to restrict to odd seeds. + // + + register unsigned int x = (seed | 1U) & 0xFFFFFFFFU, *s = state; + register int j; + + for(left=0, *s++=x, j=N; --j; + *s++ = (x*=69069U) & 0xFFFFFFFFU); +} + + +unsigned int +reloadMT(void) +{ + register unsigned int *p0=state, *p2=state+2, *pM=state+M, s0, s1; + register int j; + + if(left < -1) + seedMT(4357U); + + left=N-1, next=state+1; + + for(s0=state[0], s1=state[1], j=N-M+1; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + for(pM=state, j=M; --j; s0=s1, s1=*p2++) + *p0++ = *pM++ ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + + s1=state[0], *p0 = *pM ^ (mixBits(s0, s1) >> 1) ^ (loBit(s1) ? K : 0U); + s1 ^= (s1 >> 11); + s1 ^= (s1 << 7) & 0x9D2C5680U; + s1 ^= (s1 << 15) & 0xEFC60000U; + return(s1 ^ (s1 >> 18)); +} + + +unsigned int randomMT(void) +{ + unsigned int y; + + if(--left < 0) + return(reloadMT()); + + y = *next++; + y ^= (y >> 11); + y ^= (y << 7) & 0x9D2C5680U; + y ^= (y << 15) & 0xEFC60000U; + return(y ^ (y >> 18)); +} diff --git a/src/move.c b/src/move.c new file mode 100755 index 0000000..5c1a0db --- /dev/null +++ b/src/move.c @@ -0,0 +1,1441 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + move.c + +Abstract: + + Functions to make and unmake moves. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 09 May 2004 + +Revision History: + + $Id: move.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +void +SlidePiece(POSITION *pos, COOR cFrom, COOR cTo) +/** + +Routine description: + + Slide a piece (i.e. not a pawn) from cFrom to cTo. This is much + faster than LiftPiece / PlacePiece. + +Parameters: + + POSITION *pos : the board + COOR cFrom : square moving from + COOR cTo : square moving to + +Return value: + + void + +**/ +{ + register PIECE p; + register ULONG c; + ULONG uIndex; + +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(IS_EMPTY(pos->rgSquare[cTo].pPiece)); +#endif + p = pos->rgSquare[cFrom].pPiece; + pos->rgSquare[cFrom].pPiece = EMPTY; + ASSERT(!IS_PAWN(p)); + ASSERT(IS_VALID_PIECE(p)); + uIndex = pos->rgSquare[cFrom].uIndex; + c = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(c)); + ASSERT(pos->cNonPawns[c][uIndex] == cFrom); + pos->cNonPawns[c][uIndex] = cTo; + pos->u64NonPawnSig ^= g_u64SigSeeds[cFrom][PIECE_TYPE(p)][c]; + pos->u64NonPawnSig ^= g_u64SigSeeds[cTo][PIECE_TYPE(p)][c]; +#ifdef DEBUG + if (IS_BISHOP(p) && (IS_SQUARE_WHITE(cFrom))) + { + ASSERT(IS_SQUARE_WHITE(cTo)); + } +#endif + pos->rgSquare[cTo].pPiece = p; + pos->rgSquare[cTo].uIndex = uIndex; +#ifdef DEBUG + pos->rgSquare[cFrom].uIndex = INVALID_PIECE_INDEX; + VerifyPositionConsistency(pos, FALSE); +#endif +} + + +void +SlidePawn(POSITION *pos, COOR cFrom, COOR cTo) +/** + +Routine description: + + Slide a pawn (i.e. not a piece) from cFrom to cTo. This is much + faster than LiftPiece / PlacePiece. + +Parameters: + + POSITION *pos : the board + COOR cFrom : square moving from + COOR cTo : square moving to + +Return value: + + void + +**/ +{ + register PIECE p; + register ULONG c; + ULONG uIndex; + +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(IS_EMPTY(pos->rgSquare[cTo].pPiece)); +#endif + p = pos->rgSquare[cFrom].pPiece; + pos->rgSquare[cFrom].pPiece = EMPTY; + ASSERT(IS_PAWN(p)); + ASSERT(IS_VALID_PIECE(p)); + uIndex = pos->rgSquare[cFrom].uIndex; + c = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(c)); + ASSERT(pos->cPawns[c][uIndex] == cFrom); + pos->cPawns[c][uIndex] = cTo; + pos->u64PawnSig ^= g_u64PawnSigSeeds[cFrom][c]; + pos->u64PawnSig ^= g_u64PawnSigSeeds[cTo][c]; + pos->rgSquare[cTo].pPiece = p; + pos->rgSquare[cTo].uIndex = uIndex; +#ifdef DEBUG + pos->rgSquare[cFrom].uIndex = INVALID_PIECE_INDEX; + VerifyPositionConsistency(pos, FALSE); +#endif +} + + +void +SlidePieceWithoutSigs(POSITION *pos, COOR cFrom, COOR cTo) +/** + +Routine description: + + Slide a piece (i.e. not a pawn) from cFrom to cTo. This is way + faster than LiftPiece / PlacePiece. Also note that this version + of the routine doesn't maintain the consistency of the position + signatures and should therefore only be called from UnmakeMove. + +Parameters: + + POSITION *pos : the board + COOR cFrom : square moving from + COOR cTo : square moving to + +Return value: + + void + +**/ +{ + register PIECE p; + register ULONG c; + ULONG uIndex; + +#ifdef DEBUG + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(IS_EMPTY(pos->rgSquare[cTo].pPiece)); +#endif + p = pos->rgSquare[cFrom].pPiece; + pos->rgSquare[cFrom].pPiece = EMPTY; + ASSERT(IS_VALID_PIECE(p)); + ASSERT(!IS_PAWN(p)); + uIndex = pos->rgSquare[cFrom].uIndex; + c = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(c)); + ASSERT(pos->cNonPawns[c][uIndex] == cFrom); + pos->cNonPawns[c][uIndex] = cTo; + pos->rgSquare[cTo].pPiece = p; + pos->rgSquare[cTo].uIndex = uIndex; +#ifdef DEBUG + pos->rgSquare[cFrom].uIndex = INVALID_PIECE_INDEX; +#endif +} + + +void +SlidePawnWithoutSigs(POSITION *pos, COOR cFrom, COOR cTo) +/** + +Routine description: + + Slide a pawn (i.e. not a piece) from cFrom to cTo. This is way + faster than LiftPiece / PlacePiece. Also note that this version + of the routine doesn't maintain the consistency of the position + signatures and should therefore only be called from UnmakeMove. + +Parameters: + + POSITION *pos : the board + COOR cFrom : square moving from + COOR cTo : square moving to + +Return value: + + void + +**/ +{ + register PIECE p; + register ULONG c; + ULONG uIndex; + +#ifdef DEBUG + ASSERT(IS_ON_BOARD(cFrom)); + ASSERT(IS_ON_BOARD(cTo)); + ASSERT(IS_EMPTY(pos->rgSquare[cTo].pPiece)); +#endif + p = pos->rgSquare[cFrom].pPiece; + pos->rgSquare[cFrom].pPiece = EMPTY; + ASSERT(IS_VALID_PIECE(p)); + ASSERT(IS_PAWN(p)); + uIndex = pos->rgSquare[cFrom].uIndex; + c = GET_COLOR(p); + ASSERT(IS_VALID_COLOR(c)); + ASSERT(pos->cPawns[c][uIndex] == cFrom); + pos->cPawns[c][uIndex] = cTo; + pos->rgSquare[cTo].pPiece = p; + pos->rgSquare[cTo].uIndex = uIndex; +#ifdef DEBUG + pos->rgSquare[cFrom].uIndex = INVALID_PIECE_INDEX; +#endif +} + + +PIECE +LiftPiece(POSITION *pos, COOR cSquare) +/** + +Routine description: + + Remove the piece at square cSquare from the board. Update POSITION + (piece lists, counts, material, etc...) accordingly. + +Parameters: + + POSITION *pos, + COOR cSquare + +Return value: + + PIECE + +**/ +{ + register PIECE pLifted; + ULONG color; + register SCORE pv; + ULONG uLastIndex; + ULONG uIndex; + COOR c; + ULONG u; +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); + ASSERT(IS_ON_BOARD(cSquare)); +#endif + pLifted = pos->rgSquare[cSquare].pPiece; + if (IS_EMPTY(pLifted)) + { + return(pLifted); // ok to return an empty square + } + pos->rgSquare[cSquare].pPiece = EMPTY; + ASSERT(IS_VALID_PIECE(pLifted)); + ASSERT(!IS_KING(pLifted)); + uIndex = pos->rgSquare[cSquare].uIndex; +#ifdef DEBUG + ASSERT(IS_VALID_PIECE_INDEX(uIndex)); + pos->rgSquare[cSquare].uIndex = INVALID_PIECE_INDEX; +#endif + color = GET_COLOR(pLifted); + ASSERT(IS_VALID_COLOR(color)); + pv = PIECE_VALUE(pLifted); + ASSERT(pv > 0); + pos->iMaterialBalance[color] -= pv; + pos->iMaterialBalance[FLIP(color)] += pv; + ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]); + + if (IS_PAWN(pLifted)) + { + ASSERT(pos->cPawns[color][uIndex] == cSquare); + ASSERT(pv == VALUE_PAWN); + + pos->uPawnMaterial[color] -= pv; + ASSERT(pos->uPawnMaterial[color] <= (7 * VALUE_PAWN)); + + pos->u64PawnSig ^= g_u64PawnSigSeeds[cSquare][color]; + + // + // Remove this pawn from the pawn list. + // + pos->uPawnCount[color]--; + ASSERT(pos->uPawnCount[color] < 8); + uLastIndex = pos->uPawnCount[color]; + + // + // Assume that the pawn being lifted is not the last pawn on + // the list. We can't have a hole in the list so swap the + // last pawn on the list into this guy's spot. + // + c = pos->cPawns[color][uLastIndex]; + pos->rgSquare[c].uIndex = uIndex; + pos->cPawns[color][uIndex] = c; +#ifdef DEBUG + pos->cPawns[color][uLastIndex] = ILLEGAL_COOR; +#endif + } + else + { + // + // Piece is not a pawn + // + ASSERT(pos->cNonPawns[color][uIndex] == cSquare); + ASSERT(pos->uNonPawnMaterial[color] >= VALUE_KING); + ASSERT(pv > VALUE_PAWN); + pos->uNonPawnMaterial[color] -= pv; + ASSERT(pos->uNonPawnMaterial[color] <= VALUE_MAX_ARMY); + + // + // Remove this piece from the list. + // + pos->uNonPawnCount[color][0]--; + ASSERT(pos->uNonPawnCount[color] > 0); + uLastIndex = pos->uNonPawnCount[color][0]; // optimized... + // + // Assume that it is NOT the last piece in the list ... swap + // the last piece into this one's spot. + // + c = pos->cNonPawns[color][uLastIndex]; + pos->rgSquare[c].uIndex = uIndex; + pos->cNonPawns[color][uIndex] = c; +#ifdef DEBUG + pos->cNonPawns[color][uLastIndex] = ILLEGAL_COOR; +#endif + + // + // Change per-piece counters. + // + u = PIECE_TYPE(pLifted); + ASSERT((u >= KNIGHT) && (u < KING)); + pos->u64NonPawnSig ^= g_u64SigSeeds[cSquare][u][color]; + pos->uNonPawnCount[color][u]--; + ASSERT(pos->uNonPawnCount[color][u] <= 9); + pos->uWhiteSqBishopCount[color] -= (IS_BISHOP(pLifted) & + IS_SQUARE_WHITE(cSquare)); + ASSERT(pos->uWhiteSqBishopCount[color] <= 9); + } + +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); +#endif + return(pLifted); +} + + +PIECE +LiftPieceWithoutSigs(POSITION *pos, COOR cSquare) +/** + +Routine description: + + Remove the piece at square cSquare from the board. Update POSITION + (piece lists, counts, material, etc...) accordingly. + + Note: LiftPieceWithoutSigs can _only_ be called from UnmakeMove. + It is used to unmake a previously made move and therefore does + not worry about updating position signatures. UnmakeMove has + the pre-move signature in a history list and will klobber the + position signature soon anyway. + +Parameters: + + POSITION *pos, + COOR cSquare + +Return value: + + PIECE + +**/ +{ + register PIECE pLifted; + ULONG color; + register SCORE pv; + ULONG uLastIndex; + ULONG uIndex; + COOR c; + ULONG u; + + ASSERT(IS_ON_BOARD(cSquare)); + pLifted = pos->rgSquare[cSquare].pPiece; + if (IS_EMPTY(pLifted)) + { + return(pLifted); // ok to return an empty square + } + pos->rgSquare[cSquare].pPiece = EMPTY; + ASSERT(IS_VALID_PIECE(pLifted)); + ASSERT(!IS_KING(pLifted)); + + uIndex = pos->rgSquare[cSquare].uIndex; +#ifdef DEBUG + ASSERT(IS_VALID_PIECE_INDEX(uIndex)); + pos->rgSquare[cSquare].uIndex = INVALID_PIECE_INDEX; +#endif + color = GET_COLOR(pLifted); + ASSERT(IS_VALID_COLOR(color)); + pv = PIECE_VALUE(pLifted); + ASSERT(pv > 0); + pos->iMaterialBalance[color] -= pv; + pos->iMaterialBalance[FLIP(color)] += pv; + ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]); + + if (IS_PAWN(pLifted)) + { + ASSERT(pos->cPawns[color][uIndex] == cSquare); + ASSERT(pv == VALUE_PAWN); + + pos->uPawnMaterial[color] -= pv; + ASSERT(pos->uPawnMaterial[color] <= (7 * VALUE_PAWN)); + + // + // Remove this pawn from the pawn list. + // + pos->uPawnCount[color]--; + ASSERT(pos->uPawnCount[color] < 8); + uLastIndex = pos->uPawnCount[color]; // optimized... + + // + // Assume that the pawn being lifted is not the last pawn on + // the list. We can't have a hole in the list so swap the + // last pawn on the list into this guy's spot. + // + c = pos->cPawns[color][uLastIndex]; + pos->rgSquare[c].uIndex = uIndex; + pos->cPawns[color][uIndex] = c; +#ifdef DEBUG + pos->cPawns[color][uLastIndex] = ILLEGAL_COOR; +#endif + } + else + { + // + // Piece is not a pawn + // + ASSERT(pos->cNonPawns[color][uIndex] == cSquare); + ASSERT(pos->uNonPawnMaterial[color] >= VALUE_KING); + ASSERT(pv > VALUE_PAWN); + pos->uNonPawnMaterial[color] -= pv; + ASSERT(pos->uNonPawnMaterial[color] <= VALUE_MAX_ARMY); + + // + // Remove this piece from the list. + // + pos->uNonPawnCount[color][0]--; + ASSERT(pos->uNonPawnCount[color] > 0); + uLastIndex = pos->uNonPawnCount[color][0]; // optimized... + + // + // Assume that it is NOT the last piece in the list ... swap + // the last piece into this one's spot. + // + c = pos->cNonPawns[color][uLastIndex]; + pos->rgSquare[c].uIndex = uIndex; + pos->cNonPawns[color][uIndex] = c; +#ifdef DEBUG + pos->cNonPawns[color][uLastIndex] = ILLEGAL_COOR; +#endif + + // + // Change per-piece counters. + // + u = PIECE_TYPE(pLifted); + ASSERT((u >= KNIGHT) && (u < KING)); + pos->uNonPawnCount[color][u]--; + ASSERT(pos->uNonPawnCount[color][u] <= 9); + pos->uWhiteSqBishopCount[color] -= (IS_BISHOP(pLifted) & + IS_SQUARE_WHITE(cSquare)); + ASSERT(pos->uWhiteSqBishopCount[color] <= 9); + } + + return(pLifted); +} + + +void +PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece) +/** + +Routine description: + + Place a piece back on the board. Link it into the right piece list. + +Parameters: + + POSITION *pos, + COOR cSquare, + PIECE pPiece + +Return value: + + void + +**/ +{ + register ULONG color = GET_COLOR(pPiece); + register ULONG uIndex; + register SCORE pv; + ULONG u; + +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); + ASSERT(IS_EMPTY(pos->rgSquare[cSquare].pPiece)); + ASSERT(!IS_KING(pPiece)); +#endif + + pv = PIECE_VALUE(pPiece); + pos->iMaterialBalance[color] += pv; + pos->iMaterialBalance[FLIP(color)] -= pv; + ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]); + + if (IS_PAWN(pPiece)) + { + // + // Piece is a pawn + // + ASSERT(pv == VALUE_PAWN); + pos->uPawnMaterial[color] += pv; + ASSERT(pos->uPawnMaterial[color] <= (8 * VALUE_PAWN)); + + uIndex = pos->uPawnCount[color]; + ASSERT((uIndex >= 0) && (uIndex <= 7)); + pos->uPawnCount[color]++; + ASSERT(pos->uPawnCount[color] <= 8); + pos->cPawns[color][uIndex] = cSquare; + pos->u64PawnSig ^= g_u64PawnSigSeeds[cSquare][color]; + } + else + { + // + // Piece is not a pawn + // + ASSERT(pv > VALUE_PAWN); + pos->uNonPawnMaterial[color] += pv; + ASSERT(pos->uNonPawnMaterial[color] <= VALUE_MAX_ARMY); + uIndex = pos->uNonPawnCount[color][0]; + pos->uNonPawnCount[color][0]++; + ASSERT(pos->uNonPawnCount[color][0] <= 16); + pos->cNonPawns[color][uIndex] = cSquare; + + u = PIECE_TYPE(pPiece); + ASSERT((u >= KNIGHT) && (u < KING)); + pos->u64NonPawnSig ^= g_u64SigSeeds[cSquare][u][color]; + pos->uNonPawnCount[color][u]++; + ASSERT(pos->uNonPawnCount[color][u] <= 10); + + pos->uWhiteSqBishopCount[color] += (IS_BISHOP(pPiece) & + IS_SQUARE_WHITE(cSquare)); + ASSERT(pos->uWhiteSqBishopCount[color] <= 10); + } + + // + // Place the piece on the board + // + pos->rgSquare[cSquare].pPiece = pPiece; + pos->rgSquare[cSquare].uIndex = uIndex; + +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); +#endif +} + + +void +PlacePieceWithoutSigs(POSITION *pos, COOR cSquare, PIECE pPiece) +/** + +Routine description: + + Place a piece back on the board. Link it into the right piece list. + + Note: PlacePieceWithoutSigs can _only_ be called from UnmakeMove. + It is used to unmake a previously made move and therefore does + not worry about updating position signatures. UnmakeMove has + the pre-move signature in a history list and will klobber the + position signature soon anyway. + +Parameters: + + POSITION *pos, + COOR cSquare, + PIECE pPiece + +Return value: + + void + +**/ +{ + register ULONG color = GET_COLOR(pPiece); + register ULONG uIndex; + register SCORE pv; + ULONG u; + + ASSERT(IS_EMPTY(pos->rgSquare[cSquare].pPiece)); + ASSERT(!IS_KING(pPiece)); + + pv = PIECE_VALUE(pPiece); + pos->iMaterialBalance[color] += pv; + pos->iMaterialBalance[FLIP(color)] -= pv; + ASSERT(pos->iMaterialBalance[WHITE] * -1 == pos->iMaterialBalance[BLACK]); + + if (IS_PAWN(pPiece)) + { + // + // Piece is a pawn + // + ASSERT(pv == VALUE_PAWN); + pos->uPawnMaterial[color] += pv; + ASSERT(pos->uPawnMaterial[color] <= (8 * VALUE_PAWN)); + + uIndex = pos->uPawnCount[color]; + ASSERT((uIndex >= 0) && (uIndex <= 7)); + pos->uPawnCount[color]++; + ASSERT(pos->uPawnCount[color] <= 8); + pos->cPawns[color][uIndex] = cSquare; + } + else + { + // + // Piece is not a pawn + // + ASSERT(pv > VALUE_PAWN); + pos->uNonPawnMaterial[color] += pv; + ASSERT(pos->uNonPawnMaterial[color] <= VALUE_MAX_ARMY); + uIndex = pos->uNonPawnCount[color][0]; + pos->uNonPawnCount[color][0]++; + ASSERT(pos->uNonPawnCount[color][0] <= 16); + pos->cNonPawns[color][uIndex] = cSquare; + + u = PIECE_TYPE(pPiece); + ASSERT((u >= KNIGHT) && (u < KING)); + pos->uNonPawnCount[color][u]++; + ASSERT(pos->uNonPawnCount[color][u] <= 10); + + pos->uWhiteSqBishopCount[color] += (IS_BISHOP(pPiece) & + IS_SQUARE_WHITE(cSquare)); + ASSERT(pos->uWhiteSqBishopCount[color] <= 10); + } + + // + // Place the piece on the board + // + pos->rgSquare[cSquare].pPiece = pPiece; + pos->rgSquare[cSquare].uIndex = uIndex; +} + + +void +SaveCurrentPositionHistoryInContext(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv) +/** + +Routine description: + + This routine is called just before MakeMove to record some + information about the current board position to help unmake the + move later. It's also used to detect draws in the search. + + Note: when this function is called, ply has not been incremented. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG uPly = ctx->uPly; + POSITION *pos = &(ctx->sPosition); + PLY_INFO *pi = &ctx->sPlyInfo[uPly]; + + // + // Save data about the position we are leaving. + // + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + ASSERT((pos->u64NonPawnSig & 1) == pos->uToMove); + pi->u64NonPawnSig = pos->u64NonPawnSig; + pi->u64PawnSig = pos->u64PawnSig; + pi->u64Sig = (pos->u64NonPawnSig ^ pos->u64PawnSig); + pi->uFifty = pos->uFifty; + pi->fCastled[BLACK] = pos->fCastled[BLACK]; + pi->fCastled[WHITE] = pos->fCastled[WHITE]; + pi->uTotalNonPawns = (pos->uNonPawnCount[BLACK][0] + + pos->uNonPawnCount[WHITE][0]); + ASSERT(IS_VALID_FLAG(pos->fCastled[WHITE]) && + IS_VALID_FLAG(pos->fCastled[BLACK])); + ASSERT((pos->bvCastleInfo & ~CASTLE_ALL_POSSIBLE) == 0); + pi->bvCastleInfo = pos->bvCastleInfo; + ASSERT(VALID_EP_SQUARE(pos->cEpSquare)); + pi->cEpSquare = pos->cEpSquare; + (pi+1)->fInQsearch = pi->fInQsearch; +} + + +static ULONG g_uCastleMask[128] = +{ + 0x7, 0xF, 0xF, 0xF, 0x3, 0xF, 0xF, 0xB, 0,0,0,0,0,0,0,0, + 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0,0,0,0,0,0,0,0, + 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0,0,0,0,0,0,0,0, + 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0,0,0,0,0,0,0,0, + 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0,0,0,0,0,0,0,0, + 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0,0,0,0,0,0,0,0, + 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0xF, 0,0,0,0,0,0,0,0, + 0xD, 0xF, 0xF, 0xF, 0xC, 0xF, 0xF, 0xE, 0,0,0,0,0,0,0,0 +}; + + +FLAG +MakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv) +/** + +Routine description: + + Attempts to make MOVE mv on the POSITION in ctx. Returns TRUE if + the move was successful, FALSE if it was illegal. If the move was + successful, this function affects the POSITION (piece locations, + piece lists, castling perms, en-passant square, signatures etc...) + and also increments the ply in ctx. These changes can be reverted + at a later point by using UnmakeMove. + + Note: This function only does a very limited amount of legality + checking in order to save time because it is designed to take + moves from the move generator (which will only make illegal moves + in certain, known ways). If the move is coming from the user + (and is therefore of dubious legality)) it should be passed to + MakeUserMove, not MakeMove. MakeUserMove verifies that it is a + legal chess move in every way. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + MOVE mv + +Return value: + + FLAG + +**/ +{ + POSITION *pos = &ctx->sPosition; + PIECE pPiece; + PIECE pCaptured; + PIECE pPromoted; + COOR c; + COOR cRookFrom; + COOR cRookTo; + COOR cKing; + PIECE xPawn; + FLAG fMoveIsLegal = FALSE; + static int iSign[2] = { -1, +1 }; + +#ifdef DEBUG + cRookFrom = cRookTo = ILLEGAL_COOR; // Satisfy overzealous compiler + VerifyPositionConsistency(pos, FALSE); + SanityCheckMove(pos, mv); + ASSERT(!InCheck(pos, FLIP(pos->uToMove))); + if (InCheck(pos, pos->uToMove)) + { + ASSERT(IS_ESCAPING_CHECK(mv)); + } +#endif + SaveCurrentPositionHistoryInContext(ctx, mv); + if (mv.uMove == 0) + { + pos->uFifty++; + goto clear_ep; + } + + pPiece = mv.pMoved; + pCaptured = mv.pCaptured; + ASSERT(!IS_EMPTY(pPiece)); + ASSERT(pPiece == pos->rgSquare[mv.cFrom].pPiece); + ASSERT(GET_COLOR(pPiece) == pos->uToMove); + + // + // Is this a special move? Special moves are: promotions, enpassant, + // castling and double pawn moves. + // + if (IS_SPECIAL_MOVE(mv)) + { + if (IS_PAWN(pPiece)) + { + pPromoted = mv.pPromoted; + if (pPromoted) + { + ASSERT(!IS_PAWN(pPromoted)); + ASSERT(GET_COLOR(pPromoted) == GET_COLOR(pPiece)); + pPiece = LiftPiece(pos, mv.cFrom); + pCaptured = LiftPiece(pos, mv.cTo); + ASSERT(!pCaptured || (OPPOSITE_COLORS(pCaptured, pPiece))); + PlacePiece(pos, mv.cTo, pPromoted); + pos->uFifty = 0; + goto update_castle_and_clear_ep; + } + + // + // Is this an enpassant capture? + // + else if (pCaptured) + { + ASSERT(mv.cTo == pos->cEpSquare); + pCaptured = LiftPiece(pos, mv.cTo + + iSign[GET_COLOR(pPiece)] * 16); + ASSERT(IS_PAWN(pCaptured)); + ASSERT(OPPOSITE_COLORS(pPiece, pCaptured)); + ASSERT(IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)); + ASSERT(IS_PAWN(pPiece)); + SlidePawn(pos, mv.cFrom, mv.cTo); + pos->uFifty = 0; + goto clear_ep; + } + + // + // A special pawn move other than promotion and enpassant + // capture must be a double initial jump. + // + else + { + c = mv.cFrom; + c += (iSign[GET_COLOR(pPiece)] * -16); + ASSERT(RANK3(c) || RANK6(c)); + ASSERT(c + (iSign[GET_COLOR(pPiece)] * -16) == mv.cTo); + ASSERT(IS_EMPTY(pos->rgSquare[c].pPiece)); + ASSERT(IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)); + ASSERT(IS_PAWN(pPiece)); + SlidePawn(pos, mv.cFrom, mv.cTo); + pos->uFifty = 0; + + // + // Only change the position signature to reflect the + // possible en-passant if there's an enemy who can + // take advantage of it. + // + xPawn = BLACK_PAWN | FLIP(GET_COLOR(pPiece)); + if (((!IS_ON_BOARD(mv.cTo - 1)) || + (pos->rgSquare[mv.cTo - 1].pPiece != xPawn)) && + ((!IS_ON_BOARD(mv.cTo + 1)) || + (pos->rgSquare[mv.cTo + 1].pPiece != xPawn))) + { + goto clear_ep; + } + pos->u64NonPawnSig ^= g_u64EpSigSeeds[FILE(pos->cEpSquare)]; + ASSERT(VALID_EP_SQUARE(c)); + pos->cEpSquare = c; + pos->u64NonPawnSig ^= g_u64EpSigSeeds[FILE(pos->cEpSquare)]; + goto update_board; + } + } + else if (IS_KING(pPiece)) + { + ASSERT(!IS_ESCAPING_CHECK(mv)); + + // + // The only special king move is a castle. + // + switch (mv.cTo) + { + case C1: + ASSERT(pos->bvCastleInfo & CASTLE_WHITE_LONG); + ASSERT(IS_EMPTY(pos->rgSquare[B1].pPiece) && + IS_EMPTY(pos->rgSquare[C1].pPiece) && + IS_EMPTY(pos->rgSquare[D1].pPiece)); + if ((IsAttacked(D1, pos, BLACK)) || + (IsAttacked(C1, pos, BLACK))) + { + goto illegal; + } + cRookFrom = A1; + cRookTo = D1; + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->bvCastleInfo &= ~(WHITE_CAN_CASTLE); + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->fCastled[WHITE] = TRUE; + break; + case G1: + ASSERT(pos->bvCastleInfo & CASTLE_WHITE_SHORT); + ASSERT(IS_EMPTY(pos->rgSquare[F1].pPiece) && + IS_EMPTY(pos->rgSquare[G1].pPiece)); + if ((IsAttacked(F1, pos, BLACK)) || + (IsAttacked(G1, pos, BLACK))) + { + goto illegal; + } + cRookFrom = H1; + cRookTo = F1; + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->bvCastleInfo &= ~(WHITE_CAN_CASTLE); + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->fCastled[WHITE] = TRUE; + break; + case C8: + ASSERT(pos->bvCastleInfo & CASTLE_BLACK_LONG); + ASSERT(IS_EMPTY(pos->rgSquare[B8].pPiece) && + IS_EMPTY(pos->rgSquare[C8].pPiece) && + IS_EMPTY(pos->rgSquare[D8].pPiece)); + if ((IsAttacked(D8, pos, WHITE)) || + (IsAttacked(C8, pos, WHITE))) + { + goto illegal; + } + cRookFrom = A8; + cRookTo = D8; + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->bvCastleInfo &= ~(BLACK_CAN_CASTLE); + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->fCastled[BLACK] = TRUE; + break; + case G8: + ASSERT(pos->bvCastleInfo & CASTLE_BLACK_SHORT); + ASSERT(IS_EMPTY(pos->rgSquare[F8].pPiece) && + IS_EMPTY(pos->rgSquare[G8].pPiece)); + if ((IsAttacked(F8, pos, WHITE)) || + (IsAttacked(G8, pos, WHITE))) + { + goto illegal; + } + cRookFrom = H8; + cRookTo = F8; + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->bvCastleInfo &= ~(BLACK_CAN_CASTLE); + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->fCastled[BLACK] = TRUE; + break; +#ifdef DEBUG + default: + cRookFrom = cRookTo = ILLEGAL_COOR; + ASSERT(FALSE); + goto illegal; +#endif + } + ASSERT(IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)); + ASSERT(IS_ROOK(pos->rgSquare[cRookFrom].pPiece)); + ASSERT(IS_EMPTY(pos->rgSquare[cRookTo].pPiece)); + SlidePiece(pos, mv.cFrom, mv.cTo); // king + SlidePiece(pos, cRookFrom, cRookTo); // rook + pos->uFifty = 0; + goto clear_ep; + } +#ifdef DEBUG + else + { + ASSERT(FALSE); + goto illegal; + } +#endif + } + + // + // Normal move or normal capture + // + pos->uFifty++; + if (pCaptured) + { + pos->uFifty = 0; + pCaptured = LiftPiece(pos, mv.cTo); + ASSERT(!IS_KING(pCaptured)); + ASSERT(!IS_EMPTY(pCaptured)); + ASSERT(OPPOSITE_COLORS(pCaptured, pPiece)); + } + if (IS_PAWN(pPiece)) + { + pos->uFifty = 0; + SlidePawn(pos, mv.cFrom, mv.cTo); + } + else + { + SlidePiece(pos, mv.cFrom, mv.cTo); + } + + update_castle_and_clear_ep: + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + pos->bvCastleInfo &= g_uCastleMask[mv.cFrom]; + pos->bvCastleInfo &= g_uCastleMask[mv.cTo]; + pos->u64NonPawnSig ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + + clear_ep: + if (pos->cEpSquare != ILLEGAL_COOR) + { + pos->u64NonPawnSig ^= g_u64EpSigSeeds[FILE(pos->cEpSquare)]; + pos->cEpSquare = ILLEGAL_COOR; + pos->u64NonPawnSig ^= g_u64EpSigSeeds[FILE(pos->cEpSquare)]; + } + + update_board: + // + // At this point we have made the move on the board (moved pieces, + // updated castling permissions, updated 50 move count, updated + // signature with respect to piece location etc...) + // + // Now we switch the side on move and flip a bit in the signature + // to indicate that it's the other side's turn now. We also + // record this position in the movelist (for later detection of + // repetition of position draws) and increment either the ply or + // move num. + // + pos->u64NonPawnSig ^= 1; + pos->uToMove = FLIP(pos->uToMove); + ASSERT((pos->u64NonPawnSig & 1) == pos->uToMove); + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH - 1); + ctx->sPlyInfo[ctx->uPly].mv = mv; + ctx->uPly++; + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + + // + // Make sure the move doesn't leave his own king in check. + // + if (mv.uMove != 0) + { + cKing = pos->cNonPawns[FLIP(pos->uToMove)][0]; + ASSERT(IS_KING(pos->rgSquare[cKing].pPiece)); + + if (IS_KING(mv.pMoved) || IS_ESCAPING_CHECK(mv)) + { + // + // If this guy just moved his king OR he was in check + // before making this move we need to do a full check + // check now... this involves using the attack vector + // table to test ALL pieces in the enemy army and see if + // they are attacking the just-moved king. + // + ASSERT(GET_COLOR(mv.pMoved) == FLIP(pos->uToMove)); + if (InCheck(pos, GET_COLOR(mv.pMoved))) + { + goto takeback; + } + } + + // + // else he did not move the king and he was not in check + // before he made this move. To determine if he is in check + // now should be cheaper because all we have to consider is + // whether the move he just made exposed his king to check. + // + else + { + // + // This call will also catch positions like: + // + // 3K4/8/8/8/1k1Pp1R1/8/8/8 w - d3 0 1 + // + // ... where the black pawn capturing on d3 exposes his + // own king to the white rook's horizontal attack. + // Because the pawn captured en passant has already been + // lifted. + // + if (IS_ON_BOARD(ExposesCheck(pos, mv.cFrom, cKing))) + { + ASSERT(InCheck(pos, GET_COLOR(mv.pMoved))); + goto takeback; + } + + // + // This is a special case -- if the move was enpassant the + // guy might have exposed his king to check by removing + // the enemy pawn (i.e. exposes a diagonal attack on his + // own king) + // + if (IS_ENPASSANT(mv)) + { + ASSERT(IS_SPECIAL_MOVE(mv)); + ASSERT(!IS_PROMOTION(mv)); + ASSERT(mv.pCaptured); + ASSERT(IS_PAWN(mv.pMoved)); + ASSERT(IS_PAWN(mv.pCaptured)); + if (IS_ON_BOARD(ExposesCheck(pos, + ((pos->uToMove == WHITE) ? + (mv.cTo + 16) : + (mv.cTo - 16)), + cKing))) + { + ASSERT(InCheck(pos, GET_COLOR(mv.pMoved))); + goto takeback; + } + } + } + ASSERT(IS_EMPTY(pos->rgSquare[mv.cFrom].pPiece)); + ASSERT(!IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)); + ASSERT((pos->rgSquare[mv.cTo].pPiece == mv.pMoved) || + (pos->rgSquare[mv.cTo].pPiece == mv.pPromoted)); + } + ASSERT(!InCheck(pos, GET_COLOR(mv.pMoved))); + fMoveIsLegal = TRUE; +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); +#endif + // + // Fall into illegal... but don't worry: we're legal! + // + + illegal: + return(fMoveIsLegal); + + takeback: + // + // If we goto here it means that the guy is trying to move into + // check. We didn't determine this until after we already made + // the whole move so we can't just return false (illegal move) + // from there. First we have to unmake the move we just made. + // + ASSERT(InCheck(pos, FLIP(pos->uToMove))); + UnmakeMove(ctx, mv); +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); +#endif + return(FALSE); +} + + +FLAG +MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mvUser) +/** + +Routine description: + + This function should be called to make a move of dubious quality. + The engine calls MakeMove directly for moves it generated itself + because these are _mostly_ legal. The only exceptions being: + + 1. moves that expose the friendly king to check + 2. castles through check + + This function is intended for moves from a user or ICS. It + screens these moves by first generating available moves at this + ply and making sure it looks like one of them. It returns + TRUE if the move is legal and was played, FALSE otherwise. + + Both moves made with MakeMove and MakeUserMove can be unmade + with UnmakeMove. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + MOVE mvUser + +Return value: + + FLAG + +**/ +{ + POSITION *pos = &ctx->sPosition; + FLAG fInCheck = InCheck(pos, pos->uToMove); + FLAG fRet = FALSE; + MOVE mv; + ULONG x; + + // + // Ask the generator to give us a list of moves here + // + mv.uMove = 0; + GenerateMoves(ctx, mv, (fInCheck ? GENERATE_ESCAPES : GENERATE_ALL_MOVES)); + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + mv = ctx->sMoveStack.mvf[x].mv; + if (IS_SAME_MOVE(mvUser, mv)) + { + if (TRUE == MakeMove(ctx, mv)) + { + fRet = TRUE; + goto end; + } + } + } + + end: + return(fRet); +} + + +void +UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv) +/** + +Routine description: + + Reverses a move made by MakeMove. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv + +Return value: + + void + +**/ +{ + PIECE pPiece; + PIECE pCaptured; + PLY_INFO *pi; + POSITION *pos = &(ctx->sPosition); + static int iSign[2] = { -1, +1 }; + +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); + ASSERT(IS_ON_BOARD(mv.cTo)); + ASSERT(IS_ON_BOARD(mv.cFrom)); +#endif + if (mv.uMove == 0) + { + goto restore_saved_position_data; + } + + pPiece = mv.pMoved; + pCaptured = mv.pCaptured; + if (IS_CASTLE(mv)) + { + ASSERT(IS_KING(pPiece)); + ASSERT(IS_SPECIAL_MOVE(mv)); + + switch (mv.cTo) + { + case C1: + // + // No need to call SlidePiece here, the signatures will + // get reset to their pre-move state below + // + SlidePieceWithoutSigs(pos, D1, A1); // rook + SlidePieceWithoutSigs(pos, C1, E1); // king + ASSERT(IS_KING(pos->rgSquare[E1].pPiece)); + ASSERT(IS_ROOK(pos->rgSquare[A1].pPiece)); + break; + case G1: + SlidePieceWithoutSigs(pos, F1, H1); // rook + SlidePieceWithoutSigs(pos, G1, E1); // king + ASSERT(IS_KING(pos->rgSquare[E1].pPiece)); + ASSERT(IS_ROOK(pos->rgSquare[H1].pPiece)); + break; + case C8: + SlidePieceWithoutSigs(pos, D8, A8); // rook + SlidePieceWithoutSigs(pos, C8, E8); // king + ASSERT(IS_KING(pos->rgSquare[E8].pPiece)); + ASSERT(IS_ROOK(pos->rgSquare[A8].pPiece)); + break; + case G8: + SlidePieceWithoutSigs(pos, F8, H8); // rook + SlidePieceWithoutSigs(pos, G8, E8); // king + ASSERT(IS_KING(pos->rgSquare[E8].pPiece)); + ASSERT(IS_ROOK(pos->rgSquare[H8].pPiece)); + break; +#ifdef DEBUG + default: + ASSERT(FALSE); + break; +#endif + } + } + else + { + if (IS_PROMOTION(mv)) + { + ASSERT(IS_SPECIAL_MOVE(mv)); + ASSERT(mv.pPromoted); + + // + // LiftPiece/PlacePiece must be done here to maintain + // piece list integrity. + // + (void)LiftPieceWithoutSigs(pos, mv.cTo); + pPiece |= 2; + pPiece &= 3; + ASSERT(pPiece == mv.pMoved); + PlacePieceWithoutSigs(pos, mv.cFrom, pPiece); + } + else + { + if (IS_PAWN(pPiece)) + { + SlidePawnWithoutSigs(pos, mv.cTo, mv.cFrom); + } + else + { + SlidePieceWithoutSigs(pos, mv.cTo, mv.cFrom); + } + } + + if (pCaptured) + { + // + // If this was an enpassant capture, put the pawn back to the + // right square. + // + if (IS_ENPASSANT(mv)) + { + ASSERT(IS_SPECIAL_MOVE(mv)); + ASSERT(IS_PAWN(mv.pMoved)); + ASSERT(IS_PAWN(pCaptured)); + ASSERT(IS_ON_BOARD(mv.cTo) + 16); + ASSERT(IS_ON_BOARD(mv.cTo) - 16); + + // + // Resurrect the dead piece in the enpassant location + // where it died (not the same as where the killer moved). + // + ASSERT(IS_EMPTY(pos->rgSquare[mv.cTo + 16 * + iSign[GET_COLOR(mv.pMoved)]].pPiece)); + PlacePieceWithoutSigs(pos, + mv.cTo + 16 * iSign[GET_COLOR(mv.pMoved)], + pCaptured); + } + else + { + // + // Normal capture... resurrect the dead piece where the + // killer moved. + // + ASSERT(IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)); + PlacePieceWithoutSigs(pos, mv.cTo, pCaptured); + } + } + } + + restore_saved_position_data: + ctx->uPly--; + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + + pi = &ctx->sPlyInfo[ctx->uPly]; + pos->u64NonPawnSig = pi->u64NonPawnSig; + pos->u64PawnSig = pi->u64PawnSig; + ASSERT((pos->u64NonPawnSig & WHITE) == FLIP(pos->uToMove)); + pos->uFifty = pi->uFifty; + pos->fCastled[WHITE] = pi->fCastled[WHITE]; + pos->fCastled[BLACK] = pi->fCastled[BLACK]; + ASSERT((pi->bvCastleInfo & ~CASTLE_ALL_POSSIBLE) == 0); + pos->bvCastleInfo = pi->bvCastleInfo; + ASSERT(VALID_EP_SQUARE(pi->cEpSquare)); + ASSERT(VALID_EP_SQUARE(pos->cEpSquare)); + pos->cEpSquare = pi->cEpSquare; + pos->uToMove = FLIP(pos->uToMove); +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); +#endif +} + + +static char * +_MoveFlagsToString(BITV bv) +/** + +Routine description: + + Support routing for DumpMove. Translates bvFlags component of a + MOVE into a nice string. Not thread safe. + +Parameters: + + BITV bv + +Return value: + + char + +**/ +{ + static char buf[5]; + char *p = buf; + + if (bv & MOVE_FLAG_SPECIAL) + { + *p++ = 'S'; + } + if (bv & MOVE_FLAG_ESCAPING_CHECK) + { + *p++ = 'E'; + } + if (bv & MOVE_FLAG_CHECKING) + { + *p++ = '+'; + } + if (bv & MOVE_FLAG_KILLERMATE) + { + *p++ = '!'; + } + *p++ = '\0'; + return(buf); +} + + +void +DumpMove(ULONG u) +/** + +Routine description: + + Dump a move on stdout. This function takes a ULONG instead of a + MOVE becasue both gdb and msdev do not like to pass unions to + functions invoked at debugtime. + +Parameters: + + ULONG u + +Return value: + + void + +**/ +{ + MOVE mv; + + mv.uMove = u; + Trace("--------------------------------------------------------------------------------\n" + "MOVE:\n" + " +0x000 uMove : 0x%x\n" + " +0x000 cFrom : 0x%x (%s)\n", + mv.uMove, + mv.cFrom, CoorToString(mv.cFrom)); + Trace(" +0x001 cTo : 0x%x (%s)\n" + " +0x002 pMoved : 0x%x (%s)\n", + mv.cTo, CoorToString(mv.cTo), + mv.pMoved, PieceAbbrev(mv.pMoved)); + Trace(" +0x002 pCaptured : 0x%x (%s)\n", + mv.pCaptured, PieceAbbrev(mv.pCaptured)); + Trace(" +0x003 pPromoted : 0x%x (%s)\n", + mv.pPromoted, PieceAbbrev(mv.pPromoted)); + Trace(" +0x003 bvFlags : 0x%x (%s)\n", + mv.bvFlags, _MoveFlagsToString(mv.bvFlags)); +} diff --git a/src/movesup.c b/src/movesup.c new file mode 100755 index 0000000..8aa8ffa --- /dev/null +++ b/src/movesup.c @@ -0,0 +1,1303 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + movesup.c + +Abstract: + + Functions to support MakeMove and UnmakeMove along with some other + miscellanious move support functions. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 13 May 2004 + +Revision History: + + $Id: movesup.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +COOR +FasterExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation) +/** + +Routine description: + + This is just like ExposesCheck (see below) but it does not bother + checking whether its possible to expose check with the piece at + cRemove because we already know it is. + +Parameters: + + POSITION *pos, + COOR cRemove, + COOR cLocation + +Return value: + + COOR + +**/ +{ + register int iDelta; + register COOR cBlockIndex; + int iIndex; + PIECE xPiece; + ULONG uColor = GET_COLOR(pos->rgSquare[cLocation].pPiece); + + ASSERT(IS_KING(pos->rgSquare[cLocation].pPiece)); + iIndex = (int)cLocation - (int)cRemove; + + ASSERT(IS_ON_BOARD(cRemove)); + ASSERT(IS_ON_BOARD(cLocation)); + ASSERT(!IS_EMPTY(pos->rgSquare[cLocation].pPiece)); + ASSERT(0 != (CHECK_VECTOR_WITH_INDEX(iIndex, BLACK) & (1 << QUEEN))); + + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + ASSERT(iDelta != 0); + + for (cBlockIndex = cRemove + iDelta; + IS_ON_BOARD(cBlockIndex); + cBlockIndex += iDelta) + { + ASSERT(cBlockIndex != cRemove); + ASSERT(cBlockIndex != cLocation); + xPiece = pos->rgSquare[cBlockIndex].pPiece; + if (!IS_EMPTY(xPiece)) + { + // + // Is it an enemy? + // + if (OPPOSITE_COLORS(xPiece, uColor)) + { + // + // Does it move the right way to attack? + // + iIndex = (int)cBlockIndex - (int)cLocation; + if (0 != (CHECK_VECTOR_WITH_INDEX(iIndex, WHITE) & + (1 << (PIECE_TYPE(xPiece))))) + { + return(cBlockIndex); + } + } + + // + // Either we found another friendly piece or an enemy piece + // that was unable to reach us. Either way we are safe. + // + return(ILLEGAL_COOR); + } + } + + // + // We fell off the board without seeing another piece. + // + return(ILLEGAL_COOR); +} + + + +COOR +ExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation) +/** + +Routine description: + + Test if removing the piece at cRemove exposes the piece at + cLocation to attack by the other side. Note: there must be a + piece at cLocation because the color of that piece is used to + determine what side is "checking" and what side is "being + checked". + +Parameters: + + POSITION *pos : the board + COOR cRemove : the square where a piece hypothetically removed from + COOR cLocation : the square where the attackee is sitting + +Return value: + + COOR : the location of an attacker piece or 0x88 (!IS_ON_BOARD) if + the removal of cRemove does not expose check. + +**/ +{ + register int iDelta; + register COOR cBlockIndex; + int iIndex; + PIECE xPiece; + + ASSERT(IS_ON_BOARD(cRemove)); + ASSERT(IS_ON_BOARD(cLocation)); + ASSERT(!IS_EMPTY(pos->rgSquare[cLocation].pPiece)); + + iIndex = (int)cLocation - (int)cRemove; + + // + // If there is no way for a queen sitting at the square removed to + // reach the square we are testing (i.e. the two squares are not + // on the same rank, file, or diagonal) then there is no way + // removing it can expose cLocation to check. + // + if (0 == (CHECK_VECTOR_WITH_INDEX(iIndex, BLACK) & (1 << QUEEN))) + { + return(ILLEGAL_COOR); + } + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + for (cBlockIndex = cLocation + iDelta; + IS_ON_BOARD(cBlockIndex); + cBlockIndex += iDelta) + { + if (cBlockIndex == cRemove) + { + continue; + } + xPiece = pos->rgSquare[cBlockIndex].pPiece; + if (!IS_EMPTY(xPiece)) + { + // + // Is it an enemy? + // + if (OPPOSITE_COLORS(xPiece, pos->rgSquare[cLocation].pPiece)) + { + // + // Does it move the right way to attack? + // + iIndex = (int)cBlockIndex - (int)cLocation; + if (0 != (CHECK_VECTOR_WITH_INDEX(iIndex, GET_COLOR(xPiece)) & + (1 << (PIECE_TYPE(xPiece))))) + { + return(cBlockIndex); + } + } + + // + // Either we found another friendly piece or an enemy piece + // that was unable to reach us. Either way we are safe. + // + return(ILLEGAL_COOR); + } + } + + // + // We fell off the board without seeing another piece. + // + return(ILLEGAL_COOR); +} + + +COOR +ExposesCheckEp(POSITION *pos, + COOR cTest, + COOR cIgnore, + COOR cBlock, + COOR cKing) +/** + +Routine description: + +Parameters: + + POSITION *pos, + COOR cTest : The square from whence the attack comes + COOR cIgnore : Ignore this square, the pawn moved + COOR cBlock : This square is where the pawn moved to and now blocks + COOR cKing : The square under attack + +Return value: + + COOR + +**/ +{ + register int iDelta; + register COOR cBlockIndex; + int iIndex; + PIECE xPiece; + + ASSERT(IS_ON_BOARD(cTest)); + ASSERT(IS_ON_BOARD(cIgnore)); + ASSERT(IS_ON_BOARD(cBlock)); + ASSERT(IS_ON_BOARD(cKing)); + + iIndex = (int)cKing - (int)cTest; + + // + // If there is no way for a queen sitting at the square removed to + // reach the square we are testing (i.e. the two squares are not + // on the same rank, file, or diagonal) then no problemo. + // + if (0 == (CHECK_VECTOR_WITH_INDEX(iIndex, BLACK) & (1 << QUEEN))) + { + return(ILLEGAL_COOR); + } + + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + for (cBlockIndex = cKing + iDelta; + IS_ON_BOARD(cBlockIndex); + cBlockIndex += iDelta) + { + if (cBlockIndex == cTest) continue; + if (cBlockIndex == cIgnore) continue; + if (cBlockIndex == cBlock) return(ILLEGAL_COOR); + + xPiece = pos->rgSquare[cBlockIndex].pPiece; + if (!IS_EMPTY(xPiece)) + { + if (OPPOSITE_COLORS(xPiece, pos->rgSquare[cKing].pPiece)) + { + // + // Does it move the right way to attack? + // + iIndex = (int)cBlockIndex - (int)cKing; + if (0 != (CHECK_VECTOR_WITH_INDEX(iIndex, GET_COLOR(xPiece)) & + (1 << (PIECE_TYPE(xPiece))))) + { + return(cBlockIndex); + } + } + + // + // Either we found another friendly piece or an enemy piece + // that was unable to reach us. Either way we are safe. + // + return(ILLEGAL_COOR); + } + } + + // + // We fell off the board without seeing another piece. + // + return(ILLEGAL_COOR); +} + + +FLAG +IsAttacked(COOR cTest, POSITION *pos, ULONG uSide) +/** + +Routine description: + + Determine whether the square cTest is attacked by the side uSide. + +Parameters: + + COOR cTest : the square we want to determine if is under attack + POSITION *pos : the board + ULONG uSide : the side we want to see if is attacking cTest + +Return value: + + FLAG : TRUE if uSide attacks cTest, FALSE otherwise + +**/ +{ + ULONG u; + PIECE pPiece; + COOR cLocation; + COOR cBlockIndex; + int iIndex; + int iDelta; + static int iPawnLoc[2] = { -17, +15 }; + static PIECE pPawn[2] = { BLACK_PAWN, WHITE_PAWN }; + + ASSERT(IS_ON_BOARD(cTest)); + ASSERT(IS_VALID_COLOR(uSide)); + ASSERT((pos->uNonPawnCount[uSide][0] - 1) < 16); + + // + // Begin at the end because the king is the 0th item in the list and + // we want to consider king moves last. + // + for (u = pos->uNonPawnCount[uSide][0] - 1; + u != (ULONG)-1; + u--) + { + cLocation = pos->cNonPawns[uSide][u]; + ASSERT(IS_ON_BOARD(cLocation)); + pPiece = pos->rgSquare[cLocation].pPiece; + ASSERT(!IS_EMPTY(pPiece)); + ASSERT(!IS_PAWN(pPiece)); + ASSERT(GET_COLOR(pPiece) == uSide); + iIndex = (int)cLocation - (int)cTest; + + if (!(CHECK_VECTOR_WITH_INDEX(iIndex, uSide) & + (1 << (PIECE_TYPE(pPiece))))) + { + continue; + } + + // + // These pieces do not slide, we don't need to look for + // blockers. If they can get there then there is nothing + // we can do to stop them. + // + if (IS_KNIGHT(pPiece) || IS_KING(pPiece)) + { + return(TRUE); + } + + // + // Well, here we have a sliding piece (bishop, rook or queen) + // that is on the same line (file, rank or diagonal) as the + // cTest. We now have to see if the attacker (pPiece) is + // blocked or is free to attack cTest. + // + iDelta = NEG_DELTA_WITH_INDEX(iIndex); + for (cBlockIndex = cTest + iDelta; + cBlockIndex != cLocation; + cBlockIndex += iDelta) + { + if (!IS_EMPTY(pos->rgSquare[cBlockIndex].pPiece)) + { + break; + } + } + if (cBlockIndex == cLocation) + { + return(TRUE); + } + } + + // + // Check the locations a pawn could attack cTest from. + // + cLocation = cTest + iPawnLoc[uSide]; + if (IS_ON_BOARD(cLocation) && + (pos->rgSquare[cLocation].pPiece == pPawn[uSide])) + { + return(TRUE); + } + + cLocation += 2; + if (IS_ON_BOARD(cLocation) && + (pos->rgSquare[cLocation].pPiece == pPawn[uSide])) + { + return(TRUE); + } + return(FALSE); +} + + +FLAG +InCheck(POSITION *pos, ULONG uSide) +/** + +Routine description: + + Determine if a side is in check or not. + +Parameters: + + POSITION *pos : the board + ULONG uSide : the side we want to determine if is in check + +Return value: + + FLAG : TRUE if side is in check, FALSE otherwise. + +**/ +{ + COOR cKingLoc; +#ifdef DEBUG + PIECE pKing; +#endif + + ASSERT(IS_VALID_COLOR(uSide)); + + cKingLoc = pos->cNonPawns[uSide][0]; +#ifdef DEBUG + pKing = pos->rgSquare[cKingLoc].pPiece; + ASSERT(IS_KING(pKing)); + ASSERT(IS_VALID_COLOR(uSide)); + ASSERT(GET_COLOR(pKing) == uSide); +#endif + return(IsAttacked(cKingLoc, pos, FLIP(uSide))); +} + + +static FLAG +_SanityCheckPawnMove(POSITION *pos, MOVE mv) +/** + +Routine description: + +Parameters: + + POSITION *pos, + MOVE mv + +Return value: + + FLAG + +**/ +{ + PIECE p = mv.pMoved; + COOR cFrom = mv.cFrom; + COOR cTo = mv.cTo; + + ASSERT(mv.uMove); + ASSERT(IS_PAWN(p)); + + // + // General sanity checking... + // + if (!IS_ON_BOARD(cFrom) || !IS_ON_BOARD(cTo)) + { + return(FALSE); + } + + // + // Sanity check promotions. + // + if (mv.pPromoted) + { + if (GET_COLOR(p) == WHITE) + { + if ((RANK(cTo) != 8) && (RANK(cFrom) != 7)) return(FALSE); + } + else + { + if ((RANK(cTo) != 1) && (RANK(cFrom) != 2)) return(FALSE); + } + + if (!IS_KNIGHT(mv.pPromoted) && + !IS_BISHOP(mv.pPromoted) && + !IS_ROOK(mv.pPromoted) && + !IS_QUEEN(mv.pPromoted)) + { + return(FALSE); + } + } + + // + // Handle capture moves. + // + if (mv.pCaptured) + { + // + // Must be capturing something + // + if (IS_SPECIAL_MOVE(mv) && (!mv.pPromoted)) + { + // + // en passant + // + if (!IS_EMPTY(pos->rgSquare[cTo].pPiece)) return(FALSE); + } + else + { + // + // normal capture + // + if (IS_EMPTY(pos->rgSquare[cTo].pPiece)) return(FALSE); + if (!OPPOSITE_COLORS(mv.pMoved, mv.pCaptured)) return(FALSE); + } + + // + // Must be in the capturing position. + // + if (WHITE == GET_COLOR(p)) + { + if (((cFrom - 17) != cTo) && ((cFrom - 15) != cTo)) return(FALSE); + } + else + { + if (((cFrom + 17) != cTo) && ((cFrom + 15) != cTo)) return(FALSE); + } + + if ((IS_SPECIAL_MOVE(mv)) && + (!mv.pPromoted) && + (pos->cEpSquare != cTo)) return(FALSE); + return(TRUE); + } + else + { + // + // If the pawn is not capturing, the TO square better be empty. + // + if (!IS_EMPTY(pos->rgSquare[cTo].pPiece)) return(FALSE); + + // + // A non-capturing pawn can only push forward. One or two squares + // based on whether or not its the initial move. + // + if (WHITE == GET_COLOR(p)) + { + if (cTo == cFrom - 16) return(TRUE); + if ((cTo == cFrom - 32) && + (RANK2(cFrom)) && + (IS_EMPTY(pos->rgSquare[cFrom - 16].pPiece))) return(TRUE); + } + else + { + if (cTo == cFrom + 16) return(TRUE); + if ((cTo == cFrom + 32) && + (RANK7(cFrom)) && + (IS_EMPTY(pos->rgSquare[cFrom + 16].pPiece))) return(TRUE); + } + } + return(FALSE); +} + + +static FLAG +_SanityCheckPieceMove(POSITION *pos, MOVE mv) +/** + +Routine description: + +Parameters: + + POSITION *pos, + MOVE mv + +Return value: + + static + +**/ +{ + PIECE p = mv.pMoved; + PIECE pPieceType = p >> 1; + int iIndex; + COOR cFrom = mv.cFrom; + COOR cTo = mv.cTo; + COOR cBlock; + COOR cAttack; + COOR cKing; + int iDelta; + + ASSERT(!IS_PAWN(p)); + + // + // Handle castling + // + if (IS_CASTLE(mv)) + { + ASSERT(IS_KING(mv.pMoved)); + ASSERT(IS_SPECIAL_MOVE(mv)); + return(TRUE); + } + + // + // Make sure the piece moves in the way the move describes. + // + iIndex = (int)cFrom - (int)cTo; + if (0 == (CHECK_VECTOR_WITH_INDEX(iIndex, BLACK) & + (1 << pPieceType))) + { + return(FALSE); + } + + // + // If we get here the piece can move in the way described by the + // move but we still have to check to see if there are any other + // pieces in the way if the piece moved is not a king or knight + // (pawns handled in their own routine, see above). + // + if ((pPieceType == QUEEN) || + (pPieceType == ROOK) || + (pPieceType == BISHOP)) + { + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + for (cBlock = cFrom + iDelta; + cBlock != cTo; + cBlock += iDelta) + { + if (!IS_EMPTY(pos->rgSquare[cBlock].pPiece)) + { + break; + } + } + if (cBlock != cTo) return(FALSE); + } + + // + // Ok the piece can move the way they asked and there are no other + // pieces in the way... but it cannot expose its own king to check + // by doing so! + // + cKing = pos->cNonPawns[pos->uToMove][0]; + cAttack = ExposesCheck(pos, + cFrom, + cKing); + if ((ILLEGAL_COOR != cAttack) && (cTo != cAttack)) + { + // + // Ok if we are here then removing this piece from the from square + // does expose the king to check and the move does not capture the + // checking piece. But it's still ok as long as the TO location + // still blocks the checking piece. + // + iIndex = cAttack - cKing; + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + for (cBlock = cAttack + iDelta; + cBlock != cKing; + cBlock += iDelta) + { + if ((cBlock == cTo) || + !IS_EMPTY(pos->rgSquare[cBlock].pPiece)) break; + } + if (cBlock == cKing) return(FALSE); + } + + // + // Legal! + // + return(TRUE); +} + + +FLAG +SanityCheckMove(POSITION *pos, MOVE mv) +/** + +Routine description: + + Sanity check a move -- Note: Not a strict chess legality checker! + +Parameters: + + POSITION *pos, + MOVE mv + +Return value: + + FLAG + +**/ +{ + register PIECE p = mv.pMoved; + + if (0 == mv.uMove) + { + return(FALSE); + } + else if (mv.cTo == mv.cFrom) + { + return(FALSE); + } + else if (IS_EMPTY(pos->rgSquare[mv.cFrom].pPiece)) + { + return(FALSE); + } + else if (GET_COLOR(mv.pMoved) != pos->uToMove) + { + return(FALSE); + } + else if ((!IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)) && + (0 == mv.pCaptured)) + { + return(FALSE); + } + + if (!IS_SPECIAL_MOVE(mv)) + { + if (mv.pCaptured) + { + if (IS_EMPTY(pos->rgSquare[mv.cTo].pPiece)) + { + return(FALSE); + } + + if (((pos->rgSquare[mv.cTo].pPiece) != mv.pCaptured) || + (!OPPOSITE_COLORS(mv.pCaptured, mv.pMoved))) + { + return(FALSE); + } + } + + if (!IS_EMPTY(pos->rgSquare[mv.cTo].pPiece) && + !mv.pCaptured) + { + return(FALSE); + } + } + else + { + if (!IS_PAWN(p) && !IS_KING(p)) + { + return(FALSE); + } + } + + if (IS_PAWN(p)) + { + return(_SanityCheckPawnMove(pos, mv)); + } + else + { + return(_SanityCheckPieceMove(pos, mv)); + } +} + + +FLAG +LooksLikeFile(CHAR c) +/** + +Routine description: + + Does some char look like a file (i.e. 'a' <= char <= 'h') + +Parameters: + + CHAR c + +Return value: + + FLAG + +**/ +{ + if ((toupper(c) >= 'A') && + (toupper(c) <= 'H')) + { + return(TRUE); + } + return(FALSE); +} + +FLAG LooksLikeRank(CHAR c) +/** + +Routine description: + + Does char look like a coor rank (i.e. '1' <= char <= '8') + +Parameters: + + CHAR c + +Return value: + + FLAG + +**/ +{ + if (((c - '0') >= 1) && + ((c - '0') <= 8)) + { + return(TRUE); + } + return(FALSE); +} + + +FLAG +LooksLikeCoor(char *szData) +/** + +Routine description: + + Do the first two chars in szData look like a file/rank? + +Parameters: + + char *szData + +Return value: + + FLAG + +**/ +{ + char f = szData[0]; + char r = szData[1]; + + if (LooksLikeFile(f) && + LooksLikeRank(r)) + { + return(TRUE); + } + return(FALSE); +} + + +CHAR * +StripMove(CHAR *szMove) +/** + +Routine description: + + Strip decoration punctuation marks out of a move. + +Parameters: + + CHAR *szMove + +Return value: + + CHAR + +**/ +{ + CHAR cIgnore[] = "?!x+#-=\r\n"; // chars stripped from szMove + static CHAR szStripped[10]; + ULONG y; + CHAR *p; + + memset(szStripped, 0, sizeof(szStripped)); + p = szMove; + y = 0; + while (*p != '\0') + { + if (NULL == strchr(cIgnore, *p)) + { + szStripped[y++] = *p; + if (y >= 8) break; + } + p++; + } + return(szStripped); +} + +ULONG LooksLikeMove(char *szData) +/** + +Routine description: + + Does some char pointer point at some text that looks like a move? + If so, does the move look like SAN or ICS style? + +Parameters: + + char *szData + +Return value: + + ULONG + +**/ +{ + CHAR *szStripped = StripMove(szData); + ULONG u; + static CHAR cPieces[] = { 'P', 'N', 'B', 'R', 'Q', 'K', '\0' }; + + // + // A (stripped) move must be at least two characters long even in + // SAN. + // + if ((strlen(szStripped) < 2) || (strlen(szStripped) > 7)) + { + return(NOT_MOVE); + } + + // + // O-O, O-O-O + // + if (!STRNCMPI(szStripped, "OOO", 3) || + !STRNCMPI(szStripped, "OO", 2) || + !STRNCMPI(szStripped, "00", 2) || // duh + !STRNCMPI(szStripped, "000", 3)) + { + return(MOVE_SAN); + } + + // + // COOR COOR (d2d4) + // + if (LooksLikeCoor(szStripped) && + LooksLikeCoor(szStripped + 2)) + { + return(MOVE_ICS); + } + + // + // COOR (d4) + // + if (LooksLikeCoor(szStripped) && + strlen(szStripped) == 2) + { + return(MOVE_SAN); + } + + // + // RANK COOR + // + if ((LooksLikeRank(szStripped[0]) || + LooksLikeFile(szStripped[0])) && + LooksLikeCoor(&szStripped[1])) + { + return(MOVE_SAN); + } + + // + // PIECE COOR COOR + // PIECE COOR + // PIECE FILE COOR + // PIECE RANK COOR + // + for (u = 0; u < ARRAY_LENGTH(cPieces); u++) + { + if (szStripped[0] == cPieces[u]) // must be uppercase! + { + if (LooksLikeCoor(&szStripped[1])) + { + return(MOVE_SAN); + } + if (LooksLikeFile(szStripped[1]) && + LooksLikeCoor(&szStripped[2])) + { + return(MOVE_SAN); + } + if (LooksLikeRank(szStripped[1]) && + LooksLikeCoor(&szStripped[2])) + { + return(MOVE_SAN); + } + } + } + + // + // (COORD)=(PIECE) + // + if ((strlen(szStripped) == 4) && + LooksLikeCoor(szStripped) && + szStripped[2] == '=') + { + if (NULL != strchr(cPieces, szStripped[3])) + { + return(MOVE_SAN); + } + } + + // + // (COOR)(PIECE) + // + if ((strlen(szStripped) == 3) && + LooksLikeCoor(szStripped) && + (NULL != strchr(cPieces, szStripped[2]))) + { + return(MOVE_SAN); + } + + return(NOT_MOVE); +} + + +void FASTCALL +SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, + ULONG u) +/** + +Routine description: + + Pick the best (i.e. move with the highest "score" assigned to it + at generation time) that has not been played yet this ply and move + it to the front of the move list to be played next. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG u + +Return value: + + void FASTCALL + +**/ +{ + register ULONG v; + register ULONG uEnd = ctx->sMoveStack.uEnd[ctx->uPly]; + register SCORE iBestVal; + ULONG uLoc; + SCORE iVal; + MOVE mv; + MOVE_STACK_MOVE_VALUE_FLAGS mvfTemp; + + ASSERT(ctx->sMoveStack.uBegin[ctx->uPly] <= uEnd); + ASSERT(u >= ctx->sMoveStack.uBegin[ctx->uPly]); + ASSERT(u < uEnd); + + // + // Linear search from u..ctx->sMoveStack.uEnd[ctx->uPly] for the + // move with the best value. + // + iBestVal = ctx->sMoveStack.mvf[u].iValue; + mv = ctx->sMoveStack.mvf[u].mv; + if (!IS_CAPTURE_OR_PROMOTION(mv)) + { + iBestVal += g_HistoryCounters[mv.pMoved][mv.cTo]; + } + uLoc = u; + + for (v = u + 1; v < uEnd; v++) + { + iVal = ctx->sMoveStack.mvf[v].iValue; + mv = ctx->sMoveStack.mvf[v].mv; + if (!IS_CAPTURE_OR_PROMOTION(mv)) + { + iVal += g_HistoryCounters[mv.pMoved][mv.cTo]; + } + if (iVal > iBestVal) + { + iBestVal = iVal; + uLoc = v; + } + } + + // + // Note: the if here slows down the code, just swap em. + // + mvfTemp = ctx->sMoveStack.mvf[u]; + ctx->sMoveStack.mvf[u] = ctx->sMoveStack.mvf[uLoc]; + ctx->sMoveStack.mvf[uLoc] = mvfTemp; +} + + +void FASTCALL +SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, + ULONG u) +/** + +Routine description: + + Pick the best (i.e. move with the highest "score" assigned to it + at generation time) that has not been played yet this ply and move + it to the front of the move list to be played next. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG u + +Return value: + + void FASTCALL + +**/ +{ + register ULONG v; + register ULONG uEnd = ctx->sMoveStack.uEnd[ctx->uPly]; + register SCORE iBestVal; + ULONG uLoc; + SCORE iVal; + MOVE_STACK_MOVE_VALUE_FLAGS mvfTemp; + + ASSERT(ctx->sMoveStack.uBegin[ctx->uPly] <= uEnd); + ASSERT(u >= ctx->sMoveStack.uBegin[ctx->uPly]); + ASSERT(u < uEnd); + + // + // Linear search from u..ctx->sMoveStack.uEnd[ctx->uPly] for the + // move with the best value. + // + iBestVal = ctx->sMoveStack.mvf[u].iValue; + uLoc = u; + for (v = u + 1; v < uEnd; v++) + { + iVal = ctx->sMoveStack.mvf[v].iValue; + if (iVal > iBestVal) + { + iBestVal = iVal; + uLoc = v; + } + } + + // + // Note: the if here slows down the code, just swap em. + // + mvfTemp = ctx->sMoveStack.mvf[u]; + ctx->sMoveStack.mvf[u] = ctx->sMoveStack.mvf[uLoc]; + ctx->sMoveStack.mvf[uLoc] = mvfTemp; +} + +void FASTCALL +SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, + ULONG u) +/** + +Routine description: + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG u + +Return value: + + void FASTCALL + +**/ +{ + ULONG v = u; + ULONG uEnd = ctx->sMoveStack.uEnd[ctx->uPly]; + SCORE iBestVal = -INFINITY; + ULONG uLoc = v; + SCORE iVal; + MOVE_STACK_MOVE_VALUE_FLAGS mvfTemp; + + ASSERT(ctx->sMoveStack.uBegin[ctx->uPly] <= uEnd); + ASSERT(u >= ctx->sMoveStack.uBegin[ctx->uPly]); + ASSERT(u < uEnd); + ASSERT(MOVE_COUNT(ctx, ctx->uPly) >= 1); + + // + // Find the first move that we have not already searched. It will + // provide our initial iBestVal. + // + do + { + if (!(ctx->sMoveStack.mvf[v].bvFlags & MVF_MOVE_SEARCHED)) + { + iBestVal = ctx->sMoveStack.mvf[v].iValue; + uLoc = v; + break; + } + v++; + } + while(v < uEnd); + if (v >= uEnd) return; + + // + // Search the rest of the moves that have not yet been tried by + // RootSearch and find the one with the best value. + // + for (v = uLoc + 1; v < uEnd; v++) + { + if (!(ctx->sMoveStack.mvf[v].bvFlags & MVF_MOVE_SEARCHED)) + { + iVal = ctx->sMoveStack.mvf[v].iValue; + if (iVal > iBestVal) + { + iBestVal = iVal; + uLoc = v; + } + } + } + + // + // Move the best move we found into position u. + // + mvfTemp = ctx->sMoveStack.mvf[u]; + ctx->sMoveStack.mvf[u] = ctx->sMoveStack.mvf[uLoc]; + ctx->sMoveStack.mvf[uLoc] = mvfTemp; +} + + +static UINT64 g_uPerftNodeCount; +static UINT64 g_uPerftTotalNodes; +static UINT64 g_uPerftGenerates; + +void +Perft(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth) +{ + MOVE mv; + ULONG u; + ULONG uPly; + + g_uPerftTotalNodes += 1; + ASSERT(uDepth < MAX_PLY_PER_SEARCH); + if (uDepth == 0) + { + g_uPerftNodeCount += 1; + return; + } + + mv.uMove = 0; + g_uPerftGenerates += 1; + GenerateMoves(ctx, mv, GENERATE_DONT_SCORE); + + uPly = ctx->uPly; + for (u = ctx->sMoveStack.uBegin[uPly]; + u < ctx->sMoveStack.uEnd[uPly]; + u++) + { + mv = ctx->sMoveStack.mvf[u].mv; + if (MakeMove(ctx, mv)) + { + Perft(ctx, uDepth - 1); + UnmakeMove(ctx, mv); + } + } +} + +COMMAND(PerftCommand) +/** + +Routine description: + + This function implements the 'perft' engine command. I have no + idea what 'perft' means but some people use this command to + benchmark the speed of the move generator code. Note: the way + this is implemented here does nothing whatsoever with the move + scoring code (i.e. the SEE) + + Usage: + + perft + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + LIGHTWEIGHT_SEARCHER_CONTEXT ctx; + ULONG u; + ULONG uDepth; + double dBegin, dTime; + double dNps; + + if (argc < 2) + { + Trace("Usage: perft \n"); + return; + } + uDepth = atoi(argv[1]); + if (uDepth >= MAX_DEPTH_PER_SEARCH) + { + Trace("Error: invalid depth.\n"); + return; + } + + InitializeLightweightSearcherContext(pos, &ctx); + + g_uPerftTotalNodes = g_uPerftGenerates = 0ULL; + dBegin = SystemTimeStamp(); + for (u = 1; u <= uDepth; u++) + { + g_uPerftNodeCount = 0ULL; + Perft((SEARCHER_THREAD_CONTEXT *)&ctx, u); + Trace("%u. %" COMPILER_LONGLONG_UNSIGNED_FORMAT " node%s, " + "%" COMPILER_LONGLONG_UNSIGNED_FORMAT " generate%s.\n", + u, + g_uPerftNodeCount, + (g_uPerftNodeCount > 1) ? "s" : "", + g_uPerftGenerates, + (g_uPerftGenerates > 1) ? "s" : ""); + } + dTime = SystemTimeStamp() - dBegin; + dNps = (double)g_uPerftTotalNodes; + dNps /= dTime; + Trace("%" COMPILER_LONGLONG_UNSIGNED_FORMAT " total nodes, " + "%" COMPILER_LONGLONG_UNSIGNED_FORMAT " total generates " + "in %6.2f seconds.\n", + g_uPerftTotalNodes, + g_uPerftGenerates, + dTime); + Trace("That's approx %.0f moves/sec\n", dNps); +} diff --git a/src/pawnhash.c b/src/pawnhash.c new file mode 100755 index 0000000..8af2138 --- /dev/null +++ b/src/pawnhash.c @@ -0,0 +1,53 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + pawnhash.c + +Abstract: + + Pawn structure score hashing code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 14 Jun 2004 + +Revision History: + + $Id: pawnhash.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + + +PAWN_HASH_ENTRY * +PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Called by eval with a pointer to a POSITION, look in our pawn hash + to see if we have an entry that matches the pawn structure in the + POSITION. If so, "check out" that entry and return a pointer to + it. + + Note: there is a multi-probing scheme in place to remove + contention on MP machines. + +Parameters: + + POSITION *pos + +Return value: + + PAWN_HASH_ENTRY * + +**/ +{ + POSITION *pos = &(ctx->sPosition); + ULONG u = (ULONG)pos->u64PawnSig & (PAWN_HASH_TABLE_SIZE - 1); + return(&(ctx->rgPawnHash[u])); +} diff --git a/src/piece.c b/src/piece.c new file mode 100755 index 0000000..d5eeece --- /dev/null +++ b/src/piece.c @@ -0,0 +1,86 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + piece.c + +Abstract: + + Chess piece related code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 14 Apr 2004 + +Revision History: + + $Id: piece.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +PIECE_DATA g_PieceData[] = +{ + // piece value piece value / 100 invert value piece name + { 0, 0, 0, "NONE" }, + { VALUE_PAWN, (VALUE_PAWN / 100), INVERT_PAWN, "PAWN" }, + { VALUE_KNIGHT, (VALUE_KNIGHT / 100), INVERT_KNIGHT, "KNIGHT" }, + { VALUE_BISHOP, (VALUE_BISHOP / 100), INVERT_BISHOP, "BISHOP" }, + { VALUE_ROOK, (VALUE_ROOK / 100), INVERT_ROOK, "ROOK" }, + { VALUE_QUEEN, (VALUE_QUEEN / 100), INVERT_QUEEN, "QUEEN" }, + { VALUE_KING, 100, INVERT_KING, "KING" }, + { 0, 0, 0, "NONE" } +}; + + +CHAR * +PieceAbbrev(PIECE p) +{ + static char _PieceAbbrev[] = + { + '-', 'p', 'n', 'b', 'r', 'q', 'k', '\0' + }; + static char buf[3]; + + if (!IS_VALID_PIECE(p)) + { + buf[0] = buf[1] = '?'; + buf[2] = 0; + return(buf); + } + + buf[1] = _PieceAbbrev[PIECE_TYPE(p)]; + if (PIECE_COLOR(p) == WHITE) + { + buf[0] = '.'; + buf[1] = (char)toupper(buf[1]); + } + else + { + buf[0] = '*'; + } + buf[2] = 0; + + return(buf); +} + +ULONG +PieceValueOver100(PIECE p) +{ + return(PIECE_VALUE_OVER_100(p)); +} + +ULONG +PieceValue(PIECE p) +{ + return(PIECE_VALUE(p)); +} + +ULONG +PieceInvertedValue(PIECE p) +{ + return(INVERTED_PIECE_VALUE(p)); +} diff --git a/src/play.sh b/src/play.sh new file mode 100755 index 0000000..8a28d45 --- /dev/null +++ b/src/play.sh @@ -0,0 +1,79 @@ +#!/bin/sh + +# -----BEGIN EASILY CONFIGURABLE OPTIONS------- +bin='typhoon' +opts='--cpus 4 --hash 512m --logfile play.log --egtbpath /egtb/three;/egtb/four;/egtb/five' +dir='.' +ics='chessclub.com' +flags='' +# -----END EASILY CONFIGURABLE OPTIONS------- + +usage() { + echo "Usage: $1 [--local | --icc | --fics] [--xdebug] [--edebug]" + echo "" + echo "--local and --icc toggle between playing locally against the engine and" + echo "playing the engine on an ICS server. Playing locally is the default." + echo "" + echo "--xdebug enables debugging of the xboard protocol. --edebug uses a debug" + echo "version of the chess engine." + echo "" + exit 1 +} + +play_locally() { + xboard -ponder -fcp "${bin} ${opts}" -fd ${dir} -xpopup -xexit -size medium \ + -coords -highlight +} + +attach_to_ics() { + while true; do + xboard -ics -icshost "${ics}" -ponder -fcp "${bin} ${opts}" -fd ${dir} \ + -autoflag -xpopup -xexit -size medium -coords -highlight -zp \ + ${flags} + sleep 30 + killall typhoon + done +} + +mode='local' +for _switch ; do + case $_switch in + --xdebug) + flags='-debug' + shift + ;; + --edebug) + bin='_typhoon' + shift + ;; + --local) + mode='local' + shift + ;; + --icc) + mode='ics' + shift + ;; + --fics) + mode='fics' + ics='freechess.org' + shift + ;; + *) + usage $0 + ;; + esac +done + +case ${mode} in + local) + play_locally + ;; + ics) + attach_to_ics + ;; + fics) + attach_to_ics + ;; +esac +exit 0 diff --git a/src/poshash.c b/src/poshash.c new file mode 100644 index 0000000..e8f09b5 --- /dev/null +++ b/src/poshash.c @@ -0,0 +1,276 @@ +/*++ + +Copyright (c) Scott Gasch + +Module Name: + + poshash.c + +Abstract: + + A hash table of information about positions. + +Author: + + Scott Gasch (SGasch) 11 Nov 2006 + +Revision History: + +--*/ + +#include "chess.h" + +#define NUM_POSITION_HASH_ENTRIES (1048576) // 16Mb +POSITION_HASH_ENTRY g_PositionHash[NUM_POSITION_HASH_ENTRIES]; + +#ifdef MP +#define NUM_POSITION_HASH_LOCKS (512) +volatile static ULONG g_uPositionHashLocks[NUM_POSITION_HASH_LOCKS]; +#define POSITION_HASH_IS_LOCKED(x) ((g_uPositionHashLocks[(x)]) != 0) +#define LOCK_POSITION_HASH(x) \ + AcquireSpinLock(&(g_uPositionHashLocks[(x)])); \ + ASSERT(POSITION_HASH_IS_LOCKED(x)) +#define UNLOCK_POSITION_HASH(x) \ + ASSERT(POSITION_HASH_IS_LOCKED(x)); \ + ReleaseSpinLock(&(g_uPositionHashLocks[(x)])) +#else +#define POSITION_HASH_IS_LOCKED(x) +#define LOCK_HASH(x) +#define UNLOCK_HASH(x) +#endif + +void +InitializePositionHashSystem(void) +{ + memset(&g_PositionHash, 0, sizeof(g_PositionHash)); +#ifdef MP + memset(&g_uPositionHashLocks, 0, sizeof(g_uPositionHashLocks)); +#endif +} + +void +CleanupPositionHashSystem(void) +{ + ; // do nothing +} + +static INLINE UINT64 PositionToSignatureIgnoringMove(POSITION *pos) +{ + return((pos->u64NonPawnSig ^ pos->u64PawnSig) >> 1); +} + +// Note: sig must be pre-shifted to ignore the side-to-move bit. +static INLINE ULONG PositionSigToHashPosition(UINT64 u64Sig) +{ + ULONG u = (ULONG)u64Sig; + u &= (NUM_POSITION_HASH_ENTRIES - 1); + ASSERT(u < NUM_POSITION_HASH_ENTRIES); + return u; +} + +#ifdef MP +static INLINE ULONG HashPositionToLockNumber(ULONG u) +{ + u &= (NUM_POSITION_HASH_LOCKS - 1); + ASSERT(u < NUM_POSITION_HASH_LOCKS); + return u; +} +#endif + +void +StoreEnprisePiece(POSITION *pos, COOR cSquare) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + PIECE p = pos->rgSquare[cSquare].pPiece; + ULONG uColor = GET_COLOR(p); +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + ASSERT(p && IS_VALID_PIECE(p)); + ASSERT(!IS_PAWN(p)); + ASSERT(CAN_FIT_IN_UCHAR(cSquare)); + ASSERT(IS_ON_BOARD(cSquare)); + pHash->cEnprise[uColor] = (UCHAR)cSquare; + ASSERT(pHash->uEnpriseCount[uColor] < 16); + pHash->uEnpriseCount[uColor] += 1; + if (pHash->u64Sig != u64Sig) + { + pHash->u64Sig = u64Sig; + pHash->uEnpriseCount[uColor] = 1; + pHash->cTrapped[uColor] = ILLEGAL_COOR; + uColor = FLIP(uColor); + pHash->cEnprise[uColor] = ILLEGAL_COOR; + pHash->cTrapped[uColor] = ILLEGAL_COOR; + pHash->uEnpriseCount[uColor] = 0; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif +} + +void +StoreTrappedPiece(POSITION *pos, COOR cSquare) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + PIECE p = pos->rgSquare[cSquare].pPiece; + ULONG uColor = GET_COLOR(p); +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + ASSERT(p && IS_VALID_PIECE(p)); + ASSERT(!IS_PAWN(p)); + ASSERT(CAN_FIT_IN_UCHAR(cSquare)); + ASSERT(IS_ON_BOARD(cSquare)); + pHash->cTrapped[uColor] = cSquare; + if (pHash->u64Sig != u64Sig) + { + pHash->u64Sig = u64Sig; + pHash->cEnprise[uColor] = ILLEGAL_COOR; + pHash->uEnpriseCount[uColor] = 0; + uColor = FLIP(uColor); + pHash->cEnprise[uColor] = ILLEGAL_COOR; + pHash->cTrapped[uColor] = ILLEGAL_COOR; + pHash->uEnpriseCount[uColor] = 0; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif +} + +COOR +GetEnprisePiece(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + COOR c = ILLEGAL_COOR; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + c = pHash->cEnprise[uSide]; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return c; +} + +COOR +GetTrappedPiece(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + COOR c = ILLEGAL_COOR; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + c = pHash->cTrapped[uSide]; + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return c; +} + +FLAG +SideCanStandPat(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + FLAG fStand = TRUE; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + fStand = ((pHash->cTrapped[uSide] == ILLEGAL_COOR) && + (pHash->uEnpriseCount[uSide] < 2)); + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return fStand; +} + +ULONG +ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + ULONG u = 0; + COOR c; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + if (pHash->uEnpriseCount[uSide] > 1) + { + c = pHash->cEnprise[uSide]; + ASSERT(IS_ON_BOARD(c)); + u = PIECE_VALUE(pos->rgSquare[c].pPiece); + ASSERT(u); + } + c = pHash->cTrapped[uSide]; + if (IS_ON_BOARD(c)) + { + u = MAXU(u, PIECE_VALUE(pos->rgSquare[c].pPiece)); + ASSERT(u); + } + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return u; +} + +ULONG +ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide) +{ + UINT64 u64Sig = PositionToSignatureIgnoringMove(pos); + ULONG uEntry = PositionSigToHashPosition(u64Sig); + POSITION_HASH_ENTRY *pHash = &(g_PositionHash[uEntry]); + ULONG u = 0; + COOR c; +#ifdef MP + ULONG uLock = HashPositionToLockNumber(uEntry); + LOCK_POSITION_HASH(uLock); +#endif + if (pHash->u64Sig == u64Sig) + { + if (pHash->uEnpriseCount[uSide]) + { + c = pHash->cEnprise[uSide]; + ASSERT(IS_ON_BOARD(c)); + u += PIECE_VALUE(pos->rgSquare[c].pPiece); + ASSERT(u); + } + c = pHash->cTrapped[uSide]; + if (IS_ON_BOARD(c)) + { + u = MAXU(PIECE_VALUE(pos->rgSquare[c].pPiece), u); + ASSERT(u); + } + } +#ifdef MP + UNLOCK_POSITION_HASH(uLock); +#endif + return u; +} diff --git a/src/position.bin b/src/position.bin new file mode 100644 index 0000000..4216042 Binary files /dev/null and b/src/position.bin differ diff --git a/src/position.lrn b/src/position.lrn new file mode 100644 index 0000000..6d40222 --- /dev/null +++ b/src/position.lrn @@ -0,0 +1,5 @@ +[White "Crafty 19.13"] +[Black "unknown"] +[Date "2007.06.19"] +setboard r5k/1b1nq1bp/2p2rp/1p1p1pN/p2P3P/P2NP1P/1PQ2P1K/2R1RB/ w +{-149 6623 660} diff --git a/src/probe.c b/src/probe.c new file mode 100644 index 0000000..2d8c43d --- /dev/null +++ b/src/probe.c @@ -0,0 +1,432 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + probe.c + +Abstract: + + Routines for probing endgame tablebases; much of this code is + "borrowed" from crafty. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 02 Jul 2004 + +Revision History: + + $Id: probe.c 355 2008-07-01 15:46:43Z scott $ + +**/ + +#include "chess.h" + +#define XX (127) // sq not on the board +#define C_PIECES (3) // max num pieces of one color + +ULONG g_uEgtbLock = 0; + +// +// define INDEX type +// +#define T_INDEX64 // use 64 bit indexes +#if defined (T_INDEX64) && defined (_MSC_VER) +typedef unsigned __int64 INDEX; +#elif defined (T_INDEX64) +typedef unsigned long long INDEX; +#else +typedef unsigned long INDEX; +#endif + +// +// define square type and tb type +// +typedef unsigned int squaret; +typedef signed char tb_t; + +// +// define color +// +typedef int color; +#define x_colorWhite 0 +#define x_colorBlack 1 +#define x_colorNeutral 2 +#define COLOR_DECLARED + +// +// define pieces +// +typedef int piece; +#define x_pieceNone 0 +#define x_piecePawn 1 +#define x_pieceKnight 2 +#define x_pieceBishop 3 +#define x_pieceRook 4 +#define x_pieceQueen 5 +#define x_pieceKing 6 +#define PIECES_DECLARED + +// +// scores returned from egtb.cpp +// +#define pageL 65536 +#define tbbe_ssL ((pageL-4)/2) +#define bev_broken (tbbe_ssL+1) /* illegal or busted */ +#define bev_mi1 tbbe_ssL /* mate in 1 move */ +#define bev_mimin 1 /* mate in max moves */ +#define bev_draw 0 /* draw */ +#define bev_limax (-1) /* mated in max moves */ +#define bev_li0 (-tbbe_ssL) /* mated in 0 moves */ + +// +// define PfnCalcIndex +// +typedef INDEX(TB_FASTCALL * PfnCalcIndex)(squaret *, + squaret *, + squaret, + int fInverse); + +// +// prototypes for functions in egtb.cpp +// +extern int IDescFindFromCounters(int *); +extern int FRegisteredFun(int, color); +extern PfnCalcIndex PfnIndCalcFun(int, color); +extern int TB_FASTCALL L_TbtProbeTable(int, color, INDEX); +#define PfnIndCalc PfnIndCalcFun +#define FRegistered FRegisteredFun +extern int IInitializeTb(char *); +extern int FTbSetCacheSize(void *buffer, unsigned long size); +extern int TB_CRC_CHECK; + +// +// Globals +// +static int EGTBMenCount = 0; +void *egtb_cache = NULL; +#define EGTB_CACHE_SIZE (8*1024*1024) + + +void +InitializeEGTB(void) +/** + +Routine description: + + [Re]Initialize the Nalimov EGTB system. Called during system + startup and when the user uses "set" to change the EGTB path. + +Parameters: + + void (uses g_OPtionz.szEGTBPath) + +Return value: + + void + +**/ +{ + CHAR *szPath = g_Options.szEGTBPath; + + if ((szPath != NULL) && strlen(szPath) > 0) { + // TB_CRC_CHECK = 1; + EGTBMenCount = IInitializeTb(szPath); + if (0 != EGTBMenCount) + { + Trace("Found %d-men endgame tablebases.\n\n", EGTBMenCount); + if (NULL != egtb_cache) + { + SystemFreeMemory(egtb_cache); + egtb_cache = NULL; + } + egtb_cache = SystemAllocateMemory(EGTB_CACHE_SIZE); + if (NULL != egtb_cache) + { + FTbSetCacheSize(egtb_cache, EGTB_CACHE_SIZE); + } + } + } +} + +void +CleanupEGTB(void) +/** + +Routine description: + + Cleanup the Nalimov EGTB system. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (NULL != egtb_cache) + { + SystemFreeMemory(egtb_cache); + egtb_cache = NULL; + } +} + + +FLAG +ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore) +/** + +Routine description: + + Search for a board position in the EGTB files on disk. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore + +Return value: + + FLAG + +**/ +{ + POSITION *pos = &(ctx->sPosition); + int pcCount[10]; + int wSquares[C_PIECES*5+1], bSquares[C_PIECES*5+1]; + int iTB; + ULONG uColor; + int invert; + int *wp, *bp; + int ep; + INDEX index; + int value; + FLAG fResult; + ULONG x; + int y; + COOR c; + PIECE p; + PfnCalcIndex fp; + + // + // EGTB initialized? + // + ULONG wcount = (pos->uNonPawnCount[WHITE][0] + + pos->uPawnCount[WHITE]); + ULONG bcount = (pos->uNonPawnCount[BLACK][0] + + pos->uPawnCount[BLACK]); + if ((wcount + bcount > (ULONG)EGTBMenCount) || + (wcount > 3) || + (bcount > 3)) + { + return(FALSE); + } + INC(ctx->sCounters.egtb.uProbes); + memset(pcCount, 0, sizeof(pcCount)); + + for (x = 0; + x < pos->uPawnCount[WHITE]; + x++) + { + c = pos->cPawns[WHITE][x]; + ASSERT (IS_ON_BOARD(c)); + ASSERT(pos->rgSquare[c].pPiece && IS_PAWN(pos->rgSquare[c].pPiece)); + + c = TO64(c); + ASSERT((c >= 0) && (c <= 64)); + + y = pcCount[0]; + ASSERT(y >= 0); + ASSERT(y < (C_PIECES * 5 + 1)); + wSquares[y] = c; + pcCount[0]++; + } + + for (x = 1; + x < pos->uNonPawnCount[WHITE][0]; + x++) + { + c = pos->cNonPawns[WHITE][x]; + ASSERT (IS_ON_BOARD(c)); + + p = pos->rgSquare[c].pPiece; + ASSERT(p && !IS_PAWN(p) && !IS_KING(p)); + + // + // convert: into: + // XXX_PAWN 0 + // XXX_KNIGHT 1 + // XXX_BISHOP 2 + // XXX_ROOK 3 + // XXX_QUEEN 4 + // + p = ((p >> 1) & 0x7) - 1; + ASSERT(p > 0); + ASSERT(p < 5); + + c = TO64(c); + ASSERT((c >= 0) && (c <= 64)); + + y = p * C_PIECES + pcCount[p]; + ASSERT(y >= 0); + ASSERT(y < (C_PIECES * 5 + 1)); + wSquares[y] = c; + pcCount[p]++; + } + + for (x = 0; + x < pos->uPawnCount[BLACK]; + x++) + { + c = pos->cPawns[BLACK][x]; + ASSERT(IS_ON_BOARD(c)); + ASSERT(pos->rgSquare[c].pPiece && IS_PAWN(pos->rgSquare[c].pPiece)); + + c = TO64(c); + ASSERT(c >= 0); + ASSERT(c <= 64); + + y = pcCount[5]; + ASSERT(y >= 0); + ASSERT(y < (C_PIECES * 5 + 1)); + bSquares[y] = c; + pcCount[5]++; + } + + for (x = 1; + x < pos->uNonPawnCount[BLACK][0]; + x++) + { + c = pos->cNonPawns[BLACK][x]; + ASSERT(IS_ON_BOARD(c)); + + p = pos->rgSquare[c].pPiece; + ASSERT(p && !IS_PAWN(p) && !IS_KING(p)); + + // + // convert: into: + // XXX_PAWN 0 + // XXX_KNIGHT 1 + // XXX_BISHOP 2 + // XXX_ROOK 3 + // XXX_QUEEN 4 + // + p = ((p >> 1) & 0x7) - 1; + ASSERT(p > 0); + ASSERT(p < 5); + + c = TO64(c); + ASSERT(c >= 0); + ASSERT(c <= 64); + + y = p * C_PIECES + pcCount[5 + p]; + ASSERT(y >= 0); + ASSERT(y < (C_PIECES * 5 + 1)); + bSquares[y] = c; + pcCount[5 + p]++; + } + + AcquireSpinLock(&g_uEgtbLock); + iTB = IDescFindFromCounters(pcCount); + if (iTB == 0) + { + fResult = FALSE; + goto end; + } + + // + // Add the kings to the piece lists + // + ASSERT(pos->rgSquare[pos->cNonPawns[WHITE][0]].pPiece == WHITE_KING); + wSquares[C_PIECES * 5] = TO64(pos->cNonPawns[WHITE][0]); + ASSERT(wSquares[C_PIECES * 5] >= 0); + ASSERT(wSquares[C_PIECES * 5] <= 64); + + ASSERT(pos->rgSquare[pos->cNonPawns[BLACK][0]].pPiece == BLACK_KING); + bSquares[C_PIECES * 5] = TO64(pos->cNonPawns[BLACK][0]); + ASSERT(bSquares[C_PIECES * 5] >= 0); + ASSERT(bSquares[C_PIECES * 5] <= 64); + + if (iTB > 0) + { + uColor = (pos->uToMove == WHITE) ? 0 : 1; + invert = 0; + wp = wSquares; + bp = bSquares; + } + else + { + uColor = (pos->uToMove == WHITE) ? 1 : 0; + invert = 1; + wp = bSquares; + bp = wSquares; + iTB = -iTB; + } + + if (!FRegisteredFun(iTB, uColor)) + { + fResult = FALSE; + goto end; + } + ep = XX; + if (IS_ON_BOARD(pos->cEpSquare)) + { + ASSERT((IS_ON_BOARD(pos->cEpSquare + 1) && + IS_PAWN(pos->rgSquare[pos->cEpSquare + 1].pPiece)) || + (IS_ON_BOARD(pos->cEpSquare - 1) && + IS_PAWN(pos->rgSquare[pos->cEpSquare - 1].pPiece))); + ep = TO64(pos->cEpSquare); + } + +#if 0 + DumpPosition(pos); + Trace("iTB = %d, uColor = %u, ep = %u, invert = %u\n", + iTB, uColor, ep, invert); + Trace("wp =\t\t\tbp =\n"); + for(x = 0; x < 16; x++) + { + Trace("%u\t\t\t%u\n", wSquares[x], bSquares[x]); + } +#endif + ASSERT(IS_VALID_COLOR(uColor)); + fp = PfnIndCalcFun(iTB, uColor); + index = fp((squaret *)wp, + (squaret *)bp, + (squaret)ep, + invert); + value = L_TbtProbeTable(iTB, uColor, index); + if (value == bev_broken) + { + fResult = FALSE; + goto end; + } + + if (value > 0) + { + *piScore = INFINITY + (2*(-bev_mi1+value)) - 1; + } + else if (value < 0) + { + *piScore = -INFINITY + (2*(bev_mi1+value)); + } + else + { + *piScore = 0; // g_iDrawValue[pos->uToMove]; + } + fResult = TRUE; + + end: + ReleaseSpinLock(&g_uEgtbLock); +#ifdef PERF_COUNTERS + if (fResult == TRUE) + { + INC(ctx->sCounters.egtb.uHits); + } +#endif + return(fResult); +} diff --git a/src/psqt.h b/src/psqt.h new file mode 100755 index 0000000..d9b2ac4 --- /dev/null +++ b/src/psqt.h @@ -0,0 +1,196 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + psqt.h + +Abstract: + + Note: auto-generated from PGN file. + +Author: + + Scott Gasch (scott@wannabe.guru.org) 24 Jun 2004 + +Revision History: + + $Id: psqt.h 239 2006-08-01 05:12:52Z scott $ + +**/ + +#ifndef _PSQT_H_ +#define _PSQT_H_ + +SCORE g_iPSQT[14][128] = +{ + // empty + { + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + }, + // empty + { + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x2 (*p) + { + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 335,331,146, 56,124,384,374,471, 0,0,0,0,0,0,0,0, + 511,493,329,253,374,533,410,467, 0,0,0,0,0,0,0,0, + 194,241,162,139,177,165,122,149, 0,0,0,0,0,0,0,0, + 56, 50, 48, 83, 75, 42, 23, 34, 0,0,0,0,0,0,0,0, + 15, 14, 17, 19, 14, 8, 5, 7, 0,0,0,0,0,0,0,0, + 3, 3, 3, 2, 2, 1, 1, 1, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x3 (.P) + { + 4, 3, 3, 4, 2, 2, 1, 1, 0,0,0,0,0,0,0,0, + 19, 17, 20, 31, 18, 9, 6, 10, 0,0,0,0,0,0,0,0, + 58, 47, 53, 89, 75, 57, 35, 48, 0,0,0,0,0,0,0,0, + 206,174,192,191,267,232,184,201, 0,0,0,0,0,0,0,0, + 497,491,304,125,243,599,486,522, 0,0,0,0,0,0,0,0, + 379,408,222, 25, 77,373,343,451, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x4 (*n) + { + 8, 64, 56, 58,138,134, 42, 5, 0,0,0,0,0,0,0,0, + 21, 34,125,587,245, 69, 50, 54, 0,0,0,0,0,0,0,0, + 87,224,317,138,196,421,163, 46, 0,0,0,0,0,0,0,0, + 120, 48,283,271,314,156, 66,144, 0,0,0,0,0,0,0,0, + 47,139,178,179,226,143,150, 35, 0,0,0,0,0,0,0,0, + 11, 37, 57, 93, 56, 43, 24, 14, 0,0,0,0,0,0,0,0, + 5, 13, 28, 27, 30, 18, 4, 3, 0,0,0,0,0,0,0,0, + 1, 2, 6, 6, 7, 4, 1, 0, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x5 (.N) + { + 1, 3, 7, 8, 9, 4, 2, 0, 0,0,0,0,0,0,0,0, + 7, 13, 41, 30, 34, 22, 5, 5, 0,0,0,0,0,0,0,0, + 8, 55, 78,111, 64, 65, 24, 18, 0,0,0,0,0,0,0,0, + 47,156,142,275,283,147,181, 46, 0,0,0,0,0,0,0,0, + 128, 50,214,275,315,161, 86, 97, 0,0,0,0,0,0,0,0, + 55,173,288,179,227,334,180, 41, 0,0,0,0,0,0,0,0, + 25, 28,102,401,303, 70, 31, 56, 0,0,0,0,0,0,0,0, + 4, 45, 56, 73, 89,114, 27, 5, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x6 (*b) + { + 28, 26,134, 91, 91,220, 12, 13, 0,0,0,0,0,0,0,0, + 20,290, 79,403,315, 70,169, 16, 0,0,0,0,0,0,0,0, + 135, 81,211,224,363,245,102,105, 0,0,0,0,0,0,0,0, + 28, 88,163,122,122,189, 97, 47, 0,0,0,0,0,0,0,0, + 36, 97, 71,117, 85, 51,142, 37, 0,0,0,0,0,0,0,0, + 27, 35, 45, 50, 36, 26, 16, 44, 0,0,0,0,0,0,0,0, + 10, 19, 26, 20, 21, 15, 9, 11, 0,0,0,0,0,0,0,0, + 1, 8, 11, 9, 10, 10, 8, 1, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x7 (.B) + { + 1, 8, 10, 10, 10, 9, 7, 1, 0,0,0,0,0,0,0,0, + 10, 20, 31, 19, 26, 14, 10, 11, 0,0,0,0,0,0,0,0, + 29, 45, 46, 63, 36, 33, 21, 98, 0,0,0,0,0,0,0,0, + 31,116, 79, 99, 88, 53,250, 31, 0,0,0,0,0,0,0,0, + 42, 65,178,159,134,271, 69, 84, 0,0,0,0,0,0,0,0, + 90,135,150,354,490,210,139, 90, 0,0,0,0,0,0,0,0, + 36,167,157,303,276,123,127, 23, 0,0,0,0,0,0,0,0, + 15, 64,106, 66, 63,174, 20, 7, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x8 (*r) + { + 200,498,860,875,818,292,213,106, 0,0,0,0,0,0,0,0, + 107,100,200,218,185,172, 69, 40, 0,0,0,0,0,0,0,0, + 70, 82,103,106,114,104, 69, 48, 0,0,0,0,0,0,0,0, + 57, 55, 91, 86, 74, 67, 40, 41, 0,0,0,0,0,0,0,0, + 59, 73, 91, 76, 64, 49, 38, 33, 0,0,0,0,0,0,0,0, + 67, 58, 70, 69, 44, 31, 24, 28, 0,0,0,0,0,0,0,0, + 86, 84,110,103, 73, 42, 32, 34, 0,0,0,0,0,0,0,0, + 64, 53, 64, 65, 52, 28, 24, 33, 0,0,0,0,0,0,0,0, + }, + + // Piece 0x9 (.R) + { + 65, 58, 65, 75, 52, 27, 26, 35, 0,0,0,0,0,0,0,0, + 98, 90,127,121, 81, 43, 34, 38, 0,0,0,0,0,0,0,0, + 63, 65, 73, 92, 47, 36, 23, 29, 0,0,0,0,0,0,0,0, + 55, 57, 71, 73, 65, 38, 35, 31, 0,0,0,0,0,0,0,0, + 59, 55, 76,101, 79, 64, 43, 48, 0,0,0,0,0,0,0,0, + 80, 87,110,170,166,136, 95, 78, 0,0,0,0,0,0,0,0, + 80, 76,172,257,205,149, 56, 39, 0,0,0,0,0,0,0,0, + 173,409,738,999,863,284,191, 98, 0,0,0,0,0,0,0,0, + }, + + // Piece 0xa (*q) + { + 42,103,128,194,117, 64, 15, 8, 0,0,0,0,0,0,0,0, + 58,127,458,320,353,119, 61, 15, 0,0,0,0,0,0,0,0, + 66,284,154,184,141,202,102, 50, 0,0,0,0,0,0,0,0, + 191, 70,132,108,110,104,117, 80, 0,0,0,0,0,0,0,0, + 50, 83, 66, 78, 72, 67, 64, 97, 0,0,0,0,0,0,0,0, + 38, 29, 42, 43, 46, 32, 27, 35, 0,0,0,0,0,0,0,0, + 22, 34, 43, 42, 38, 27, 12, 16, 0,0,0,0,0,0,0,0, + 30, 29, 33, 33, 33, 18, 15, 20, 0,0,0,0,0,0,0,0, + }, + + // Piece 0xb (.Q) + { + 25, 28, 31, 36, 31, 17, 15, 24, 0,0,0,0,0,0,0,0, + 26, 34, 48, 41, 42, 26, 16, 24, 0,0,0,0,0,0,0,0, + 28, 36, 43, 52, 46, 46, 34, 58, 0,0,0,0,0,0,0,0, + 41, 59, 56, 71, 74, 59, 86,117, 0,0,0,0,0,0,0,0, + 107, 66, 99,131,120,130,142,112, 0,0,0,0,0,0,0,0, + 58,212,146,269,239,246,159, 78, 0,0,0,0,0,0,0,0, + 34, 79,318,415,404,160, 53, 19, 0,0,0,0,0,0,0,0, + 24, 56, 91,123,111, 45, 14, 6, 0,0,0,0,0,0,0,0, + }, + + // Piece 0xc (*k) + { + 18, 77,152, 82,116,333,682,325, 0,0,0,0,0,0,0,0, + 9, 25, 55, 85,156,176,222,132, 0,0,0,0,0,0,0,0, + 5, 19, 38, 65, 86,108, 78, 34, 0,0,0,0,0,0,0,0, + 3, 10, 20, 25, 35, 20, 25, 11, 0,0,0,0,0,0,0,0, + 3, 11, 17, 23, 24, 23, 18, 8, 0,0,0,0,0,0,0,0, + 2, 6, 7, 8, 8, 7, 6, 3, 0,0,0,0,0,0,0,0, + 0, 2, 2, 2, 2, 2, 2, 0, 0,0,0,0,0,0,0,0, + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + }, + + // Piece 0xd (.K) + { + 0, 0, 0, 0, 0, 0, 0, 0, 0,0,0,0,0,0,0,0, + 0, 2, 2, 2, 2, 1, 2, 0, 0,0,0,0,0,0,0,0, + 2, 7, 8, 9, 6, 7, 5, 3, 0,0,0,0,0,0,0,0, + 3, 13, 19, 21, 23, 18, 18, 8, 0,0,0,0,0,0,0,0, + 5, 11, 20, 34, 36, 33, 22, 11, 0,0,0,0,0,0,0,0, + 5, 20, 36, 72, 98, 98, 75, 33, 0,0,0,0,0,0,0,0, + 12, 26, 50, 80,126,157,160,135, 0,0,0,0,0,0,0,0, + 25,148,187, 59, 83,261,619,311, 0,0,0,0,0,0,0,0, + } +}; + +#endif /* _PSQT_H_ */ diff --git a/src/recogn.c b/src/recogn.c new file mode 100644 index 0000000..c0b1bb8 --- /dev/null +++ b/src/recogn.c @@ -0,0 +1,1347 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + recogn.c + +Abstract: + + This code is based on an article by Ernst A. Heinz: "Efficient + Interior-Node Recognition" * ICCA Journal Volume 21, No. 3, pp + 156-167 (also "Scalable Search in Computer Chess" pp 65-81). This + code also borrows ideas from Thorsten Greiner's AMY chess program. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 16 Oct 2005 + +Revision History: + +**/ + +#include "chess.h" + +extern ULONG g_uIterateDepth; +static COOR QUEENING_SQUARE_BY_COLOR_FILE[2][8] = +{ + { A1, B1, C1, D1, E1, F1, G1, H1 }, + { A8, B8, C8, D8, E8, F8, G8, H8 } +}; + +#define RECOGN_INDEX(w, b) \ + (((b) | (w)) + (32 * ((w) && (b)))) + +typedef ULONG RECOGNIZER(SEARCHER_THREAD_CONTEXT *ctx, SCORE *piScore); + +static RECOGNIZER *g_pRecognizers[64]; +static BITV g_bvRecognizerAvailable[32]; + +static ULONG +_MakeMaterialSig(IN FLAG fPawn, + IN FLAG fKnight, + IN FLAG fBishop, + IN FLAG fRook, + IN FLAG fQueen) +/** + +Routine description: + + Make a material signature ULONG out of flags representing the + presence of pawns, knights, bishops, rooks, queens on the board. + +Parameters: + + FLAG fPawn, + FLAG fKnight, + FLAG fBishop, + FLAG fRook, + FLAG fQueen + +Return value: + + static ULONG + +**/ +{ + ULONG x; + + ASSERT(IS_VALID_FLAG(fPawn)); + ASSERT(IS_VALID_FLAG(fKnight)); + ASSERT(IS_VALID_FLAG(fBishop)); + ASSERT(IS_VALID_FLAG(fRook)); + ASSERT(IS_VALID_FLAG(fQueen)); + + x = fPawn | (fKnight << 1) | (fBishop << 2) | (fRook << 3) | (fQueen << 4); + + ASSERT((0 <= x) && (x <= 31)); + return(x); +} + + +#ifdef DEBUG + + +static FLAG +_TablebasesSaySideWins(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uSide) +{ + SCORE iScore; + if (TRUE == ProbeEGTB(ctx, &iScore)) + { + if (ctx->sPosition.uToMove == uSide) + { + return iScore > 0; + } + else + { + return iScore < 0; + } + } + return TRUE; +} + +static FLAG +_TablebasesSayDraw(IN SEARCHER_THREAD_CONTEXT *ctx) +{ + SCORE iScore; + if (TRUE == ProbeEGTB(ctx, &iScore)) + { + return iScore == 0; + } + return TRUE; +} + +static FLAG +_TablebasesSayDrawOrWin(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uSide) +{ + SCORE iScore; + if (TRUE == ProbeEGTB(ctx, &iScore)) + { + return ((iScore == 0) || + ((iScore > 0) && (ctx->sPosition.uToMove == uSide)) || + ((iScore < 0) && (ctx->sPosition.uToMove != uSide))); + } + return TRUE; +} + + +static FLAG +_SanityCheckRecognizers(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iScore, + IN ULONG uVal) { + ULONG uToMove = ctx->sPosition.uToMove; + switch(uVal) { + case UNRECOGNIZED: + return TRUE; + case RECOGN_EXACT: + if (iScore == 0) { + return _TablebasesSayDraw(ctx); + } else if (iScore > 0) { + return _TablebasesSaySideWins(ctx, uToMove); + } else { + ASSERT(iScore < 0); + return _TablebasesSaySideWins(ctx, !uToMove); + } + case RECOGN_LOWER: + if (iScore == 0) { + return _TablebasesSayDrawOrWin(ctx, uToMove); + } else if (iScore > 0) { + return _TablebasesSaySideWins(ctx, uToMove); + } else { + ASSERT(iScore < 0); + return _TablebasesSaySideWins(ctx, !uToMove); + } + case RECOGN_UPPER: + if (iScore == 0) { + return _TablebasesSayDrawOrWin(ctx, !uToMove); + } else if (iScore > 0) { + return _TablebasesSayDrawOrWin(ctx, !uToMove); + } else { + ASSERT(iScore < 0); + return _TablebasesSaySideWins(ctx, !uToMove); + } + default: + ASSERT(FALSE); + return FALSE; + } +} + +static FLAG +_NothingBut(IN POSITION *pos, + IN PIECE p, + IN ULONG uColor) +/** + +Routine description: + + Support routine to assert that nothing but the piece bits + enumerated in parameter p are present in the position pos for side + uColor. + +Parameters: + + POSITION *pos, + PIECE p, + ULONG uColor + +Return value: + + #ifdef DEBUG +static FLAG + +**/ +{ + static PIECE q[] = { KNIGHT, BISHOP, ROOK, QUEEN }; + ULONG u; + + if (!(p & PAWN)) + { + if (pos->uPawnCount[uColor] > 0) return(FALSE); + } + + for (u = 0; u < ARRAY_LENGTH(q); u++) + { + if (!(p & q[u])) + { + if (pos->uNonPawnCount[uColor][q[u]] > 0) return(FALSE); + } + } + return(TRUE); +} +#endif + +static ULONG +_RecognizeKK(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + + Encode the knowledge that two lone kings on the board are a draw. + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + *piScore = 0; + return(RECOGN_EXACT); +} + +static ULONG +_RecognizeKBK(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + + Attempt to recognize KB*KB+ positions. + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + ULONG uStrong; + ULONG uBishops; + COOR cWeakKing; + ULONG u; + ULONG uAdjacent; + POSITION *pos = &ctx->sPosition; + + ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && + (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT(_NothingBut(pos, BISHOP, WHITE)); + ASSERT(_NothingBut(pos, BISHOP, BLACK)); + + // + // Recognize KBKB as a draw unless there's a cornered king (in + // which case it may be a mate-in-1) + // + if ((pos->uNonPawnCount[WHITE][0] == 2) && + (pos->uNonPawnCount[BLACK][0] == 2)) + { + if ((CORNER_DISTANCE(pos->cNonPawns[WHITE][0]) != 0) && + (CORNER_DISTANCE(pos->cNonPawns[BLACK][0]) != 0)) + { + *piScore = 0; + return(RECOGN_EXACT); + } + } + + // + // Otherwise we want to deal with KB+ vs lone K. KBKBB etc are + // too hard to recognize. + // + if ((pos->uNonPawnCount[WHITE][0] != 1) && + (pos->uNonPawnCount[BLACK][0] != 1)) + { + return(UNRECOGNIZED); + } + + // + // If we get here then one side has no pieces (except the king). + // + uStrong = BLACK; + if (pos->uNonPawnCount[WHITE][0] > 1) + { + uStrong = WHITE; + } + ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + + // + // KB vs K is a draw, KB+ vs K is still a draw if all bishops are the + // same color. + // + uBishops = pos->uNonPawnCount[uStrong][BISHOP]; + if ((uBishops == 1) || + (pos->uWhiteSqBishopCount[uStrong] == 0) || + (pos->uWhiteSqBishopCount[uStrong] == uBishops)) + { + *piScore = 0; + return(RECOGN_EXACT); + } + + // + // If we get here the strong side has more than one bishop and has + // at least one bishop on each color. + // + + // + // If the weak king is next to a strong side piece, fail to + // recognize since the weak king may take the bishop with the + // move. Note: we allow the weak king to be adjacent to up to one + // enemy bishop as long as it's the strong side's turn to move. + // + cWeakKing = pos->cNonPawns[FLIP(uStrong)][0]; + ASSERT(DISTANCE(cWeakKing, pos->cNonPawns[uStrong][0]) > 1); + uAdjacent = 0; + for (u = 1; u < pos->uNonPawnCount[uStrong][0]; u++) + { + uAdjacent += DISTANCE(cWeakKing, pos->cNonPawns[uStrong][u] == 1); + } + if (uAdjacent > 1) + { + return(UNRECOGNIZED); + } + + // + // If it's the weak side's turn and the strong king is close + // enough that the weak side may be stalemated, fail to recognize. + // + if (pos->uToMove != uStrong) + { + ASSERT(pos->uToMove == FLIP(uStrong)); + if (uAdjacent == 1) + { + return(UNRECOGNIZED); + } + + ASSERT(IS_ON_BOARD(pos->cNonPawns[uStrong][0])); + ASSERT(IS_KING(pos->rgSquare[pos->cNonPawns[uStrong][0]].pPiece)); + u = DISTANCE(cWeakKing, pos->cNonPawns[uStrong][0]); + ASSERT(u != 1); + if ((u == 2) && (ON_EDGE(cWeakKing))) + { + return(UNRECOGNIZED); + } + } + + // + // This is a recognized win for the strong side. Compute a score + // that encourages cornering the weak king and making progress + // towards a checkmate. + // + *piScore = (pos->iMaterialBalance[uStrong] + VALUE_QUEEN - + (u * 16) - (CORNER_DISTANCE(cWeakKing) * 32)); + ASSERT(IS_VALID_SCORE(*piScore)); + if (pos->uToMove != uStrong) + { + *piScore *= -1; + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); +} + +static ULONG +_RecognizeKNK(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + + Recognize KN*KN+ positions. + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + POSITION *pos = &ctx->sPosition; + ULONG uStrong; + + ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && + (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT(_NothingBut(pos, KNIGHT, WHITE)); + ASSERT(_NothingBut(pos, KNIGHT, BLACK)); + + // + // KNKN is a draw unless someone has a K in the corner (in which case, + // with the friend knight in the way, there's a possible mate) + // + if ((pos->uNonPawnCount[WHITE][0] == 2) && + (pos->uNonPawnCount[BLACK][0] == 2)) + { + if ((CORNER_DISTANCE(pos->cNonPawns[WHITE][0]) != 0) && + (CORNER_DISTANCE(pos->cNonPawns[BLACK][0]) != 0)) + { + *piScore = 0; + return(RECOGN_EXACT); + } + return(UNRECOGNIZED); + } + + // + // KNNKN etc... unrecognized. Heinz says "exceptional wins possible for + // any side by mates in seven or less moves." TODO: add this knowledge. + // + if ((pos->uNonPawnCount[WHITE][0] != 1) || + (pos->uNonPawnCount[BLACK][0] != 1)) + { + return(UNRECOGNIZED); + } + + // + // If we get here somebody has no pieces (except a lone king). + // + uStrong = WHITE; + if (pos->uNonPawnCount[BLACK][0] > 1) + { + uStrong = BLACK; + } + ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + + // + // Call KNNK a draw unless the weak K is on the edge of the board + // where a checkmate is possible (e.g. 8/8/8/8/8/N2N4/4K3/2k5 b - -) + // Everything else in here is a draw. + // + ASSERT(pos->uNonPawnCount[uStrong][0] < 4); + if (ON_EDGE(pos->cNonPawns[FLIP(uStrong)][0])) + { + return(UNRECOGNIZED); + } + *piScore = 0; + return(RECOGN_EXACT); +} + + +static ULONG +_RecognizeKBNK(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + ULONG uStrong; + COOR cWeakKing; + COOR cKnight; + ULONG u; + ULONG uDist; + ULONG uAdjacent; + POSITION *pos = &ctx->sPosition; + + ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && + (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT(_NothingBut(pos, BISHOP | KNIGHT, WHITE)); + ASSERT(_NothingBut(pos, BISHOP | KNIGHT, BLACK)); + + if ((pos->uNonPawnCount[WHITE][0] > 1) && + (pos->uNonPawnCount[BLACK][0] > 1)) + { + // + // Do not recognize stuff like KNNKB or KNKBB etc... + // + if (pos->uNonPawnCount[WHITE][0] + pos->uNonPawnCount[BLACK][0] > 4) + { + return(UNRECOGNIZED); + } + + // + // This is KNKB; unless someone's king is on the edge, + // recognize a draw. + // + ASSERT((pos->uNonPawnCount[WHITE][0] == 2) && + (pos->uNonPawnCount[BLACK][0] == 2)); + if (ON_EDGE(pos->cNonPawns[WHITE][0]) || + ON_EDGE(pos->cNonPawns[BLACK][0])) + { + return(UNRECOGNIZED); + } + *piScore = 0; + return(RECOGN_EXACT); + } + + // + // If we get here we are in a KBNK endgame. + // + uStrong = WHITE; + if (pos->uNonPawnCount[BLACK][0] > 1) + { + uStrong = BLACK; + } + ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + cWeakKing = pos->cNonPawns[FLIP(uStrong)][0]; + ASSERT(IS_ON_BOARD(cWeakKing)); + ASSERT(IS_KING(pos->rgSquare[cWeakKing].pPiece)); + + // + // Don't recognize anything where the N is in a corner near the + // lone king. It's possible for the lone king to trap it there + // thus drawing the game. + // + cKnight = pos->cNonPawns[uStrong][KNIGHT]; + if ((CORNER_DISTANCE(cKnight) == 0) && + (DISTANCE(cWeakKing, cKnight) == 1)) + { + return(UNRECOGNIZED); + } + + // + // Don't recognize anything if the weak king is next to a strong side's + // piece. + // + uAdjacent = 0; + for (u = 1; u < pos->uNonPawnCount[uStrong][0]; u++) + { + uAdjacent = (DISTANCE(pos->cNonPawns[uStrong][u], cWeakKing) == 1); + } + if (!uAdjacent) + { + return(UNRECOGNIZED); + } + + // + // Don't recognize if the two kings are close enough to each other + // that there might be a stalemate if the weak side is on move and + // on the edge. + // + if (pos->uToMove != uStrong) + { + ASSERT(pos->uToMove == FLIP(uStrong)); + if (uAdjacent == 1) + { + return(UNRECOGNIZED); + } + + ASSERT(IS_ON_BOARD(pos->cNonPawns[uStrong][0])); + ASSERT(IS_KING(pos->rgSquare[pos->cNonPawns[uStrong][0]].pPiece)); + u = DISTANCE(cWeakKing, pos->cNonPawns[uStrong][0]); + ASSERT(u != 1); + if ((u == 2) && (ON_EDGE(cWeakKing))) + { + return(UNRECOGNIZED); + } + } + + // + // Calculate a score that grabs the search's attention and makes + // progress towards driving the weak king to the correct corner to + // mate him. + // + if (pos->uWhiteSqBishopCount[uStrong] > 0) + { + uDist = WHITE_CORNER_DISTANCE(cWeakKing); + } + else + { + uDist = BLACK_CORNER_DISTANCE(cWeakKing); + } + ASSERT((0 <= uDist) && (uDist <= 7)); + + *piScore = (pos->iMaterialBalance[uStrong] + (7 * VALUE_PAWN) + - (uDist * 32) - (u * 16)); + ASSERT(IS_VALID_SCORE(*piScore)); + if (pos->uToMove != uStrong) + { + *piScore *= -1; + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); +} + + +static ULONG +_RecognizeKNKP(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + + Recognize KN+KP+ positions. + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + ULONG uStrong; + POSITION *pos = &ctx->sPosition; + + ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && + (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT(_NothingBut(pos, PAWN | KNIGHT, WHITE)); + ASSERT(_NothingBut(pos, PAWN | KNIGHT, BLACK)); + + // + // Call the side with knight(s) "strong" + // + uStrong = WHITE; + if (pos->uNonPawnCount[BLACK][0] > 1) + { + uStrong = BLACK; + } + ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + + // + // Don't recognize KNNKP or KNKP with K on edge + // + if ((pos->uNonPawnCount[uStrong][KNIGHT] > 2) || + (ON_EDGE(pos->cNonPawns[FLIP(uStrong)][0]))) + { + return(UNRECOGNIZED); + } + + // + // This is at least a draw for the side with the pawn(s) and at + // best a draw for the side with the knight(s) + // + *piScore = 0; + if (pos->uToMove == uStrong) + { + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); +} + + +static ULONG +_RecognizeKBKP(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + + Recognize KB+P*KP+ positions including knowledge about "wrong color + bishop(s)". + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + ULONG uStrong; + BITBOARD bb; + ULONG u; + COOR c; + COOR cWeakKing; + POSITION *pos = &ctx->sPosition; + + ASSERT((pos->uNonPawnCount[WHITE][0] <= 3) && + (pos->uNonPawnCount[BLACK][0] <= 3)); + ASSERT(_NothingBut(pos, PAWN | BISHOP, WHITE)); + ASSERT(_NothingBut(pos, PAWN | BISHOP, BLACK)); + + // + // Call the side with bishop(s) "strong" + // + uStrong = WHITE; + if (pos->uNonPawnCount[BLACK][BISHOP] > 0) + { + uStrong = BLACK; + } + ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + + cWeakKing = pos->cNonPawns[FLIP(uStrong)][0]; + ASSERT(IS_ON_BOARD(cWeakKing)); + ASSERT(IS_KING(pos->rgSquare[cWeakKing].pPiece)); + + // + // Construct a strong side bitboard of pawn locations + // + bb = 0ULL; + for (u = 0; u < pos->uPawnCount[uStrong]; u++) + { + c = pos->cPawns[uStrong][u]; + ASSERT(IS_ON_BOARD(c)); + bb |= COOR_TO_BB(c); + } + + if ((pos->uNonPawnCount[BLACK][0] + pos->uPawnCount[BLACK] > 1) && + (pos->uNonPawnCount[WHITE][0] + pos->uPawnCount[WHITE] > 1)) + { + // + // Neither side has a lone king. This is either KBKP+ or + // KBP+KP+. + // + if (pos->uPawnCount[uStrong] > 0) + { + // + // Strong side can maybe take an adjacent pawn and survive the + // bad bishop. + // + if (uStrong == pos->uToMove) + { + return(UNRECOGNIZED); + } + + // + // Make sure the strong side has the right color bishop + // for his pawns. + // + if (uStrong == WHITE) + { + if (!(bb & ~BBFILE[A]) && + (pos->uWhiteSqBishopCount[WHITE] == 0) && + (DISTANCE(cWeakKing, A8) <= 1)) + { + goto at_best_draw_for_strong; + } + + if (!(bb & ~BBFILE[H]) && + (pos->uWhiteSqBishopCount[WHITE] == + pos->uNonPawnCount[WHITE][BISHOP]) && + (DISTANCE(cWeakKing, H8) <= 1)) + { + goto at_best_draw_for_strong; + } + } + else + { + if (!(bb & ~BBFILE[A]) && + (pos->uWhiteSqBishopCount[BLACK] == + pos->uNonPawnCount[BLACK][BISHOP]) && + (DISTANCE(cWeakKing, A1) <= 1)) + { + goto at_best_draw_for_strong; + } + + if (!(bb & ~BBFILE[H]) && + (pos->uWhiteSqBishopCount[BLACK] == 0) && + (DISTANCE(cWeakKing, H1) <= 1)) + { + goto at_best_draw_for_strong; + } + } + return(UNRECOGNIZED); + } + else + { + // + // Strong side has no pawns... there's a mate-in-1 here if + // the weak king is stuck in the corner. + // + if ((pos->uNonPawnCount[uStrong][BISHOP] > 1) || + (CORNER_DISTANCE(cWeakKing) == 0)) + { + return(UNRECOGNIZED); + } + goto at_best_draw_for_strong; + } + } + else + { + // + // KBPK: make sure the bishop is the right color. This time + // there is no need to check for on-move. + // + ASSERT(pos->uNonPawnCount[FLIP(uStrong)][0] == 1); + ASSERT(pos->uNonPawnCount[uStrong][0] > 1); + + if (uStrong == WHITE) + { + if (!(bb & ~BBFILE[A]) && + (pos->uWhiteSqBishopCount[WHITE] == 0) && + (DISTANCE(cWeakKing, A8) <= 1)) + { + goto draw; + } + if (!(bb & ~BBFILE[H]) && + (pos->uWhiteSqBishopCount[WHITE] == + pos->uNonPawnCount[WHITE][BISHOP]) && + (DISTANCE(cWeakKing, H8) <= 1)) + { + goto draw; + } + } + else + { + if (!(bb & ~BBFILE[A]) && + (pos->uWhiteSqBishopCount[BLACK] == + pos->uNonPawnCount[BLACK][BISHOP]) && + (DISTANCE(cWeakKing, A1) <= 1)) + { + goto draw; + } + if (!(bb & ~BBFILE[H]) && + (pos->uWhiteSqBishopCount[BLACK] == 0) && + (DISTANCE(cWeakKing, H1) <= 1)) + { + goto draw; + } + } + return(UNRECOGNIZED); + } +#ifdef DEBUG + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +#endif + + at_best_draw_for_strong: + *piScore = 0; + if (pos->uToMove == uStrong) + { + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); + + draw: + *piScore = 0; + return(RECOGN_EXACT); +} + +static void +_GetPassersCriticalSquares(IN ULONG uColor, + IN COOR cPawn, + IN OUT COOR *cSquare) +/** + +Routine description: + + In an effort to classify KPK positions I read some stuff in + "Pandolfini's Endgame Course" about critical squares. A critical + square of a passed pawn is one that, if occupied by the friendly + king, is sufficient to queen that pawn by force. This code is a + helper routing for the KPK recognizer that returns the critical + square given a pawn's location for color uColor. + + Note: rook pawns only have one critical square so this code + returns the same square three times in this case. + +Parameters: + + ULONG uColor, + COOR cPawn, + COOR *cSquare + +Return value: + + static void + +**/ +{ + static COOR cCriticalSquare[2][128] = + { + { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0,0,0,0,0,0,0,0, + 0x61, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x66, 0,0,0,0,0,0,0,0, + 0x61, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x66, 0,0,0,0,0,0,0,0, + 0x61, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x66, 0,0,0,0,0,0,0,0, + 0x61, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x66, 0,0,0,0,0,0,0,0, + 0x61, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x66, 0,0,0,0,0,0,0,0, + 0x61, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x66, 0,0,0,0,0,0,0,0, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0,0,0,0,0,0,0,0, + }, + { + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0,0,0,0,0,0,0,0, + 0x11, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x16, 0,0,0,0,0,0,0,0, + 0x11, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x16, 0,0,0,0,0,0,0,0, + 0x11, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x16, 0,0,0,0,0,0,0,0, + 0x11, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x16, 0,0,0,0,0,0,0,0, + 0x11, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x16, 0,0,0,0,0,0,0,0, + 0x11, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x16, 0,0,0,0,0,0,0,0, + 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0x88, 0,0,0,0,0,0,0,0, + } + }; + ULONG uFile = FILE(cPawn); + + ASSERT(IS_VALID_COLOR(uColor)); + ASSERT(IS_ON_BOARD(cPawn)); + ASSERT((RANK(cPawn) != 1) && (RANK(cPawn) != 8)); + + if ((uFile == A) || (uFile == H)) + { + cSquare[0] = cCriticalSquare[uColor][cPawn]; + cSquare[1] = cCriticalSquare[uColor][cPawn]; + cSquare[2] = cCriticalSquare[uColor][cPawn]; + goto end; + } + cSquare[1] = cCriticalSquare[uColor][cPawn]; + cSquare[0] = cSquare[1] - 1; + cSquare[2] = cSquare[1] + 1; + + end: + ASSERT(cSquare[0] != 0); + ASSERT(cSquare[1] != 0); + ASSERT(cSquare[2] != 0); + ASSERT(IS_ON_BOARD(cSquare[0])); + ASSERT(IS_ON_BOARD(cSquare[1])); + ASSERT(IS_ON_BOARD(cSquare[2])); +} + + +static ULONG +_RecognizeKPK(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore) +/** + +Routine description: + + Attempt to recognize KP+KP* positions. + +Parameters: + + POSITION *pos, + SCORE *piScore + +Return value: + + static ULONG + +**/ +{ + ULONG uStrong; + ULONG uWeak; + COOR cPawn, cQueen; + COOR cCritical[3]; + ULONG uDist[2]; + ULONG u; + PAWN_HASH_ENTRY *pHash; + POSITION *pos = &ctx->sPosition; + + ASSERT(pos->uNonPawnCount[WHITE][0] == 1); + ASSERT(pos->uNonPawnCount[BLACK][0] == 1); + ASSERT(_NothingBut(pos, PAWN, WHITE)); + ASSERT(_NothingBut(pos, PAWN, BLACK)); + + // + // Look to see if one side has a winning passed pawn + // + pHash = PawnHashLookup(ctx); + ASSERT(pHash != NULL); + if (pHash->u64Key == pos->u64PawnSig) + { + pos->iScore[BLACK] = pos->iScore[WHITE] = 0; + if (TRUE == EvalPasserRaces(pos, pHash)) + { + // + // Someone wins. + // + ASSERT((pos->iScore[BLACK] == 0) || (pos->iScore[WHITE] == 0)); + ASSERT((pos->iScore[BLACK] != 0) || (pos->iScore[WHITE] != 0)); + if (pos->iScore[BLACK] > 0) + { + ASSERT(pos->iScore[WHITE] == 0); + *piScore = (pos->iMaterialBalance[BLACK] + 2 * VALUE_PAWN + + pos->iScore[BLACK]); + ASSERT(IS_VALID_SCORE(*piScore)); + if (pos->uToMove == WHITE) + { + *piScore *= -1; + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); + } + else + { + ASSERT(pos->iScore[WHITE] > 0); + *piScore = (pos->iMaterialBalance[WHITE] + 2 * VALUE_PAWN + + pos->iScore[WHITE]); + ASSERT(IS_VALID_SCORE(*piScore)); + if (pos->uToMove == BLACK) + { + *piScore *= -1; + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); + } + } + } + + // + // No one has a winning passer or we did not find the hash entry. + // + if ((pos->uPawnCount[WHITE] > 0) && (pos->uPawnCount[BLACK] > 0)) + { + return(UNRECOGNIZED); + } + + // + // If we get here then no one has a winning passer and one side + // has only a lone king -- no pawns. Do some more "sophisticated" + // analysis looking for a won passer. Also: this is at best a + // draw for the weak side. + // + uStrong = WHITE; + if (pos->uPawnCount[WHITE] == 0) + { + uStrong = BLACK; + } + ASSERT(pos->uPawnCount[uStrong] > 0); + uWeak = FLIP(uStrong); + ASSERT(pos->uPawnCount[uWeak] == 0); + + if (pos->uPawnCount[uStrong] > 1) + { + *piScore = 0; + if (pos->uToMove == uStrong) + { + return(RECOGN_LOWER); + } + return(RECOGN_UPPER); + } + + // + // The side with pawns has only one pawn, do some more + // sophisticated analysis here to spot winning KPK + // configurations earlier by using "critical squares" + // + ASSERT(pos->uPawnCount[uStrong] == 1); + cPawn = pos->cPawns[uStrong][0]; + ASSERT(IS_ON_BOARD(cPawn)); + ASSERT(IS_PAWN(pos->rgSquare[cPawn].pPiece)); + + // + // Step 1: the strong king must be closer to the pawn than + // the weak king. + // + uDist[uStrong] = DISTANCE(pos->cNonPawns[uStrong][0], cPawn); + ASSERT((1 <= uDist[uStrong]) && (uDist[uStrong] <= 7)); + uDist[uWeak] = DISTANCE(pos->cNonPawns[uWeak][0], cPawn); + ASSERT((1 <= uDist[uWeak]) && (uDist[uWeak] <= 7)); + if (uDist[uStrong] <= uDist[uWeak]) + { + // + // Step 2: the strong king must be closer to one of the + // passer's critical squares than the weak king. + // + _GetPassersCriticalSquares(uStrong, cPawn, cCritical); + for (u = 0; u < 3; u++) + { + uDist[uStrong] = DISTANCE(pos->cNonPawns[uStrong][0], + cCritical[u]); + ASSERT((0 <= uDist[uStrong]) && (uDist[uStrong] <= 7)); + uDist[uWeak] = DISTANCE(pos->cNonPawns[uWeak][0], + cCritical[u]); + + // + // Assume if the weak side is on move he will move + // towards the critical square. Also assume that + // in so doing he will increase the path that the + // strong king must take to get to the critical + // square. + // + if (uDist[uWeak] > 0) { + uDist[uWeak] -= (pos->uToMove == uWeak); + } + if (uDist[uStrong] > 0) { + uDist[uStrong] += (pos->uToMove == uWeak) * 2; + } + ASSERT((0 <= uDist[uWeak]) && (uDist[uWeak] <= 7)); + if (uDist[uStrong] < uDist[uWeak]) + { + cQueen = + QUEENING_SQUARE_BY_COLOR_FILE[uStrong][FILE(cPawn)]; + *piScore = (pos->iMaterialBalance[uStrong] + + VALUE_QUEEN + (2 * VALUE_PAWN) - + (RANK_DISTANCE(cPawn, cQueen) * 32)); + if (pos->uToMove == uWeak) + { + *piScore *= -1; + return(RECOGN_UPPER); + } + return(RECOGN_LOWER); + } + } + } + + // + // If we get here then the weak king is as close to or + // closer to the lone passer than the strong king -or- the + // weak king is as close to or closer to the passer's + // critical squares than the strong king. This may still + // be won for the strong side but we don't know -- the + // logic is ugly. This is still at best drawn for the + // weak side though. + // + *piScore = 0; + if (pos->uToMove == uStrong) + { + return(RECOGN_LOWER); + } + return(RECOGN_UPPER); +} + + +static void +_NewRecognizer(IN RECOGNIZER *pFunct, + IN ULONG uWhiteSig, + IN ULONG uBlackSig) +/** + +Routine description: + + Register a recognizer function. + +Parameters: + + RECOGNIZER *pFunct, + ULONG uWhiteSig, + ULONG uBlackSig + +Return value: + + static void + +**/ +{ + g_bvRecognizerAvailable[uWhiteSig] |= (1 << uBlackSig); + g_bvRecognizerAvailable[uBlackSig] |= (1 << uWhiteSig); + g_pRecognizers[RECOGN_INDEX(uWhiteSig, uBlackSig)] = pFunct; +} + +void +InitializeInteriorNodeRecognizers(void) +/** + +Routine description: + + Init this recognizer module + +Parameters: + + void + +Return value: + + void + +**/ +{ + memset(g_pRecognizers, 0, sizeof(g_pRecognizers)); + memset(g_bvRecognizerAvailable, 0, sizeof(g_bvRecognizerAvailable)); + + // KK P N B R Q + _NewRecognizer(_RecognizeKK, + _MakeMaterialSig(0, 0, 0, 0, 0), + _MakeMaterialSig(0, 0, 0, 0, 0)); + + // KB+K P N B R Q + _NewRecognizer(_RecognizeKBK, + _MakeMaterialSig(0, 0, 1, 0, 0), + _MakeMaterialSig(0, 0, 0, 0, 0)); + + // KB+KB+ P N B R Q + _NewRecognizer(_RecognizeKBK, + _MakeMaterialSig(0, 0, 1, 0, 0), + _MakeMaterialSig(0, 0, 1, 0, 0)); + + // KN+K P N B R Q + _NewRecognizer(_RecognizeKNK, + _MakeMaterialSig(0, 1, 0, 0, 0), + _MakeMaterialSig(0, 0, 0, 0, 0)); + + // KN+KN+ P N B R Q + _NewRecognizer(_RecognizeKNK, + _MakeMaterialSig(0, 1, 0, 0, 0), + _MakeMaterialSig(0, 1, 0, 0, 0)); + + // KN+KB+ P N B R Q + _NewRecognizer(_RecognizeKBNK, + _MakeMaterialSig(0, 1, 0, 0, 0), + _MakeMaterialSig(0, 0, 1, 0, 0)); + + // KN+B+K P N B R Q + _NewRecognizer(_RecognizeKBNK, + _MakeMaterialSig(0, 1, 1, 0, 0), + _MakeMaterialSig(0, 0, 0, 0, 0)); + + // KN+KP+ P N B R Q + _NewRecognizer(_RecognizeKNKP, + _MakeMaterialSig(1, 0, 0, 0, 0), + _MakeMaterialSig(0, 1, 0, 0, 0)); + + // KB+KP+ P N B R Q + _NewRecognizer(_RecognizeKBKP, + _MakeMaterialSig(1, 0, 0, 0, 0), + _MakeMaterialSig(0, 0, 1, 0, 0)); + + // KP+B+KP+ P N B R Q + _NewRecognizer(_RecognizeKBKP, + _MakeMaterialSig(1, 0, 1, 0, 0), + _MakeMaterialSig(1, 0, 0, 0, 0)); + + + // KP+B+K P N B R Q + _NewRecognizer(_RecognizeKBKP, + _MakeMaterialSig(1, 0, 1, 0, 0), + _MakeMaterialSig(0, 0, 0, 0, 0)); + + // KP+K P N B R Q + _NewRecognizer(_RecognizeKPK, + _MakeMaterialSig(0, 0, 0, 0, 0), + _MakeMaterialSig(1, 0, 0, 0, 0)); + + // KP+KP+ P N B R Q + _NewRecognizer(_RecognizeKPK, + _MakeMaterialSig(1, 0, 0, 0, 0), + _MakeMaterialSig(1, 0, 0, 0, 0)); +} + + +ULONG +RecognLookup(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piScore, + IN FLAG fProbeEGTB) +/** + +Routine description: + + This is the interface to the recogn module; it is called from + Search and Qsearch. Its job is to: 1. check high speed internal + node recognizer functions if a recognizable material signature is + present on the board and 2. probe on-disk EGTB files if no useful + recognizer result is found. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore, + FLAG fProbeEGTB + +Return value: + + ULONG + +**/ +{ + ULONG uVal; + POSITION *pos = &ctx->sPosition; + ULONG uSig[2]; + RECOGNIZER *pRec; + SCORE iScore; + + // + // Try interior node recognizers + // + if ((pos->uNonPawnCount[WHITE][0] <= 3) && + (pos->uNonPawnCount[BLACK][0] <= 3)) + { + uSig[BLACK] = _MakeMaterialSig((pos->uPawnCount[BLACK] > 0), + (pos->uNonPawnCount[BLACK][KNIGHT] > 0), + (pos->uNonPawnCount[BLACK][BISHOP] > 0), + (pos->uNonPawnCount[BLACK][ROOK] > 0), + (pos->uNonPawnCount[BLACK][QUEEN] > 0)); + uSig[WHITE] = _MakeMaterialSig((pos->uPawnCount[WHITE] > 0), + (pos->uNonPawnCount[WHITE][KNIGHT] > 0), + (pos->uNonPawnCount[WHITE][BISHOP] > 0), + (pos->uNonPawnCount[WHITE][ROOK] > 0), + (pos->uNonPawnCount[WHITE][QUEEN] > 0)); + pRec = g_pRecognizers[RECOGN_INDEX(uSig[WHITE], uSig[BLACK])]; + if (NULL != pRec) + { + if (g_bvRecognizerAvailable[uSig[WHITE]] & (1 << uSig[BLACK])) + { + uVal = pRec(ctx, &iScore); + if (UNRECOGNIZED != uVal) + { + *piScore = iScore; + ASSERT((-NMATE < iScore) && (iScore < +NMATE)); + ASSERT(_SanityCheckRecognizers(ctx, iScore, uVal)); + return(uVal); + } + } + } + } + + // + // Try EGTB probe as long as some conditions are met + // + if ((FALSE != fProbeEGTB) && + ((pos->uNonPawnCount[WHITE][0] + pos->uNonPawnCount[BLACK][0] + + pos->uPawnCount[WHITE] + pos->uPawnCount[BLACK]) <= 5)) + { + if (TRUE == ProbeEGTB(ctx, &iScore)) + { + // + // We have an exact score from EGTB but if it's a mate in N + // we still have to adjust it for the present ply. + // + if (iScore >= +NMATE) { + iScore -= ctx->uPly; + } + else if (iScore <= -NMATE) { + iScore += ctx->uPly; + } +#ifdef DEBUG + else + { + ASSERT(iScore == 0); // iDrawValue[side] + } +#endif + *piScore = iScore; + return(RECOGN_EXACT); + } + } + return(UNRECOGNIZED); +} diff --git a/src/root.c b/src/root.c new file mode 100755 index 0000000..87ee4be --- /dev/null +++ b/src/root.c @@ -0,0 +1,1526 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + root.c + +Abstract: + + Routines dealing with the root of the search tree. Specifically + move ordering at the root node, searching, search support, pondering, + pondering support, and the main iterative deepening loop. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 21 May 2004 + +Revision History: + + $Id: root.c 356 2008-07-02 16:18:12Z scott $ + +**/ + +#include "chess.h" + +volatile MOVE_TIMER g_MoveTimer; +ULONG g_uIterateDepth; +ULONG g_uSoftExtendLimit; +ULONG g_uHardExtendLimit; +ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; +FLAG g_fCanSplit[MAX_PLY_PER_SEARCH]; +SCORE g_iRootScore[2] = {0, 0}; +SCORE g_iScore; + + +static void +_SetMoveTimerForPonder(void) +/** + +Routine description: + + Set the move timer before a ponder operation. A time limit of -1 + means search forever... so the only way out of the ponder is for + new user input to interrupt it. + +Parameters: + + void + +Return value: + + static void + +**/ +{ + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.dSoftTimeLimit = -1; + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.uNodeCheckMask = 0x200 - 1; + g_MoveTimer.bvFlags = 0; +} + + +void +SetMoveTimerToThinkForever(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + void + +**/ +{ + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.dSoftTimeLimit = -1; + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.uNodeCheckMask = 0x1000000 - 1; + g_MoveTimer.bvFlags = 0; +} + + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor) +/** + +Routine description: + + Set the move timer for a search operation. + +Parameters: + + FLAG fSwitchOver : if TRUE then this search is a converted ponder + (i.e. they made the ponder move and now we are searching). + +Return value: + + void + +**/ +{ + ULONG uMovesDone = GetMoveNumber(uColor); + double dClock = (double)g_Options.uMyClock; + double dSec = 0; + ULONG uMargin = 0; + ULONG uMovesToDo; + + // + // If switching over from a ponder search leave the start time and + // move flags alone (i.e. N seconds in the past already). + // + if (FALSE == fSwitchOver) + { + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.bvFlags = 0; + } + + // + // Check the clock more often in search if there is little time + // left on the clock -- we can't afford an oversearch when the + // bullet game is down to the wire. + // +#ifdef DEBUG + g_MoveTimer.uNodeCheckMask = 0x800 - 1; +#else + if (WeAreRunningASuite()) + { + g_MoveTimer.uNodeCheckMask = 0x20000 - 1; + } + else if (g_Options.u64MaxNodeCount) + { + g_MoveTimer.uNodeCheckMask = 0x1000 - 1; + } + else + { + if (dClock < 10.0) + { + g_MoveTimer.uNodeCheckMask = 0x400 - 1; + } + else + { + g_MoveTimer.uNodeCheckMask = 0x8000 - 1; + } + } +#endif + + switch (g_Options.eClock) + { + // + // Fixed time per move. Think for g_uMyIncrement seconds exactly and + // no hard time limit. + // + case CLOCK_FIXED: + dSec = (double)g_Options.uMyIncrement; + uMargin = 0; + break; + + // + // N moves per time control or entire game in time control. + // + case CLOCK_NORMAL: + if (g_Options.uMovesPerTimePeriod != 0) + { + // + // N moves per time control. + // + ASSERT(g_Options.uMovesPerTimePeriod < 256); + uMovesToDo = + (g_Options.uMovesPerTimePeriod - + ((uMovesDone - 1) % g_Options.uMovesPerTimePeriod)); +#ifdef DEBUG + Trace("SetMoveTimer: %u moves left to do this in %s sec.\n", + uMovesToDo, TimeToString(dClock)); +#endif + ASSERT(uMovesToDo <= g_Options.uMovesPerTimePeriod); + dSec = (dClock / (double)uMovesToDo); + dSec *= 0.95; + uMargin = (ULONG)(dSec * 2.2); + if (uMovesToDo <= 5) + { + dSec *= 0.75; + uMargin /= 2; + } + break; + } + else + { + // + // Fixed time finish entire game. + // +#ifdef DEBUG + Trace("SetMoveTimer: finish the game in %s sec.\n", + TimeToString(dClock)); +#endif + dSec = dClock / 60; + uMargin = (ULONG)(dSec * 2.2); + } + break; + + // + // We get back a certain number of seconds with each move made. + // + case CLOCK_INCREMENT: + dSec = g_Options.uMyIncrement; + dSec += (dClock / 50); + uMargin = (int)(dSec * 2.2); + +#ifdef DEBUG + Trace("SetMoveTimer: finish the game in %s sec (+%u per move).\n", + TimeToString(dClock), g_Options.uMyIncrement); +#endif + + // + // If we are running out of time, think for less than the + // increment. + // + if (dClock < 20.0) + { + dSec -= g_Options.uMyIncrement; + uMargin = 0; + } + ASSERT(dSec > 0); + break; + + case CLOCK_NONE: +#ifdef DEBUG + Trace("SetMoveTimer: no time limit, think until interrupted.\n"); +#endif + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.dSoftTimeLimit = -1; + goto post; + + default: + ASSERT(FALSE); + break; + } + if ((dSec + uMargin) >= (dClock * 7 / 8)) uMargin = 0; + g_MoveTimer.dSoftTimeLimit = g_MoveTimer.dStartTime + dSec; + g_MoveTimer.dHardTimeLimit = g_MoveTimer.dStartTime + dSec + uMargin; + + post: + if (TRUE == g_Options.fShouldPost) + { + if (g_MoveTimer.dSoftTimeLimit > 0) + { + Trace("SetMoveTimer: Soft time limit %s seconds.\n", + TimeToString(g_MoveTimer.dSoftTimeLimit - + g_MoveTimer.dStartTime)); + ASSERT(g_MoveTimer.dHardTimeLimit > 0); + Trace("SetMoveTimer: Hard time limit %s seconds.\n", + TimeToString(g_MoveTimer.dHardTimeLimit - + g_MoveTimer.dStartTime)); + if (TRUE == fSwitchOver) + { + Trace("SetMoveTimer: Already searched %s seconds.\n", + TimeToString(SystemTimeStamp() - + g_MoveTimer.dStartTime)); + } + } +#ifdef DEBUG + Trace("SetMoveTimer: Checking input and timer every %u nodes.\n", + g_MoveTimer.uNodeCheckMask); +#endif + } +} + + +void +ReInitializeSearcherContext(POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Reinitializes a SEARCHER_THREAD_CONTEXT structure. + +Parameters: + + POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + if (NULL != pos) + { + memmove(&(ctx->sPosition), pos, sizeof(POSITION)); + } + ctx->uPly = 0; + ctx->uPositional = 133; + memset(&(ctx->sCounters), 0, sizeof(COUNTERS)); +} + + +void +InitializeSearcherContext(POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Initialize a SEARCHER_THREAD_CONTEXT structure. + +Parameters: + + POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG u; + + memset(ctx, 0, sizeof(SEARCHER_THREAD_CONTEXT)); + ReInitializeSearcherContext(pos, ctx); + ctx->sMoveStack.uUnblockedKeyValue[0] = 1; + for (u = 1; + u < MAX_PLY_PER_SEARCH; + u++) + { + ctx->sMoveStack.uUnblockedKeyValue[u] = + ctx->sMoveStack.uUnblockedKeyValue[u-1] + 0x28F5C28; + } +} + + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx) +/** + +Routine description: + + Initialize a LIGHTWEIGHT_SEARCHER_CONTEXT structure. + +Parameters: + + POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG u; + + memset(ctx, 0, sizeof(LIGHTWEIGHT_SEARCHER_CONTEXT)); + if (NULL != pos) + { + memmove(&(ctx->sPosition), pos, sizeof(POSITION)); + } + ctx->uPly = 0; + ctx->uPositional = 133; + ctx->sMoveStack.uUnblockedKeyValue[0] = 1; + for (u = 1; + u < MAX_PLY_PER_SEARCH; + u++) + { + ctx->sMoveStack.uUnblockedKeyValue[u] = + ctx->sMoveStack.uUnblockedKeyValue[u-1] + 0x28F5C28; + } +} + + +void +PostMoveSearchReport(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Dump a report to stdout after every move. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + +Return value: + + void + +**/ +{ + double d; + char buf[256]; +#ifdef PERF_COUNTERS + double n; +#endif + d = (double)g_MoveTimer.dEndTime - (double)g_MoveTimer.dStartTime + 0.01; + ASSERT(d); + Trace("---------------------------------------------\n" + "Searched for %5.1f seconds, saw %" + COMPILER_LONGLONG_UNSIGNED_FORMAT + " nodes (%" + COMPILER_LONGLONG_UNSIGNED_FORMAT + " qnodes) (%6.0f nps).\n", + d, ctx->sCounters.tree.u64TotalNodeCount, + ctx->sCounters.tree.u64QNodeCount, + ((double)ctx->sCounters.tree.u64TotalNodeCount / d)); + if (g_Options.fThinking) + { + snprintf(buf, ARRAY_LENGTH(buf), "d%u, %s, %3.1fs, %6.0fknps, PV=%s", + ctx->uRootDepth / ONE_PLY, + ScoreToString(ctx->iRootScore), + d, + ((double)ctx->sCounters.tree.u64TotalNodeCount / d / 1000), + ctx->szLastPV); + Trace("tellothers %s\n", buf); + } +#ifdef MP +#ifdef PERF_COUNTERS + if (ctx->sCounters.parallel.uNumSplits > 0) + { + n = (double)ctx->sCounters.parallel.uNumSplits; + Trace("Split %u times total ", + ctx->sCounters.parallel.uNumSplits); + Trace("(~%7.2fx/sec).\n", (n / d)); + d = n + 1; + ASSERT(d); + n = (double)ctx->sCounters.parallel.uNumSplitsTerminated; + Trace(" ...%u (%5.2f percent) terminated early.\n", + ctx->sCounters.parallel.uNumSplitsTerminated, ((n/d) * 100.0)); + DumpHelperIdlenessReport(); + } +#endif +#endif + +#ifdef TEST + AnalyzeFullHashTable(); +#endif +#ifdef PERF_COUNTERS + d = (double)(ctx->sCounters.hash.u64Probes) + 1; + ASSERT(d); + Trace("Hashing percentages: (%5.3f total, %5.3f useful)\n", + ((double)(ctx->sCounters.hash.u64OverallHits) / d) * 100.0, + ((double)(ctx->sCounters.hash.u64UsefulHits) / d) * 100.0); + d = (double)(ctx->sCounters.pawnhash.u64Probes) + 1; + ASSERT(d); + n = (double)(ctx->sCounters.pawnhash.u64Hits); + Trace("Pawn hash hitrate: %5.3f percent.\n", (n/d) * 100.0); + n = (double)(ctx->sCounters.tree.u64NullMoveSuccess); + d = (double)(ctx->sCounters.tree.u64NullMoves) + 1; + ASSERT(d); + Trace("Null move cutoff rate: %5.3f percent.\n", + ((n / d) * 100.0)); +#ifdef TEST_ENDGAME + n = (double)(ctx->sCounters.tree.u64EndgamePruningSuccess); + d = n + (double)(ctx->sCounters.tree.u64EndgamePruningFailures); + if (d != 0.0) + { + Trace("Endgame pruning heuristic success rate was %5.3f percent.\n" + "Endgame pruning heuristic was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64EndgamePruningSuccess, + (ctx->sCounters.tree.u64EndgamePruningSuccess + + ctx->sCounters.tree.u64EndgamePruningFailures)); + } + else + { + Trace("Never used endgame pruning heuristic.\n"); + } +#endif +#ifdef TEST_NULL + n = (double)(ctx->sCounters.tree.u64AvoidNullSuccess); + d = n + (double)(ctx->sCounters.tree.u64AvoidNullFailures); + if (d != 0.0) + { + Trace("Avoid null move heuristic rate was %5.3f percent.\n" + "Avoid null move heuristic was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64AvoidNullSuccess, + (ctx->sCounters.tree.u64AvoidNullSuccess + + ctx->sCounters.tree.u64AvoidNullFailures)); + } + else + { + Trace("Never used the avoid null move heuristic.\n"); + } + n = (double)(ctx->sCounters.tree.u64QuickNullSuccess); + n += (double)(ctx->sCounters.tree.u64QuickNullDeferredSuccess); + d = n + (double)(ctx->sCounters.tree.u64QuickNullFailures); + if (d != 0.0) + { + Trace("Quick null move heuristic rate was %5.3f percent.\n" + "Quick null move heuristic rate was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " (" + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ") / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64QuickNullSuccess, + ctx->sCounters.tree.u64QuickNullDeferredSuccess, + (ctx->sCounters.tree.u64QuickNullSuccess + + ctx->sCounters.tree.u64QuickNullDeferredSuccess + + ctx->sCounters.tree.u64QuickNullFailures)); + } + else + { + Trace("Never used the quick null move heuristic.\n"); + } +#endif + n = (double)ctx->sCounters.tree.u64BetaCutoffsOnFirstMove; + d = (double)ctx->sCounters.tree.u64BetaCutoffs + 1; + Trace("First move beta cutoff rate was %5.3f percent.\n", + ((n / d) * 100.0)); +#ifdef LAZY_EVAL + d = (double)ctx->sCounters.tree.u64LazyEvals; + d += (double)ctx->sCounters.tree.u64FullEvals; + d += (double)ctx->sCounters.tree.u64EvalHashHits; + d += 1; + ASSERT(d); + Trace("Eval percentages: (%5.2f hash, %5.2f lazy, %5.2f full)\n", + ((double)ctx->sCounters.tree.u64EvalHashHits / d) * 100.0, + ((double)ctx->sCounters.tree.u64LazyEvals / d) * 100.0, + ((double)ctx->sCounters.tree.u64FullEvals / d) * 100.0); +#endif + Trace("Extensions: (%u +, %u q+, %u 1mv, %u !kmvs, %u mult+, %u pawn\n" + " %u threat, %u zug, %u sing, %u endg, %u bm, %u recap)\n", + ctx->sCounters.extension.uCheck, + ctx->sCounters.extension.uQExtend, + ctx->sCounters.extension.uOneLegalMove, + ctx->sCounters.extension.uNoLegalKingMoves, + ctx->sCounters.extension.uMultiCheck, + ctx->sCounters.extension.uPawnPush, + ctx->sCounters.extension.uMateThreat, + ctx->sCounters.extension.uZugzwang, + ctx->sCounters.extension.uSingularReplyToCheck, + ctx->sCounters.extension.uEndgame, + ctx->sCounters.extension.uBotvinnikMarkoff, + ctx->sCounters.extension.uRecapture); +#ifdef EVAL_TIME + n = (double)ctx->sCounters.tree.u64CyclesInEval; + Trace("Avg. cpu cycles in eval: %8.1f.\n", (n / d)); +#endif +#endif +} + + +SCORE +RootSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth) +/** + +Routine description: + + Search at the root of the whole tree. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth, + +Return value: + + SCORE + +**/ +{ + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + SCORE iBestScore = -INFINITY; + SCORE iInitialAlpha = iAlpha; + MOVE mv; + ULONG x, y; + SCORE iScore; + ULONG uNextDepth; + UINT64 u64StartingNodeCount; + ULONG uNumLegalMoves; + +#ifdef DEBUG + POSITION *pos = &ctx->sPosition; + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT((ctx->uPly == 0) || (ctx->uPly == 1)); // 1 is for under a ponder + memcpy(&pi->sPosition, pos, sizeof(POSITION)); +#endif + + ctx->sCounters.tree.u64TotalNodeCount++; + pi->PV[ctx->uPly] = NULLMOVE; + pi->mvBest = NULLMOVE; + g_MoveTimer.bvFlags |= TIMER_SEARCHING_FIRST_MOVE; +#ifdef DEBUG + Trace("---- depth=%u, a=%d, b=%d ----\n", uDepth / ONE_PLY, iAlpha, iBeta); +#endif + + uNumLegalMoves = 0; + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectMoveAtRoot(ctx, x); + if (ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED) break; + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; + mv = ctx->sMoveStack.mvf[x].mv; + mv.bvFlags |= WouldGiveCheck(ctx, mv); + + if (MakeMove(ctx, mv)) + { + uNumLegalMoves++; + u64StartingNodeCount = ctx->sCounters.tree.u64TotalNodeCount; + + // + // TODO: Fancy recap shit here? + // + + uNextDepth = uDepth - ONE_PLY; + if (IS_CHECKING_MOVE(mv)) + { + uNextDepth += HALF_PLY; + ctx->sPlyInfo[ctx->uPly].iExtensionAmount = HALF_PLY; + } + + ctx->sSearchFlags.fVerifyNullmove = TRUE; + ctx->sSearchFlags.uQsearchDepth = 0; + if (uNumLegalMoves == 1) + { + // + // Move 1, full a..b window + // + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + else + { + // + // Moves 2..N, minimal window search + // + ASSERT(x > 0); + ASSERT(uNumLegalMoves > 1); + iScore = -Search(ctx, -iAlpha - 1, -iAlpha, uNextDepth); + if ((iAlpha < iScore) && (iScore < iBeta)) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + } + ctx->sSearchFlags.fVerifyNullmove = FALSE; + UnmakeMove(ctx, mv); + if (WE_SHOULD_STOP_SEARCHING) + { + iBestScore = INVALID_SCORE; + goto end; + } +#ifdef DEBUG + Trace("%2u. %-8s => node=%" COMPILER_LONGLONG_UNSIGNED_FORMAT + ", predict=%d, actual=%d, ", + x + 1, + MoveToSan(mv, &ctx->sPosition), + u64StartingNodeCount, + ctx->sMoveStack.mvf[x].iValue, + iScore); + ASSERT(PositionsAreEquivalent(&pi->sPosition, &ctx->sPosition)); +#endif + // + // Keep track of how many moves are under each one we + // search and use this as the basis for root move ordering + // next iteration. + // + u64StartingNodeCount = (ctx->sCounters.tree.u64TotalNodeCount - + u64StartingNodeCount); + u64StartingNodeCount >>= 9; + u64StartingNodeCount &= (MAX_INT / 4); + ctx->sMoveStack.mvf[x].iValue = + (SCORE)(u64StartingNodeCount + iScore); +#ifdef DEBUG + Trace("next_predict: %d\n", ctx->sMoveStack.mvf[x].iValue); + ASSERT(iBestScore <= iAlpha); + ASSERT(iAlpha < iBeta); +#endif + if (iScore > iBestScore) + { + iBestScore = iScore; + pi->mvBest = mv; + if (iScore > iAlpha) + { + // + // We have a best move so far. As of now it is + // the one we'll be playing. Also make sure to + // search it first at the next depth. + // +#ifdef DEBUG + Trace("Best so far... root score=%d.\n", iScore); +#endif + ctx->mvRootMove = mv; + ctx->iRootScore = iScore; + ctx->uRootDepth = uDepth; + ctx->sMoveStack.mvf[x].iValue = MAX_INT; + + // + // If there was a previous PV move then knock its + // score down so that it will be considered second + // on the next depth. + // + for (y = ctx->sMoveStack.uBegin[ctx->uPly]; + y < x; + y++) + { + if (ctx->sMoveStack.mvf[y].iValue == MAX_INT) + { + ctx->sMoveStack.mvf[y].iValue /= 2; + } + } + + UpdatePV(ctx, mv); + if (iScore >= iBeta) + { + // + // Root fail high... + // + UpdateDynamicMoveOrdering(ctx, + uDepth, + mv, + iScore, + x + 1); + UtilPrintPV(ctx, iAlpha, iBeta, iScore, mv); + KEEP_TRACK_OF_FIRST_MOVE_FHs(iBestScore == -INFINITY); + ctx->sMoveStack.mvf[x].bvFlags &= ~MVF_MOVE_SEARCHED; + goto end; + } + else + { + // + // Root PV change... + // + UtilPrintPV(ctx, iAlpha, iBeta, iScore, mv); + iAlpha = iScore; + } + } + } + g_MoveTimer.bvFlags &= ~TIMER_SEARCHING_FIRST_MOVE; + } + } + + if (iAlpha == iInitialAlpha) + { + // + // Root fail low... + // + ASSERT(iBestScore <= iAlpha); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + UtilPrintPV(ctx, iAlpha, iBeta, iBestScore, mv); + } + + end: + return(iBestScore); +} + + + +static GAME_RESULT +_DetectPreMoveTerminalStates(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fInCheck, + MOVE *pmv) { + ULONG u; + MOVE mv; + MOVE mvLegal; + ULONG uNumLegal = 0; + GAME_RESULT ret; + POSITION *pos = &ctx->sPosition; + ULONG uMajors[2], uMinors[2], uWhiteBishops[2], uBlackBishops[2]; + + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + pmv->uMove = 0; + + // Look for insufficient material. + FOREACH_COLOR(u) { + uMajors[u] = (pos->uNonPawnCount[u][ROOK] + + pos->uNonPawnCount[u][QUEEN]); + uMinors[u] = (pos->uNonPawnCount[u][KNIGHT] + + pos->uNonPawnCount[u][BISHOP]); + uWhiteBishops[u] = pos->uWhiteSqBishopCount[u]; + uBlackBishops[u] = pos->uNonPawnCount[u][BISHOP] - uWhiteBishops[u]; + } + FOREACH_COLOR(u) { + if ((pos->uPawnCount[u] != 0) || + (pos->uPawnCount[FLIP(u)] != 0)) { + continue; + } + if (pos->uNonPawnCount[u][0] == 1) { + if (uMajors[FLIP(u)] == 0 && + uMinors[FLIP(u)] == 1) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "insufficient material"); + return ret; + } else if (uMajors[FLIP(u)] == 0 && + (uMinors[FLIP(u)] == uWhiteBishops[FLIP(u)] || + uMinors[FLIP(u)] == uBlackBishops[FLIP(u)])) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "insufficient material"); + return ret; + } + } else if ((pos->uNonPawnCount[u][0] == 1 + uWhiteBishops[u] && + pos->uNonPawnCount[FLIP(u)][0] == + 1 + uWhiteBishops[FLIP(u)]) || + (pos->uNonPawnCount[u][0] == 1 + uBlackBishops[u] && + pos->uNonPawnCount[FLIP(u)][0] == + 1 + uBlackBishops[FLIP(u)])) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "insufficient material"); + return ret; + } + } + + // Count the number of legal moves the side on move has in this position. + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) { + mv = ctx->sMoveStack.mvf[u].mv; + if (MakeMove(ctx, mv)) { + mvLegal = mv; + uNumLegal += 1; + UnmakeMove(ctx, mv); + if (uNumLegal > 1) { + return ret; + } + } + } + + // If there's only one legal move then tell the caller what it is. + if (uNumLegal == 1) { + *pmv = mvLegal; + return ret; + } + + // There are no legal moves so its checkmate or stalemate. + ASSERT(uNumLegal == 0); + if (TRUE == fInCheck) { + if (ctx->sPosition.uToMove == WHITE) { + ret.eResult = RESULT_BLACK_WON; + strcpy(ret.szDescription, "black checkmated white"); + return ret; + } + ret.eResult = RESULT_WHITE_WON; + strcpy(ret.szDescription, "white checkmated black"); + return ret; + } + ret.eResult = RESULT_DRAW; + sprintf(ret.szDescription, "%s stalemated %s", + (ctx->sPosition.uToMove == WHITE) ? "black" : "white", + (ctx->sPosition.uToMove == WHITE) ? "while" : "black"); + return ret; +} + + + +static GAME_RESULT +_DetectPostMoveTerminalStates(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + This function is called by Iterate and MakeTheMove to declare + wins/losses/draws. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG + +**/ +{ + GAME_RESULT ret; + FLAG fInCheck = InCheck(&ctx->sPosition, ctx->sPosition.uToMove); + + // Did we just make the 50th+ move without progress? + if (ctx->sPosition.uFifty >= 100) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "fifty moves without progress"); + return ret; + } + GenerateMoves(ctx, NULLMOVE, (fInCheck ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + + // Did we just repeat a position for the 3rd time? + if (IsLegalDrawByRepetition()) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "third repetition of position"); + return ret; + } + + // Otherwise look for checkmates, stalemates and insufficient material. + MOVE mvUnused; + return _DetectPreMoveTerminalStates(ctx, + fInCheck, + &mvUnused); +} + + +static void +_IterateSetSearchGlobals(ULONG uDepth) +{ + ULONG u, v; + ULONG uDontSplitLessThan; + + // + // Set some globals that will be used throughout this search. + // + g_uIterateDepth = uDepth; + ASSERT(g_uIterateDepth > 0); + ASSERT(g_uIterateDepth < MAX_PLY_PER_SEARCH); + + // + // For use in scaling back extensions that are very far from + // the root. + // + // Iterate g_Soft g_Hard + // | | | | | | | | | + // 0 1 2 2.5 3 3.5 4 (x Iterate) + // |-------------------|----|----|---------|----... + // |full full full full|-1/4|-1/2|-3/4 -3/4|none... + // + g_uSoftExtendLimit = g_uIterateDepth * 2; + g_uHardExtendLimit = g_uIterateDepth * 4; + for (u = 0; u < MAX_PLY_PER_SEARCH; u++) + { + if (u < g_uSoftExtendLimit) + { + g_uExtensionReduction[u] = 0; + } + else if (u < (g_uSoftExtendLimit + g_uIterateDepth / 2)) + { + g_uExtensionReduction[u] = QUARTER_PLY; + } + else if (u < (g_uSoftExtendLimit + g_uIterateDepth)) + { + g_uExtensionReduction[u] = HALF_PLY; + } + else if (u < g_uHardExtendLimit) + { + g_uExtensionReduction[u] = THREE_QUARTERS_PLY; + } + else + { + g_uExtensionReduction[u] = 5 * ONE_PLY; + } + } + + // + // Determine how much depth we need below a point in the tree in + // order to split the search (which is based on iteration depth). + // + uDontSplitLessThan = (ULONG)((double)(uDepth) * 0.30); + for (v = 0; v < MAX_PLY_PER_SEARCH; v++) + { + g_fCanSplit[v] = ((v + 1) >= uDontSplitLessThan); + } + g_fCanSplit[0] = FALSE; +} + + +#define SKIP_GRADUAL_OPENING 600 +#define INITIAL_HALF_WINDOW 75 +#define FIRST_FAIL_STEP 150 +#define SECOND_FAIL_STEP 375 + +void +_IterateWidenWindow(ULONG uColor, + SCORE iScore, + SCORE *piBound, + ULONG *puState, + int iDir) +{ + SCORE iRoughScore = g_iRootScore[uColor]; + static SCORE _Steps[] = + { + FIRST_FAIL_STEP, + SECOND_FAIL_STEP, + INFINITY + }; + +// Trace("State = %u.\n", *puState); +// Trace("Bound from %d to ", *piBound); + if ((abs(iRoughScore - iScore) > SKIP_GRADUAL_OPENING) || + (*puState == 2)) + { + *piBound = iDir * INFINITY; + *puState = 2; + } + else + { + ASSERT(*puState < 2); + *piBound = iScore; + *piBound += iDir * _Steps[*puState]; + *puState += 1; + } +// Trace("%d.\n", *piBound); +// Trace("State = %u\n", *puState); +} + + +GAME_RESULT Iterate(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Main iterative deepening loop for both thinking and pondering. + Call RootSearch with progressively deeper depths while there is + remaining time, we haven't found a forced mate, and there's no + user interruption. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG : is the game over? + +**/ +{ + ULONG uNumRootFailLows = 0; + ULONG uDepth; + ULONG uFailState = 0; + ULONG uColor; + ULONG u; + SCORE iAlpha = -INFINITY; + SCORE iBeta = +INFINITY; + SCORE iScore; + FLAG fInCheck = InCheck(&(ctx->sPosition), ctx->sPosition.uToMove); + MOVE mv; + GAME_RESULT ret; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); + VerifyPositionConsistency(&board, FALSE); +#endif + + uColor = ctx->sPosition.uToMove; + g_iRootScore[uColor] = GetRoughEvalScore(ctx, iAlpha, iBeta, TRUE); + g_iRootScore[FLIP(uColor)] = -g_iRootScore[uColor]; + + // + // Generate moves here so that RootSearch doesn't have to. + // + ASSERT((ctx->uPly == 0) || (ctx->uPly == 1)); // 1 is under a ponder + ctx->sPlyInfo[ctx->uPly].fInCheck = fInCheck; + GenerateMoves(ctx, NULLMOVE, (fInCheck ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + ASSERT(ctx->sMoveStack.uBegin[0] == 0); + + // + // See if we are sitting at a checkmate or stalemate position; no + // sense searching if so. + // + ret = _DetectPreMoveTerminalStates(ctx, + fInCheck, + &mv); + if (ret.eResult != RESULT_IN_PROGRESS) { + goto end; + } + + // Game still in progress but only one legal move available? + if (mv.uMove != 0) { + ctx->mvRootMove = mv; + ctx->iRootScore = 0; + ctx->uRootDepth = 0; + ctx->sPlyInfo[0].PV[0] = mv; + ctx->sPlyInfo[0].PV[1] = NULLMOVE; + strcpy(ctx->szLastPV, "only"); + if (!g_Options.fPondering) { + Trace("ONLY MOVE --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + g_MoveTimer.bvFlags |= TIMER_CURRENT_OBVIOUS; + } else { + Trace("ONLY PONDER --> move immediately if prediction correct.\n"); + g_MoveTimer.bvFlags |= TIMER_MOVE_IMMEDIATELY; + g_MoveTimer.bvFlags |= TIMER_CURRENT_OBVIOUS; + } + goto end; + } + + for (uDepth = 1; + uDepth <= g_Options.uMaxDepth; + uDepth++) + { + // + // Re-rank the moves based on nodecounts and mark all moves as + // not yet searched at this depth. + // + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) + { + ctx->sMoveStack.mvf[u].bvFlags &= ~MVF_MOVE_SEARCHED; + } + + // + // Make sure a..b window makes sense and set some other per-depth + // globals used by the search. + // + _IterateSetSearchGlobals(uDepth); + + // + // Try to get a PV for this depth before we're out of time... + // + do + { + if (iBeta > INFINITY) iBeta = +INFINITY; + if (iAlpha < -INFINITY) iAlpha = -INFINITY; + if (iAlpha >= iBeta) iAlpha = iBeta - 1; + iScore = RootSearch(ctx, + iAlpha, + iBeta, + uDepth * ONE_PLY + HALF_PLY); + if (g_MoveTimer.bvFlags & TIMER_STOPPING) break; + mv = ctx->mvRootMove; + + // + // Got a PV, we're done with this depth. + // + if ((iAlpha < iScore) && (iScore < iBeta)) + { + ASSERT(iScore == ctx->iRootScore); + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + iAlpha = iScore - INITIAL_HALF_WINDOW; + iBeta = iScore + INITIAL_HALF_WINDOW; + g_iRootScore[uColor] = iScore; + g_iRootScore[FLIP(uColor)] = -iScore; + g_MoveTimer.bvFlags &= ~TIMER_RESOLVING_ROOT_FH; + g_MoveTimer.bvFlags &= ~TIMER_RESOLVING_ROOT_FL; + uFailState = 0; + (void)CheckTestSuiteMove(mv, iScore, uDepth); + break; + } + + // + // Root fail low? We'll have to research with a wider + // window. + // + else if (iScore <= iAlpha) + { + ASSERT(ctx->mvRootMove.uMove); + g_MoveTimer.bvFlags |= TIMER_RESOLVING_ROOT_FL; + uNumRootFailLows++; + if (uNumRootFailLows > 3) + { + g_MoveTimer.bvFlags |= TIMER_MANY_ROOT_FLS; + } + _IterateWidenWindow(uColor, iScore, &iAlpha, &uFailState, -1); + + // + // Consider all moves again with wider window... + // + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) + { + ctx->sMoveStack.mvf[u].bvFlags &= ~MVF_MOVE_SEARCHED; + } + } + + // + // Must be a root fail high. + // + else + { + ASSERT(iScore >= iBeta); + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + g_MoveTimer.bvFlags |= TIMER_RESOLVING_ROOT_FH; + _IterateWidenWindow(uColor, iScore, &iBeta, &uFailState, +1); + } + } + while(1); // repeat until we run out of time or fall inside a..b + + // + // We are here because either: + // + // 1. we completed a search depth, + // or 2. we ran out of time, + // or 3. there is one legal move and we want to make it immediately, + // or 4. there was user input and we unrolled the search. + // + + // + // TODO: Scale back history between iterative depths? + // + + // + // Mate-in-n when we have searched n? Stop searching. + // + if (IS_VALID_SCORE(iScore) && + (ULONG)abs(iScore) >= (INFINITY - uDepth)) + { + Trace("FORCED MATE --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + + // + // Have we reached user's maxdepth option? Stop searching. + // + if (uDepth >= g_Options.uMaxDepth) + { + Trace("DEPTH LIMIT --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + + // + // Did the move timer expire? Stop searching. + // + if (g_MoveTimer.bvFlags & TIMER_STOPPING) break; + } + g_Options.u64NodesSearched = ctx->sCounters.tree.u64TotalNodeCount; + g_MoveTimer.dEndTime = SystemTimeStamp(); + + // + // Here we are at the end of a search. If we were: + // + // ...Searching then: ...Pondering then: + // + // 1. we ran out of time 1. they made a different move than + // the predicted move and we aborted + // 2. we ran out of depth + // 2. we ran out of depth + // 3. we found a mate-in-n + // 3. we found a mate-in-n + // TODO: node count limit? + // (4. if they made the predicted move + // then we converted to a search) + // + ASSERT(ctx->mvRootMove.uMove); + ASSERT(SanityCheckMove(&board, ctx->mvRootMove)); + if (g_MoveTimer.bvFlags & TIMER_RESOLVING_ROOT_FL) + { + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly] = ctx->mvRootMove; + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly+1] = NULLMOVE; + } + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + end: + return ret; +} + +void +MakeTheMove(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Make the move that search selected in the official game list. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG + +**/ +{ + MOVE mv = ctx->mvRootMove; + ASSERT(mv.uMove); + + if (TRUE == g_Options.fThinking) + { + // + // TODO: keep track of how many moves in a row we are at or + // below a draw score and use this to respond to draw offers. + // + + // + // Was this a search that converted from a ponder? + // + if (TRUE == g_Options.fSuccessfulPonder) + { + if (FALSE == OfficiallyMakeMove(g_Options.mvPonder, 0, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)g_Options.mvPonder.uMove, + NULL, + NULL, + __FILE__, + __LINE__); + } + g_Options.fSuccessfulPonder = FALSE; + } + + // Only do d2d4 stuff if we're under xboard -- it's the standard. + if (g_Options.fRunningUnderXboard) { + Trace("move %s\n", MoveToIcs(mv)); + } else { + Trace("move %s\n", MoveToSan(mv, &ctx->sPosition)); + } + + if (FALSE == OfficiallyMakeMove(mv, g_iScore, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)mv.uMove, + NULL, + NULL, + __FILE__, + __LINE__); + } + if (g_Options.fVerbosePosting) + { + PostMoveSearchReport(ctx); + PostMoveTestSuiteReport(ctx); + } + } + g_Options.fPondering = g_Options.fThinking = FALSE; +} + + +GAME_RESULT +Ponder(POSITION *pos) +/** + +Routine description: + + Prepare to ponder. + +Parameters: + + POSITION *pos + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + GAME_RESULT ret; + + InitializeSearcherContext(pos, &ctx); + g_Options.fPondering = TRUE; + g_Options.fThinking = FALSE; + g_Options.fSuccessfulPonder = FALSE; + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + + // + // When do we not want to ponder + // + if ((g_Options.ePlayMode == FORCE_MODE) || (g_Options.uMyClock < 10)) + { + g_Options.fPondering = FALSE; + return ret; + } + + // + // What should we ponder? + // + g_Options.mvPonder = GetPonderMove(pos); + if (g_Options.mvPonder.uMove == 0) + { + g_Options.fPondering = FALSE; + return ret; + } + ASSERT(SanityCheckMove(pos, g_Options.mvPonder)); + + // + // Prepare to ponder by doing some maintenance on the dynamic move + // ordering scheme counters, changing the dirty tag in the hash + // code, and clearing the root nodes-per-move hash. + // + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + // + // Make the move ponder move. + // + if (FALSE == MakeMove(&ctx, g_Options.mvPonder)) + { + ASSERT(FALSE); + g_Options.fPondering = FALSE; + return ret; + } + + // + // TODO: probe the book + // + + _SetMoveTimerForPonder(); + + // + // TODO: Any preEval? + // + + // + // TODO: Set draw value + // + + MakeStatusLine(); +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + ASSERT(ctx.uPly == 1); + ret = Iterate(&ctx); + ASSERT(ctx.uPly == 1); + if (ret.eResult == RESULT_IN_PROGRESS) { + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } else { + return ret; + } +} + + +GAME_RESULT Think(POSITION *pos) +/** + +Routine description: + + Prepare to think. + +Parameters: + + POSITION *pos + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + static ULONG _resign_count = 0; + MOVE mvBook; + CHAR *p; + + InitializeSearcherContext(pos, &ctx); + g_MoveTimer.bvFlags = 0; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + g_Options.fSuccessfulPonder = FALSE; + + // + // Prepare to think by doing some maintenance on the dynamic move + // ordering scheme counters, changing the dirty tag in the hash + // code, and clearing the root nodes-per-move hash. + // + if (NULL != (p = PositionToFen(&(ctx.sPosition)))) + { + Trace("The root position is: %s\n", p); + SystemFreeMemory(p); + } + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + // + // Check the opening book, maybe it has a move for us. + // + if (g_uBookProbeFailures < 3 && + !WeAreRunningASuite() && + g_Options.szBookName[0] != '\0') { + mvBook = BookMove(pos, BOOKMOVE_SELECT_MOVE); + if (mvBook.uMove == 0) + { + g_uBookProbeFailures++; + } + else + { + g_uBookProbeFailures = 0; + ASSERT(SanityCheckMove(pos, mvBook)); + ctx.mvRootMove = mvBook; + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } + } + + // + // TODO: Any preEval? + // + + // + // Set time limit for move + // + SetMoveTimerForSearch(FALSE, pos->uToMove); + + // + // TODO: Set draw value + // +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + GAME_RESULT ret = Iterate(&ctx); + if (ret.eResult == RESULT_IN_PROGRESS) { + if (g_Options.iResignThreshold != 0 && + g_iRootScore[ctx.sPosition.uToMove] < g_Options.iResignThreshold) { + _resign_count++; + if (_resign_count > 2) { + if (ctx.sPosition.uToMove == WHITE) { + ret.eResult = RESULT_BLACK_WON; + strcpy(ret.szDescription, "white resigned"); + } else { + ret.eResult = RESULT_WHITE_WON; + strcpy(ret.szDescription, "black resigned"); } + Trace("tellics resign\n"); + } + return ret; + } else { + _resign_count = 0; + } + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } else { + return ret; + } +} diff --git a/src/san.c b/src/san.c new file mode 100755 index 0000000..725e555 --- /dev/null +++ b/src/san.c @@ -0,0 +1,596 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + san.c + +Abstract: + + Code to support Standard Algebraic Notation parsing. SAN is a + format for expressing moves: e.g. "Nd4". + + See also ics.c. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 13 May 2004 + +Revision History: + + $Id: san.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +CHAR g_cPieces[] = { 'P', 'N', 'B', 'R', 'Q', 'K', '\0' }; + +static MOVE +_ParseCastleSan(CHAR *szCapturedMove, POSITION *pos) +/** + +Routine description: + + Parse a SAN-format castle move string. + +Parameters: + + CHAR *szCapturedMove, + POSITION *pos + +Return value: + + static MOVE + +**/ +{ + MOVE mv = {0}; + + ASSERT(IS_VALID_COLOR(pos->uToMove)); + if ((!STRCMPI(szCapturedMove, "OO")) || + (!STRCMPI(szCapturedMove, "00"))) + { + switch(pos->uToMove) + { + case WHITE: + if ((pos->rgSquare[E1].pPiece != WHITE_KING) || + (InCheck(pos, WHITE))) + { + goto end; + } + + if (pos->bvCastleInfo & CASTLE_WHITE_SHORT) + { + ASSERT(pos->rgSquare[H1].pPiece == WHITE_ROOK); + if (!IS_EMPTY(pos->rgSquare[F1].pPiece) || + !IS_EMPTY(pos->rgSquare[G1].pPiece) || + IsAttacked(F1, pos, BLACK) || + IsAttacked(G1, pos, BLACK)) + { + goto end; + } + mv.uMove = + MAKE_MOVE(E1, G1, WHITE_KING, 0, 0, MOVE_FLAG_SPECIAL); + goto end; + } + break; + + case BLACK: + if ((pos->rgSquare[E8].pPiece != BLACK_KING) || + (InCheck(pos, BLACK))) + { + goto end; + } + + if (pos->bvCastleInfo & CASTLE_BLACK_SHORT) + { + ASSERT(pos->rgSquare[H8].pPiece == BLACK_ROOK); + if (!IS_EMPTY(pos->rgSquare[F8].pPiece) || + !IS_EMPTY(pos->rgSquare[G8].pPiece) || + IsAttacked(F8, pos, WHITE) || + IsAttacked(G8, pos, WHITE)) + { + goto end; + } + mv.uMove = + MAKE_MOVE(E8, G8, BLACK_KING, 0, 0, MOVE_FLAG_SPECIAL); + goto end; + } + break; +#ifdef DEBUG + default: + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + goto end; +#endif + } + } + else if ((!STRCMPI(szCapturedMove, "OOO")) || + (!STRCMPI(szCapturedMove, "000"))) + { + switch(pos->uToMove) + { + case WHITE: + if ((pos->rgSquare[E1].pPiece != WHITE_KING) || + (InCheck(pos, WHITE))) + { + goto end; + } + + if (pos->bvCastleInfo & CASTLE_WHITE_LONG) + { + ASSERT(pos->rgSquare[A1].pPiece == WHITE_ROOK); + if (!IS_EMPTY(pos->rgSquare[D1].pPiece) || + !IS_EMPTY(pos->rgSquare[C1].pPiece) || + !IS_EMPTY(pos->rgSquare[B1].pPiece) || + IsAttacked(D1, pos, BLACK) || + IsAttacked(C1, pos, BLACK)) + { + goto end; + } + mv.uMove = + MAKE_MOVE(E1, C1, WHITE_KING, 0, 0, MOVE_FLAG_SPECIAL); + goto end; + } + break; + + case BLACK: + if ((pos->rgSquare[E8].pPiece != BLACK_KING) || + (InCheck(pos, BLACK))) + { + goto end; + } + + if (pos->bvCastleInfo & CASTLE_BLACK_LONG) + { + ASSERT(pos->rgSquare[A8].pPiece == BLACK_ROOK); + if (!IS_EMPTY(pos->rgSquare[D8].pPiece) || + !IS_EMPTY(pos->rgSquare[C8].pPiece) || + !IS_EMPTY(pos->rgSquare[B8].pPiece) || + IsAttacked(D8, pos, WHITE) || + IsAttacked(C8, pos, WHITE)) + { + goto end; + } + mv.uMove = + MAKE_MOVE(E8, C8, BLACK_KING, 0, 0, MOVE_FLAG_SPECIAL); + goto end; + } + break; + +#ifdef DEBUG + default: + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + goto end; +#endif + } + } + + end: + return(mv); +} + +static MOVE +_ParseNormalSan(CHAR *szCapturedMove, POSITION *pos) +/** + +Routine description: + + Parse a "normal" SAN move. Note: these SAN string should begin + with a piece code (or have pawn implied). This parser relies on + the fact that the piece code is uppercase. This is in order to + distinguish between file b and Bishop. + +Parameters: + + CHAR *szCapturedMove, + POSITION *pos + +Return value: + + static MOVE + +**/ +{ + static LIGHTWEIGHT_SEARCHER_CONTEXT ctx; + CHAR *p, *q; + PIECE pPieceType = PAWN; + ULONG u; + COOR cFileRestr = 99; + COOR cRankRestr = 99; + COOR cFrom = ILLEGAL_COOR; + COOR cTo = ILLEGAL_COOR; + PIECE pMoved; + PIECE pCaptured; + PIECE pPromoted = 0; + FLAG fSpecial = FALSE; + MOVE mv; + ULONG uNumMatches = 0; + + p = szCapturedMove; + + // + // Is the first thing a piece code? If not PAWN is implied. + // + if (isupper(*p)) + { + if (NULL != (q = strchr(g_cPieces, *p))) + { + pPieceType = (PIECE)((BYTE *)q - (BYTE *)g_cPieces); + pPieceType++; + ASSERT(IS_VALID_PIECE(pPieceType)); + } + p++; + } + + // + // Is the next thing a board coor? If not it should be a rank or + // file restrictor. + // + while ((*p != '\0') && + (FALSE == LooksLikeCoor(p))) + { + if (LooksLikeFile(*p)) + { + cFileRestr = toupper(*p) - 'A'; + } + else if (LooksLikeRank(*p)) + { + cRankRestr = *p - '0'; + } + else + { + goto illegal; + } + p++; + } + if (*p == '\0') goto illegal; + + // + // We got the piece code taken care of and any rank/file + // restrictions done with. See if we just have two coors left. + // + if ((strlen(p) > 3) && + LooksLikeCoor(p) && + LooksLikeCoor(p + 2)) + { + cFrom = FILE_RANK_TO_COOR((toupper(*p) - 'A'), + *(p+1) - '0'); + cTo = FILE_RANK_TO_COOR((toupper(*(p+2)) - 'A'), + *(p+3) - '0'); + if (!IS_ON_BOARD(cFrom) || !IS_ON_BOARD(cTo)) + { + goto illegal; + } + p += 4; + goto found_coors; + } + else if ((strlen(p) > 1) && + LooksLikeCoor(p)) + { + cTo = FILE_RANK_TO_COOR(toupper(*p) - 'A', + *(p+1) - '0'); + if (!IS_ON_BOARD(cTo)) + { + goto illegal; + } + p += 2; + } + + // + // We need to find out what piece can move to cTo + // + if (!IS_ON_BOARD(cFrom)) + { + if (!IS_ON_BOARD(cTo)) + { + goto illegal; + } + + // + // Handle promotion + // + switch (*(p)) + { + case 'N': + pPromoted = BLACK_KNIGHT | pos->uToMove; + fSpecial = MOVE_FLAG_SPECIAL; + break; + case 'B': + pPromoted = BLACK_BISHOP | pos->uToMove; + fSpecial = MOVE_FLAG_SPECIAL; + break; + case 'R': + pPromoted = BLACK_ROOK | pos->uToMove; + fSpecial = MOVE_FLAG_SPECIAL; + break; + case 'Q': + pPromoted = BLACK_QUEEN | pos->uToMove; + fSpecial = MOVE_FLAG_SPECIAL; + break; + default: + break; + } + + InitializeLightweightSearcherContext(pos, &ctx); + mv.uMove = 0; + GenerateMoves((SEARCHER_THREAD_CONTEXT *)&ctx, + mv, + (InCheck(pos, pos->uToMove) ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + for (u = ctx.sMoveStack.uBegin[0]; + u < ctx.sMoveStack.uEnd[0]; + u++) + { + mv = ctx.sMoveStack.mvf[u].mv; + pMoved = mv.pMoved; + if (PIECE_TYPE(pMoved) == pPieceType) + { + if ((99 != cFileRestr) && + (FILE(mv.cFrom) != cFileRestr)) continue; + if ((99 != cRankRestr) && + (RANK(mv.cFrom) != cRankRestr)) continue; + + if ((mv.cTo == cTo) && + (mv.pPromoted == pPromoted)) + { + if (TRUE == MakeMove((SEARCHER_THREAD_CONTEXT *)&ctx, mv)) + { + UnmakeMove((SEARCHER_THREAD_CONTEXT *)&ctx, mv); + cFrom = mv.cFrom; + cTo = mv.cTo; + uNumMatches++; + } + } + } + } + + // + // Note: 4 moves match for promotions + // + if (uNumMatches == 1) + { + goto found_coors; + } + } + goto illegal; + + found_coors: + pMoved = pos->rgSquare[cFrom].pPiece; + if (IS_EMPTY(pMoved)) + { + goto illegal; + } + pCaptured = pos->rgSquare[cTo].pPiece; + if (!IS_EMPTY(pCaptured) && + !OPPOSITE_COLORS(pMoved, pCaptured)) + { + goto illegal; + } + + // + // Handle enpassant + // + if ((cTo == pos->cEpSquare) && (IS_PAWN(pMoved))) + { + if (WHITE == pos->uToMove) + { + pCaptured = pos->rgSquare[cTo + 16].pPiece; + if (pCaptured != BLACK_PAWN) goto illegal; + } + else + { + pCaptured = pos->rgSquare[cTo - 16].pPiece; + if (pCaptured != WHITE_PAWN) goto illegal; + } + fSpecial = MOVE_FLAG_SPECIAL; + } + + // + // Handle double jump + // + if (IS_PAWN(pMoved) && DISTANCE(cFrom, cTo) > 1) + { + fSpecial = MOVE_FLAG_SPECIAL; + } + + mv.uMove = MAKE_MOVE(cFrom, cTo, pMoved, pCaptured, pPromoted, fSpecial); + if (FALSE == SanityCheckMove(pos, mv)) + { + goto illegal; + } + return(mv); + + illegal: + mv.uMove = 0; + return(mv); +} + + +MOVE +ParseMoveSan(CHAR *szInput, + POSITION *pos) +/** + +Routine description: + + Given a move string in SAN format and a current board position, + parse the move and make it into a valid MOVE structure. + +Parameters: + + CHAR *szInput, + POSITION *pos + +Return value: + + MOVE + +**/ +{ + CHAR szCapturedMove[SMALL_STRING_LEN_CHAR]; + MOVE mv; + + mv.uMove = 0; + memset(szCapturedMove, 0, sizeof(szCapturedMove)); + strncpy(szCapturedMove, StripMove(szInput), SMALL_STRING_LEN_CHAR - 1); + + if (MOVE_SAN != LooksLikeMove(szCapturedMove)) + { + return(mv); // fail + } + + mv = _ParseCastleSan(szCapturedMove, pos); + if (mv.uMove != 0) + { + goto end; + } + + mv = _ParseNormalSan(szCapturedMove, pos); + if (mv.uMove != 0) + { + goto end; + } + + return(mv); // fail + + end: + if (InCheck(pos, pos->uToMove)) + { + mv.bvFlags |= MOVE_FLAG_ESCAPING_CHECK; + } + return(mv); +} + + +CHAR * +MoveToSan(MOVE mv, POSITION *pos) +/** + +Routine description: + + Given a move and a current board position, convert the MOVE + structure into a SAN text string. + +Parameters: + + MOVE mv, + POSITION *pos + +Return value: + + CHAR + +**/ +{ + static char szTextMove[10]; + char *p; + ULONG u = 0; + MOVE x; + + ASSERT(IS_ON_BOARD(mv.cFrom)); + ASSERT(IS_ON_BOARD(mv.cTo)); + if (0 == mv.uMove) + { + return(NULL); + } + + do + { + p = szTextMove; + memset(szTextMove, 0, sizeof(szTextMove)); + + // + // Handle castles. + // + if (IS_KING(mv.pMoved) && (IS_SPECIAL_MOVE(mv))) + { + if ((mv.cTo == G1) || (mv.cTo == G8)) + { + strcpy(szTextMove, "O-O"); + if (IS_CHECKING_MOVE(mv)) + { + *p++ = '+'; + } + goto end; + } + else if ((mv.cTo == C1) || (mv.cTo == C8)) + { + strcpy(szTextMove, "O-O-O"); + if (IS_CHECKING_MOVE(mv)) + { + *p++ = '+'; + } + goto end; + } + ASSERT(FALSE); + strcpy(szTextMove, "ILLEGAL"); + goto end; + } + + if (!IS_PAWN(mv.pMoved)) + { + *p++ = g_cPieces[(PIECE_TYPE(mv.pMoved)) - 1]; + if (u == 1) + { + *p++ = FILE(mv.cFrom) + 'a'; + } + else if (u == 2) + { + *p++ = RANK(mv.cFrom) + '0'; + } + else if (u == 3) + { + *p++ = FILE(mv.cFrom) + 'a'; + *p++ = RANK(mv.cFrom) + '0'; + } + } + else + { + if (u > 0) + { + *p++ = FILE(mv.cFrom) + 'a'; + } + } + + if (mv.pCaptured) + { + if (IS_PAWN(mv.pMoved)) + { + *p++ = FILE(mv.cFrom) + 'a'; + } + *p++ = 'x'; + } + *p++ = FILE(mv.cTo) + 'a'; + *p++ = RANK(mv.cTo) + '0'; + + if (mv.pPromoted) + { + *p++ = '='; + *p++ = g_cPieces[(PIECE_TYPE(mv.pPromoted)) - 1]; + } + + u++; + if (u >= 4) + { + strcpy(szTextMove, "ILLEGAL"); + goto end; + } + + if (IS_CHECKING_MOVE(mv)) + { + *p++ = '+'; + } + x = ParseMoveSan(szTextMove, pos); + } + while ((mv.cTo != x.cTo) || + (mv.cFrom != x.cFrom)); + +end: + return(szTextMove); +} diff --git a/src/save/._chess.h b/src/save/._chess.h new file mode 100755 index 0000000..c896cad Binary files /dev/null and b/src/save/._chess.h differ diff --git a/src/save/._main.c b/src/save/._main.c new file mode 100755 index 0000000..405bb0d Binary files /dev/null and b/src/save/._main.c differ diff --git a/src/save/._root.c b/src/save/._root.c new file mode 100755 index 0000000..99f2e5f Binary files /dev/null and b/src/save/._root.c differ diff --git a/src/save/._util.c b/src/save/._util.c new file mode 100755 index 0000000..e0d6387 Binary files /dev/null and b/src/save/._util.c differ diff --git a/src/save/._vars.c b/src/save/._vars.c new file mode 100644 index 0000000..d436fe6 Binary files /dev/null and b/src/save/._vars.c differ diff --git a/src/save/chess.h b/src/save/chess.h new file mode 100755 index 0000000..e86911a --- /dev/null +++ b/src/save/chess.h @@ -0,0 +1,2982 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + chess.h + +Abstract: + +Author: + + Scott Gasch (scott.gasch@gmail.com) 7 Apr 2004 + +Revision History: + + $Id: chess.h 350 2008-06-28 03:12:34Z scott $ + +**/ + +#ifndef CHESS_ +#define CHESS_ + +#include "compiler.h" + +// +// Datatype wrappers +// +#define MIN_CHAR (0x80) +#define MAX_CHAR (0x7f) +typedef char CHAR; + +#define MIN_BYTE (0x00) +#define MAX_BYTE (0xff) +typedef unsigned char BYTE; + +#define MIN_UCHAR (0x00) +#define MAX_UCHAR (0xff) +typedef unsigned char UCHAR; +#define CAN_FIT_IN_UCHAR(x) ((x) <= MAX_UCHAR) + +#define MIN_SHORT (0x8000) +#define MAX_SHORT (0x7fff) +typedef signed short SHORT; + +#define MIN_USHORT (0x0000) +#define MAX_USHORT (0xffff) +typedef unsigned short USHORT; +#define CAN_FIT_IN_USHORT(x) ((x) <= MAX_USHORT) + +#define MIN_WORD (0x0000) +#define MAX_WORD (0xffff) +typedef unsigned short WORD; + +#define MIN_INT (0x80000000) +#define MAX_INT (0x7fffffff) +typedef signed int INT; + +#define MIN_DWORD (0x00000000) +#define MAX_DWORD (0xffffffff) +typedef unsigned int DWORD; + +#define MIN_UINT (0x00000000) +#define MAX_UINT (0xffffffff) +typedef unsigned int UINT; + +#define MIN_ULONG (0x00000000) +#define MAX_ULONG (0xffffffff) +typedef unsigned int ULONG; + +#define MIN_INT64 (0x8000000000000000) +#define MAX_INT64 (0x7fffffffffffffff) +typedef signed COMPILER_LONGLONG INT64; + +#define MIN_UINT64 (0x0000000000000000) +#define MAX_UINT64 (0xffffffffffffffff) +typedef unsigned COMPILER_LONGLONG UINT64; + +#define MIN_BITBOARD (0x0000000000000000) +#define MAX_BITBOARD (0xffffffffffffffff) +typedef UINT64 BITBOARD; + +#define MIN_BITV MIN_UINT +#define MAX_BITV MAX_UINT +typedef unsigned int BITV; + +#define MIN_FLAG MIN_UINT +#define MAX_FLAG MAX_UINT +typedef unsigned int FLAG; +#define IS_VALID_FLAG(x) (((x) == TRUE) || ((x) == FALSE)) + +typedef unsigned int COOR; +typedef unsigned int PIECE; +typedef signed int SCORE; + +#define BIT1 (0x1) +#define BIT2 (0x2) +#define BIT3 (0x4) +#define BIT4 (0x8) +#define BIT5 (0x10) +#define BIT6 (0x20) +#define BIT7 (0x40) +#define BIT8 (0x80) +#define BIT9 (0x100) +#define BIT10 (0x200) +#define BIT11 (0x400) +#define BIT12 (0x800) +#define BIT13 (0x1000) +#define BIT14 (0x2000) +#define BIT15 (0x4000) +#define BIT16 (0x8000) +#define BIT17 (0x10000) +#define BIT18 (0x20000) +#define BIT19 (0x40000) +#define BIT20 (0x80000) +#define BIT21 (0x100000) +#define BIT22 (0x200000) +#define BIT23 (0x400000) +#define BIT24 (0x800000) +#define BIT25 (0x1000000) +#define BIT26 (0x2000000) +#define BIT27 (0x4000000) +#define BIT28 (0x8000000) +#define BIT29 (0x10000000) +#define BIT30 (0x20000000) +#define BIT31 (0x40000000) +#define BIT32 (0x80000000) + +typedef struct _DLIST_ENTRY +{ + struct _DLIST_ENTRY *pFlink; + struct _DLIST_ENTRY *pBlink; +} DLIST_ENTRY; + +// +// Constants +// +#define YES (1) +#define NO (0) +#ifndef TRUE +#define TRUE (YES) +#endif +#ifndef FALSE +#define FALSE (NO) +#endif + +// +// Calculate the length of an array (i.e. number of elements) +// +#define ARRAY_LENGTH(x) (sizeof(x) / sizeof((x)[0])) +#define COMMAND(x) \ + void (x)(CHAR *szInput, ULONG argc, CHAR *argv[], POSITION *pos) +#define MB (1024 * 1024) + +// +// Calculate the address of the base of the structure given its type, and an +// address of a field within the structure. +// +#ifndef OFFSET_OF +#define OFFSET_OF(field, type) \ + (ULONG)(&((type *)0)->field) +#endif +#ifndef CONTAINING_STRUCT +#define CONTAINING_STRUCT(address, type, field) \ + ((type *)((BYTE *)(address) - (BYTE *)(OFFSET_OF(field, type)))) +#endif + +#define WHITE (1) +#define BLACK (0) +#define BAD_COLOR (2) +#define IS_VALID_COLOR(x) (((x) == WHITE) || ((x) == BLACK)) +#define FOREACH_COLOR(x) for((x) = BLACK; (x) < BAD_COLOR; (x)++) +#define RANDOM_COLOR (rand() & 1) +#define FLIP(color) ((color) ^ 1) +#define COLOR_NAME(color) (((color) == WHITE) ? "white" : "black") + +#define MAX_MOVES_PER_PLY (218) +#define MAX_PLY_PER_SEARCH (64) +#define MAX_MOVES_PER_GAME (1024) +#define SMALL_STRING_LEN_CHAR (256) +#define MEDIUM_STRING_LEN_CHAR (8192) +#define BIG_STRING_LEN_CHAR (16384) + +#define QUARTER_PLY 16 +#define HALF_PLY 32 +#define THREE_QUARTERS_PLY 48 +#define ONE_PLY 64 +#define TWO_PLY 128 +#define THREE_PLY 192 +#define FOUR_PLY 256 +#define MAX_DEPTH_PER_SEARCH (MAX_PLY_PER_SEARCH * ONE_PLY) + +#define IS_VALID_DEPTH(x) (((x) >= 0) && \ + ((x) <= MAX_DEPTH_PER_SEARCH) && \ + (((x) & 0xfffff00f) == 0)) + +#define INFINITY (MAX_SHORT) +#define INVALID_SCORE (INFINITY + 1) +#define IS_VALID_SCORE(x) (((x) >= -INFINITY) && \ + ((x) <= +INFINITY)) +#define NMATE (+INFINITY - 200) +#define MATED_SCORE(ply) (-INFINITY + (ply)) + +#define IS_A_POWER_OF_2(x) (((x) & (x - 1)) == 0) +// +// Program version number +// +#define VERSION "1.00" +#define REVISION "$Id: chess.h 350 2008-06-28 03:12:34Z scott $\n" + +// +// Function decorators +// +#define IN +#define OUT +#define INOUT +#define UNUSED +#define NOTHING + +// ---------------------------------------------------------------------- +// +// PIECE: +// +// a piece (4 bits) = type (3 bits) + color (1 bit) +// +// 3 1 0 +// . . . . +// | | | +// type C +// +#define KING (6) // 110X +#define QUEEN (5) // 101X +#define ROOK (4) // 100X +#define BISHOP (3) // 011X +#define KNIGHT (2) // 010X +#define PAWN (1) // 001X +#define EMPTY (0) // 000X + +// (WHATEVER << 1) +#define BLACK_PAWN (2) // 0010 +#define BLACK_KNIGHT (4) // 0100 +#define BLACK_BISHOP (6) // 0110 +#define BLACK_ROOK (8) // 1000 +#define BLACK_QUEEN (10) // 1010 +#define BLACK_KING (12) // 1100 + +// (WHATEVER << 1) | WHITE +#define WHITE_PAWN (3) // 0011 +#define WHITE_KNIGHT (5) // 0101 +#define WHITE_BISHOP (7) // 0111 +#define WHITE_ROOK (9) // 1001 +#define WHITE_QUEEN (11) // 1011 +#define WHITE_KING (13) // 1101 + +#define PIECE_TYPE(p) ((p) >> 1) +#define PIECE_COLOR(p) ((p) & WHITE) +#define RANDOM_PIECE (rand() % 12) + 2; +#define IS_PAWN(p) (((p) & 0xE) == BLACK_PAWN) +#define IS_KNIGHT(p) (((p) & 0xE) == BLACK_KNIGHT) +#define IS_BISHOP(p) (((p) & 0xE) == BLACK_BISHOP) +#define IS_ROOK(p) (((p) & 0xE) == BLACK_ROOK) +#define IS_QUEEN(p) (((p) & 0xE) == BLACK_QUEEN) +#define IS_KING(p) (((p) & 0xE) == BLACK_KING) +#define IS_KNIGHT_OR_KING(p) (((p) & 0x6) == 0x4) +#define IS_VALID_PIECE(p) ((PIECE_TYPE((p)) >= PAWN) && \ + (PIECE_TYPE((p)) <= KING)) +#define IS_WHITE_PIECE(p) ((p) & WHITE) +#define IS_BLACK_PIECE(p) (!IS_WHITE(p)) +#define OPPOSITE_COLORS(p, q) (((p) ^ (q)) & WHITE) +#define SAME_COLOR(p,q) (!OPPOSITE_COLORS(p, q)) +#define GET_COLOR(p) ((p) & WHITE) + +// ---------------------------------------------------------------------- +// +// a coordinate (8 bits) = rank + file (0x88) +// +// 7 4 3 0 +// . . . . . . . . +// | | | +// rank file +// | | +// | +--- 0-7 = file A thru file H +// | +// +------------ 0-7 = rank 1 thru rank 8 +// +// given a coordinate, C, if C & 0x88 then it is illegal (off board) +// +// +// 0x00 0x01 0x02 0x03 0x04 0x05 0x06 0x07 +// +---------------------------------------+ +// 8 | 00 |:01:| 02 |:03:| 04 |:05:| 06 |:07:| 0x00 +// 7 |:10:| 11 |:12:| 13 |:14:| 15 |:16:| 17 | 0x10 +// 6 | 20 |:21:| 22 |:23:| 24 |:25:| 26 |:27:| 0x20 +// 5 |:30:| 31 |:32:| 33 |:34:| 35 |:36:| 37 | 0x30 +// 4 | 40 |:41:| 42 |:43:| 44 |:45:| 46 |:47:| 0x40 +// 3 |:50:| 51 |:52:| 53 |:54:| 55 |:56:| 57 | 0x50 +// 2 | 60 |:61:| 62 |:63:| 64 |:65:| 66 |:67:| 0x60 +// 1 |:70:| 71 |:72:| 73 |:74:| 75 |:76:| 77 | 0x70 +// +---------------------------------------+ +// A B C D E F G H +// +#define A (0) +#define B (1) +#define C (2) +#define D (3) +#define E (4) +#define F (5) +#define G (6) +#define H (7) + +#define A8 (0x00) +#define B8 (0x01) +#define C8 (0x02) +#define D8 (0x03) +#define E8 (0x04) +#define F8 (0x05) +#define G8 (0x06) +#define H8 (0x07) + +#define A7 (0x10) +#define B7 (0x11) +#define C7 (0x12) +#define D7 (0x13) +#define E7 (0x14) +#define F7 (0x15) +#define G7 (0x16) +#define H7 (0x17) + +#define A6 (0x20) +#define B6 (0x21) +#define C6 (0x22) +#define D6 (0x23) +#define E6 (0x24) +#define F6 (0x25) +#define G6 (0x26) +#define H6 (0x27) + +#define A5 (0x30) +#define B5 (0x31) +#define C5 (0x32) +#define D5 (0x33) +#define E5 (0x34) +#define F5 (0x35) +#define G5 (0x36) +#define H5 (0x37) + +#define A4 (0x40) +#define B4 (0x41) +#define C4 (0x42) +#define D4 (0x43) +#define E4 (0x44) +#define F4 (0x45) +#define G4 (0x46) +#define H4 (0x47) + +#define A3 (0x50) +#define B3 (0x51) +#define C3 (0x52) +#define D3 (0x53) +#define E3 (0x54) +#define F3 (0x55) +#define G3 (0x56) +#define H3 (0x57) + +#define A2 (0x60) +#define B2 (0x61) +#define C2 (0x62) +#define D2 (0x63) +#define E2 (0x64) +#define F2 (0x65) +#define G2 (0x66) +#define H2 (0x67) + +#define A1 (0x70) +#define B1 (0x71) +#define C1 (0x72) +#define D1 (0x73) +#define E1 (0x74) +#define F1 (0x75) +#define G1 (0x76) +#define H1 (0x77) + +// TODO: if use this anywhere that matters, consider double loop +// and unrolling the inside loop to prevent the multiple +// continue for invalid squares +#define FOREACH_SQUARE(x) for((x) = (A8); (x) <= (H1); (x)++) + +#define IS_ON_BOARD(c) (!((c) & 0x88)) +#define RANDOM_COOR (rand() & 0x77) +#define FILE_RANK_TO_COOR(f, r) (((8 - (r)) << 4) | (f)) +#define RANK(c) (8 - ((c) >> 4)) +#define RANK1(c) (((c) & 0xF0) == 0x70) +#define RANK2(c) (((c) & 0xF0) == 0x60) +#define RANK3(c) (((c) & 0xF0) == 0x50) +#define RANK4(c) (((c) & 0xF0) == 0x40) +#define RANK5(c) (((c) & 0xF0) == 0x30) +#define RANK6(c) (((c) & 0xF0) == 0x20) +#define RANK7(c) (((c) & 0xF0) == 0x10) +#define RANK8(c) (((c) & 0xF0) == 0x00) +#define FILE(c) ((c) & 0x0F) +#define FILEA(c) (((c) & 0x0F) == 0x00) +#define FILEB(c) (((c) & 0x0F) == 0x01) +#define FILEC(c) (((c) & 0x0F) == 0x02) +#define FILED(c) (((c) & 0x0F) == 0x03) +#define FILEE(c) (((c) & 0x0F) == 0x04) +#define FILEF(c) (((c) & 0x0F) == 0x05) +#define FILEG(c) (((c) & 0x0F) == 0x06) +#define FILEH(c) (((c) & 0x0F) == 0x07) +#define IS_WHITE_SQUARE_FR(f, r) (((f) + (r) - 1) & 1) +#define IS_WHITE_SQUARE_COOR(c) (IS_WHITE_SQUARE_FR(FILE(c), RANK(c))) +#define VALID_EP_SQUARE(c) (((c) == ILLEGAL_COOR) || ((c) == 0) || \ + (RANK3(c)) || \ + (RANK6(c))) + +// ---------------------------------------------------------------------- +// +// a move (4 bytes) = from/to, moved, captured, promoted and special +// +// 31 24 23 16 15 12 11 8 7 4 3 0 +// . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . +// | from | to | moved | capt | prom | flags | +// | | | | | +// | | | | | +// | | | | | +// | | +-------+-------+-- type and +// | | color of +// | | piece moved +// | | captured and +// | | promote targ +// +---------------+-- board location where +// move begins and ends +// +// +// Special flag asserted on special move types: +// +// if (special) +// { +// if (moved == PAWN) +// { +// if (promotion) +// { +// move is a promote (w/ or w/o capture) +// } +// else if (capture) +// { +// move is an en passant catpure +// } +// else +// { +// move is a double jump +// } +// } +// else if (moved == KING) +// { +// move is a castle (long or short) +// } +// else +// { +// invalid use of special flag +// } +// } +// +typedef union _MOVE +{ + ULONG uMove; + struct + { + UCHAR cFrom : 8; + UCHAR cTo : 8; + UCHAR pMoved : 4; + UCHAR pCaptured : 4; + UCHAR pPromoted : 4; + UCHAR bvFlags : 4; + }; +} MOVE; + +#define IS_SAME_MOVE(a, b) \ + (((a).uMove & 0x0FFFFFFF) == (((b).uMove & 0x0FFFFFFF))) + +#define MAKE_MOVE(from,to,piece,cap,prom,flags) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20) | \ + ((ULONG)(prom) << 24) | \ + ((ULONG)(flags) << 28)) + +#define MAKE_MOVE_WITH_NO_PROM_OR_FLAGS(from,to,piece,cap) \ + (((ULONG)(from)) | \ + ((ULONG)(to) << 8) | \ + ((ULONG)(piece) << 16) | \ + ((ULONG)(cap) << 20)) + +// +// Move flag values: +// +#define MOVE_FLAG_SPECIAL (1) // en pass, prom, castle, double +#define IS_SPECIAL_MOVE(mv) \ + ((mv).uMove & 0x10000000) + +#define IS_CASTLE(mv) \ + (IS_SPECIAL_MOVE(mv) && IS_KING((mv).pMoved)) + +#ifdef DEBUG +#define IS_PROMOTION(mv) \ + (IS_SPECIAL_MOVE(mv) && ((mv).pPromoted)) +#else +#define IS_PROMOTION(mv) \ + ((mv).pPromoted) +#endif + +#define IS_CAPTURE_OR_PROMOTION(mv) \ + ((mv).uMove & 0x0FF00000) + +#define IS_ENPASSANT(mv) \ + (IS_SPECIAL_MOVE(mv) && (mv.pCaptured) && !IS_PROMOTION(mv)) + +#define IS_DOUBLE_JUMP(mv) \ + (IS_SPECIAL_MOVE(mv) && !IS_CAPTURE_OR_PROMOTION(mv)) + +#define MOVE_FLAG_KILLERMATE (2) // killer mate +#define IS_KILLERMATE_MOVE(mv) ((mv).uMove & 0x20000000) + +#define MOVE_FLAG_ESCAPING_CHECK (4) // escaping check +#define IS_ESCAPING_CHECK(mv) ((mv).uMove & 0x40000000) + +#define MOVE_FLAG_CHECKING (8) // checking move +#define IS_CHECKING_MOVE(mv) ((mv).uMove & 0x80000000) + +// ---------------------------------------------------------------------- +// +// Move list +// +#define MAX_MOVE_LIST (MAX_MOVES_PER_GAME + MAX_PLY_PER_SEARCH) + +// ---------------------------------------------------------------------- + +#pragma pack(1) +typedef union _ATTACK_BITV +{ + ULONG uWholeThing; + struct + { + union + { + UCHAR uSmall; + struct + { + UCHAR uNumAttacks : 3; // 0..2 + UCHAR uKing : 1; // 4..7 + UCHAR uQueen : 1; + UCHAR uRook : 1; + UCHAR uMinor : 1; + UCHAR uPawn : 1; + } small; + }; + + // -------------------- + union + { + USHORT uBig; + struct + { + USHORT uKing : 1; // 8..23 + USHORT uQueens : 4; + USHORT uRooks : 4; + USHORT uMinors : 4; + USHORT uPawns : 2; + USHORT uUnusedFlag1 : 1; + } big; + }; + + // ------------------- + union + { + UCHAR uXray; + struct + { + UCHAR uNumXrays : 3; + UCHAR uUnusedFlag2 : 1; + UCHAR uQueen : 1; // 24..28 + UCHAR uRook : 1; + UCHAR uBishop : 1; + UCHAR uUnusedFlag3 : 1; + } xray; + }; + }; +} +ATTACK_BITV; + +#define UNSAFE_FOR_MINOR(x) ((ULONG)((x).uWholeThing) & 0x00000080UL) +#define UNSAFE_FOR_ROOK(x) ((ULONG)((x).uWholeThing) & 0x000000C0UL) +#define UNSAFE_FOR_QUEEN(x) ((ULONG)((x).uWholeThing) & 0x000000E0UL) + +#define PAWN_BIT 0x00000080UL +#define MINOR_BIT 0x00000040UL +#define MINOR_XRAY_BIT 0x40000000UL +#define ROOK_BIT 0x00000020UL +#define ROOK_XRAY_BIT 0x20000000UL +#define QUEEN_BIT 0x00000010UL +#define QUEEN_XRAY_BIT 0x10000000UL + +#define INVALID_PIECE_INDEX (17) +#define IS_VALID_PIECE_INDEX(x) ((x) < INVALID_PIECE_INDEX) + +typedef union _SQUARE +{ + struct + { + PIECE pPiece; + ULONG uIndex; + }; + ATTACK_BITV bvAttacks[2]; +} +SQUARE; +#pragma pack() + +// +// POSITION +// +typedef struct _POSITION +{ + SQUARE rgSquare[128]; // where the pieces are, + // also, the attack table + UINT64 u64NonPawnSig; // hash signature + UINT64 u64PawnSig; // pawn hash signature + ULONG uToMove; // whose turn? + ULONG uFifty; // 50 moves w/o progress = draw + FLAG fCastled[2]; // record when sides have castled + BITV bvCastleInfo; // who can castle how? + COOR cEpSquare; // en-passant capture square + + COOR cPawns[2][8]; // location of pawns on the board + ULONG uPawnMaterial[2]; // pawn material of each side + ULONG uPawnCount[2]; // number of pawns for each side + + COOR cNonPawns[2][16]; // location of pieces on the board + ULONG uNonPawnMaterial[2]; // piece material of each side + ULONG uNonPawnCount[2][8]; // number of non-pawns / type + // 0 and 1 are the sum, + // 2..6 are per PIECE_TYPE + + ULONG uWhiteSqBishopCount[2]; // num bishops on white squares + SCORE iMaterialBalance[2]; // material balance + + // temporary storage space for use in eval + COOR cTrapped[2]; + ULONG uArmyScaler[2]; + ULONG uClosedScaler; + SCORE iScore[2]; + SCORE iReducedMaterialDownScaler[2]; + SCORE iTempScore; + ULONG uMinMobility[2]; + COOR cPiece; + ULONG uMinorsAtHome[2]; + BITBOARD bb; + ULONG uPiecesPointingAtKing[2]; +} +POSITION; + +// +// Castling permission bitvector flags. +// +#define CASTLE_WHITE_SHORT (1) +#define CASTLE_WHITE_LONG (2) +#define WHITE_CAN_CASTLE \ + (CASTLE_WHITE_SHORT | CASTLE_WHITE_LONG) +#define CASTLE_BLACK_SHORT (4) +#define CASTLE_BLACK_LONG (8) +#define BLACK_CAN_CASTLE \ + (CASTLE_BLACK_SHORT | CASTLE_BLACK_LONG) +#define CASTLE_NONE_POSSIBLE (0) +#define CASTLE_ALL_POSSIBLE \ + (WHITE_CAN_CASTLE | BLACK_CAN_CASTLE) + +// ---------------------------------------------------------------------- +// +// Move stack +// +#define MAX_MOVE_STACK (MAX_PLY_PER_SEARCH * \ + MAX_MOVES_PER_PLY) + +// +// Main part of the move stack, triads of moves, their values and flags +// that denote where the values came from +// +#define MVF_MOVE_SEARCHED (1) +#define MVF_EXTEND_MOVE (2) +#define MVF_REDUCE_MOVE (4) +#define MVF_PRUNE_SUBTREE (8) + +typedef struct _MOVE_STACK_MOVE_VALUE_FLAGS +{ + SCORE iValue; + MOVE mv; + BITV bvFlags; +} +MOVE_STACK_MOVE_VALUE_FLAGS; + +typedef struct _KEY_POINTER +{ + int iPointer; + ULONG uKey; +} +KEY_POINTER; + +typedef union _GENERATOR_FLAGS +{ + struct { + UCHAR uMoveCount; + UCHAR uKingMoveCount; + UCHAR uCheckingPieces; + UCHAR uUnused; + }; + ULONG uAllGenFlags; +} +GENERATOR_FLAGS; + +// +// A move stack +// +typedef struct _MOVE_STACK +{ +#ifdef DEBUG + POSITION board[MAX_PLY_PER_SEARCH]; +#endif + // + // Unblocked squares map, used for check detection + // + ULONG uUnblockedKeyValue[MAX_PLY_PER_SEARCH]; + KEY_POINTER sUnblocked[MAX_PLY_PER_SEARCH][128]; + + // + // The main move list, a long series of moves, their values and some + // flag bits to tell search what the values are based upon. + // + MOVE_STACK_MOVE_VALUE_FLAGS mvf[MAX_MOVE_STACK]; + + // + // uBegin[ply] and uEnd[ply] specify the start and end of moves gen- + // erated for a position at ply distance from the root. + // + ULONG uPly; + ULONG uBegin[MAX_PLY_PER_SEARCH]; + ULONG uEnd[MAX_PLY_PER_SEARCH]; + MOVE mvHash[MAX_PLY_PER_SEARCH]; + GENERATOR_FLAGS sGenFlags[MAX_PLY_PER_SEARCH]; +} +MOVE_STACK; + +#define GENERATE_NO_MOVES \ + ctx->sMoveStack.uEnd[ctx->uPly] = \ + ctx->sMoveStack.uBegin[ctx->uPly] + 1; \ + ctx->sMoveStack.uBegin[ctx->uPly + 1] = \ + ctx->sMoveStack.uEnd[ctx->uPly] + +#define GENERATE_ALL_MOVES (1) +#define GENERATE_ESCAPES (2) +#define GENERATE_CAPTURES_PROMS_CHECKS (3) +#define GENERATE_CAPTURES_PROMS (4) +#define GENERATE_DONT_SCORE (5) +#ifdef TEST +#define GENERATE_ALL_MOVES_CHECK_OK (6) +#endif + +#define MOVE_COUNT(ctx, x) \ + (((ctx)->sMoveStack.uEnd[(x)]) - (ctx)->sMoveStack.uBegin[(x)]) +#define ONE_LEGAL_MOVE(ctx, x) \ + (MOVE_COUNT(ctx, x) == 1) +#define NUM_KING_MOVES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uKingMoveCount) +#define NUM_CHECKING_PIECES(ctx, x) \ + ((ctx)->sMoveStack.sGenFlags[(x)].uCheckingPieces) + + +// ---------------------------------------------------------------------- +// +// Accumulators +// +typedef struct _COUNTERS +{ + struct + { + UINT64 u64Probes; + UINT64 u64OverallHits; + UINT64 u64UsefulHits; + UINT64 u64UpperBoundHits; + UINT64 u64LowerBoundHits; + UINT64 u64ExactScoreHits; + } + hash; + + struct + { + UINT64 u64Probes; + UINT64 u64Hits; + } + pawnhash; + + struct + { + UINT64 u64TotalNodeCount; + UINT64 u64QNodeCount; + UINT64 u64LeafCount; + UINT64 u64TerminalPositionCount; + UINT64 u64BetaCutoffs; + UINT64 u64BetaCutoffsOnFirstMove; + UINT64 u64NullMoves; + UINT64 u64NullMoveSuccess; +#ifdef TEST_NULL + UINT64 u64QuickNullSuccess; + UINT64 u64QuickNullDeferredSuccess; + UINT64 u64QuickNullFailures; + UINT64 u64AvoidNullSuccess; + UINT64 u64AvoidNullFailures; +#endif + UINT64 u64EvalHashHits; + UINT64 u64LazyEvals; + UINT64 u64FullEvals; + UINT64 u64CyclesInEval; + } + tree; + + struct + { + ULONG uNumSplits; + ULONG uNumSplitsTerminated; + } + parallel; + + struct + { + ULONG uPawnPush; + ULONG uCheck; + ULONG uMateThreat; + ULONG uRecapture; + ULONG uOneLegalMove; + ULONG uNoLegalKingMoves; + ULONG uMultiCheck; + ULONG uSingularMove; + ULONG uZugzwang; + ULONG uSingularReplyToCheck; + ULONG uEndgame; + ULONG uBotvinnikMarkoff; + ULONG uQExtend; + } + extension; + + struct + { + ULONG uProbes; + ULONG uHits; + } + egtb; +} +COUNTERS; + +typedef struct _CUMULATIVE_SEARCH_FLAGS +{ + // search + ULONG uNumChecks[2]; // not used + FLAG fInSuspiciousBranch; // not used + FLAG fInReducedDepthBranch; // not used + FLAG fAvoidNullmove; // restore + FLAG fVerifyNullmove; // restore + + // qsearch + ULONG uQsearchDepth; // restore + ULONG uQsearchNodes; // incremental + ULONG uQsearchCheckDepth; // restore + FLAG fCouldStandPat[2]; // restore +} +CUMULATIVE_SEARCH_FLAGS; + +// ---------------------------------------------------------------------- +// +// Searcher thread record +// +typedef struct _SPLIT_INFO +{ + // locks / counters + volatile ULONG uLock; // lock for this split node + volatile ULONG uNumThreadsHelping; // num threads in this node + volatile FLAG fTerminate; // signal helpers to terminate + + // moves in the split node + ULONG uRemainingMoves; // num moves remaining to do + ULONG uOnDeckMove; // next move to do + ULONG uNumMoves; + ULONG uAlreadyDone; + MOVE_STACK_MOVE_VALUE_FLAGS + mvf[MAX_MOVES_PER_PLY]; // the moves to search + + // input to the split node + POSITION sRootPosition; // the root position + MOVE mvPathToHere[MAX_PLY_PER_SEARCH]; // path from root to split + MOVE mvLast; // last move before split + ULONG uDepth; // remaining depth at split + INT iPositionExtend; // positional extension + SCORE iAlpha; // original alpha at split + SCORE iBeta; // beta at split + ULONG uSplitPositional; // pos->uPositional at split + CUMULATIVE_SEARCH_FLAGS sSearchFlags; // flags at split time + + // output from the split node + MOVE mvBest; // the best move + SCORE iBestScore; // it's score + COUNTERS sCounters; // updated counters + MOVE PV[MAX_PLY_PER_SEARCH]; + +#ifdef DEBUG + ULONG uSplitPly; + POSITION sSplitPosition; +#endif +} +SPLIT_INFO; + +typedef struct _PLY_INFO +{ +#ifdef DEBUG + POSITION sPosition; + SCORE iAlpha; + SCORE iBeta; +#endif + SCORE iEval; + INT iExtensionAmount; + FLAG fInCheck; + FLAG fInQsearch; + MOVE mv; + MOVE mvBest; + MOVE PV[MAX_PLY_PER_SEARCH]; + + SCORE iKingScore[2]; + ULONG uMinMobility[2]; + UINT64 u64NonPawnSig; + UINT64 u64PawnSig; + UINT64 u64Sig; + ULONG uFifty; + FLAG fCastled[2]; + ULONG uTotalNonPawns; + BITV bvCastleInfo; + COOR cEpSquare; +} +PLY_INFO; + +#define EVAL_HASH +#ifdef EVAL_HASH +#define EVAL_HASH_TABLE_SIZE (2097152) // 32Mb (per thread) +typedef struct _EVAL_HASH_ENTRY +{ + UINT64 u64Key; + SCORE iEval; + ULONG uPositional; + COOR cTrapped[2]; + +} EVAL_HASH_ENTRY; +#endif + +#define PAWN_HASH_TABLE_SIZE (131072) // 5.5Mb (per thread) +typedef struct _PAWN_HASH_ENTRY +{ + UINT64 u64Key; + BITBOARD bbPawnLocations[2]; + BITBOARD bbPasserLocations[2]; + BITBOARD bbStationaryPawns[2]; + SHORT iScore[2]; + UCHAR uCountPerFile[2][10]; + UCHAR uNumRammedPawns; + UCHAR uNumUnmovedPawns[2]; +} +PAWN_HASH_ENTRY; + +#define NUM_SPLIT_PTRS_IN_CONTEXT (8) + +typedef struct _SEARCHER_THREAD_CONTEXT +{ + ULONG uPly; // its distance from root + ULONG uPositional; // positional component of score + POSITION sPosition; // the board + MOVE_STACK sMoveStack; // the move stack + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; + MOVE mvKiller[MAX_PLY_PER_SEARCH][2]; + MOVE mvKillerEscapes[MAX_PLY_PER_SEARCH][2]; + MOVE mvNullmoveRefutations[MAX_PLY_PER_SEARCH]; + COUNTERS sCounters; + ULONG uThreadNumber; + SPLIT_INFO *pSplitInfo[NUM_SPLIT_PTRS_IN_CONTEXT]; + MOVE mvRootMove; + SCORE iRootScore; + ULONG uRootDepth; + PAWN_HASH_ENTRY rgPawnHash[PAWN_HASH_TABLE_SIZE]; +#ifdef EVAL_HASH + EVAL_HASH_ENTRY rgEvalHash[EVAL_HASH_TABLE_SIZE]; +#endif + CHAR szLastPV[SMALL_STRING_LEN_CHAR]; +} +SEARCHER_THREAD_CONTEXT; + +// +// When I added the pawn hash table and eval hash tables to searcher +// thread contexts they became too heavy to just allocate on the fly +// for things like checking the legality of SAN moves or seeing if an +// opening book line leads to a draw. This +// LIGHTWEIGHT_SEARCHER_CONTEXT structure can be cast into a full +// SEARCHER_THREAD_CONTEXT and passed safely into the Generate, +// MakeMove and UnMakeMove functions because they presently only +// need: +// +// 1. uPly +// 2. sPosition +// 3. sPlyInfo +// 4. sMoveStack +// +typedef struct _LIGHTWEIGHT_SEARCHER_CONTEXT +{ + ULONG uPly; + ULONG uPositional; + POSITION sPosition; + MOVE_STACK sMoveStack; + CUMULATIVE_SEARCH_FLAGS sSearchFlags; + PLY_INFO sPlyInfo[MAX_PLY_PER_SEARCH+1]; +} +LIGHTWEIGHT_SEARCHER_CONTEXT; + +// ---------------------------------------------------------------------- +// +// Global game options +// +typedef struct _GAME_OPTIONS +{ + ULONG uMyClock; + ULONG uOpponentsClock; + FLAG fGameIsRated; + FLAG fOpponentIsComputer; + ULONG uSecPerMove; + ULONG uMaxDepth; + UINT64 u64MaxNodeCount; + FLAG fShouldPonder; + FLAG fPondering; + FLAG fThinking; + FLAG fSuccessfulPonder; + MOVE mvPonder; + FLAG fShouldPost; + FLAG fForceDrawWorthZero; + ULONG uMyIncrement; + ULONG uMovesPerTimePeriod; + CHAR szAnalyzeProgressReport[SMALL_STRING_LEN_CHAR]; + FLAG fShouldAnnounceOpening; + SCORE iLastEvalScore; + UINT64 u64NodesSearched; + CHAR szLogfile[SMALL_STRING_LEN_CHAR]; + CHAR szEGTBPath[SMALL_STRING_LEN_CHAR]; + CHAR szBookName[SMALL_STRING_LEN_CHAR]; + ULONG uNumProcessors; + ULONG uNumHashTableEntries; + FLAG fNoInputThread; + FLAG fVerbosePosting; + FLAG fRunningUnderXboard; + FLAG fStatusLine; + FLAG fFastScript; + FLAG fShouldResign; + + enum + { + CLOCK_NORMAL = 0, + CLOCK_FIXED, + CLOCK_INCREMENT, + CLOCK_NONE + } + eClock; + + enum + { + GAME_UNKNOWN = 0, + GAME_BULLET, + GAME_BLITZ, + GAME_STANDARD + } + eGameType; + + enum + { + I_PLAY_WHITE = 0, + I_PLAY_BLACK, + FORCE_MODE, + EDIT_MODE, + ANALYZE_MODE + } + ePlayMode; +} +GAME_OPTIONS; +extern GAME_OPTIONS g_Options; + +// ---------------------------------------------------------------------- +// +// Move timer +// + +#define TIMER_SEARCHING_FIRST_MOVE (0x1) +#define TIMER_SEARCHING_IMPORTANT_MOVE (0x2) +#define TIMER_RESOLVING_ROOT_FL (0x4) +#define TIMER_RESOLVING_ROOT_FH (0x8) +#define TIMER_JUST_OUT_OF_BOOK (0x10) +#define TIMER_CURRENT_OBVIOUS (0x20) +#define TIMER_CURRENT_WONT_UNBLOCK (0x40) +#define TIMER_ROOT_POSITION_CRITICAL (0x80) +#define TIMER_MOVE_IMMEDIATELY (0x100) +#define TIMER_MANY_ROOT_FLS (0x200) +#define TIMER_STOPPING (0x400) +#define TIMER_SPLIT_FAILED (0x800) + +typedef struct _MOVE_TIMER +{ + double dStartTime; + double dEndTime; + double dSoftTimeLimit; + double dHardTimeLimit; + ULONG uNodeCheckMask; + volatile BITV bvFlags; +} +MOVE_TIMER; + +// ---------------------------------------------------------------------- +// +// Special move tag literals +// +#define ILLEGALMOVE ((ULONG)0x1DDD8888) + +// +// useful macros +// +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine); + +#define ASSERT(x) if (x) \ + { ; } \ + else \ + { _assert(__FILE__, __LINE__); } +#define VERIFY(x) ASSERT(x) +#else +#define ASSERT(x) ; +#define VERIFY(x) x; +#endif // DEBUG + +#ifdef PERF_COUNTERS +#define INC(x) ((x) += 1) +#else +#define INC(x) +#endif + +#define BREAKPOINT SystemDebugBreakpoint() + +#define MIN(x, y) (((x) < (y)) ? (x) : (y)) +#define MAX(x, y) (((x) > (y)) ? (x) : (y)) + +#ifdef _X86_ +// +// Note: MAXU, MINU and ABS_DIFF require arguments with the high order +// bit CLEAR to work right. +// +// These are branchless constructs. MAXU and MINU are equivalent to +// MIN and MAX (with the above restriction on inputs) +// +// MIN0 and MAX0 are equivalent to MAX(0, x) and MIN(0, x). These +// macros have no restiction on argument type. +// +// ABS_DIFF is equivalent to abs(x - y). Again, x and y must have +// their high-order bits CLEAR for this to work. +// +// Note: gcc generates code with cmovs so no need for MAXU/MINU on +// that compiler. +// +#define MINU(x, y) \ + (((((int)((x)-(y)))>>31) & ((x)-(y)))+(y)) +#define MAXU(x, y) \ + (((((int)((x)-(y)))>>31) & ((y)-(x)))+(x)) +#define MIN0(x) \ + ((x) & (((int)(x)) >> 31)) +#define MAX0(x) \ + ((x) & ~(((int)(x)) >> 31)) + + +#define ABS_DIFF(a, b) \ + (((b)-(a)) - ((((b) - (a)) & (((int)((b) - (a))) >> 31) ) << 1)) + +#endif // _X86_ + +#ifndef MINU +#define MINU(x, y) (MIN((x), (y))) +#endif + +#ifndef MAXU +#define MAXU(x, y) (MAX((x), (y))) +#endif + +#ifndef MIN0 +#define MIN0(x) (MIN((x), 0)) +#endif + +#ifndef MAX0 +#define MAX0(x) (MAX((x), 0)) +#endif + +#ifndef ABS_DIFF +#define ABS_DIFF(a, b) (abs((a) - (b))) +#endif + +#define FILE_DISTANCE(a, b) (ABS_DIFF(FILE((a)), FILE((b)))) +#define RANK_DISTANCE(a, b) (ABS_DIFF(((a) & 0xF0), ((b) & 0xF0)) >> 4) +#define REAL_DISTANCE(a, b) (MAXU(FILE_DISTANCE((a), (b)), \ + RANK_DISTANCE((a), (b)))) +#ifdef DEBUG +#define DISTANCE(a, b) DistanceBetweenSquares((a), (b)) +#else +#define DISTANCE(a, b) g_pDistance[(a) - (b)] +#endif // DEBUG + +#define IS_EMPTY( square ) (!(square)) +#define IS_OCCUPIED( square ) ((square)) + +#define IS_DEAD( listindex ) ((listindex) > 119) +#define IS_ALIVE( listindex ) ((listindex) <= 119) +#define ILLEGAL_COOR (0x88) +#define EDGE_DISTANCE(c) (MIN(MIN(abs(RANK(c) - 7), RANK(c)), \ + MIN(abs(FILE(c) - 7), FILE(c)))) +#define NOT_ON_EDGE(c) ((((c) & 0xF0) != 0x00) && \ + (((c) & 0xF0) != 0x70) && \ + (((c) & 0x0F) != 0x00) && \ + (((c) & 0x0F) != 0x07)) +#define ON_EDGE(c) (RANK8(c) || \ + RANK1(c) || \ + FILEA(c) || \ + FILEH(c)) +#define CORNER_DISTANCE(c) (MAX(MIN((ULONG)abs(RANK(c) - 7), RANK(c)),\ + MIN((ULONG)abs(FILE(c) - 7), FILE(c)))) +#define IN_CORNER(c) (((c) == A8) || \ + ((c) == A1) || \ + ((c) == H8) || \ + ((c) == H1)) +#define WHITE_CORNER_DISTANCE(c) (MIN(DISTANCE((c), A8), \ + DISTANCE((c), H1))) +#define BLACK_CORNER_DISTANCE(c) (MIN(DISTANCE((c), H8), \ + DISTANCE((c), A1))) +#define SYM_SQ(c) ((7 - (((c) & 0xF0) >> 4)) << 4) \ + | (7 - ((c) & 0x0F)) +#define ARRAY_SIZE(a) (sizeof((a)) / sizeof((a[0]))) +#define MAKE_PSQT(a, b, c, d) (((a) << 24) | ((b) << 16) | \ + ((c) << 8) | (d)) +#define TO64(x) ((x) & 0x7) + ((0x7 - ((x)>>4)) << 3) +#define COOR_TO_BIT_NUMBER(c) (((((c) & 0x70) >> 1) | ((c) & 0x7))) +#define SLOWCOOR_TO_BB(c) (1ULL << COOR_TO_BIT_NUMBER(c)) +#define COOR_TO_BB(c) (BBSQUARE[COOR_TO_BIT_NUMBER(c)]) +#define SLOW_BIT_NUMBER_TO_COOR(b) ((((b) / 8) << 4) + ((b) & 7)) +#define BIT_NUMBER_TO_COOR(b) ((((b) & 0xF8) << 1) | ((b) & 7)) + +#define BBRANK88 \ + SLOWCOOR_TO_BB(A8) | SLOWCOOR_TO_BB(B8) | SLOWCOOR_TO_BB(C8) | \ + SLOWCOOR_TO_BB(D8) | SLOWCOOR_TO_BB(E8) | SLOWCOOR_TO_BB(F8) | \ + SLOWCOOR_TO_BB(G8) | SLOWCOOR_TO_BB(H8) + +#define BBRANK77 \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(C7) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(F7) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(H7) + +#define BBRANK66 \ + SLOWCOOR_TO_BB(A6) | SLOWCOOR_TO_BB(B6) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(D6) | SLOWCOOR_TO_BB(E6) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(G6) | SLOWCOOR_TO_BB(H6) + +#define BBRANK55 \ + SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(C5) | \ + SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(F5) | \ + SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(H5) + +#define BBRANK44 \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(C4) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(F4) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(H4) + +#define BBRANK33 \ + SLOWCOOR_TO_BB(A3) | SLOWCOOR_TO_BB(B3) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(D3) | SLOWCOOR_TO_BB(E3) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(G3) | SLOWCOOR_TO_BB(H3) + +#define BBRANK22 \ + SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(C2) | \ + SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(F2) | \ + SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(H2) + +#define BBRANK11 \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(C1) | \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(F1) | \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(H1) + +#define BBFILEA \ + SLOWCOOR_TO_BB(A1) | SLOWCOOR_TO_BB(A2) | SLOWCOOR_TO_BB(A3) | \ + SLOWCOOR_TO_BB(A4) | SLOWCOOR_TO_BB(A5) | SLOWCOOR_TO_BB(A6) | \ + SLOWCOOR_TO_BB(A7) | SLOWCOOR_TO_BB(A8) + +#define BBFILEB \ + SLOWCOOR_TO_BB(B1) | SLOWCOOR_TO_BB(B2) | SLOWCOOR_TO_BB(B3) | \ + SLOWCOOR_TO_BB(B4) | SLOWCOOR_TO_BB(B5) | SLOWCOOR_TO_BB(B6) | \ + SLOWCOOR_TO_BB(B7) | SLOWCOOR_TO_BB(B8) + +#define BBFILEC \ + SLOWCOOR_TO_BB(C1) | SLOWCOOR_TO_BB(C2) | SLOWCOOR_TO_BB(C3) | \ + SLOWCOOR_TO_BB(C4) | SLOWCOOR_TO_BB(C5) | SLOWCOOR_TO_BB(C6) | \ + SLOWCOOR_TO_BB(C7) | SLOWCOOR_TO_BB(C8) + +#define BBFILED \ + SLOWCOOR_TO_BB(D1) | SLOWCOOR_TO_BB(D2) | SLOWCOOR_TO_BB(D3) | \ + SLOWCOOR_TO_BB(D4) | SLOWCOOR_TO_BB(D5) | SLOWCOOR_TO_BB(D6) | \ + SLOWCOOR_TO_BB(D7) | SLOWCOOR_TO_BB(D8) + +#define BBFILEE \ + SLOWCOOR_TO_BB(E1) | SLOWCOOR_TO_BB(E2) | SLOWCOOR_TO_BB(E3) | \ + SLOWCOOR_TO_BB(E4) | SLOWCOOR_TO_BB(E5) | SLOWCOOR_TO_BB(E6) | \ + SLOWCOOR_TO_BB(E7) | SLOWCOOR_TO_BB(E8) + +#define BBFILEF \ + SLOWCOOR_TO_BB(F1) | SLOWCOOR_TO_BB(F2) | SLOWCOOR_TO_BB(F3) | \ + SLOWCOOR_TO_BB(F4) | SLOWCOOR_TO_BB(F5) | SLOWCOOR_TO_BB(F6) | \ + SLOWCOOR_TO_BB(F7) | SLOWCOOR_TO_BB(F8) + +#define BBFILEG \ + SLOWCOOR_TO_BB(G1) | SLOWCOOR_TO_BB(G2) | SLOWCOOR_TO_BB(G3) | \ + SLOWCOOR_TO_BB(G4) | SLOWCOOR_TO_BB(G5) | SLOWCOOR_TO_BB(G6) | \ + SLOWCOOR_TO_BB(G7) | SLOWCOOR_TO_BB(G8) + +#define BBFILEH \ + SLOWCOOR_TO_BB(H1) | SLOWCOOR_TO_BB(H2) | SLOWCOOR_TO_BB(H3) | \ + SLOWCOOR_TO_BB(H4) | SLOWCOOR_TO_BB(H5) | SLOWCOOR_TO_BB(H6) | \ + SLOWCOOR_TO_BB(H7) | SLOWCOOR_TO_BB(H8) + +#define BBRANK72 \ + BBRANK77 | BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK62 \ + BBRANK66 | BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK52 \ + BBRANK55 | BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK42 \ + BBRANK44 | BBRANK33 | BBRANK22 + +#define BBRANK32 \ + BBRANK33 | BBRANK22 + +#define BBRANK27 \ + BBRANK22 | BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK37 \ + BBRANK33 | BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK47 \ + BBRANK44 | BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK57 \ + BBRANK55 | BBRANK66 | BBRANK77 + +#define BBRANK67 \ + BBRANK66 | BBRANK77 + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +// +// util.c +// +COMMAND(LearnPsqtFromPgn); + +COMMAND(GeneratePositionAndBestMoveSuite); + +CHAR * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx); + +CHAR * +ReadNextGameFromPgnFile(FILE *pf); + +COOR +DistanceBetweenSquares(COOR a, COOR b); + +void CDECL +Trace(CHAR *szMessage, ...); + +void CDECL +Log(CHAR *szMessage, ...); + +void CDECL +Bug(CHAR *szMessage, ...); + +char * +FindChunk(char *sz, ULONG uTargetChunk); + +FLAG +BufferIsZeroed(BYTE *p, ULONG u); + +char * +ColorToString(ULONG u); + +char * +CoorToString(COOR c); + +char * +ScoreToString(SCORE iScore); + +char * +TimeToString(double d); + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock); + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock); + +void +ReleaseSpinLock(volatile ULONG *pSpinLock); + +BYTE +Checksum(BYTE *p, ULONG uSize); + +FLAG +BackupFile(CHAR *szFile); + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv); + +#define CANNOT_INITIALIZE_SPLIT (1) +#define INCONSISTENT_POSITION (2) +#define UNEXPECTED_SYSTEM_CALL_FAILURE (3) +#define SHOULD_NOT_GET_HERE (4) +#define GOT_ILLEGAL_MOVE_WHILE_PONDERING (5) +#define CANNOT_OFFICIALLY_MAKE_MOVE (6) +#define DETECTED_INCORRECT_INITIALIZATION (7) +#define INCONSISTENT_STATE (8) +#define FATAL_ACCESS_DENIED (9) +#define TESTCASE_FAILURE (10) +#define INITIALIZATION_FAILURE (11) + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *a1, + void *a2, + void *a3, + char *file, ULONG line); + + +// +// main.c +// +#define LOGFILE_NAME "typhoon.log" +extern FILE *g_pfLogfile; + +void +Banner(void); + +FLAG +PreGameReset(FLAG fResetBoard); + +// +// system dependent exports (see win32.c or fbsd.c) +// +typedef ULONG (THREAD_ENTRYPOINT)(ULONG); + +#ifdef DEBUG +ULONG +GetHeapMemoryUsage(void); +#endif + +void +SystemDebugBreakpoint(void); + +CHAR * +SystemStrDup(CHAR *p); + +double +SystemTimeStamp(void); + +FLAG +SystemDoesFileExist(CHAR *szFilename); + +void +SystemDeferExecution(ULONG uMs); + +void +SystemFreeMemory(void *pMem); + +void * +SystemAllocateMemory(ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadOnly(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryNoAccess(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes); + +FLAG +SystemDependentInitialization(void); + +UINT64 FASTCALL +SystemReadTimeStampCounter(void); + +// +// This routine _must_ implement a full memory fence -- it is used in +// util.c to implement spinlocks. +// +FLAG +SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle); + +FLAG +SystemWaitForThreadToExit(ULONG uThreadHandle); + +FLAG +SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode); + +FLAG +SystemDeleteThread(ULONG uThreadHandle); + +CHAR * +SystemGetDateString(void); + +CHAR * +SystemGetTimeString(void); + +FLAG +SystemCopyFile(CHAR *szSource, CHAR *szDest); + +FLAG +SystemDeleteFile(CHAR *szFile); + +ULONG +SystemCreateLock(void); + +FLAG +SystemDeleteLock(ULONG u); + +FLAG +SystemBlockingWaitForLock(ULONG u); + +FLAG +SystemReleaseLock(ULONG u); + +ULONG +SystemCreateSemaphore(ULONG u); + +FLAG +SystemDeleteSemaphore(ULONG u); + +void +SystemReleaseSemaphoreResource(ULONG u); + +void +SystemObtainSemaphoreResource(ULONG u); + + +// +// fen.c +// +#define STARTING_POSITION_IN_FEN \ + "rnbqkbnr/pppppppp/--------/8/8/--------/PPPPPPPP/RNBQKBNR w KQkq - 0 1" + +FLAG +LooksLikeFen(char *szFen); + +char * +PositionToFen(POSITION *p); + +FLAG +FenToPosition(POSITION *p, char *szFen); + +// +// testfen.c +// +#ifdef TEST +void +TestFenCode(void); +#endif + +// +// piece.c +// +// INVERTED VALUE == (VALUE_QUEEN / VALUE_PIECE) * VALUE_PAWN; +#define VALUE_PAWN 100 +#define INVERT_PAWN 900 +#define VALUE_KNIGHT 300 +#define INVERT_KNIGHT 300 +#define VALUE_BISHOP 300 +#define INVERT_BISHOP 300 +#define VALUE_ROOK 500 +#define INVERT_ROOK 180 +#define VALUE_QUEEN 975 +#define INVERT_QUEEN 100 +#define VALUE_KING (INFINITY) +#define INVERT_KING 1 + +#define VALUE_FULL_ARMY (8 * VALUE_PAWN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_QUEEN + VALUE_KING +#define VALUE_MAX_ARMY (9 * VALUE_QUEEN) + (2 * VALUE_KNIGHT) + \ + (2 * VALUE_BISHOP) + (2 * VALUE_ROOK) + \ + VALUE_KING + +typedef struct _PIECE_DATA +{ + ULONG uValue; + ULONG uValueOver100; + ULONG uInvertedValue; + CHAR *szName; +} PIECE_DATA; + +extern PIECE_DATA g_PieceData[8]; + +#define PIECE_VALUE_OVER_100(p) (g_PieceData[PIECE_TYPE(p)].uValueOver100) +extern ULONG +PieceValueOver100(PIECE p); + +#define PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uValue) +extern ULONG +PieceValue(PIECE p); + +#define INVERTED_PIECE_VALUE(p) (g_PieceData[PIECE_TYPE(p)].uInvertedValue) +extern ULONG +PieceInvertedValue(PIECE p); + +CHAR * +PieceAbbrev(PIECE p); + +// +// board.c +// +FLAG +VerifyPositionConsistency(POSITION *pos, FLAG fContinueOnError); + +FLAG +PositionsAreEquivalent(POSITION *p1, POSITION *p2); + +CHAR * +DrawTextBoardFromPosition(POSITION *pos); + +void +DumpPosition(POSITION *pos); + +CHAR * +CastleInfoString(BITV bv); + +void +SetRootToInitialPosition(void); + +// +// move.c +// +void +SlidePiece(POSITION *pos, COOR cFrom, COOR cTo); + +PIECE +LiftPiece(POSITION *pos, COOR cSquare); + +void +PlacePiece(POSITION *pos, COOR cSquare, PIECE pPiece); + +FLAG +MakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +void +UnmakeMove(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv); + +FLAG +MakeUserMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mvUser); + +void +DumpMove(ULONG u); + +// +// movesup.c +// +#define MOVE_TO_INDEX(mv) (((mv).uMove & 0xFFFF) + \ + (0x10000 * GET_COLOR(mv.pMoved))) + +COOR +FasterExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheck(POSITION *pos, + COOR cRemove, + COOR cLocation); + +COOR +ExposesCheckEp(POSITION *pos, + COOR cTest, + COOR cIgnore, + COOR cBlock, + COOR cKing); + +FLAG +IsAttacked(COOR cTest, POSITION *pos, ULONG uSide); + +FLAG +InCheck(POSITION *pos, ULONG uSide); + +FLAG +SanityCheckMove(POSITION *pos, MOVE mv); + +FLAG +LooksLikeFile(CHAR c); + +FLAG +LooksLikeRank(CHAR c); + +FLAG +LooksLikeCoor(CHAR *szData); + +CHAR * +StripMove(CHAR *szMove); + +ULONG +LooksLikeMove(CHAR *szData); + +void FASTCALL +SelectBestWithHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectBestNoHistory(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +void FASTCALL +SelectMoveAtRoot(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +#define NOT_MOVE 0 +#define MOVE_ICS 1 +#define MOVE_SAN 2 + +COMMAND(PerftCommand); + + +// +// testmove.c +// +#ifdef TEST +void +TestLiftPlaceSlidePiece(void); + +void +TestExposesCheck(void); + +void +TestIsAttacked(void); + +void +TestMakeUnmakeMove(void); +#endif + +// +// generate.c +// +#define SORT_THESE_FIRST (0x40000000) +#define FIRST_KILLER (0x20000000) +#define SECOND_KILLER (0x10000000) +#define THIRD_KILLER (0x08000000) +#define FOURTH_KILLER (0x04000000) +#define GOOD_MOVE (0x02000000) +#define STRIP_OFF_FLAGS (0x00FFFFFF) + +extern const int g_iQKDeltas[9]; +extern const int g_iNDeltas[9]; +extern const int g_iBDeltas[5]; +extern const int g_iRDeltas[5]; + +void +GenerateMoves(SEARCHER_THREAD_CONTEXT *ctx, + MOVE mvOrderFirst, + ULONG uType); + +FLAG +WouldGiveCheck(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv); + +// +// testgenerate.c +// +#ifdef TEST + +void +PlyTest(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fRootPositionInCheck); + +void +TestMoveGenerator(void); + +void +TestLegalMoveGenerator(void); + +#endif + +// +// sig.c +// +extern UINT64 g_u64SigSeeds[128][7][2]; +extern UINT64 g_u64PawnSigSeeds[128][2]; +extern UINT64 g_u64CastleSigSeeds[16]; +extern UINT64 g_u64EpSigSeeds[9]; + +void +InitializeSigSystem(void); + +UINT64 +ComputePawnSig(POSITION *pos); + +UINT64 +ComputeSig(POSITION *pos); + +// +// mersenne.c +// +void +seedMT(unsigned int seed); + +unsigned int +reloadMT(void); + +unsigned int +randomMT(void); + +// +// data.c +// +typedef struct _VECTOR_DELTA +{ + UCHAR iVector[2]; + signed char iDelta; + signed char iNegDelta; +} +VECTOR_DELTA; + +extern ULONG g_uDistance[256]; +extern ULONG *g_pDistance; +extern VECTOR_DELTA g_VectorDelta[256]; +extern VECTOR_DELTA *g_pVectorDelta; +extern CHAR g_SwapTable[14][32][32]; +extern SCORE _PSQT[14][128]; +extern ULONG g_uSearchSortLimits[]; +extern MOVE NULLMOVE; +extern MOVE HASHMOVE; +extern MOVE RECOGNMOVE; +extern MOVE DRAWMOVE; +extern MOVE MATEMOVE; +extern FLAG g_fIsWhiteSquare[128]; +extern BITBOARD BBFILE[8]; +extern BITBOARD BBRANK[9]; +extern BITBOARD BBWHITESQ; +extern BITBOARD BBBLACKSQ; +extern BITBOARD BBLEFTSIDE; +extern BITBOARD BBRIGHTSIDE; +extern BITBOARD BBSQUARE[64]; +extern BITBOARD BBROOK_PAWNS; +extern BITBOARD BBPRECEEDING_RANKS[8][2]; +extern BITBOARD BBADJACENT_FILES[8]; +extern BITBOARD BBADJACENT_RANKS[9]; + +void +InitializeWhiteSquaresTable(void); + +void +InitializeVectorDeltaTable(void); + +void +InitializeSwapTable(void); + +void +InitializeDistanceTable(void); + +void +InitializeSearchDepthArray(void); + +ULONG +GetSearchSortLimit(ULONG); + +#ifdef DEBUG +#define SEARCH_SORT_LIMIT(x) (GetSearchSortLimit((x))) +#else +#define SEARCH_SORT_LIMIT(x) (g_uSearchSortLimits[(x)]) +#endif + +#ifdef DEBUG +ULONG CheckVectorWithIndex(int i, ULONG uColor); +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + CheckVectorWithIndex(i, color) + +int DirectionBetweenSquaresWithIndex(int i); +#define CHECK_DELTA_WITH_INDEX(i) \ + DirectionBetweenSquaresWithIndex(i) + +int DirectionBetweenSquaresFromTo(COOR, COOR); +#define DIRECTION_BETWEEN_SQUARES(from, to) \ + DirectionBetweenSquaresFromTo(from, to) + +int NegativeDirectionBetweenSquaresWithIndex(int i); +#define NEG_DELTA_WITH_INDEX(i) \ + NegativeDirectionBetweenSquaresWithIndex(i) + +FLAG IsSquareWhite(COOR c); +#define IS_SQUARE_WHITE(c) \ + IsSquareWhite(c) + +#else +#define CHECK_VECTOR_WITH_INDEX(i, color) \ + (g_pVectorDelta[(i)].iVector[(color)]) + +#define CHECK_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iDelta) + +#define DIRECTION_BETWEEN_SQUARES(cFrom, cTo) \ + CHECK_DELTA_WITH_INDEX((int)(cFrom) - (int)(cTo)) + +#define NEG_DELTA_WITH_INDEX(i) \ + (g_pVectorDelta[(i)].iNegDelta) + +#define IS_SQUARE_WHITE(c) \ + (g_fIsWhiteSquare[(c)]) +#endif + +// +// san.c +// +MOVE +ParseMoveSan(CHAR *szInput, + POSITION *pos); + +CHAR * +MoveToSan(MOVE mv, POSITION *pos); + +// +// testsan.c +// +void +TestSan(void); + +// +// list.c +// +void +InitializeListHead(IN DLIST_ENTRY *pListHead); + +FLAG +IsListEmpty(IN DLIST_ENTRY *pListHead); + +FLAG +RemoveEntryList(IN DLIST_ENTRY *pEntry); + +DLIST_ENTRY * +RemoveHeadList(IN DLIST_ENTRY *pListHead); + +DLIST_ENTRY * +RemoveTailList(IN DLIST_ENTRY *pListHead); + +void +InsertTailList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +void +InsertHeadList(IN DLIST_ENTRY *pListHead, + IN DLIST_ENTRY *pEntry); + +// +// command.c +// +void +ParseUserInput(FLAG fSearching); + +FLAG +InitializeCommandSystem(void); + +void +CleanupCommandSystem(void); + +// +// input.c +// +void +InitInputSystemInBatchMode(void); + +ULONG +InitInputSystemWithDedicatedThread(void); + +void +PushNewInput(CHAR *buf); + +CHAR * +PeekNextInput(void); + +CHAR * +ReadNextInput(void); + +CHAR * +BlockingReadInput(void); + +ULONG +NumberOfPendingInputEvents(void); + +volatile extern FLAG g_fExitProgram; + +// +// ics.c +// +MOVE +ParseMoveIcs(CHAR *szInput, POSITION *pos); + +CHAR * +MoveToIcs(MOVE mv); + +// +// testics.c +// +void +TestIcs(void); + +// +// gamelist.c +// +typedef enum _ERESULT +{ + RESULT_BLACK_WON = -1, + RESULT_DRAW = 0, + RESULT_WHITE_WON = 1, + RESULT_IN_PROGRESS, + RESULT_ABANDONED, + RESULT_UNKNOWN +} ERESULT; + +typedef struct _GAME_RESULT +{ + ERESULT eResult; + CHAR szDescription[256]; +} GAME_RESULT; + +typedef struct _GAME_PLAYER +{ + CHAR *szName; + CHAR *szDescription; + FLAG fIsComputer; + ULONG uRating; +} +GAME_PLAYER; + +typedef struct _GAME_HEADER +{ + CHAR *szGameDescription; + CHAR *szLocation; + GAME_PLAYER sPlayer[2]; + FLAG fGameIsRated; + UINT64 u64OpeningSig; + ERESULT eResult; + CHAR *szResultComment; + CHAR *szInitialFen; +} +GAME_HEADER; + +typedef struct _GAME_MOVE +{ + DLIST_ENTRY links; + ULONG uNumber; + MOVE mv; + CHAR *szComment; + CHAR *szDecoration; + CHAR *szMoveInSan; + CHAR *szMoveInIcs; + CHAR *szUndoPositionFen; + SCORE iMoveScore; + UINT64 u64PositionSigAfterMove; + UINT64 u64PositionSigBeforeMove; + volatile FLAG fInUse; +} +GAME_MOVE; + +typedef struct _GAME_DATA +{ + GAME_HEADER sHeader; + DLIST_ENTRY sMoveList; +} +GAME_DATA; + +extern GAME_DATA g_GameData; + +POSITION * +GetRootPosition(void); + +FLAG +SetRootPosition(CHAR *szFen); + +void +ResetGameList(void); + +ULONG +GetMoveNumber(ULONG uColor); + +void +SetGameResultAndDescription(ERESULT r, CHAR *sz); + +INT +GetGameResult(void); + +void +SetMyName(void); + +void +SetOpponentsName(CHAR *sz); + +void +SetMyRating(ULONG u); + +void +SetOpponentsRating(ULONG u); + +void +DumpGameList(void); + +void +TellGamelistThatIPlayColor(ULONG u); + +void +DumpPgn(void); + +FLAG +LoadPgn(CHAR *szPgn); + +ULONG +CountOccurrancesOfSigInOfficialGameList(UINT64 u64Sig); + +FLAG +DoesSigAppearInOfficialGameList(UINT64 u64Sig); + +FLAG +OfficiallyTakebackMove(void); + +FLAG +OfficiallyMakeMove(MOVE mv, SCORE iMoveScore, FLAG fFast); + +GAME_MOVE * +GetNthOfficialMoveRecord(ULONG n); + +void +MakeStatusLine(void); + +FLAG +IsLegalDrawByRepetition(void); + +// +// script.c +// +COMMAND(ScriptCommand); + +COMMAND(SolutionCommand); + +COMMAND(AvoidCommand); + +COMMAND(IdCommand); + +void +PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *); + +FLAG +CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth); + +FLAG +WeAreRunningASuite(void); + + +// +// vars.c +// +COMMAND(SetCommand); + +// +// root.c +// +extern ULONG g_uSoftExtendLimit; +extern ULONG g_uHardExtendLimit; +extern volatile MOVE_TIMER g_MoveTimer; +extern ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; + +#ifdef PERF_COUNTERS +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) \ + ctx->sCounters.tree.u64BetaCutoffs++; \ + if (x) \ + { \ + ctx->sCounters.tree.u64BetaCutoffsOnFirstMove++;\ + } +#else +#define KEEP_TRACK_OF_FIRST_MOVE_FHs(x) +#endif + +#define GAME_NOT_OVER 0 +#define GAME_WHITE_WON 1 +#define GAME_BLACK_WON 2 +#define GAME_DRAW_STALEMATE 3 +#define GAME_DRAW_REPETITION 4 +#define GAME_ONE_LEGAL_MOVE 5 +#define GAME_DRAW_FIFTY_MOVES_WO_PROGRESS 6 + +GAME_RESULT +Think(POSITION *pos); + +GAME_RESULT +Ponder(POSITION *pos); + +GAME_RESULT +Iterate(SEARCHER_THREAD_CONTEXT *ctx); + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor); + +void +SetMoveTimerToThinkForever(void); + +void +ClearRootNodecountHash(void); + +// +// draw.c +// +FLAG +IsDraw(SEARCHER_THREAD_CONTEXT *ctx); + + +// +// search.c +// +#define QPLIES_OF_NON_CAPTURE_CHECKS (1) +#define FUTILITY_BASE_MARGIN (50) // + ctx->uPositional (min 100) +#define DO_IID +#define IID_R_FACTOR (TWO_PLY + HALF_PLY) + +#ifndef MP +#define WE_SHOULD_STOP_SEARCHING (g_MoveTimer.bvFlags & TIMER_STOPPING) +#else +#define WE_SHOULD_STOP_SEARCHING ((g_MoveTimer.bvFlags & TIMER_STOPPING) || \ + (ThreadUnderTerminatingSplit(ctx))) +#endif + +SCORE FASTCALL +QSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta); + +SCORE FASTCALL +Search(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth); + + +// +// searchsup.c +// +SCORE +ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv, + IN ULONG uMoveNum); + +FLAG +ThreadUnderTerminatingSplit(SEARCHER_THREAD_CONTEXT *); + +FLAG +WeShouldDoHistoryPruning(IN SCORE iRoughEval, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN ULONG uLegalMoves, + IN MOVE mv, + IN ULONG uMoveNum, + IN INT iExtend); + +FLAG +WeShouldTryNullmovePruning(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SCORE iRoughEval, + IN ULONG uNullDepth); + +FLAG +TryNullmovePruning(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN OUT FLAG *pfThreat, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uNullDepth, + IN OUT INT *piOrigExtend, + OUT SCORE *piNullScore); + +void +UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv); + +FLAG +CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx); + +void +ComputeReactionToCheckExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uGenFlags, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN SCORE iAlpha, + IN OUT INT *piExtend, + IN OUT INT *piOrigExtend); + +void +ComputeMoveExtension(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN ULONG uDepth, + IN OUT INT *piExtend); + +SCORE +RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uDepth, + IN SCORE iAlpha, + IN SCORE iBeta); + +FLAG +MateDistancePruningCutoff(IN ULONG uPly, + IN FLAG fInCheck, + IN OUT SCORE *piBestScore, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta); + +FLAG +CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta, + IN OUT SCORE *piScore); + +ULONG +SelectNullmoveRFactor(IN SEARCHER_THREAD_CONTEXT *ctx, + IN INT uDepth); + +#define VERIFY_BEFORE (1) +#define VERIFY_AFTER (2) + +FLAG +SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uCurrent, + IN ULONG uType); + + +// +// testsearch.c +// +FLAG +TestSearch(void); + +// +// see.c +// +#define SEE_HEAPS + +SCORE +SEE(POSITION *pos, + MOVE mv); + +typedef struct _SEE_THREESOME +{ + PIECE pPiece; + COOR cLoc; + ULONG uVal; +} SEE_THREESOME; + +typedef struct _SEE_LIST +{ + ULONG uCount; + SEE_THREESOME data[16]; +} +SEE_LIST; + +SCORE +ControlsSquareMinusPiece(ULONG uSide, + POSITION *pos, + COOR c, + COOR cIgnore); + +// +// testsee.c +// +SCORE +DebugSEE(POSITION *pos, + MOVE mv); + +void +TestGetAttacks(void); + +// +// hash.c +// +#define NUM_HASH_ENTRIES_PER_LINE 4 +#define HASH_FLAG_EXACT 0x1 +#define HASH_FLAG_LOWER 0x2 +#define HASH_FLAG_UPPER 0x4 +#define HASH_FLAG_VALID_BOUNDS 0x7 +#define HASH_FLAG_THREAT 0x8 +#define HASH_FLAG_DIRTY 0xF0 + +typedef struct _HASH_ENTRY +{ + MOVE mv; // 0 1 2 3 + UCHAR uDepth; // 4 + UCHAR bvFlags; // 5 ==> d d d d | thr up low exact + signed short iValue; // 6 7 + UINT64 u64Sig; // 8 9 A B C D E F == 16 bytes +} HASH_ENTRY; + +FLAG +InitializeHashSystem(void); + +void +CleanupHashSystem(void); + +void +ClearHashTable(void); + +void +DirtyHashTable(void); + +void +StoreLowerBound(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); +void +StoreExactScore(MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat, + ULONG uPly); + +void +StoreUpperBound(//MOVE mvBestMove, + POSITION *pos, + SCORE iValue, + ULONG uDepth, + FLAG fThreat); + +HASH_ENTRY * +HashLookup(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + ULONG uNextDepth, + SCORE iAlpha, + SCORE iBeta, + FLAG *pfThreat, + FLAG *pfAvoidNull, + MOVE *pHashMove, + SCORE *piScore); + +COOR +CheckHashForDangerSquare(POSITION *pos); + +MOVE +GetPonderMove(POSITION *pos); + +extern ULONG g_uHashTableSizeEntries; +extern ULONG g_uHashTableSizeBytes; +extern HASH_ENTRY *g_pHashTable; + +// +// testhash.c +// +void +AnalyzeFullHashTable(void); + +// +// positionhash.c +// +// IDEA: store "mate threat" flag in here? +// IDEA: store "king safety" numbers in here? +// +typedef struct _POSITION_HASH_ENTRY { + UINT64 u64Sig; + UCHAR cEnprise[2]; + UCHAR uEnpriseCount[2]; + UCHAR cTrapped[2]; +} POSITION_HASH_ENTRY; + +void +InitializePositionHashSystem(void); + +void +CleanupPositionHashSystem(void); + +void +StoreEnprisePiece(POSITION *pos, COOR cSquare); + +void +StoreTrappedPiece(POSITION *pos, COOR cSquare); + +COOR +GetEnprisePiece(POSITION *pos, ULONG uSide); + +ULONG +GetEnpriseCount(POSITION *pos, ULONG uSide); + +COOR +GetTrappedPiece(POSITION *pos, ULONG uSide); + +FLAG +SideCanStandPat(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleDespiteMove(POSITION *pos, ULONG uSide); + +ULONG +ValueOfMaterialInTroubleAfterNull(POSITION *pos, ULONG uSide); + +// +// pawnhash.c +// +#define COOR_TO_BIT(x) ((x) & 0x7) + ((0x7 - ((x) >> 4)) << 3) + +void +ClearPawnHashStats(void); + +void +ReportPawnHashStats(void); + +PAWN_HASH_ENTRY * +PawnHashLookup(SEARCHER_THREAD_CONTEXT *ctx); + +// +// eval.c +// +#define LAZY_EVAL +#define LAZE_EVAL_BASE_SCORE 10 +extern const int g_iAhead[2]; +extern const int g_iBehind[2]; + +ULONG +DNABufferSizeBytes(); + +char * +ExportEvalDNA(); + +FLAG +WriteEvalDNA(char *szFilename); + +FLAG +ImportEvalDNA(char *p); + +FLAG +ReadEvalDNA(char *szFilename); + + + +SCORE +Eval(SEARCHER_THREAD_CONTEXT *, SCORE, SCORE); + +FLAG +EvalPasserRaces(POSITION *, + PAWN_HASH_ENTRY *); + +ULONG +CountKingSafetyDefects(POSITION *pos, + ULONG uSide); + +// +// testeval.c +// +#ifdef EVAL_DUMP +void +TestEval(void); + +void +EvalTraceReport(void); + +void +EvalTrace(ULONG uColor, PIECE p, COOR c, SCORE iVal, CHAR *szMessage); + +SCORE +EvalSigmaForPiece(POSITION *pos, COOR c); + +void +EvalTraceClear(void); + +void +TestEvalWithSymmetry(void); + +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); \ + EvalTrace((COL), (PIE), (COO), (ADJ), (MESS)); +#else +#define EVAL_TERM(COL, PIE, COO, VAL, ADJ, MESS) \ + (VAL) += (ADJ); +#endif + +// +// bitboard.c +// +void +InitializeBitboards(void); + +ULONG CDECL +SlowCountBits(BITBOARD bb); + +ULONG CDECL +DeBruijnFirstBit(BITBOARD bb); + +ULONG CDECL +SlowFirstBit(BITBOARD bb); + +ULONG CDECL +SlowLastBit(BITBOARD bb); + +#ifdef CROUTINES +#define CountBits SlowCountBits +#define FirstBit SlowFirstBit +#define LastBit SlowLastBit +#endif + +COOR +CoorFromBitBoardRank8ToRank1(BITBOARD *pbb); + +COOR +CoorFromBitBoardRank1ToRank8(BITBOARD *pbb); + +// +// x86.asm +// +ULONG CDECL +CountBits(BITBOARD bb); + +ULONG CDECL +FirstBit(BITBOARD bb); + +ULONG CDECL +LastBit(BITBOARD bb); + +ULONG CDECL +LockCompareExchange(volatile void *pDest, + ULONG uExch, + ULONG uComp); + +ULONG CDECL +LockIncrement(volatile void *pDest); + +ULONG CDECL +LockDecrement(volatile void *pDest); + +FLAG CDECL +CanUseParallelOpcodes(); + +ULONG CDECL +ParallelCompareUlong(ULONG uComparand, void *pComparators); + +ULONG CDECL +ParallelCompareVector(void *pComparand, void *pComparators); + +void CDECL +GetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); + +void CDECL +SlowGetAttacks(SEE_LIST *pList, + POSITION *pos, + COOR cSquare, + ULONG uSide); +#ifdef CROUTINES +#define GetAttacks SlowGetAttacks +#endif + +#ifdef _X86_ +// +// Note: this is most of the stuff that x86.asm assumes about the +// internal data structures. If any of this fails then either the +// assembly language code needs to be updated or you need to use the C +// version of the routine in see.c instead. +// +#define ASSERT_ASM_ASSUMPTIONS \ + ASSERT(VALUE_PAWN == 100); \ + ASSERT(OFFSET_OF(uCount, SEE_LIST) == 0); \ + ASSERT(OFFSET_OF(data, SEE_LIST) == 4); \ + ASSERT(sizeof(SEE_THREESOME) == 12); \ + ASSERT(OFFSET_OF(pPiece, SEE_THREESOME) == 0); \ + ASSERT(OFFSET_OF(cLoc, SEE_THREESOME) == 4); \ + ASSERT(OFFSET_OF(uVal, SEE_THREESOME) == 8); \ + ASSERT(OFFSET_OF(cNonPawns, POSITION) == 0x478); \ + ASSERT(OFFSET_OF(uNonPawnCount, POSITION) == 0x500); \ + ASSERT(OFFSET_OF(rgSquare, POSITION) == 0); \ + ASSERT(sizeof(SQUARE) == 8); \ + ASSERT(sizeof(VECTOR_DELTA) == 4); \ + ASSERT(sizeof(g_VectorDelta) == 256 * 4); \ + ASSERT(OFFSET_OF(iVector, VECTOR_DELTA) == 0); \ + ASSERT(OFFSET_OF(iDelta, VECTOR_DELTA) == 2); \ + ASSERT(OFFSET_OF(iNegDelta, VECTOR_DELTA) == 3); \ + ASSERT(sizeof(g_PieceData) == 8 * 4 * 4); \ + ASSERT(OFFSET_OF(uValue, PIECE_DATA) == 0); +#else +#define ASSERT_ASM_ASSUMPTIONS +#endif + +// +// testbitboard.c +// +void +TestBitboards(void); + +// +// dynamic.c +// +extern ULONG g_HistoryCounters[14][128]; + +ULONG +GetMoveFailHighPercentage(MOVE mv); + +void +UpdateDynamicMoveOrdering(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uRemainingDepth, + MOVE mvBest, + SCORE iScore, + ULONG uCurrent); + +void +NewKillerMove(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv, SCORE iScore); + +FLAG +InitializeDynamicMoveOrdering(void); + +void +CleanupDynamicMoveOrdering(void); + +void +ClearDynamicMoveOrdering(void); + +void +MaintainDynamicMoveOrdering(void); + +void +IncrementMoveHistoryCounter(MOVE mv, ULONG u); + +void +DecrementMoveHistoryCounter(MOVE mv, ULONG u); + +// +// split.c +// +extern volatile ULONG g_uNumHelpersAvailable; +extern ULONG g_uNumHelperThreads; + +FLAG +InitializeParallelSearch(void); + +FLAG +CleanupParallelSearch(void); + +void +ClearHelperThreadIdleness(void); + +void +DumpHelperIdlenessReport(void); + +SCORE +StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN SCORE iBeta, + IN OUT SCORE *piBestScore, + IN OUT MOVE *pmvBest, + IN ULONG uMoveNum, + IN INT iPositionExtend, + IN ULONG uDepth); + +void +InitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +ReInitializeSearcherContext(POSITION *pos, SEARCHER_THREAD_CONTEXT *ctx); + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx); + +// +// book.c +// + +#define BOOK_PROBE_MISS_LIMIT (7) +#define FLAG_DISABLED (1) +#define FLAG_ALWAYSPLAY (2) +#define FLAG_DELETED (4) + +#define BOOKMOVE_SELECT_MOVE (1) +#define BOOKMOVE_DUMP (2) + +#pragma pack(4) +typedef struct _BOOK_ENTRY +{ + UINT64 u64Sig; // 8 bytes + UINT64 u64NextSig; // 8 bytes + MOVE mvNext; // 4 bytes + ULONG uWins; // 4 bytes + ULONG uDraws; // 4 bytes + ULONG uLosses; // 4 bytes + BITV bvFlags; // 4 bytes +} +BOOK_ENTRY; +#pragma pack() + +typedef struct _OPENING_NAME_MAPPING +{ + UINT64 u64Sig; + CHAR *szString; +} +OPENING_NAME_MAPPING; + +#define BOOK_EDITING_RECORD "bkedit.edt" +#define OPENING_LEARNING_FILENAME "bklearn.bin" + +typedef struct _OPENING_LEARNING_ENTRY +{ + UINT64 u64Sig; + ULONG uWhiteWins; + ULONG uDraws; + ULONG uBlackWins; +} +OPENING_LEARNING_ENTRY; + +FLAG +InitializeOpeningBook(void); + +void +ResetOpeningBook(void); + +void +CleanupOpeningBook(void); + +MOVE +BookMove(POSITION *pos, + BITV bvFlags); + +COMMAND(BookCommand); + +extern ULONG g_uBookProbeFailures; +extern FLAG g_fTournamentMode; +extern CHAR *g_szBookName; + +// +// bench.c +// +COMMAND(BenchCommand); + +// +// testdraw.c +// +void +TestDraw(void); + +// +// probe.c +// +FLAG +ProbeEGTB(SEARCHER_THREAD_CONTEXT *ctx, SCORE *score); + +void +InitializeEGTB(void); + +void +CleanupEGTB(void); + +// +// dumptree.c +// +#ifdef DUMP_TREE + +void +InitializeTreeDump(void); + +void +CleanupTreeDump(void); + +void +DTEnterNode(SEARCHER_THREAD_CONTEXT *ctx, + ULONG uDepth, + FLAG fIsQNode, + SCORE iAlpha, + SCORE iBeta); + +void +DTLeaveNode(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fQNode, + SCORE iBestScore, + MOVE mvBestMove); + +void CDECL +DTTrace(ULONG uPly, CHAR *szMessage, ...); + +#define DTTRACE(...) DTTrace(ctx->uPly, __VA_ARGS__) + +#else + +#define DTTRACE(...) + +#define DTEnterNode(...) + +#define DTLeaveNode(...) + +#define InitializeTreeDump(...) + +#define CleanupTreeDump(...) + +#endif + +// +// testsup.c +// +FLAG +IsBoardLegal(POSITION *pos); + +void +GenerateRandomLegalPosition(POSITION *pos); + +void +GenerateRandomLegalSymetricPosition(POSITION *pos); + +// +// recogn.c +// +#define UNRECOGNIZED (0) +#define RECOGN_EXACT (1) +#define RECOGN_UPPER (2) +#define RECOGN_LOWER (3) +#define RECOGN_EGTB (4) + +void +InitializeInteriorNodeRecognizers(void); + +ULONG +RecognLookup(SEARCHER_THREAD_CONTEXT *ctx, + SCORE *piScore, + FLAG fProbeEGTB); + +#ifdef EVAL_HASH +void +ClearEvalHashStats(void); + +void +ReportEvalHashStats(void); + +SCORE +ProbeEvalHash(SEARCHER_THREAD_CONTEXT *ctx); + +SCORE +GetRoughEvalScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN FLAG fUseHash); + +void +StoreEvalHash(SEARCHER_THREAD_CONTEXT *ctx, SCORE iScore); +#endif // EVAL_HASH + +#endif // CHESS diff --git a/src/save/main.c b/src/save/main.c new file mode 100755 index 0000000..a1a0f1f --- /dev/null +++ b/src/save/main.c @@ -0,0 +1,745 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + main.c + +Abstract: + + Program entry point and setup code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: main.c 351 2008-06-28 04:21:53Z scott $ + +**/ + +#include "chess.h" + +FILE *g_pfLogfile = NULL; +GAME_OPTIONS g_Options; +CHAR g_szInitialCommand[SMALL_STRING_LEN_CHAR]; +ULONG g_uInputThreadHandle = (ULONG)-1; + +void +Banner(void) +/** + +Routine description: + + Describe the compile/build options and program version. + +Parameters: + + void + +Return value: + + void + +**/ +{ + char *p; + + Trace("Typhoon %s (built on %s %s):\n", VERSION, __DATE__, __TIME__); + Trace(" Copyright (C) 2000-2007, Scott Gasch (scott.gasch@gmail.com)\n"); + Trace(" " REVISION); + Trace(" " COMPILER_STRING); + Trace(" Make profile used: %s\n", PROFILE); +#ifdef MP + Trace(" Multiprocessor enabled; %u searcher thread%s\n", + g_Options.uNumProcessors, (g_Options.uNumProcessors > 1) ? "s" : ""); +#else + Trace(" Single processor version\n"); +#endif +#ifdef DEBUG + Trace(" DEBUG build\n"); +#endif +#ifdef TEST + Trace(" Testcode compiled in\n"); +#endif +#ifdef EVAL_DUMP + Trace(" Evaluation terms\n"); +#endif +#ifdef EVAL_TIME + Trace(" Evaluation timing\n"); +#endif +#ifdef PERF_COUNTERS + Trace(" Performance counters\n"); +#ifdef TEST_NULL + Trace(" Testing nullmove prediction algorithms\n"); +#endif +#endif +#ifdef DUMP_TREE + Trace(" Search tree dumpfile generation enabled\n"); +#endif + Trace(" Hash sizes: %u Mb (main), %u Mb / thread (pawn), %u Mb / thread (eval)\n", + (g_uHashTableSizeEntries * sizeof(HASH_ENTRY)) / MB, + PAWN_HASH_TABLE_SIZE * sizeof(PAWN_HASH_ENTRY) / MB, + EVAL_HASH_TABLE_SIZE * sizeof(EVAL_HASH_ENTRY) / MB); + Trace(" QCheckPlies: %u\n", QPLIES_OF_NON_CAPTURE_CHECKS); + Trace(" FutilityBase: %u\n", FUTILITY_BASE_MARGIN); + p = ExportEvalDNA(); + Trace(" Logging Eval DNA.\n"); + Log(p); + free(p); +#ifdef DO_IID + Trace(" IID R-factor: %u ply\n", IID_R_FACTOR / ONE_PLY); +#endif +} + + +void +EndLogging(void) +/** + +Routine description: + + Close the main logfile. + +Parameters: + + void + +Return value: + + void + +**/ +{ + if (NULL != g_pfLogfile) + { + fflush(g_pfLogfile); + fflush(stdout); + fclose(g_pfLogfile); + g_pfLogfile = NULL; + } +} + + +FLAG +BeginLogging(void) +/** + +Routine description: + + Open the main logfile. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (NULL != g_pfLogfile) + { + EndLogging(); + } + ASSERT(g_pfLogfile == NULL); + ASSERT(strlen(g_Options.szLogfile)); + + // + // If the logfile we want to write already exists, back it up. + // + if (TRUE == SystemDoesFileExist(g_Options.szLogfile)) + { + VERIFY(BackupFile(g_Options.szLogfile)); + } + ASSERT(FALSE == SystemDoesFileExist(g_Options.szLogfile)); + + g_pfLogfile = fopen(g_Options.szLogfile, "wb+"); + if (NULL == g_pfLogfile) + { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Can't open logfile", + (void *)&(g_Options.szLogfile), + (void *)"write", + NULL, + __FILE__, __LINE__); + } + return(TRUE); +} + + +FLAG +PreGameReset(FLAG fResetBoard) +/** + +Routine description: + + Reset internal state between games. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (TRUE == fResetBoard) + { + SetRootToInitialPosition(); + } + SetMyName(); + ClearDynamicMoveOrdering(); + ClearHashTable(); + ResetOpeningBook(); + return(TRUE); +} + + +static ULONG +_ParseHashOption(char *p, + ULONG uEntrySize) +{ + ULONG u, v; + CHAR c; + + if ((!STRCMPI(p, "none")) || (!STRCMPI(p, "no"))) return(0); + if (2 == sscanf(p, "%u%1c", &u, &c)) + { + v = u; + switch(c) + { + case 'K': + case 'k': + u *= 1024; + break; + case 'M': + case 'm': + u *= 1024 * 1024; + break; + case 'G': + case 'g': + u *= 1024 * 1024 * 1024; + break; + default: + Trace("Error (unrecognized size): \"%s\"\n", p); + break; + } + if (u < v) + { + Trace("Error (size too large): \"%s\"\n", p); + u = v; + } + u /= uEntrySize; + } + else + { + u = (ULONG)atoi(p); + } + + while(!IS_A_POWER_OF_2(u)) + { + u &= (u - 1); + } + return(u); +} + + + +void +InitializeOptions(int argc, char *argv[]) +/** + +Routine description: + + Set global options to their initial state. This code also is + responsible for parsing the commandline in order to override the + default state of global options. + +Parameters: + + int argc, + char *argv[] + +Return value: + + void + +**/ +{ + int i; + + // + // Defaults + // + memset(&g_Options, 0, sizeof(g_Options)); + g_szInitialCommand[0] = '\0'; + g_Options.uMyClock = g_Options.uOpponentsClock = 600; + g_Options.fGameIsRated = FALSE; + g_Options.fOpponentIsComputer = FALSE; + g_Options.uSecPerMove = 0; + g_Options.uMaxDepth = MAX_PLY_PER_SEARCH - 1; + g_Options.fShouldPonder = TRUE; + g_Options.fPondering = g_Options.fThinking = FALSE; + g_Options.mvPonder.uMove = 0; + g_Options.fShouldPost = TRUE; + g_Options.fForceDrawWorthZero = FALSE; + g_Options.uMyIncrement = 0; + g_Options.uMovesPerTimePeriod = 0; + g_Options.szAnalyzeProgressReport[0] = '\0'; + g_Options.fShouldAnnounceOpening = TRUE; + g_Options.eClock = CLOCK_NONE; + g_Options.eGameType = GAME_UNKNOWN; + g_Options.ePlayMode = FORCE_MODE; + g_Options.fNoInputThread = FALSE; + g_Options.fVerbosePosting = TRUE; + strcpy(g_Options.szEGTBPath, "/egtb/three;/etc/four;/egtb/five"); + strcpy(g_Options.szLogfile, "typhoon.log"); + strcpy(g_Options.szBookName, "book.bin"); + g_Options.uNumHashTableEntries = 0x10000; + g_Options.uNumProcessors = 1; + g_Options.fStatusLine = TRUE; + g_Options.fShouldResign = FALSE; + g_Options.u64MaxNodeCount = 0ULL; + + i = 1; + while(i < argc) + { +#ifdef MP + if ((!STRCMPI(argv[i], "--cpus")) && (argc > i)) + { + g_Options.uNumProcessors = (ULONG)atoi(argv[i+1]); + if ((g_Options.uNumProcessors == 0) || + (g_Options.uNumProcessors > 64)) + { + g_Options.uNumProcessors = 2; + } + i++; + } + else +#endif + if ((!STRCMPI(argv[i], "--command")) && (argc > i)) + { + strncpy(g_szInitialCommand, + argv[i+1], + SMALL_STRING_LEN_CHAR - 2); + strcat(g_szInitialCommand, "\r\n"); + i++; + } + else if ((!STRCMPI(argv[i], "--hash")) && (argc > i)) + { + g_Options.uNumHashTableEntries = + _ParseHashOption(argv[i+1], + sizeof(HASH_ENTRY)); + i++; + } + else if ((!STRCMPI(argv[i], "--egtbpath")) && (argc > i)) + { + g_Options.szEGTBPath[0] = '\0'; + strncpy(g_Options.szEGTBPath, argv[i+1], SMALL_STRING_LEN_CHAR); + i++; + } + else if (!STRCMPI(argv[i], "--batch")) + { + g_Options.fNoInputThread = TRUE; + } + else if ((!STRCMPI(argv[i], "--dnafile")) && (argc > i)) + { + if (!ReadEvalDNA(argv[i+1])) + { + UtilPanic(INITIALIZATION_FAILURE, + (void *)"Bad DNA file", + (void *)&(argv[i+1]), + (void *)"read", + NULL, + __FILE__, __LINE__); + } + i++; + } + else if ((!STRCMPI(argv[i], "--logfile")) && (argc > i)) + { + strncpy(g_Options.szLogfile, argv[i+1], + SMALL_STRING_LEN_CHAR); + i++; + } + else if (!STRCMPI(argv[i], "--help")) { + Trace("Usage: %s [--batch] [--command arg] [--logfile arg] [--egtbpath arg]\n" + " [--dnafile arg] [--cpus arg] [--hash arg]\n\n" + " --batch : operate the engine without an input thread\n" + " --command : specify initial command(s) (requires arg)\n" + " --cpus : indicate the number of cpus to use (requires arg, MP build)\n" + " --hash : indicate desired hash size (requires arg)\n" + " --egtbpath : supplies the egtb path to engine (requires arg)\n" + " --logfile : indicate desired output logfile name (requires arg)\n" + " --dnafile : indicate desired eval profile input (requres arg)\n\n" + "Example: %s --hash 256m --cpus 2\n" + " %s --logfile test.out --batch --command \"test\" --dnafile test.in\n", argv[0], argv[0], argv[0]); + exit(-1); + } + else + { + Trace("Error (unknown argument): \"%s\"; try --help\n", argv[i]); + } + + // + // TODO: parse other commandline options and override above + // + + i++; + } +} + + +void +CleanupOptions(void) +/** + +Routine description: + + Cleanup options... + +Parameters: + + void + +Return value: + + void + +**/ +{ + NOTHING; +} + + +FLAG +MainProgramInitialization(int argc, char *argv[]) +/** + +Routine description: + + Perform main program initialization. This includes stuff like: + precomputing some data structures, resetting the global options, + parsing the commandline to override said options, and calling out + to other modules to tell them to initialize themselves. + +Parameters: + + int argc, + char *argv[] + +Return value: + + FLAG + +**/ +{ + srand((unsigned int)time(0)); + InitializeOptions(argc, argv); + InitializeTreeDump(); + InitializeEGTB(); + InitializeSigSystem(); + InitializeInteriorNodeRecognizers(); + InitializeSearchDepthArray(); + InitializeWhiteSquaresTable(); + InitializeVectorDeltaTable(); + InitializeSwapTable(); + InitializeDistanceTable(); + InitializeOpeningBook(); + InitializeDynamicMoveOrdering(); + InitializeHashSystem(); + InitializePositionHashSystem(); +#ifdef MP + InitializeParallelSearch(); +#endif + VERIFY(PreGameReset(TRUE)); + return(BeginLogging()); +} + + +FLAG +MainProgramCleanup(void) +/** + +Routine description: + + Perform main program cleanup. Tear down the stuff we set up in + MainProgramInitialization. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + CleanupOpeningBook(); + CleanupEGTB(); + CleanupDynamicMoveOrdering(); +#ifdef MP + CleanupParallelSearch(); +#endif + CleanupPositionHashSystem(); + CleanupHashSystem(); + CleanupTreeDump(); + CleanupOptions(); + EndLogging(); + return(TRUE); +} + + +#ifdef TEST +FLAG +RunStartupProgramTest(void) +/** + +Routine description: + + If we built this version with -DTEST then this code is the start + of the self-test that runs at program startup time. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + ULONG u, x, y; + +#ifdef _X86_ + Trace("Testing CPP macros...\n"); + for (u = 0; u < 1000000; u++) + { + x = rand() * rand(); + y = rand() * rand(); + x = x & ~(0x80000000); + y = y & ~(0x80000000); + + if (MAX(x, y) != MAXU(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "max maxu", NULL, NULL, __FILE__, __LINE__); + } + + if (MAXU(x, y) != MAXU(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "maxu assoc", NULL, NULL, __FILE__, __LINE__); + } + + if (MIN(x, y) != MINU(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "min minu", NULL, NULL, __FILE__, __LINE__); + } + + if (MINU(x, y) != MINU(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "minu assoc", NULL, NULL, __FILE__, __LINE__); + } + + if (abs(x - y) != ABS_DIFF(x, y)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "abs_diff", NULL, NULL, __FILE__, __LINE__); + } + + if (ABS_DIFF(x, y) != ABS_DIFF(y, x)) + { + UtilPanic(TESTCASE_FAILURE, + NULL, "abs_diff assoc", NULL, NULL, __FILE__, __LINE__); + } + } +#endif + + TestDraw(); +#ifdef EVAL_DUMP + TestEval(); +#endif + TestBitboards(); + TestSan(); + TestIcs(); + TestGetAttacks(); + TestMoveGenerator(); + TestLegalMoveGenerator(); + TestFenCode(); + TestLiftPlaceSlidePiece(); + TestExposesCheck(); + TestIsAttacked(); + TestMakeUnmakeMove(); + TestSearch(); + + return(TRUE); +} +#endif // TEST + + + +void DeclareTerminalStates(GAME_RESULT result) { + switch(result.eResult) { + case RESULT_IN_PROGRESS: + return; + case RESULT_BLACK_WON: + Trace("0-1 {%s}\n", result.szDescription); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_WHITE_WON: + Trace("1-0 {%s}\n", result.szDescription); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_DRAW: + Trace("1/2-1/2 {%s}\n", result.szDescription); + Trace("tellics draw\n"); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + case RESULT_ABANDONED: + case RESULT_UNKNOWN: + ASSERT(FALSE); + SetGameResultAndDescription(result.eResult, result.szDescription); + DumpPgn(); + g_Options.ePlayMode = FORCE_MODE; + break; + } +} + + +// Main work loop +void MainProgramLoop() { + POSITION pos; + GAME_RESULT result; + FLAG fThink; + FLAG fPonder; + + while (!g_fExitProgram) { + + // Prepare to search or ponder + memcpy(&pos, GetRootPosition(), sizeof(POSITION)); + fThink = fPonder = FALSE; + result.eResult = RESULT_IN_PROGRESS; + result.szDescription[0] = '\0'; + + // What should we do? + switch(g_Options.ePlayMode) { + case I_PLAY_WHITE: + Trace("I play white.\n"); + fThink = (pos.uToMove == WHITE); + fPonder = (pos.uToMove == BLACK); + break; + case I_PLAY_BLACK: + Trace("I play black.\n"); + fThink = (pos.uToMove == BLACK); + fPonder = (pos.uToMove == WHITE); + break; + case FORCE_MODE: + default: + Trace("Force mode\n"); + fThink = fPonder = FALSE; + break; + } + + if (fThink) { + Trace("Think...\n"); + result = Think(&pos); + if ((NumberOfPendingInputEvents() != 0) && + (FALSE == g_fExitProgram)) + { + MakeStatusLine(); + ParseUserInput(FALSE); + } + DeclareTerminalStates(result); + } else if (fPonder) { + Trace("Ponder...\n"); + if (g_Options.fShouldPonder) { + result = Ponder(&pos); + } + if (FALSE == g_fExitProgram) + { + MakeStatusLine(); + ParseUserInput(FALSE); + } + DeclareTerminalStates(result); + } else { + Trace("Force mode, consume input and continue\n"); + MakeStatusLine(); + ParseUserInput(FALSE); + } + } +} + + +int CDECL +main(int argc, char *argv[]) +/** + +Routine description: + + Chess engine entry point and main loop. + +Parameters: + + int argc, + char *argv[] + +Return value: + + int CDECL + +**/ +{ + // Initial setup work... + Trace("Setting up, please wait...\n"); + if (FALSE == SystemDependentInitialization()) + { + Trace("main: Operating system dependent init code failed, " + "aborting.\n"); + exit(-1); + } + if (FALSE == MainProgramInitialization(argc, argv)) + { + Trace("main: Main program init code failed, aborting.\n"); + exit(-1); + } + Banner(); +#ifdef TEST + (void)RunStartupProgramTest(); +#endif + if (TRUE == g_Options.fNoInputThread) + { + InitInputSystemInBatchMode(); + } + else + { + g_uInputThreadHandle = InitInputSystemWithDedicatedThread(); + } + + // Enter the main work loop code... + MainProgramLoop(); + + // If we get here g_fExitProgram is set -- clean up. + Trace("MAIN THREAD: thread terminating.\n"); + if (FALSE == MainProgramCleanup()) + { + Trace("main: Main program cleanup code failed, aborting.\n"); + exit(-1); + } + exit(0); +} diff --git a/src/save/root.c b/src/save/root.c new file mode 100755 index 0000000..ddd6015 --- /dev/null +++ b/src/save/root.c @@ -0,0 +1,1462 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + root.c + +Abstract: + + Routines dealing with the root of the search tree. Specifically + move ordering at the root node, searching, search support, pondering, + pondering support, and the main iterative deepening loop. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 21 May 2004 + +Revision History: + + $Id: root.c 351 2008-06-28 04:21:53Z scott $ + +**/ + +#include "chess.h" + +volatile MOVE_TIMER g_MoveTimer; +ULONG g_uIterateDepth; +ULONG g_uSoftExtendLimit; +ULONG g_uHardExtendLimit; +ULONG g_uExtensionReduction[MAX_PLY_PER_SEARCH]; +FLAG g_fCanSplit[MAX_PLY_PER_SEARCH]; +extern FILE *g_pfLogfile; +SCORE g_iRootScore[2] = {0, 0}; +SCORE g_iScore; + + +static void +_SetMoveTimerForPonder(void) +/** + +Routine description: + + Set the move timer before a ponder operation. A time limit of -1 + means search forever... so the only way out of the ponder is for + new user input to interrupt it. + +Parameters: + + void + +Return value: + + static void + +**/ +{ + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.dSoftTimeLimit = -1; + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.uNodeCheckMask = 0x200 - 1; + g_MoveTimer.bvFlags = 0; +} + + +void +SetMoveTimerToThinkForever(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + void + +**/ +{ + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.dSoftTimeLimit = -1; + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.uNodeCheckMask = 0x1000000 - 1; + g_MoveTimer.bvFlags = 0; +} + + +void +SetMoveTimerForSearch(FLAG fSwitchOver, ULONG uColor) +/** + +Routine description: + + Set the move timer for a search operation. + +Parameters: + + FLAG fSwitchOver : if TRUE then this search is a converted ponder + (i.e. they made the ponder move and now we are searching). + +Return value: + + void + +**/ +{ + ULONG uMovesDone = GetMoveNumber(uColor); + double dClock = (double)g_Options.uMyClock; + double dSec = 0; + ULONG uMargin = 0; + ULONG uMovesToDo; + + // + // If switching over from a ponder search leave the start time and + // move flags alone (i.e. N seconds in the past already). + // + if (FALSE == fSwitchOver) + { + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.bvFlags = 0; + } + + // + // Check the clock more often in search if there is little time + // left on the clock -- we can't afford an oversearch when the + // bullet game is down to the wire. + // +#ifdef DEBUG + g_MoveTimer.uNodeCheckMask = 0x800 - 1; +#else + if (WeAreRunningASuite()) + { + g_MoveTimer.uNodeCheckMask = 0x20000 - 1; + } + else if (g_Options.u64MaxNodeCount) + { + g_MoveTimer.uNodeCheckMask = 0x1000 - 1; + } + else + { + if (dClock < 10.0) + { + g_MoveTimer.uNodeCheckMask = 0x400 - 1; + } + else + { + g_MoveTimer.uNodeCheckMask = 0x8000 - 1; + } + } +#endif + + switch (g_Options.eClock) + { + // + // Fixed time per move. Think for g_uMyIncrement seconds exactly and + // no hard time limit. + // + case CLOCK_FIXED: + dSec = (double)g_Options.uMyIncrement; + uMargin = 0; + break; + + // + // N moves per time control or entire game in time control. + // + case CLOCK_NORMAL: + if (g_Options.uMovesPerTimePeriod != 0) + { + // + // N moves per time control. + // + ASSERT(g_Options.uMovesPerTimePeriod < 256); + uMovesToDo = + (g_Options.uMovesPerTimePeriod - + ((uMovesDone - 1) % g_Options.uMovesPerTimePeriod)); +#ifdef DEBUG + Trace("SetMoveTimer: %u moves left to do this in %s sec.\n", + uMovesToDo, TimeToString(dClock)); +#endif + ASSERT(uMovesToDo <= g_Options.uMovesPerTimePeriod); + dSec = (dClock / (double)uMovesToDo); + dSec *= 0.95; + uMargin = (ULONG)(dSec * 2.2); + if (uMovesToDo <= 5) + { + dSec *= 0.75; + uMargin /= 2; + } + break; + } + else + { + // + // Fixed time finish entire game. + // +#ifdef DEBUG + Trace("SetMoveTimer: finish the game in %s sec.\n", + TimeToString(dClock)); +#endif + dSec = dClock / 60; + uMargin = (ULONG)(dSec * 2.2); + } + break; + + // + // We get back a certain number of seconds with each move made. + // + case CLOCK_INCREMENT: + dSec = g_Options.uMyIncrement; + dSec += (dClock / 50); + uMargin = (int)(dSec * 2.2); + +#ifdef DEBUG + Trace("SetMoveTimer: finish the game in %s sec (+%u per move).\n", + TimeToString(dClock), g_Options.uMyIncrement); +#endif + + // + // If we are running out of time, think for less than the + // increment. + // + if (dClock < 20.0) + { + dSec -= g_Options.uMyIncrement; + uMargin = 0; + } + ASSERT(dSec > 0); + break; + + case CLOCK_NONE: +#ifdef DEBUG + Trace("SetMoveTimer: no time limit, think until interrupted.\n"); +#endif + g_MoveTimer.dHardTimeLimit = -1; + g_MoveTimer.dSoftTimeLimit = -1; + goto post; + + default: + ASSERT(FALSE); + break; + } + if ((dSec + uMargin) >= (dClock * 7 / 8)) uMargin = 0; + g_MoveTimer.dSoftTimeLimit = g_MoveTimer.dStartTime + dSec; + g_MoveTimer.dHardTimeLimit = g_MoveTimer.dStartTime + dSec + uMargin; + + post: + if (TRUE == g_Options.fShouldPost) + { + if (g_MoveTimer.dSoftTimeLimit > 0) + { + Trace("SetMoveTimer: Soft time limit %s seconds.\n", + TimeToString(g_MoveTimer.dSoftTimeLimit - + g_MoveTimer.dStartTime)); + ASSERT(g_MoveTimer.dHardTimeLimit > 0); + Trace("SetMoveTimer: Hard time limit %s seconds.\n", + TimeToString(g_MoveTimer.dHardTimeLimit - + g_MoveTimer.dStartTime)); + if (TRUE == fSwitchOver) + { + Trace("SetMoveTimer: Already searched %s seconds.\n", + TimeToString(SystemTimeStamp() - + g_MoveTimer.dStartTime)); + } + } +#ifdef DEBUG + Trace("SetMoveTimer: Checking input and timer every %u nodes.\n", + g_MoveTimer.uNodeCheckMask); +#endif + } +} + + +void +ReInitializeSearcherContext(POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Reinitializes a SEARCHER_THREAD_CONTEXT structure. + +Parameters: + + POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + if (NULL != pos) + { + memmove(&(ctx->sPosition), pos, sizeof(POSITION)); + } + ctx->uPly = 0; + ctx->uPositional = 133; + memset(&(ctx->sCounters), 0, sizeof(COUNTERS)); +} + + +void +InitializeSearcherContext(POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Initialize a SEARCHER_THREAD_CONTEXT structure. + +Parameters: + + POSITION *pos, + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG u; + + memset(ctx, 0, sizeof(SEARCHER_THREAD_CONTEXT)); + ReInitializeSearcherContext(pos, ctx); + ctx->sMoveStack.uUnblockedKeyValue[0] = 1; + for (u = 1; + u < MAX_PLY_PER_SEARCH; + u++) + { + ctx->sMoveStack.uUnblockedKeyValue[u] = + ctx->sMoveStack.uUnblockedKeyValue[u-1] + 0x28F5C28; + } +} + + +void +InitializeLightweightSearcherContext(POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx) +/** + +Routine description: + + Initialize a LIGHTWEIGHT_SEARCHER_CONTEXT structure. + +Parameters: + + POSITION *pos, + LIGHTWEIGHT_SEARCHER_CONTEXT *ctx + +Return value: + + void + +**/ +{ + ULONG u; + + memset(ctx, 0, sizeof(LIGHTWEIGHT_SEARCHER_CONTEXT)); + if (NULL != pos) + { + memmove(&(ctx->sPosition), pos, sizeof(POSITION)); + } + ctx->uPly = 0; + ctx->uPositional = 133; + ctx->sMoveStack.uUnblockedKeyValue[0] = 1; + for (u = 1; + u < MAX_PLY_PER_SEARCH; + u++) + { + ctx->sMoveStack.uUnblockedKeyValue[u] = + ctx->sMoveStack.uUnblockedKeyValue[u-1] + 0x28F5C28; + } +} + + +void +PostMoveSearchReport(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Dump a report to stdout after every move. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + +Return value: + + void + +**/ +{ + double d; + char buf[256]; +#ifdef PERF_COUNTERS + double n; +#endif + d = (double)g_MoveTimer.dEndTime - (double)g_MoveTimer.dStartTime + 0.01; + ASSERT(d); + Trace("---------------------------------------------\n" + "Searched for %5.1f seconds, saw %" + COMPILER_LONGLONG_UNSIGNED_FORMAT + " nodes (%" + COMPILER_LONGLONG_UNSIGNED_FORMAT + " qnodes) (%6.0f nps).\n", + d, ctx->sCounters.tree.u64TotalNodeCount, + ctx->sCounters.tree.u64QNodeCount, + ((double)ctx->sCounters.tree.u64TotalNodeCount / d)); + if (g_Options.fThinking) + { + snprintf(buf, ARRAY_LENGTH(buf), "d%u, %s, %3.1fs, %6.0fknps, PV=%s", + ctx->uRootDepth / ONE_PLY, + ScoreToString(ctx->iRootScore), + d, + ((double)ctx->sCounters.tree.u64TotalNodeCount / d / 1000), + ctx->szLastPV); + Trace("tellothers %s\n", buf); + } +#ifdef MP +#ifdef PERF_COUNTERS + if (ctx->sCounters.parallel.uNumSplits > 0) + { + n = (double)ctx->sCounters.parallel.uNumSplits; + Trace("Split %u times total ", + ctx->sCounters.parallel.uNumSplits); + Trace("(~%7.2fx/sec).\n", (n / d)); + d = n + 1; + ASSERT(d); + n = (double)ctx->sCounters.parallel.uNumSplitsTerminated; + Trace(" ...%u (%5.2f percent) terminated early.\n", + ctx->sCounters.parallel.uNumSplitsTerminated, ((n/d) * 100.0)); + DumpHelperIdlenessReport(); + } +#endif +#endif + +#ifdef TEST + AnalyzeFullHashTable(); +#endif +#ifdef PERF_COUNTERS + d = (double)(ctx->sCounters.hash.u64Probes) + 1; + ASSERT(d); + Trace("Hashing percentages: (%5.3f total, %5.3f useful)\n", + ((double)(ctx->sCounters.hash.u64OverallHits) / d) * 100.0, + ((double)(ctx->sCounters.hash.u64UsefulHits) / d) * 100.0); + d = (double)(ctx->sCounters.pawnhash.u64Probes) + 1; + ASSERT(d); + n = (double)(ctx->sCounters.pawnhash.u64Hits); + Trace("Pawn hash hitrate: %5.3f percent.\n", (n/d) * 100.0); + n = (double)(ctx->sCounters.tree.u64NullMoveSuccess); + d = (double)(ctx->sCounters.tree.u64NullMoves) + 1; + ASSERT(d); + Trace("Null move cutoff rate: %5.3f percent.\n", + ((n / d) * 100.0)); +#ifdef TEST_ENDGAME + n = (double)(ctx->sCounters.tree.u64EndgamePruningSuccess); + d = n + (double)(ctx->sCounters.tree.u64EndgamePruningFailures); + if (d != 0.0) + { + Trace("Endgame pruning heuristic success rate was %5.3f percent.\n" + "Endgame pruning heuristic was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64EndgamePruningSuccess, + (ctx->sCounters.tree.u64EndgamePruningSuccess + + ctx->sCounters.tree.u64EndgamePruningFailures)); + } + else + { + Trace("Never used endgame pruning heuristic.\n"); + } +#endif +#ifdef TEST_NULL + n = (double)(ctx->sCounters.tree.u64AvoidNullSuccess); + d = n + (double)(ctx->sCounters.tree.u64AvoidNullFailures); + if (d != 0.0) + { + Trace("Avoid null move heuristic rate was %5.3f percent.\n" + "Avoid null move heuristic was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64AvoidNullSuccess, + (ctx->sCounters.tree.u64AvoidNullSuccess + + ctx->sCounters.tree.u64AvoidNullFailures)); + } + else + { + Trace("Never used the avoid null move heuristic.\n"); + } + n = (double)(ctx->sCounters.tree.u64QuickNullSuccess); + n += (double)(ctx->sCounters.tree.u64QuickNullDeferredSuccess); + d = n + (double)(ctx->sCounters.tree.u64QuickNullFailures); + if (d != 0.0) + { + Trace("Quick null move heuristic rate was %5.3f percent.\n" + "Quick null move heuristic rate was " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT " (" + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ") / " + "%"COMPILER_LONGLONG_UNSIGNED_FORMAT ".\n", + ((n / d) * 100.0), + ctx->sCounters.tree.u64QuickNullSuccess, + ctx->sCounters.tree.u64QuickNullDeferredSuccess, + (ctx->sCounters.tree.u64QuickNullSuccess + + ctx->sCounters.tree.u64QuickNullDeferredSuccess + + ctx->sCounters.tree.u64QuickNullFailures)); + } + else + { + Trace("Never used the quick null move heuristic.\n"); + } +#endif + n = (double)ctx->sCounters.tree.u64BetaCutoffsOnFirstMove; + d = (double)ctx->sCounters.tree.u64BetaCutoffs + 1; + Trace("First move beta cutoff rate was %5.3f percent.\n", + ((n / d) * 100.0)); +#ifdef LAZY_EVAL + d = (double)ctx->sCounters.tree.u64LazyEvals; + d += (double)ctx->sCounters.tree.u64FullEvals; + d += (double)ctx->sCounters.tree.u64EvalHashHits; + d += 1; + ASSERT(d); + Trace("Eval percentages: (%5.2f hash, %5.2f lazy, %5.2f full)\n", + ((double)ctx->sCounters.tree.u64EvalHashHits / d) * 100.0, + ((double)ctx->sCounters.tree.u64LazyEvals / d) * 100.0, + ((double)ctx->sCounters.tree.u64FullEvals / d) * 100.0); +#endif + Trace("Extensions: (%u +, %u q+, %u 1mv, %u !kmvs, %u mult+, %u pawn\n" + " %u threat, %u zug, %u sing, %u endg, %u bm, %u recap)\n", + ctx->sCounters.extension.uCheck, + ctx->sCounters.extension.uQExtend, + ctx->sCounters.extension.uOneLegalMove, + ctx->sCounters.extension.uNoLegalKingMoves, + ctx->sCounters.extension.uMultiCheck, + ctx->sCounters.extension.uPawnPush, + ctx->sCounters.extension.uMateThreat, + ctx->sCounters.extension.uZugzwang, + ctx->sCounters.extension.uSingularReplyToCheck, + ctx->sCounters.extension.uEndgame, + ctx->sCounters.extension.uBotvinnikMarkoff, + ctx->sCounters.extension.uRecapture); +#ifdef EVAL_TIME + n = (double)ctx->sCounters.tree.u64CyclesInEval; + Trace("Avg. cpu cycles in eval: %8.1f.\n", (n / d)); +#endif +#endif + fflush(g_pfLogfile); +} + + +SCORE +RootSearch(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth) +/** + +Routine description: + + Search at the root of the whole tree. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + ULONG uDepth, + +Return value: + + SCORE + +**/ +{ + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + SCORE iBestScore = -INFINITY; + SCORE iInitialAlpha = iAlpha; + MOVE mv; + ULONG x, y; + SCORE iScore; + ULONG uNextDepth; + UINT64 u64StartingNodeCount; + ULONG uNumLegalMoves; + +#ifdef DEBUG + POSITION *pos = &ctx->sPosition; + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT((ctx->uPly == 0) || (ctx->uPly == 1)); // 1 is for under a ponder + memcpy(&pi->sPosition, pos, sizeof(POSITION)); +#endif + + ctx->sCounters.tree.u64TotalNodeCount++; + pi->PV[ctx->uPly] = NULLMOVE; + pi->mvBest = NULLMOVE; + g_MoveTimer.bvFlags |= TIMER_SEARCHING_FIRST_MOVE; +#ifdef DEBUG + Trace("---- depth=%u, a=%d, b=%d ----\n", uDepth / ONE_PLY, iAlpha, iBeta); +#endif + + uNumLegalMoves = 0; + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectMoveAtRoot(ctx, x); + if (ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED) break; + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; + mv = ctx->sMoveStack.mvf[x].mv; + mv.bvFlags |= WouldGiveCheck(ctx, mv); + + if (MakeMove(ctx, mv)) + { + uNumLegalMoves++; + u64StartingNodeCount = ctx->sCounters.tree.u64TotalNodeCount; + + // + // TODO: Fancy recap shit here? + // + + uNextDepth = uDepth - ONE_PLY; + if (IS_CHECKING_MOVE(mv)) + { + uNextDepth += HALF_PLY; + ctx->sPlyInfo[ctx->uPly].iExtensionAmount = HALF_PLY; + } + + ctx->sSearchFlags.fVerifyNullmove = TRUE; + ctx->sSearchFlags.uQsearchDepth = 0; + if (uNumLegalMoves == 1) + { + // + // Move 1, full a..b window + // + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + else + { + // + // Moves 2..N, minimal window search + // + ASSERT(x > 0); + ASSERT(uNumLegalMoves > 1); + iScore = -Search(ctx, -iAlpha - 1, -iAlpha, uNextDepth); + if ((iAlpha < iScore) && (iScore < iBeta)) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + } + ctx->sSearchFlags.fVerifyNullmove = FALSE; + UnmakeMove(ctx, mv); + if (WE_SHOULD_STOP_SEARCHING) + { + iBestScore = INVALID_SCORE; + goto end; + } +#ifdef DEBUG + Trace("%2u. %-8s => node=%" COMPILER_LONGLONG_UNSIGNED_FORMAT + ", predict=%d, actual=%d, ", + x + 1, + MoveToSan(mv, &ctx->sPosition), + u64StartingNodeCount, + ctx->sMoveStack.mvf[x].iValue, + iScore); + ASSERT(PositionsAreEquivalent(&pi->sPosition, &ctx->sPosition)); +#endif + // + // Keep track of how many moves are under each one we + // search and use this as the basis for root move ordering + // next iteration. + // + u64StartingNodeCount = (ctx->sCounters.tree.u64TotalNodeCount - + u64StartingNodeCount); + u64StartingNodeCount >>= 9; + u64StartingNodeCount &= (MAX_INT / 4); + ctx->sMoveStack.mvf[x].iValue = + (SCORE)(u64StartingNodeCount + iScore); +#ifdef DEBUG + Trace("next_predict: %d\n", ctx->sMoveStack.mvf[x].iValue); + ASSERT(iBestScore <= iAlpha); + ASSERT(iAlpha < iBeta); +#endif + if (iScore > iBestScore) + { + iBestScore = iScore; + pi->mvBest = mv; + if (iScore > iAlpha) + { + // + // We have a best move so far. As of now it is + // the one we'll be playing. Also make sure to + // search it first at the next depth. + // +#ifdef DEBUG + Trace("Best so far... root score=%d.\n", iScore); +#endif + ctx->mvRootMove = mv; + ctx->iRootScore = iScore; + ctx->uRootDepth = uDepth; + ctx->sMoveStack.mvf[x].iValue = MAX_INT; + + // + // If there was a previous PV move then knock its + // score down so that it will be considered second + // on the next depth. + // + for (y = ctx->sMoveStack.uBegin[ctx->uPly]; + y < x; + y++) + { + if (ctx->sMoveStack.mvf[y].iValue == MAX_INT) + { + ctx->sMoveStack.mvf[y].iValue /= 2; + } + } + + UpdatePV(ctx, mv); + if (iScore >= iBeta) + { + // + // Root fail high... + // + UpdateDynamicMoveOrdering(ctx, + uDepth, + mv, + iScore, + x + 1); + UtilPrintPV(ctx, iAlpha, iBeta, iScore, mv); + KEEP_TRACK_OF_FIRST_MOVE_FHs(iBestScore == -INFINITY); + ctx->sMoveStack.mvf[x].bvFlags &= ~MVF_MOVE_SEARCHED; + goto end; + } + else + { + // + // Root PV change... + // + UtilPrintPV(ctx, iAlpha, iBeta, iScore, mv); + iAlpha = iScore; + } + } + } + g_MoveTimer.bvFlags &= ~TIMER_SEARCHING_FIRST_MOVE; + } + } + + if (iAlpha == iInitialAlpha) + { + // + // Root fail low... + // + ASSERT(iBestScore <= iAlpha); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + UtilPrintPV(ctx, iAlpha, iBeta, iBestScore, mv); + } + + end: + return(iBestScore); +} + + + +static GAME_RESULT +_DetectPreMoveTerminalStates(SEARCHER_THREAD_CONTEXT *ctx, + FLAG fInCheck, + MOVE *pmv) { + ULONG u; + MOVE mv; + MOVE mvLegal; + ULONG uNumLegal = 0; + GAME_RESULT ret; + + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + pmv->uMove = 0; + + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) { + mv = ctx->sMoveStack.mvf[u].mv; + if (MakeMove(ctx, mv)) { + mvLegal = mv; + uNumLegal += 1; + UnmakeMove(ctx, mv); + if (uNumLegal > 1) { + return ret; + } + } + } + if (uNumLegal == 1) { + *pmv = mvLegal; + return ret; + } + ASSERT(uNumLegal == 0); + if (TRUE == fInCheck) { + if (ctx->sPosition.uToMove == WHITE) { + ret.eResult = RESULT_BLACK_WON; + strcpy(ret.szDescription, "black checkmated white"); + return ret; + } + ret.eResult = RESULT_WHITE_WON; + strcpy(ret.szDescription, "white checkmated black"); + return ret; + } + ret.eResult = RESULT_DRAW; + sprintf(ret.szDescription, "%s stalemated %s", + (ctx->sPosition.uToMove == WHITE) ? "black" : "white", + (ctx->sPosition.uToMove == WHITE) ? "while" : "black"); + return ret; +} + + + +static GAME_RESULT +_DetectPostMoveTerminalStates(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + This function is called by Iterate and MakeTheMove to declare + wins/losses/draws. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG + +**/ +{ + GAME_RESULT ret; + FLAG fInCheck = InCheck(&ctx->sPosition, ctx->sPosition.uToMove); + + // Did we just make the 50th+ move without progress? + if (ctx->sPosition.uFifty >= 100) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "fifty moves without progress"); + return ret; + } + GenerateMoves(ctx, NULLMOVE, (fInCheck ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + + // Did we just repeat a position for the 3rd time? + if (IsLegalDrawByRepetition()) { + ret.eResult = RESULT_DRAW; + strcpy(ret.szDescription, "third repetition of position"); + return ret; + } + + // Otherwise look for checkmates and stalemates. + MOVE mvUnused; + return _DetectPreMoveTerminalStates(ctx, + fInCheck, + &mvUnused); +} + + +static void +_IterateSetSearchGlobals(ULONG uDepth) +{ + ULONG u, v; + ULONG uDontSplitLessThan; + + // + // Set some globals that will be used throughout this search. + // + g_uIterateDepth = uDepth; + ASSERT(g_uIterateDepth > 0); + ASSERT(g_uIterateDepth < MAX_PLY_PER_SEARCH); + + // + // For use in scaling back extensions that are very far from + // the root. + // + // Iterate g_Soft g_Hard + // | | | | | | | | | + // 0 1 2 2.5 3 3.5 4 (x Iterate) + // |-------------------|----|----|---------|----... + // |full full full full|-1/4|-1/2|-3/4 -3/4|none... + // + g_uSoftExtendLimit = g_uIterateDepth * 2; + g_uHardExtendLimit = g_uIterateDepth * 4; + for (u = 0; u < MAX_PLY_PER_SEARCH; u++) + { + if (u < g_uSoftExtendLimit) + { + g_uExtensionReduction[u] = 0; + } + else if (u < (g_uSoftExtendLimit + g_uIterateDepth / 2)) + { + g_uExtensionReduction[u] = QUARTER_PLY; + } + else if (u < (g_uSoftExtendLimit + g_uIterateDepth)) + { + g_uExtensionReduction[u] = HALF_PLY; + } + else if (u < g_uHardExtendLimit) + { + g_uExtensionReduction[u] = THREE_QUARTERS_PLY; + } + else + { + g_uExtensionReduction[u] = 5 * ONE_PLY; + } + } + + // + // Determine how much depth we need below a point in the tree in + // order to split the search (which is based on iteration depth). + // + uDontSplitLessThan = (ULONG)((double)(uDepth) * 0.30); + for (v = 0; v < MAX_PLY_PER_SEARCH; v++) + { + g_fCanSplit[v] = ((v + 1) >= uDontSplitLessThan); + } + g_fCanSplit[0] = FALSE; +} + + +#define SKIP_GRADUAL_OPENING 600 +#define INITIAL_HALF_WINDOW 75 +#define FIRST_FAIL_STEP 150 +#define SECOND_FAIL_STEP 375 + +void +_IterateWidenWindow(ULONG uColor, + SCORE iScore, + SCORE *piBound, + ULONG *puState, + int iDir) +{ + SCORE iRoughScore = g_iRootScore[uColor]; + static SCORE _Steps[] = + { + FIRST_FAIL_STEP, + SECOND_FAIL_STEP, + INFINITY + }; + +// Trace("State = %u.\n", *puState); +// Trace("Bound from %d to ", *piBound); + if ((abs(iRoughScore - iScore) > SKIP_GRADUAL_OPENING) || + (*puState == 2)) + { + *piBound = iDir * INFINITY; + *puState = 2; + } + else + { + ASSERT(*puState < 2); + *piBound = iScore; + *piBound += iDir * _Steps[*puState]; + *puState += 1; + } +// Trace("%d.\n", *piBound); +// Trace("State = %u\n", *puState); +} + + +GAME_RESULT Iterate(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Main iterative deepening loop for both thinking and pondering. + Call RootSearch with progressively deeper depths while there is + remaining time, we haven't found a forced mate, and there's no + user interruption. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG : is the game over? + +**/ +{ + ULONG uNumRootFailLows = 0; + ULONG uDepth; + ULONG uFailState = 0; + ULONG uColor; + ULONG u; + SCORE iAlpha = -INFINITY; + SCORE iBeta = +INFINITY; + SCORE iScore; + FLAG fInCheck = InCheck(&(ctx->sPosition), ctx->sPosition.uToMove); + MOVE mv; + GAME_RESULT ret; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); + VerifyPositionConsistency(&board, FALSE); +#endif + + uColor = ctx->sPosition.uToMove; + g_iRootScore[uColor] = GetRoughEvalScore(ctx, iAlpha, iBeta, TRUE); + g_iRootScore[FLIP(uColor)] = -g_iRootScore[uColor]; + + // + // Generate moves here so that RootSearch doesn't have to. + // + ASSERT((ctx->uPly == 0) || (ctx->uPly == 1)); // 1 is under a ponder + ctx->sPlyInfo[ctx->uPly].fInCheck = fInCheck; + GenerateMoves(ctx, NULLMOVE, (fInCheck ? GENERATE_ESCAPES : + GENERATE_ALL_MOVES)); + ASSERT(ctx->sMoveStack.uBegin[0] == 0); + + // + // See if we are sitting at a checkmate or stalemate position; no + // sense searching if so. + // + ret = _DetectPreMoveTerminalStates(ctx, + fInCheck, + &mv); + if (ret.eResult != RESULT_IN_PROGRESS) { + goto end; + } + + // Game still in progress but only one legal move available? + if (mv.uMove != 0) { + ctx->mvRootMove = mv; + ctx->iRootScore = 0; + ctx->uRootDepth = 0; + ctx->sPlyInfo[0].PV[0] = mv; + ctx->sPlyInfo[0].PV[1] = NULLMOVE; + strcpy(ctx->szLastPV, "only"); + if (!g_Options.fPondering) { + Trace("ONLY MOVE --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + g_MoveTimer.bvFlags |= TIMER_CURRENT_OBVIOUS; + } else { + Trace("ONLY PONDER --> move immediately if prediction correct.\n"); + g_MoveTimer.bvFlags |= TIMER_MOVE_IMMEDIATELY; + g_MoveTimer.bvFlags |= TIMER_CURRENT_OBVIOUS; + } + goto end; + } + + for (uDepth = 1; + uDepth <= g_Options.uMaxDepth; + uDepth++) + { + // + // Re-rank the moves based on nodecounts and mark all moves as + // not yet searched at this depth. + // + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) + { + ctx->sMoveStack.mvf[u].bvFlags &= ~MVF_MOVE_SEARCHED; + } + + // + // Make sure a..b window makes sense and set some other per-depth + // globals used by the search. + // + _IterateSetSearchGlobals(uDepth); + + // + // Try to get a PV for this depth before we're out of time... + // + do + { + if (iBeta > INFINITY) iBeta = +INFINITY; + if (iAlpha < -INFINITY) iAlpha = -INFINITY; + if (iAlpha >= iBeta) iAlpha = iBeta - 1; + iScore = RootSearch(ctx, + iAlpha, + iBeta, + uDepth * ONE_PLY + HALF_PLY); + if (g_MoveTimer.bvFlags & TIMER_STOPPING) break; + mv = ctx->mvRootMove; + + // + // Got a PV, we're done with this depth. + // + if ((iAlpha < iScore) && (iScore < iBeta)) + { + ASSERT(iScore == ctx->iRootScore); + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + iAlpha = iScore - INITIAL_HALF_WINDOW; + iBeta = iScore + INITIAL_HALF_WINDOW; + g_iRootScore[uColor] = iScore; + g_iRootScore[FLIP(uColor)] = -iScore; + g_MoveTimer.bvFlags &= ~TIMER_RESOLVING_ROOT_FH; + g_MoveTimer.bvFlags &= ~TIMER_RESOLVING_ROOT_FL; + uFailState = 0; + (void)CheckTestSuiteMove(mv, iScore, uDepth); + break; + } + + // + // Root fail low? We'll have to research with a wider + // window. + // + else if (iScore <= iAlpha) + { + ASSERT(ctx->mvRootMove.uMove); + g_MoveTimer.bvFlags |= TIMER_RESOLVING_ROOT_FL; + uNumRootFailLows++; + if (uNumRootFailLows > 3) + { + g_MoveTimer.bvFlags |= TIMER_MANY_ROOT_FLS; + } + _IterateWidenWindow(uColor, iScore, &iAlpha, &uFailState, -1); + + // + // Consider all moves again with wider window... + // + for (u = ctx->sMoveStack.uBegin[ctx->uPly]; + u < ctx->sMoveStack.uEnd[ctx->uPly]; + u++) + { + ctx->sMoveStack.mvf[u].bvFlags &= ~MVF_MOVE_SEARCHED; + } + } + + // + // Must be a root fail high. + // + else + { + ASSERT(iScore >= iBeta); + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + g_MoveTimer.bvFlags |= TIMER_RESOLVING_ROOT_FH; + _IterateWidenWindow(uColor, iScore, &iBeta, &uFailState, +1); + } + } + while(1); // repeat until we run out of time or fall inside a..b + + // + // We are here because either: + // + // 1. we completed a search depth, + // or 2. we ran out of time, + // or 3. there is one legal move and we want to make it immediately, + // or 4. there was user input and we unrolled the search. + // + + // + // TODO: Scale back history between iterative depths? + // + + // + // Mate-in-n when we have searched n? Stop searching. + // + if (IS_VALID_SCORE(iScore) && + (ULONG)abs(iScore) >= (INFINITY - uDepth)) + { + Trace("FORCED MATE --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + + // + // Have we reached user's maxdepth option? Stop searching. + // + if (uDepth >= g_Options.uMaxDepth) + { + Trace("DEPTH LIMIT --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + + // + // Did the move timer expire? Stop searching. + // + if (g_MoveTimer.bvFlags & TIMER_STOPPING) break; + } + g_Options.u64NodesSearched = ctx->sCounters.tree.u64TotalNodeCount; + g_MoveTimer.dEndTime = SystemTimeStamp(); + + // + // Here we are at the end of a search. If we were: + // + // ...Searching then: ...Pondering then: + // + // 1. we ran out of time 1. they made a different move than + // the predicted move and we aborted + // 2. we ran out of depth + // 2. we ran out of depth + // 3. we found a mate-in-n + // 3. we found a mate-in-n + // TODO: node count limit? + // (4. if they made the predicted move + // then we converted to a search) + // + ASSERT(ctx->mvRootMove.uMove); + ASSERT(SanityCheckMove(&board, ctx->mvRootMove)); + if (g_MoveTimer.bvFlags & TIMER_RESOLVING_ROOT_FL) + { + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly] = ctx->mvRootMove; + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly+1] = NULLMOVE; + } + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + end: + return ret; +} + +void +MakeTheMove(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Make the move that search selected in the official game list. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + FLAG + +**/ +{ + MOVE mv = ctx->mvRootMove; + ASSERT(mv.uMove); + + if (TRUE == g_Options.fThinking) + { + // + // TODO: keep track of how many moves in a row we are at or + // below a draw score and use this to respond to draw offers. + // + + // + // Was this a search that converted from a ponder? + // + if (TRUE == g_Options.fSuccessfulPonder) + { + if (FALSE == OfficiallyMakeMove(g_Options.mvPonder, 0, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)g_Options.mvPonder.uMove, + NULL, + NULL, + __FILE__, + __LINE__); + } + g_Options.fSuccessfulPonder = FALSE; + } + + // + // Tell the server about our move and actually play it on the + // root board. + // + Trace("move %s\n", MoveToSan(mv, &ctx->sPosition)); + if (FALSE == OfficiallyMakeMove(mv, g_iScore, FALSE)) + { + UtilPanic(CANNOT_OFFICIALLY_MAKE_MOVE, + GetRootPosition(), + (void *)mv.uMove, + NULL, + NULL, + __FILE__, + __LINE__); + } + if (g_Options.fVerbosePosting) + { + PostMoveSearchReport(ctx); + PostMoveTestSuiteReport(ctx); + } + } + g_Options.fPondering = g_Options.fThinking = FALSE; +} + + +GAME_RESULT +Ponder(POSITION *pos) +/** + +Routine description: + + Prepare to ponder. + +Parameters: + + POSITION *pos + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + GAME_RESULT ret; + + InitializeSearcherContext(pos, &ctx); + g_Options.fPondering = TRUE; + g_Options.fThinking = FALSE; + g_Options.fSuccessfulPonder = FALSE; + ret.eResult = RESULT_IN_PROGRESS; + ret.szDescription[0] = '\0'; + + // + // When do we not want to ponder + // + if ((g_Options.ePlayMode == FORCE_MODE) || (g_Options.uMyClock < 10)) + { + g_Options.fPondering = FALSE; + return ret; + } + + // + // What should we ponder? + // + g_Options.mvPonder = GetPonderMove(pos); + if (g_Options.mvPonder.uMove == 0) + { + g_Options.fPondering = FALSE; + return ret; + } + ASSERT(SanityCheckMove(pos, g_Options.mvPonder)); + + // + // Prepare to ponder by doing some maintenance on the dynamic move + // ordering scheme counters, changing the dirty tag in the hash + // code, and clearing the root nodes-per-move hash. + // + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + // + // Make the move ponder move. + // + if (FALSE == MakeMove(&ctx, g_Options.mvPonder)) + { + ASSERT(FALSE); + g_Options.fPondering = FALSE; + return ret; + } + + // + // TODO: probe the book + // + + _SetMoveTimerForPonder(); + + // + // TODO: Any preEval? + // + + // + // TODO: Set draw value + // + + MakeStatusLine(); +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + ASSERT(ctx.uPly == 1); + ret = Iterate(&ctx); + ASSERT(ctx.uPly == 1); + if (ret.eResult == RESULT_IN_PROGRESS) { + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } else { + return ret; + } +} + + +GAME_RESULT Think(POSITION *pos) +/** + +Routine description: + + Prepare to think. + +Parameters: + + POSITION *pos + +Return value: + + FLAG + +**/ +{ + static SEARCHER_THREAD_CONTEXT ctx; + MOVE mvBook; + CHAR *p; + + InitializeSearcherContext(pos, &ctx); + g_MoveTimer.bvFlags = 0; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + g_Options.fSuccessfulPonder = FALSE; + + // + // Prepare to think by doing some maintenance on the dynamic move + // ordering scheme counters, changing the dirty tag in the hash + // code, and clearing the root nodes-per-move hash. + // + if (NULL != (p = PositionToFen(&(ctx.sPosition)))) + { + Trace("The root position is: %s\n", p); + SystemFreeMemory(p); + } + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + // + // Check the opening book, maybe it has a move for us. + // + if ((g_uBookProbeFailures < 3) && (!WeAreRunningASuite())) + { + mvBook = BookMove(pos, BOOKMOVE_SELECT_MOVE); + if (mvBook.uMove == 0) + { + g_uBookProbeFailures++; + } + else + { + g_uBookProbeFailures = 0; + ASSERT(SanityCheckMove(pos, mvBook)); + ctx.mvRootMove = mvBook; + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } + } + + // + // TODO: Any preEval? + // + + // + // Set time limit for move + // + SetMoveTimerForSearch(FALSE, pos->uToMove); + + // + // TODO: Set draw value + // +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + GAME_RESULT ret = Iterate(&ctx); + if (ret.eResult == RESULT_IN_PROGRESS) { + MakeTheMove(&ctx); + return _DetectPostMoveTerminalStates(&ctx); + } else { + return ret; + } +} diff --git a/src/save/util.c b/src/save/util.c new file mode 100755 index 0000000..90431e2 --- /dev/null +++ b/src/save/util.c @@ -0,0 +1,1254 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + util.c + +Abstract: + + General purpose utility code to support the engine. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: util.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uIterateDepth; +extern ULONG g_uFullWidthDepth; + +#define STATE_UNKNOWN (0) +#define STATE_HEADER (1) +#define STATE_MOVELIST (2) + +CHAR * +ReadNextGameFromPgnFile(FILE *pf) +/** + +Routine description: + + Reads the next game in a PGN file and returns a pointer to it. + +Parameters: + + FILE *pf : open file pointer + +Return value: + + CHAR * : NULL on error, else caller must free via SystemFreeMemory. + +**/ +{ + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + CHAR *p; + long lStartOfGame = -1; + long lEndOfGame = -1; + long lBefore; + ULONG uBytes; + ULONG uState = STATE_UNKNOWN; + + while(1) + { + lBefore = ftell(pf); + if (fgets(buf, ARRAY_LENGTH(buf), pf) <= 0) + { + //Trace("fgets failed, errno=%u.\n", errno); + break; + } + + // + // Skip leading whitespace on this line... + // + p = buf; + while(*p && isspace(*p)) p++; + + if (*p == '\0') + { + // + // We just read a blank line + // + switch(uState) + { + case STATE_UNKNOWN: + break; + + case STATE_HEADER: + uState = STATE_MOVELIST; + break; + + case STATE_MOVELIST: + lEndOfGame = lBefore; + uBytes = lEndOfGame - lStartOfGame; + if (uBytes <= 0) + { + return(NULL); + } + + p = SystemAllocateMemory(uBytes + 1); + ASSERT(p); + fseek(pf, lStartOfGame, SEEK_SET); + if (1 != fread(p, uBytes, 1, pf)) + { + SystemFreeMemory(p); + return(NULL); + } + p[uBytes] = '\0'; + return(p); + } + } + else + { + // + // We saw a non-blank line + // + switch(uState) + { + case STATE_HEADER: + case STATE_MOVELIST: + break; + + case STATE_UNKNOWN: + if (*p == '[') + { + uState = STATE_HEADER; + lStartOfGame = lBefore; + } + break; + } + } + } + return(NULL); +} + + +COMMAND(LearnPsqtFromPgn) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + +Return value: + + FLAG + +**/ +{ + CHAR *szFilename; + ULONG uPSQT[12][128]; + CHAR *pPGN; + FILE *pf = NULL; + DLIST_ENTRY *p; + GAME_MOVE *q; + ULONG x, y, z; + double d; + struct stat s; +#ifdef DEBUG + ULONG uHeap; +#endif + + if (argc < 2) + { + Trace("Error (missing filename)\n"); + return; + } + szFilename = argv[1]; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPsqtFromPgn: file \"%s\" doesn't exist.\n", + szFilename); + return; + } + + if (0 != stat(szFilename, &s)) + { + Trace("Stat failed.\n"); + return; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPsqtFromPgn: error reading file \"%s\".\n", + szFilename); + return; + } + + memset(uPSQT, 0, sizeof(uPSQT)); +#ifdef DEBUG + ResetGameList(); + uHeap = GetHeapMemoryUsage(); +#endif + while((pPGN = ReadNextGameFromPgnFile(pf)) != NULL) + { + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("(%5.2f%% done)\r", d); + + if (TRUE == LoadPgn(pPGN)) + { + p = g_GameData.sMoveList.pFlink; + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if ((q->uNumber > 10) && + (q->uNumber < 50) && + (!q->mv.pCaptured)) + { + uPSQT[q->mv.pMoved - 2][q->mv.cTo] += 1; + } + p = p->pFlink; + } + } + SystemFreeMemory(pPGN); +#ifdef DEBUG + ResetGameList(); + ASSERT(uHeap == GetHeapMemoryUsage()); +#endif + } + fclose(pf); + + z = 0; + for (x = 0; x < 12; x++) + { + for (y = 0; y < 128; y++) + { + if (uPSQT[x][y] > z) + { + z = uPSQT[x][y]; + } + } + } + + Trace("ULONG g_PSQT[12][128] = {\n"); + for (x = 0; x < 12; x++) + { + Trace("// Piece 0x%x (%s)\n", x + 2, PieceAbbrev((PIECE)(x + 2))); + Trace("{\n"); + + for (y = 0; y < 128; y++) + { + if (y % 16 == 0) Trace("\n"); + d = (double)uPSQT[x][y]; + d /= (double)z; + d *= (double)1000.0; + Trace("%4u,", (ULONG)d); + } + Trace("},\n"); + } + Trace("};\n"); +} + + +COMMAND(GeneratePositionAndBestMoveSuite) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + +Return value: + + FLAG + +**/ +{ + CHAR *szFilename; + CHAR *pPGN; + FILE *pf = NULL; + DLIST_ENTRY *p; + GAME_MOVE *q; + SEARCHER_THREAD_CONTEXT *ctx = NULL; + FLAG fPost = g_Options.fShouldPost; + struct stat s; + double d; + POSITION board; + + if (argc < 2) + { + Trace("Error (missing filename)\n"); + goto end; + } + szFilename = argv[1]; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPsqtFromPgn: file \"%s\" doesn't exist.\n", + szFilename); + goto end; + } + + if (0 != stat(szFilename, &s)) + { + Trace("Stat failed.\n"); + goto end; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPsqtFromPgn: error reading file \"%s\".\n", + szFilename); + goto end; + } + + ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT)); + if (NULL == ctx) + { + Trace("Out of memory.\n"); + goto end; + } + + g_Options.fShouldPost = FALSE; + while((pPGN = ReadNextGameFromPgnFile(pf)) != NULL) + { + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("(%5.2f%% done)\r", d); + + if (TRUE == LoadPgn(pPGN)) + { + p = g_GameData.sMoveList.pFlink; + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if ((q->uNumber > 20) && (q->uNumber < 60)) + { + if (FenToPosition(&board, q->szUndoPositionFen)) + { + InitializeSearcherContext(&board, ctx); + g_MoveTimer.bvFlags = 0; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + g_Options.fSuccessfulPonder = FALSE; + + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + g_MoveTimer.uNodeCheckMask = 0x1000 - 1; + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.bvFlags = 0; + g_MoveTimer.dSoftTimeLimit = + g_MoveTimer.dStartTime + 3.0; + g_MoveTimer.dHardTimeLimit = + g_MoveTimer.dStartTime + 3.0; + g_Options.uMaxDepth = MAX_DEPTH_PER_SEARCH - 1; + + // + // TODO: Set draw value + // +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + GAME_RESULT result = Iterate(ctx); + if (result.eResult == RESULT_IN_PROGRESS) { + ASSERT(SanityCheckMove(&board, + ctx->sPlyInfo[0].PV[0])); + Trace("setboard %s\n", q->szUndoPositionFen); + Trace("gmmove %s\n", q->szMoveInSan); + Trace("solution %s\n", + MoveToSan(ctx->sPlyInfo[0].PV[0], &board)); + } + } + } + p = p->pFlink; + } + } + SystemFreeMemory(pPGN); + } + + end: + if (NULL != pf) + { + fclose(pf); + } + + if (NULL != ctx) + { + SystemFreeMemory(ctx); + } + + g_Options.fShouldPost = fPost; +} + + +char * +FindChunk(char *sz, ULONG uTargetChunk) +/** + +Routine description: + + A support routine used by FenToPosition. Used to parse apart a + string and return the Nth chunk of text (delimited by whitespace) + +Parameters: + + char *sz, + ULONG uTargetChunk + +Return value: + + char * + +**/ +{ + char *p = sz; + ULONG u = 0; + + if (0 == uTargetChunk) return(p); + + do + { + // + // Skip whitespace between chunks + // + while(isspace(*p) && *p) p++; + if (!*p) return(NULL); + + u++; + if (u == uTargetChunk) return(p); + + // + // Skip chunks + // + while(!isspace(*p) && &p) p++; + if (!*p) return(NULL); + } + while(1); + +#ifdef DEBUG + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +#endif + return(NULL); +} + + + +CHAR * +ScoreToString(SCORE iScore) +/** + +Routine description: + + Format a chess score as a string that looks like: + + +0.100 + -4.951 + +MATE20 + -MATE4 + +0.000 + + etc... + + Note: NOT thread safe. + +Parameters: + + SCORE iScore + +Return value: + + CHAR * + +**/ +{ + static char szBuf[10]; + ULONG uDist; + + if (abs(iScore) < +NMATE) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), + "%c%u.%02u", + (iScore < 0) ? '-' : '+', + abs(iScore / 100), + abs(iScore % 100)); + return(szBuf); + } + + if (iScore > 0) + { + uDist = +INFINITY - iScore; + uDist /= 2; + if (uDist) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "+MATE%u", uDist); + } + else + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "+MATE"); + } + } + else + { + uDist = +INFINITY + iScore; + uDist /= 2; + if (uDist) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "-MATE%u", uDist); + } + else + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "-MATE"); + } + } + return(szBuf); +} + + + +CHAR * +CoorToString(COOR c) +/** + +Routine description: + + Take a chessboard coordinate and convert it into a string. Note: + NOT thread safe. + +Parameters: + + COOR c + +Return value: + + CHAR * + +**/ +{ + static char buf[3]; + + if (IS_ON_BOARD(c)) + { + buf[0] = 'a' + FILE(c); + buf[1] = '0' + RANK(c); + buf[2] = '\0'; + } + else + { + buf[0] = '-'; + buf[1] = '\0'; + } + return(buf); +} + + +CHAR * +ColorToString(ULONG u) +/** + +Routine description: + + Convert a color into a string ("WHITE" or "BLACK"). Callers + should not mess with the contents of the buffer returned! + +Parameters: + + ULONG u + +Return value: + + char + +**/ +{ + static CHAR *szColor[2] = + { + "BLACK", + "WHITE" + }; + ASSERT(IS_VALID_COLOR(u)); + return(szColor[u]); +} + + +CHAR * +TimeToString(double d) +/** + +Routine description: + + Convert a time value into a string. e.g. + + 00:00:01.021 // seconds with ms + 00:15:21.998 // minutes+seconds + 01:59:23.232 // hours+minutes+sec + 27:08:11:103 // we don't do days + + Note: NOT thread safe. The caller should not mess with the + buffer returned. + +Parameters: + + double d + +Return value: + + CHAR * + +**/ +{ + ULONG uTotalSecs = (ULONG)d; + double dFract = d - (double)uTotalSecs; + ULONG uHours; + ULONG uMinutes; + ULONG uFract; + static char buf[13]; + + dFract *= 1000; + uFract = (int)dFract; + uHours = uTotalSecs / 60 / 60; + uTotalSecs -= uHours * 60 * 60; + uMinutes = uTotalSecs / 60; + uTotalSecs -= uMinutes * 60; + ASSERT(uTotalSecs < 60); + + if (uHours != 0) + { + snprintf(buf, ARRAY_LENGTH(buf), + "%2u:%02u:%02u.%03u", + uHours, uMinutes, uTotalSecs, uFract); + } + else + { + snprintf(buf, ARRAY_LENGTH(buf), + "%02u:%02u.%03u", + uMinutes, uTotalSecs, uFract); + } + return(buf); +} + + +FLAG +BufferIsZeroed(BYTE *p, ULONG u) +/** + +Routine description: + + Verify that a buffer is zeroed out. + +Parameters: + + BYTE *p : buffer start + ULONG u : buffer length + +Return value: + + FLAG + +**/ +{ + while(u) + { + if (*p != (BYTE)0) + { + return(FALSE); + } + p++; + u--; + } + return(TRUE); +} + + +void CDECL +Trace(CHAR *szMessage, ...) +/** + +Routine description: + + Trace a logging message on stdout and to the logfile + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send to logfile + // + if (NULL != g_pfLogfile) + { + fprintf(g_pfLogfile, buf); + } + + // + // Send to stdout + // + fprintf(stdout, buf); + fflush(stdout); +} + + +void CDECL +Log(CHAR *szMessage, ...) +/** + +Routine description: + + Trace a logging message to the logfile only + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send to logfile + // + if (NULL != g_pfLogfile) + { + fprintf(g_pfLogfile, buf); + } +} + + +void CDECL +Bug(CHAR *szMessage, ...) +/** + +Routine description: + + Trace an error message to stderr and the logfile + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send it to logfile + // + if (NULL != g_pfLogfile) + { + fprintf(g_pfLogfile, buf); + fflush(g_pfLogfile); + } + + // + // Send it to stderr + // + fprintf(stderr, buf); + fflush(stderr); +} + + +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine) +/** + +Routine description: + + An assertion handler + +Parameters: + + CHAR *szFile, + UINT uLine + +Return value: + + void + +**/ +{ + Bug("Assertion failure in %s, line %u.\n", szFile, uLine); + BREAKPOINT; +} +#endif + + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock) +/** + +Routine description: + + Atomically acquire a lock or spin trying. + +Parameters: + + ULONG *pSpinlock : a pointer to the lock + +Return value: + + ULONG : the number of times we had to spin + +**/ +{ + ULONG uLoops = 0; + while(0 != LockCompareExchange(pSpinlock, 1, 0)) + { + uLoops++; + } + ASSERT(*pSpinlock == 1); + return(uLoops); +} + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock) +{ + return(0 != LockCompareExchange(pSpinlock, 1, 0)); +} + +void +ReleaseSpinLock(volatile ULONG *pSpinlock) +/** + +Routine description: + + Release a lock so someone else can acquire it. + +Parameters: + + ULONG *pSpinlock : a pointer to the lock + +Return value: + + void + +**/ +{ + ULONG u; + ASSERT(*pSpinlock == 1); + u = LockCompareExchange(pSpinlock, 0, 1); + ASSERT(u == 1); +} + + +FLAG +BackupFile(CHAR *szFile) +/** + +Routine description: + + Backup a file to file.000. If file.000 already exists, back it up + to file.001 etc... + + Note: this function is recursive and can require quite a lot of + stack space. Also it is full of race conditions and should not be + used when some other code may be accessing the filesystem at the + same time. + +Parameters: + + CHAR *szFile : the file to backup + +Return value: + + FLAG + +**/ +{ + ULONG u; + CHAR buf[SMALL_STRING_LEN_CHAR]; + CHAR *p; + + if (TRUE == SystemDoesFileExist(szFile)) + { + if ((strlen(szFile) > 3) && + (isdigit(szFile[0])) && + (isdigit(szFile[1])) && + (isdigit(szFile[2]))) + { + u = (szFile[0] - '0') * 100; + u += (szFile[1] - '0') * 10; + u += szFile[2] - '0' + 1; + p = &(szFile[3]); + } + else + { + u = 0; + p = szFile; + } + snprintf(buf, ARRAY_LENGTH(buf), "%03u%s", u, p); + if (TRUE == SystemDoesFileExist(buf)) + { + BackupFile(buf); + } + return(SystemCopyFile(szFile, buf) && SystemDeleteFile(szFile)); + } + return(FALSE); +} + + +BYTE +Checksum(BYTE *p, ULONG uSize) +/** + +Routine description: + + Compute the checksum of a buffer. + +Parameters: + + BYTE *p, + ULONG uSize + +Return value: + + BYTE + +**/ +{ + BYTE b = 0; + while(uSize) + { + b ^= *p; + p++; + uSize--; + } + return(b); +} + +void +FinishPVTailFromHash(SEARCHER_THREAD_CONTEXT *ctx, + CHAR *buf, + ULONG uLenRemain) +{ + MOVE PV[MAX_PLY_PER_SEARCH]; + MOVE mv; + ULONG uPly = ctx->uPly; + ULONG uLen; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + + if (NULL == g_pHashTable) return; + do + { + mv = GetPonderMove(&ctx->sPosition); + if (mv.uMove == 0) break; + PV[ctx->uPly] = mv; + + uLen = (ULONG)strlen(MoveToSan(mv, &ctx->sPosition)) + 1; + ASSERT(uLen <= 11); + if (uLenRemain <= uLen) break; + strcat(buf, MoveToSan(PV[ctx->uPly], &ctx->sPosition)); + strcat(buf, " "); + uLenRemain -= uLen; + + if (FALSE == MakeMove(ctx, mv)) break; + } + while(1); + + // + // Unmake the moves + // + while(ctx->uPly > uPly) + { + UnmakeMove(ctx, PV[ctx->uPly - 1]); + } + ASSERT(ctx->uPly == uPly); + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); +} + + + +char * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Return a string buffer representing the principle variation. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + CHAR * + +**/ +{ + static CHAR buf[SMALL_STRING_LEN_CHAR]; + ULONG u = ctx->uPly; + ULONG v = u; + MOVE mv; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + + buf[0] = '\0'; + while((mv.uMove = ctx->sPlyInfo[v].PV[u].uMove) != 0) + { + if (mv.uMove == HASHMOVE.uMove) + { + strncat(buf, " ", ARRAY_LENGTH(buf) - strlen(buf) - 1); + FinishPVTailFromHash(ctx, buf, ARRAY_LENGTH(buf) - strlen(buf)); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else if (mv.uMove == RECOGNMOVE.uMove) + { + strncat(buf, "", ARRAY_LENGTH(buf) - strlen(buf) - 1); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else if (mv.uMove == DRAWMOVE.uMove) + { + strncat(buf, "<=>", ARRAY_LENGTH(buf) - strlen(buf) - 1); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else + { + strncat(buf, MoveToSan(mv, &ctx->sPosition), + ARRAY_LENGTH(buf) - strlen(buf)); + strncat(buf, " ", ARRAY_LENGTH(buf) - strlen(buf) - 1); + } + + if (FALSE == MakeMove(ctx, mv)) break; + u++; + + if (strlen(buf) > (SMALL_STRING_LEN_CHAR - 10)) break; + } + + // + // Unmake the moves + // + u--; + while(ctx->uPly > v) + { + UnmakeMove(ctx, ctx->sPlyInfo[v].PV[u]); + u--; + } + ASSERT(ctx->uPly == v); + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); + return(buf); +} + + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *arg1, void *arg2, void *arg3, + char *szFile, ULONG uLine) +{ + Bug("Typhoon PANIC 0x%x (%p, %p, %p, %p)\n" + "Location: %s at line %u\n\n", + uPanicCode, pos, arg1, arg2, arg3, szFile, uLine); + Banner(); + Bug("----------------------------------------------------------------\n"); + switch(uPanicCode) { + case CANNOT_INITIALIZE_SPLIT: + case GOT_ILLEGAL_MOVE_WHILE_PONDERING: + case CANNOT_OFFICIALLY_MAKE_MOVE: + DumpPosition(pos); + DumpMove((ULONG)arg1); + break; + case INITIALIZATION_FAILURE: + Bug("%s\n", (char *)arg1); + break; + default: + break; + } + fflush(stdout); + fflush(g_pfLogfile); + BREAKPOINT; + exit(-1); +} + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv) +/** + +Routine description: + + Print a PV out to stdout and the log. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv + +Return value: + + void + +**/ +{ + double dNow = SystemTimeStamp(); + + ASSERT(ctx->uThreadNumber == 0); + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(IS_VALID_SCORE(iScore)); + + dNow -= g_MoveTimer.dStartTime; + + // + // Set the last PV in the context if we have a root PV or a root + // fail high. + // + if ((iAlpha < iScore) && (iScore < iBeta)) + { + strncpy(ctx->szLastPV, WalkPV(ctx), SMALL_STRING_LEN_CHAR); + } + else if (iScore > iBeta) + { + strncpy(ctx->szLastPV, MoveToSan(mv, &(ctx->sPosition)), + SMALL_STRING_LEN_CHAR); + } + + if ((TRUE == g_Options.fThinking) && (TRUE == g_Options.fShouldPost)) + { + // + // Maybe output the PV. Note: xboard gets confused by PV + // lines that don't match its requirements exactly; if we are + // running under xboard, match its expected format. Otherwise + // be more helpful / verbose. + // + if ((dNow > 0.35) || ((dNow > 0.15) && (g_Options.fVerbosePosting))) + { + if (TRUE == g_Options.fRunningUnderXboard) + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + else if (iScore <= iAlpha) + { + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" FL --\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount); + } + else + { + ASSERT(iScore >= iBeta); + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s ++\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + } + else // !running under xboard + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + Trace("%2u %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + else if (iScore <= iAlpha) + { + Trace("%2u- %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" FL --\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount); + } + else + { + ASSERT(iScore >= iBeta); + Trace("%2u+ %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s ++\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + } + } + } +} diff --git a/src/save/vars.c b/src/save/vars.c new file mode 100644 index 0000000..1db4c72 --- /dev/null +++ b/src/save/vars.c @@ -0,0 +1,483 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + vars.c + +Abstract: + + This is code that implements variables in the engine. Some of + these variables are read only but others can be set by the engine + user to affect certain aspects of engine operation. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 18 May 2004 + +Revision History: + + $Id: vars.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uNumInputEvents; + +typedef void(PUSERVARFUN)(void); + +// +// Here's how we expose engine variables to the user. +// +typedef struct _USER_VARIABLE +{ + char *szName; // variable name + char *szType; // variable type: + // * - char *, strdup/free + // H - hash size + // B - boolean + // U - unsigned + // I - int + // M - move + // D - double + // S - string buffer + void *pValue; // pointer to value + PUSERVARFUN *pFunction; // funct to call when it changes +} USER_VARIABLE; + +extern ULONG g_uBookProbeFailures; + +USER_VARIABLE g_UserVarList[] = +{ + { "AnnounceOpening", + "B", + (void *)&(g_Options.fShouldAnnounceOpening), + NULL }, + { "BatchMode", + "b", + (void *)&(g_Options.fNoInputThread), + NULL }, + { "BlackPlayer", + "*", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].szName), + NULL }, + { "BlackRating", + "U", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].uRating), + NULL }, + { "BlackDescription", + "*", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].szDescription), + NULL }, + { "BlackIsComputer", + "B", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].fIsComputer), + NULL }, + { "BookFileName", + "S", + (void *)&(g_Options.szBookName), + NULL }, + { "BookProbeFailures", + "u", + (void *)&(g_uBookProbeFailures), + NULL }, + { "ComputerTimeRemainingSec", + "U", + (void *)&(g_Options.uOpponentsClock), + NULL }, //&DoVerifyClocks }, + { "EGTBPath", + "S", + (void *)&(g_Options.szEGTBPath), + InitializeEGTB }, + { "FastScript", + "B", + (void *)&(g_Options.fFastScript), + NULL }, + { "GameDescription", + "*", + (void *)&(g_GameData.sHeader.szGameDescription), + NULL }, + { "GameLocation", + "*", + (void *)&(g_GameData.sHeader.szLocation), + NULL }, + { "GameIsRated", + "B", + (void *)&(g_GameData.sHeader.fGameIsRated), + NULL }, + { "GameResultComment", + "*", + (void *)&(g_GameData.sHeader.szResultComment), + NULL }, + { "LastEval", + "I", + (void *)&(g_Options.iLastEvalScore), + NULL }, + { "LogfileName", + "S", + (void *)&(g_Options.szLogfile), + NULL }, + { "MoveToPonder", + "m", + (void *)&(g_Options.mvPonder), + NULL }, + { "MovesPerTimePeriod", + "U", + (void *)&(g_Options.uMovesPerTimePeriod), + NULL }, + { "OpponentTimeRemainingSec", + "U", + (void *)&(g_Options.uMyClock), + NULL }, //&DoVerifyClocks }, + { "PendingInputEvents", + "u", + (void *)&(g_uNumInputEvents), + NULL }, + { "PonderingNow", + "b", + (void *)&(g_Options.fPondering), + NULL }, + { "PostLines", + "B", + (void *)&(g_Options.fShouldPost), + NULL }, + { "Resign", + "B", + (void *)&(g_Options.fShouldResign), + NULL }, + { "SearchDepthLimit", + "U", + (void *)&(g_Options.uMaxDepth), + NULL }, //&DoVerifySearchDepth }, + { "SearchTimeLimit", + "U", + (void *)&(g_Options.uMyIncrement), + NULL }, //&DoVerifySearchTime }, + { "SearchStartedTime", + "d", + (void *)&(g_MoveTimer.dStartTime), + NULL }, + { "SearchSoftTimeLimit", + "d", + (void *)&(g_MoveTimer.dSoftTimeLimit), + NULL }, + { "SearchHardTimeLimit", + "d", + (void *)&(g_MoveTimer.dHardTimeLimit), + NULL }, + { "SearchNodesBetweenTimeCheck", + "u", + (void *)&(g_MoveTimer.uNodeCheckMask), + NULL }, + { "StatusLine", + "B", + (void *)&(g_Options.fStatusLine), + NULL }, + { "ThinkOnOpponentsTime", + "B", + (void *)&(g_Options.fShouldPonder), + NULL }, + { "ThinkingNow", + "b", + (void *)&(g_Options.fThinking), + NULL }, + { "TournamentMode", + "B", + (void *)&(g_fTournamentMode), + NULL }, + { "VerbosePosting", + "B", + (void *)&(g_Options.fVerbosePosting), + NULL }, + { "WhitePlayer", + "*", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].szName), + NULL }, + { "WhiteRating", + "U", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].uRating), + NULL }, + { "WhiteDescription", + "*", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].szDescription), + NULL }, + { "WhiteIsComputer", + "B", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].fIsComputer), + NULL }, + { "Xboard", + "B", + (void *)&(g_Options.fRunningUnderXboard), + NULL } +}; + + + + +COMMAND(SetCommand) +/** + +Routine description: + + This function implements the 'set' engine command. + + Usage: + + set [variable name [value]] + + With no arguments, set dumps a list of all variables and their + current values. + + With one argument, set displays the specified variable's value. + + With two arguments, set changes the value of the specified + variable to the given value. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x, y; + FLAG fFound; + + if (argc == 1) + { + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + switch(toupper(g_UserVarList[x].szType[0])) + { + case 'H': + case 'U': + Trace("%-28s => %u\n", + g_UserVarList[x].szName, + *((unsigned int *)g_UserVarList[x].pValue)); + break; + case 'I': + Trace("%-28s => %d\n", + g_UserVarList[x].szName, + *((int *)g_UserVarList[x].pValue)); + break; + case 'S': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (char *)g_UserVarList[x].pValue); + break; + case 'M': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + MoveToIcs(*((MOVE *)g_UserVarList[x].pValue))); + break; + case 'B': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (*((FLAG *)g_UserVarList[x].pValue) == TRUE) ? + "TRUE" : "FALSE"); + break; + case 'D': + Trace("%-28s => %f\n", + g_UserVarList[x].szName, + *((double *)g_UserVarList[x].pValue)); + break; + case '*': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + *((char **)g_UserVarList[x].pValue)); + break; + default: + Trace("%-28s => ???\n", + g_UserVarList[x].szName); + // ASSERT(FALSE); + break; + } + } + return; + } + else if (argc == 2) + { + fFound = FALSE; + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + if (!STRNCMPI(argv[1], + g_UserVarList[x].szName, + strlen(argv[1]))) + { + fFound = TRUE; + switch(toupper(g_UserVarList[x].szType[0])) + { + case 'H': + case 'U': + Trace("%-28s => %u\n", + g_UserVarList[x].szName, + *((unsigned int *)g_UserVarList[x].pValue)); + break; + case 'I': + Trace("%-28s => %d\n", + g_UserVarList[x].szName, + *((int *)g_UserVarList[x].pValue)); + break; + case 'S': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (char *)g_UserVarList[x].pValue); + break; + case 'M': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + MoveToIcs(*((MOVE *)g_UserVarList[x].pValue))); + break; + case 'B': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (*((FLAG *)g_UserVarList[x].pValue) == TRUE) ? + "TRUE" : "FALSE"); + break; + case 'D': + Trace("%-28s => %f\n", + g_UserVarList[x].szName, + *((double *)g_UserVarList[x].pValue)); + break; + case '*': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + *((char **)g_UserVarList[x].pValue)); + break; + default: + Trace("%-28s => ???\n", + g_UserVarList[x].szName); + // ASSERT(FALSE); + break; + } + } + } + + if (FALSE == fFound) + { + Trace("Error (invalid variable): %s\n", argv[1]); + } + return; + } + else + { + ASSERT(argc > 2); + + fFound = FALSE; + + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + if (!STRNCMPI(argv[1], + g_UserVarList[x].szName, + strlen(argv[1]))) + { + fFound = TRUE; + + if (islower(g_UserVarList[x].szType[0])) + { + Trace("Error (variable is read only): %s\n", + argv[1]); + } + + switch(g_UserVarList[x].szType[0]) + { + case 'H': + y = atoi(argv[2]); + if ((y < 0) || (y & (y - 1))) + { + Trace("Error (invalid size): %d\n", y); + } + else + { + *((int *)g_UserVarList[x].pValue) = y; + } + break; + + case '*': + if (NULL != *((char **)g_UserVarList[x].pValue)) + { + SystemFreeMemory( *((char **)g_UserVarList[x].pValue ) ); + } + *((char **)g_UserVarList[x].pValue) = STRDUP(argv[2]); + if (NULL == *((char **)g_UserVarList[x].pValue)) + { + Trace("Error (out of memory)\n"); + return; + } + break; + + case 'S': + strncpy(((char *)g_UserVarList[x].pValue), + argv[2], + 127); + break; + + case 'U': + y = atoi(argv[2]); + if (y < 0) + { + Trace("Error (invalid value): %d\n", y); + return; + } + *((unsigned *)g_UserVarList[x].pValue) = y; + break; + + case 'I': + y = atoi(argv[2]); + *((int *)g_UserVarList[x].pValue) = y; + break; + + case 'B': + if (toupper(*(argv[2])) == 'T') + { + *((FLAG *)g_UserVarList[x].pValue) = TRUE; + } + else if (toupper(*(argv[2])) == 'F') + { + *((FLAG *)g_UserVarList[x].pValue) = FALSE; + } + else + { + Trace("Error (invalid value, must be TRUE or " + "FALSE): %s\n", argv[2]); + } + break; + + default: + ASSERT(FALSE); + break; + } + + if (NULL != g_UserVarList[x].pFunction) + { + (void)(g_UserVarList[x].pFunction)(); + } + } + } + + if (FALSE == fFound) + { + Trace("Error (invalid variable): %s\n", argv[1]); + } + } +} + +// +// TODO: unset? +// diff --git a/src/script.c b/src/script.c new file mode 100755 index 0000000..4fb413d --- /dev/null +++ b/src/script.c @@ -0,0 +1,680 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + script.c + +Abstract: + + Some glue code to support running test scripts and keeping track + of test suite results. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 18 May 2004 + +Revision History: + + $Id: script.c 355 2008-07-01 15:46:43Z scott $ + +**/ + +#include "chess.h" + +// ---------------------------------------------------------------------- +// +// Global testsuite position counters +// +#define SUITE_MAX_SOLUTIONS (4) +#define SUITE_MAX_AVOIDS (4) +#define SUITE_NUM_HISTOGRAM (8) + +// +// A big struct of counters we want to maintain when running test scripts. +// +typedef struct _SUITE_COUNTERS +{ + CHAR szId[SMALL_STRING_LEN_CHAR]; + ULONG uNumSolutions; + MOVE mvSolution[SUITE_MAX_SOLUTIONS]; + ULONG uNumAvoids; + MOVE mvAvoid[SUITE_MAX_AVOIDS]; + ULONG uCorrect; + ULONG uIncorrect; + ULONG uTotal; + UINT64 u64TotalNodeCount; + double dCurrentSolutionTime; + ULONG uCurrentSolvedPlies; + ULONG uSigmaDepth; + double dSigmaSolutionTime; + double dAverageNps; + double dAverageFirstMoveBeta; + double dAverageTimeToSolution; + ULONG uHistogram[SUITE_NUM_HISTOGRAM]; +} +SUITE_COUNTERS; +static SUITE_COUNTERS g_SuiteCounters; + + +static void +_ClearSuiteData(void) +/** + +Routine description: + + Clear data/counters we have for the current test script. + +Parameters: + + void + +Return value: + + static void + +**/ +{ + g_SuiteCounters.uNumSolutions = 0; + memset(g_SuiteCounters.mvSolution, + 0, + sizeof(g_SuiteCounters.mvSolution)); + g_SuiteCounters.uNumAvoids = 0; + memset(g_SuiteCounters.mvAvoid, + 0, + sizeof(g_SuiteCounters.mvAvoid)); + memset(g_SuiteCounters.szId, + 0, + sizeof(g_SuiteCounters.szId)); + g_SuiteCounters.uCurrentSolvedPlies = 0; + g_SuiteCounters.dCurrentSolutionTime = 0; +} + + +COMMAND(IdCommand) +/** + +Routine description: + + This function implements the 'id' engine command. + + Usage: + + id [optional string] + + With no agruments, id returns the current position's id tag. + With a string argument, id sets the current position's id tag. + + id tags are useful[?] for naming positions in test suites... + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + CHAR *p; + ULONG u; + + if (argc < 2) + { + Trace("The current position's id is: \"%s\"\n", + g_SuiteCounters.szId); + } + else + { + p = szInput; + while(*p && !isspace(*p)) + { + p++; + } + while(*p && isspace(*p)) + { + p++; + } + u = 0; + while(*p) + { + if (!isspace(*p)) + { + g_SuiteCounters.szId[u] = *p; + u++; + } + if (u > ARRAY_LENGTH(g_SuiteCounters.szId)) + { + break; + } + p++; + } + } +} + +COMMAND(SolutionCommand) +/** + +Routine description: + + This function implements the 'solution' engine command. + + Usage: + + solution [optional move string] + + With no agruments, solution prints out a list of the "correct + solution" move(s) set for the current position. + + With a move string argument solution sets another move as the + correct answer to the current position. The move string can + be in ICS or SAN format. + + When the engine is allowed to search a position it will + compare its best move from the search against the solution + move(s) for the position and keep track of how many it gets + right/wrong and how long it took to solve. + + A position can have up to three solutions. A position cannot + have both solution moves and avoid moves. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG u; + MOVE mv; + + if (argc < 2) + { + Trace("There %s %u solution move%s set:\n", + (g_SuiteCounters.uNumSolutions > 1) ? "are" : "is", + g_SuiteCounters.uNumSolutions, + (g_SuiteCounters.uNumSolutions > 1) ? "s" : ""); + for(u = 0; + u < g_SuiteCounters.uNumSolutions; + u++) + { + Trace(" %s\n", MoveToSan(g_SuiteCounters.mvSolution[u], pos)); + } + } + else + { + mv.uMove = 0; + switch(LooksLikeMove(argv[1])) + { + case MOVE_SAN: + mv = ParseMoveSan(argv[1], pos); + break; + case MOVE_ICS: + mv = ParseMoveIcs(argv[1], pos); + break; + case NOT_MOVE: + break; + } + + if (mv.uMove == 0) + { + Trace("Error (bad move): %s\n", argv[1]); + return; + } + + if (g_SuiteCounters.uNumSolutions < SUITE_MAX_SOLUTIONS) + { + g_SuiteCounters.mvSolution[g_SuiteCounters.uNumSolutions] = mv; + g_SuiteCounters.uNumSolutions++; + } + } +} + + +COMMAND(AvoidCommand) +/** + +Routine description: + + This function implements the 'avoid' engine command. + + Usage: + + avoid [optional move string] + + With no agruments, avoid prints out a list of the "don't play + this" move(s) set for the current position. + + With a move string argument, avoid sets another move as the + incorrect answer to the current position. The move string can + be in ICS or SAN format. + + When the engine is allowed to search a position it will + compare its best move from the search against the avoid + move(s) for the position and keep track of how many it gets + right/wrong and how long it took to solve. + + A position can have up to three avoid moves. A position + cannot have both solution moves and avoid moves. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG u; + MOVE mv; + + if (argc < 2) + { + Trace("There %s %u avoid move%s set:\n", + (g_SuiteCounters.uNumAvoids > 1) ? "are" : "is", + g_SuiteCounters.uNumAvoids, + (g_SuiteCounters.uNumAvoids > 1) ? "s" : ""); + for(u = 0; + u < g_SuiteCounters.uNumAvoids; + u++) + { + Trace(" %s\n", MoveToSan(g_SuiteCounters.mvAvoid[u], pos)); + } + } + else + { + mv.uMove = 0; + switch(LooksLikeMove(argv[1])) + { + case MOVE_SAN: + mv = ParseMoveSan(argv[1], pos); + break; + case MOVE_ICS: + mv = ParseMoveIcs(argv[1], pos); + break; + case NOT_MOVE: + break; + } + + if (mv.uMove == 0) + { + Trace("Error (bad move): %s\n", argv[1]); + return; + } + + if (g_SuiteCounters.uNumAvoids < SUITE_MAX_AVOIDS) + { + g_SuiteCounters.mvAvoid[g_SuiteCounters.uNumAvoids] = mv; + g_SuiteCounters.uNumAvoids++; + } + } +} + + + +COMMAND(ScriptCommand) +/** + +Routine description: + + This function implements the 'script' engine command. + + Usage: + + script + + The script command opens the reads the required filename and + reads it line by line. Each line of the script file is + treated as a command and executed in sequence. Each command + is executed fully before the next script line is read and + executed. When all lines in the script file have been read + and executed the engine will print out a post-script report of + test suite statistics and then begin to pay attention to + commands from the keyboard again. + + Scripts are meant to facilitate execution of test suites. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + FILE *p; + static CHAR szLine[SMALL_STRING_LEN_CHAR]; + double dSuiteStart; + ULONG u, v, uMax; + double dMult; + + if (argc < 2) + { + Trace("Error (Usage: script ): %s\n", argv[0]); + return; + } + if (FALSE == SystemDoesFileExist(argv[1])) + { + Trace("Error (file doesn't exist): %s\n", argv[1]); + return; + } + + p = fopen(argv[1], "rb"); + if (NULL != p) + { + // Doing the script... + dSuiteStart = SystemTimeStamp(); + memset(&(g_SuiteCounters), 0, sizeof(g_SuiteCounters)); + while(fgets(szLine, ARRAY_LENGTH(szLine), p)) + { + Trace("SCRIPT> %s\n", szLine); + if (!STRNCMPI(szLine, "go", 2)) + { + (void)Think(pos); + g_SuiteCounters.u64TotalNodeCount += + g_Options.u64NodesSearched; + } + else + { + PushNewInput(szLine); + if (TRUE == g_fExitProgram) break; + ParseUserInput(FALSE); + } + } + fclose(p); + + // Banner and end results + dMult = (double)g_Options.uMyIncrement / (double)SUITE_NUM_HISTOGRAM; + Banner(); + Trace("\n" + "TEST SCRIPT execution complete. Final statistics:\n" + "--------------------------------------------------\n" + " correct solutions : %u\n" + " incorrect solutions : %u\n" + " total problems : %u\n" + " total nodecount : %" + COMPILER_LONGLONG_UNSIGNED_FORMAT "\n" + " avg. search speed : %6.1f nps\n" + " avg. solution time : %3.1f sec\n" + " avg. search depth : %4.1f ply\n" + " script time : %6.1f sec\n\n", + g_SuiteCounters.uCorrect, + g_SuiteCounters.uIncorrect, + g_SuiteCounters.uTotal, + g_SuiteCounters.u64TotalNodeCount, + ((double)g_SuiteCounters.u64TotalNodeCount / + (SystemTimeStamp() - dSuiteStart)), + (g_SuiteCounters.dSigmaSolutionTime / + (double)g_SuiteCounters.uCorrect), + ((double)g_SuiteCounters.uSigmaDepth / + (double)g_SuiteCounters.uTotal), + (SystemTimeStamp() - dSuiteStart)); + + // Histogram stuff + if (g_SuiteCounters.uTotal > 0) { + uMax = g_SuiteCounters.uHistogram[0]; + for (u = 1; u < SUITE_NUM_HISTOGRAM; u++) + { + if (g_SuiteCounters.uHistogram[u] > uMax) + { + uMax = g_SuiteCounters.uHistogram[u]; + } + } + ASSERT(uMax > 0); + for (u = 0; u < SUITE_NUM_HISTOGRAM; u++) + { + Trace("%4.1f .. %4.1f: ", + (double)u * dMult, (double)(u + 1) * dMult); + for (v = 0; + v < 50 * g_SuiteCounters.uHistogram[u] / uMax; + v++) + { + Trace("*"); + } + Trace("\n"); + } + } + } +} + +FLAG +WeAreRunningASuite(void) +/** + +Routine description: + + A function that returns TRUE if the engine is running a test suite + and FALSE otherwise. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (g_SuiteCounters.uNumSolutions + + g_SuiteCounters.uNumAvoids) + { + return(TRUE); + } + return(FALSE); +} + + +FLAG +CheckTestSuiteMove(MOVE mv, SCORE iScore, ULONG uDepth) +/** + +Routine description: + + This function is called by RootSearch when it has finished a + search. The MOVE parameter is the best move that the search + found. This code checks that move against the solution or avoid + moves for the current position, determines if we "got it right" + and updates the test suite counters accordingly. + +Parameters: + + MOVE mv + +Return value: + + FLAG + +**/ +{ + FLAG fSolved = FALSE; + ULONG u; + + if (!WeAreRunningASuite()) return FALSE; + + // + // There is(are) solution move(s). + // + if (g_SuiteCounters.uNumSolutions) + { + ASSERT(g_SuiteCounters.uNumAvoids == 0); + fSolved = FALSE; + for (u = 0; u < g_SuiteCounters.uNumSolutions; u++) + { + if ((mv.cFrom == g_SuiteCounters.mvSolution[u].cFrom) && + (mv.cTo == g_SuiteCounters.mvSolution[u].cTo)) + { + fSolved = TRUE; + break; + } + } + if (!fSolved) { + g_SuiteCounters.uCurrentSolvedPlies = 0; + g_SuiteCounters.dCurrentSolutionTime = 0.0; + } else { + if (g_SuiteCounters.uCurrentSolvedPlies == 0) { + g_SuiteCounters.dCurrentSolutionTime = + (SystemTimeStamp() - g_MoveTimer.dStartTime); + } + g_SuiteCounters.uCurrentSolvedPlies++; + } + } + else if (g_SuiteCounters.uNumAvoids) + { + // + // Handle avoid-move problems. + // + fSolved = TRUE; + for (u = 0; u < g_SuiteCounters.uNumAvoids; u++) + { + if ((mv.cFrom == g_SuiteCounters.mvAvoid[u].cFrom) && + (mv.cTo == g_SuiteCounters.mvAvoid[u].cTo)) + { + fSolved = FALSE; + } + } + if (!fSolved) + { + g_SuiteCounters.uCurrentSolvedPlies = 0; + g_SuiteCounters.dCurrentSolutionTime = 0.0; + } else { + if (g_SuiteCounters.uCurrentSolvedPlies == 0) { + g_SuiteCounters.dCurrentSolutionTime = + (SystemTimeStamp() - g_MoveTimer.dStartTime); + } + g_SuiteCounters.uCurrentSolvedPlies++; + } + } + else + { + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + } + + // + // Handle "FastScript" variable for solution moves. + // + if ((g_Options.fFastScript) && + (g_SuiteCounters.uCurrentSolvedPlies > 4) && + (iScore >= 0)) + { + if (((g_Options.uMyIncrement != 0) && + (SystemTimeStamp() - g_MoveTimer.dStartTime >= + (double)g_Options.uMyIncrement / 3)) || + ((g_Options.uMaxDepth != 0) && + (uDepth >= g_Options.uMaxDepth / 3))) + { + Trace("FAST SCRIPT --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + } + } + return(fSolved); +} + + +void +PostMoveTestSuiteReport(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + If we're running a suite, print a little blurb after each move to + act as a running total of how we're doing. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + void + +**/ +{ + MOVE mv = ctx->mvRootMove; + ULONG uDepth = ctx->uRootDepth / ONE_PLY, y; + double dMult; + + // + // This is the real move the searched picked when all was said and + // done (i.e. it ran out of time or reached a fixed depth). See + // if it's right. + // + if (WeAreRunningASuite()) + { + g_SuiteCounters.uTotal++; + g_SuiteCounters.uSigmaDepth += uDepth; + + if (CheckTestSuiteMove(mv, -1, uDepth)) + { + Trace("Problem %s solved in %3.1f sec.\n", + g_SuiteCounters.szId, + g_SuiteCounters.dCurrentSolutionTime); + g_SuiteCounters.uCorrect++; + g_SuiteCounters.dSigmaSolutionTime += + g_SuiteCounters.dCurrentSolutionTime; + + dMult = (double)g_Options.uMyIncrement / + (double)SUITE_NUM_HISTOGRAM; + ASSERT(SUITE_NUM_HISTOGRAM > 0); + for (y = 1; y <= SUITE_NUM_HISTOGRAM; y++) + { + if (g_SuiteCounters.dCurrentSolutionTime < ((double)y * dMult)) + { + g_SuiteCounters.uHistogram[y-1]++; + break; + } + if (y == SUITE_NUM_HISTOGRAM) + { + // + // This one is actually > time-to-think. This + // really happens... like we had 20 sec to think + // and solved it in 20.1 or something before the + // stop-searching timer was checked. + // + g_SuiteCounters.uHistogram[y-1]++; + } + } + } + else + { + Trace(">>>>> Problem %s was not solved. <<<<<\n\n", + g_SuiteCounters.szId); + g_SuiteCounters.uIncorrect++; + } + Trace("Current suite score: %u correct of %u problems.\n", + g_SuiteCounters.uCorrect, + g_SuiteCounters.uTotal); + _ClearSuiteData(); + } +} diff --git a/src/search.c b/src/search.c new file mode 100755 index 0000000..3b8000c --- /dev/null +++ b/src/search.c @@ -0,0 +1,1375 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + search.c + +Abstract: + + Recursive chess tree searching. See also split.c. + + "A type 1 node is also called a PV node. The root of the tree is + a type-1 node, and the *first* successor of a type-1 node is a + type-1 node also. A type-1 node must have all branches examined, + but it is unique in that we don't know anything about alpha and + beta yet, because we haven't searched the first move to establish + them. + + A type 2 node is either (a) a successor of any type-3 node, or, + (b) it's any successor (other than the first) of a type-1 node. + With perfect move ordering, the first branch at a type-2 node will + "refute" the move made at the previous ply via the alpha/beta + algorithm. This node requires good move ordering, because you + have to find a move good enough that your opponent would not play + the move he chose that led to this position. If you try a poor + move first, it won't produce a cutoff, and you have to search + another move (or more) until you find the "good" move that would + make him not play his move. + + A type-3 node follows a type-2 node. Here, you have to try every + move at your disposal. Since your opponent (at the previous ply) + has played a "strong" move (supposedly the "best" move) you are + going to have to try every move you have in an effort to refute + this move. None will do so (unless your opponent tried some poor + move first due to incorrect move ordering). Here, move ordering + is not worth the trouble, since the ordering won't let you avoid + searching some moves. Of course, with the transposition / + refutation table, ordering might help you get more "hits" if your + table is not large enough... + + As you can see, at type-1 nodes you have to do good move ordering + to choose that "1" move (or to choose that one out of a very few) + that is good enough to cause a cutoff, while avoiding choosing + those that are no good. At a type-1 node, the same thing applies. + If you don't pick the best move first (take the moves at the root + for example) you will search an inferior move, establish alpha or + beta incorrectly, and thereby increase the size of the total tree + by a *substantial* amount. + + By the way, some authors call type-1 nodes "PV" nodes, type-2 + nodes "CUT" nodes, and type-3 nodes "ALL" nodes. These make it + easier to read, but, unfortunately, I "cut my teeth" on the + Knuth/Moore paper and think in terms of type 1,2,3." + + --Bob Hyatt, r.g.c.c + +Author: + + Scott Gasch (scott.gasch@gmail.com) 21 May 2004 + +Revision History: + + $Id: search.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uIterateDepth; +extern FLAG g_fCanSplit[MAX_PLY_PER_SEARCH]; + +#define TRY_HASH_MOVE (0) +#define GENERATE_MOVES (1) +#define PREPARE_TO_TRY_MOVES (2) +#define TRY_GENERATED_MOVES (3) + +#ifdef DEBUG +#define VERIFY_HASH_HIT \ + ASSERT(IS_VALID_SCORE(iScore)); \ + ASSERT(((ULONG)pHash->uDepth << 4) >= uDepth); \ + switch (pHash->bvFlags & HASH_FLAG_VALID_BOUNDS) \ + { \ + case HASH_FLAG_LOWER: \ + ASSERT(iScore >= iBeta); \ + ASSERT(iScore > -NMATE); \ + ASSERT(iScore <= +NMATE); \ + break; \ + case HASH_FLAG_UPPER: \ + ASSERT(iScore <= iAlpha); \ + ASSERT(iScore < +NMATE); \ + ASSERT(iScore >= -NMATE); \ + break; \ + case HASH_FLAG_EXACT: \ + ASSERT((-NMATE <= iScore) && \ + (iScore <= +NMATE)); \ + break; \ + default: \ + ASSERT(FALSE); \ + } +#else +#define VERIFY_HASH_HIT +#endif + +/** + +Routine description: + + This is the full-width portion of the main chess tree search. In + general, its job is to ask the move generator to make a list of + all the moves possible at the board position in ctx, to make each + move in turn, and to search each resulting position recursively. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : the context to search in + SCORE iAlpha : the lower bound of the interesting score window + SCORE iBeta : the upper bound of the interesting score window + ULONG uDepth : the depth remaining before QSearch is invoked + +Return value: + + SCORE : a score + + Also affects the transposition table, searcher context, and just + about every other large data structure in the engine... + +**/ +SCORE FASTCALL +Search(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uDepth) +{ + POSITION *pos = &ctx->sPosition; + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + MOVE mvLast = (pi-1)->mv; + SCORE iBestScore = -INFINITY; + SCORE iInitialAlpha; + SCORE iRoughEval; + MOVE mv, mvBest, mvHash; + ULONG x = 0; + SCORE iScore; + INT iOrigExtend = 0; + INT iExtend; + ULONG uNextDepth; + ULONG uLegalMoves = 0; + HASH_ENTRY *pHash; + FLAG fThreat; + FLAG fSkipNull; + FLAG fIsDraw; + ULONG uStage = TRY_HASH_MOVE; + ULONG u; + ULONG uFutilityMargin = 0; +#ifdef DEBUG + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(ctx->uPly > 0); + ASSERT((mvLast.uMove != 0) || (pf->fAvoidNullmove == TRUE)); + ASSERT(IS_VALID_FLAG(pf->fAvoidNullmove)); + ASSERT(IS_VALID_FLAG(pf->fVerifyNullmove)); + memcpy(&pi->sPosition, pos, sizeof(POSITION)); +#endif + + // Jump directly to Qsearch if remaining depth is low enough. + // This is the only place Qsearch is entered. + if (uDepth < ONE_PLY) + { + pf->fCouldStandPat[BLACK] = pf->fCouldStandPat[WHITE] = FALSE; + pf->uQsearchNodes = pf->uQsearchDepth = 0; + pf->uQsearchCheckDepth = QPLIES_OF_NON_CAPTURE_CHECKS; + pi->fInQsearch = TRUE; + iBestScore = QSearch(ctx, iAlpha, iBeta); + ASSERT(pf->uQsearchNodes < 20000); + ASSERT(pf->uQsearchDepth == 0); + goto end; + } + pi->fInQsearch = FALSE; + + // Common initialization code (which may cause a cutoff or change the + // bounds or decide that we need to stop searching now). + if (TRUE == CommonSearchInit(ctx, + &iAlpha, + &iBeta, + &iBestScore)) + { + goto end; + } + DTEnterNode(ctx, uDepth, FALSE, iAlpha, iBeta); + iInitialAlpha = iAlpha; + ASSERT((IS_CHECKING_MOVE(mvLast) && (TRUE == pi->fInCheck)) || + (!IS_CHECKING_MOVE(mvLast) && (FALSE == pi->fInCheck))); + + // Prepare next depth for nullmove and hashtable lookup + uNextDepth = uDepth - SelectNullmoveRFactor(ctx, uDepth) - ONE_PLY; + if (uNextDepth > MAX_DEPTH_PER_SEARCH) uNextDepth = 0; + + // Check the transposition table. This may give us a cutoff + // without doing any work if we have previously stored the score + // of this search in the hash. It also may set mvHash even if it + // can't give us a cutoff. It also may set fSkipNull (see below) + // based on uNextDepth to inform us that a nullmove search is + // unlikely to succeed here. + mvHash.uMove = 0; + pHash = HashLookup(ctx, + uDepth, + uNextDepth, + iAlpha, + iBeta, + &fThreat, + &fSkipNull, + &mvHash, + &iScore); + if (NULL != pHash) + { + VERIFY_HASH_HIT; + u = pHash->bvFlags & HASH_FLAG_VALID_BOUNDS; + if (0 != mvHash.uMove) + { + // This is an idea posted by Dieter Brusser on CCC: If we + // get a hash hit that leads to a draw then only accept it + // if it has a score of zero, allows us to fail high when + // a draw would also have allowed a fail high, or allows a + // fail low when a draw would also have allowed a fail + // low. + VERIFY(MakeMove(ctx, mvHash)); + fIsDraw = IsDraw(ctx); + UnmakeMove(ctx, mvHash); + if ((FALSE == fIsDraw) || (iScore == 0) || + ((u == HASH_FLAG_LOWER) && (iScore >= iBeta) && (0 >= iBeta)) || + ((u == HASH_FLAG_UPPER) && (iScore <= iAlpha) && (0 <= iAlpha))) + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + UpdatePV(ctx, HASHMOVE); + } + iBestScore = iScore; + goto end; + } + } + else + { + // The hash move is empty. Either this is an upper bound + // in which case we have no best move since the node that + // generated it was a fail low -or- this is a lower bound + // recorded after a null move search. In the latter case + // we only accept the cutoff if we are considering null + // moves at this node too. + ASSERT(u != HASH_FLAG_EXACT); + if ((HASH_FLAG_UPPER == u) || (FALSE == pf->fAvoidNullmove)) + { + ASSERT(((u == HASH_FLAG_UPPER) && (iScore <= iAlpha)) || + ((u == HASH_FLAG_LOWER) && (iScore >= iBeta))); + iBestScore = iScore; + goto end; + } + } + } + + // Probe interior node recognizers; allow probes of ondisk EGTB files + // if it looks like we can get hit. + switch(RecognLookup(ctx, &iScore, ctx->uPly <= (g_uIterateDepth / 2))) + { + case UNRECOGNIZED: + break; + case RECOGN_EXACT: + case RECOGN_EGTB: + if ((iAlpha < iScore) && (iScore < iBeta)) + { + UpdatePV(ctx, RECOGNMOVE); + } + iBestScore = iScore; + goto end; + case RECOGN_LOWER: + if (iScore >= iBeta) + { + iBestScore = iScore; + goto end; + } + break; + case RECOGN_UPPER: + if (iScore <= iAlpha) + { + iBestScore = iScore; + goto end; + } + break; +#ifdef DEBUG + default: + ASSERT(FALSE); +#endif + } + + // Maybe do nullmove pruning + iRoughEval = GetRoughEvalScore(ctx, iAlpha, iBeta, FALSE); + GENERATE_NO_MOVES; + if (!fSkipNull && + !fThreat && + WeShouldTryNullmovePruning(ctx, + iAlpha, + iBeta, + iRoughEval, + uNextDepth)) + { + if (TryNullmovePruning(ctx, + &fThreat, + iAlpha, + iBeta, + uNextDepth, + &iOrigExtend, + &iScore)) + { + if (iScore > iBeta) { + StoreLowerBound(mvHash, pos, iScore, uDepth, FALSE); + } + iBestScore = iScore; // TODO: try just beta here + goto end; + } + } + + // Maybe increment positional extension level b/c of nullmove search + // or hash table results. + if (fThreat) + { + iOrigExtend += THREE_QUARTERS_PLY; + INC(ctx->sCounters.extension.uMateThreat); + } + + // Main search loop, try moves under this position. Before we get + // into the move loop, save the extensions merited by this + // position in the tree (pre-move) and the original search flags. + // Also clear the avoid null bit in the search flags -- we were + // either told to avoid it or not but there is no need to avoid it + // for the rest of the line... + mvBest.uMove = 0; + pf->fAvoidNullmove = FALSE; + do + { + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + + // Becase we want to try the hash move before generating any + // moves (in case it fails high and we can avoid the work) we + // have this ugly crazy looking switch statement... + switch(uStage) + { + case TRY_HASH_MOVE: + uStage++; + x = 0; + ASSERT(iBestScore == -INFINITY); + ASSERT(uLegalMoves == 0); + if (mvHash.uMove != 0) + { + mv = mvHash; + break; + } + // else fall through + + case GENERATE_MOVES: + ASSERT(ctx->uPly > 0); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + x = ctx->sMoveStack.uBegin[ctx->uPly]; + uStage++; + if (IS_CHECKING_MOVE(mvLast)) + { + ASSERT(InCheck(pos, pos->uToMove)); + GenerateMoves(ctx, mvHash, GENERATE_ESCAPES); + if (MOVE_COUNT(ctx, ctx->uPly)) + { + if (NUM_CHECKING_PIECES(ctx, ctx->uPly) > 1) + { + iOrigExtend += QUARTER_PLY; + INC(ctx->sCounters.extension.uMultiCheck); + } else if (NUM_KING_MOVES(ctx, ctx->uPly) == 0) { + iOrigExtend += QUARTER_PLY; + INC(ctx->sCounters.extension.uNoLegalKingMoves); + } + } + } + else + { + ASSERT(!InCheck(pos, pos->uToMove)); + GenerateMoves(ctx, mvHash, GENERATE_ALL_MOVES); + } + // fall through + + case PREPARE_TO_TRY_MOVES: + ASSERT(x == ctx->sMoveStack.uBegin[ctx->uPly]); + ASSERT((uLegalMoves == 0) || + ((uLegalMoves == 1) && (mvHash.uMove))); +#ifdef DO_IID + if (MOVE_COUNT(ctx, ctx->uPly)) + { + SelectBestNoHistory(ctx, x); + + // EXPERIMENT: If we got no best move from the + // hash table and the best move we got from the + // generator looks crappy (i.e. is not a winning + // or even capture/promotion) then rescore the + // moves we generated at this ply using a + // shallower search. "Internal Iterative + // Deepening" or something like it. + if ((iAlpha + 1 != iBeta) && + (mvHash.uMove == 0) && + (ctx->sMoveStack.mvf[x].iValue < SORT_THESE_FIRST) && + (uDepth >= FOUR_PLY)) + { + ASSERT(uDepth >= (IID_R_FACTOR + ONE_PLY)); + ASSERT(ctx->sSearchFlags.fAvoidNullmove == FALSE); + ctx->sSearchFlags.fAvoidNullmove = TRUE; + RescoreMovesViaSearch(ctx, uDepth, iAlpha, iBeta); + ctx->sSearchFlags.fAvoidNullmove = FALSE; + } + } +#endif + // This is very similar to Ernst Heinz's "extended + // futility pruning" except that it uses the added + // dynamic criteria of "ValueOfMaterialInTrouble" + // condition as a safety net. Note: before we actually + // prune away moves we will also make sure there is + // no per-move extension. + ASSERT(!uFutilityMargin); + if ((iRoughEval + VALUE_ROOK <= iAlpha) && + (uDepth <= TWO_PLY) && + (ctx->uPly >= 2) && + (iOrigExtend == 0) && + (ctx->sPlyInfo[ctx->uPly - 2].iExtensionAmount <= 0) && + (ValueOfMaterialInTroubleDespiteMove(pos, pos->uToMove))) + { + uFutilityMargin = (iAlpha - iRoughEval) / 2; + ASSERT(uFutilityMargin); + } + uStage++; + ASSERT(x == ctx->sMoveStack.uBegin[ctx->uPly]); + // fall through + + case TRY_GENERATED_MOVES: + if (x < ctx->sMoveStack.uEnd[ctx->uPly]) + { + ASSERT(x >= ctx->sMoveStack.uBegin[ctx->uPly]); + if (uLegalMoves < SEARCH_SORT_LIMIT(ctx->uPly)) + { + SelectBestWithHistory(ctx, x); + } + mv = ctx->sMoveStack.mvf[x].mv; +#ifdef DEBUG + ASSERT(0 == (ctx->sMoveStack.mvf[x].bvFlags & + MVF_MOVE_SEARCHED)); + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; +#endif + mv.bvFlags |= WouldGiveCheck(ctx, mv); + + // Note: x is the index of the NEXT move to be + // considered, this move's index is (x-1). + x++; + break; + } + // else fall through + + default: + goto no_more_moves; + } + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(pos, mv)); + +#ifdef MP + // Can we search the remaining moves in parallel? + ASSERT((uDepth / ONE_PLY - 1) >= 0); + ASSERT((uDepth / ONE_PLY - 1) < MAX_PLY_PER_SEARCH); + if (((uLegalMoves >= 2)) && + (0 != g_uNumHelpersAvailable) && + (0 == uFutilityMargin) && + (TRUE == g_fCanSplit[uDepth / ONE_PLY - 1]) && + (MOVE_COUNT(ctx, ctx->uPly) > 3)) + { + ASSERT(pf->fAvoidNullmove == FALSE); + ASSERT(uStage == TRY_GENERATED_MOVES); + ASSERT(x != 0); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + ASSERT(iBestScore <= iAlpha); + ctx->sMoveStack.mvf[x-1].bvFlags &= ~MVF_MOVE_SEARCHED; + iScore = StartParallelSearch(ctx, + &iAlpha, + iBeta, + &iBestScore, + &mvBest, + (x - 1), + iOrigExtend, + uDepth); + ASSERT(iAlpha < iBeta); + ASSERT((IS_SAME_MOVE(pi->PV[ctx->uPly], mvBest)) || + (iScore <= iAlpha) || (iScore >= iBeta)); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); +#ifdef DEBUG + VerifyPositionConsistency(pos, FALSE); +#endif + if (IS_VALID_SCORE(iScore)) + { + pi->mvBest = mvBest; + goto no_more_moves; + } + else + { + ASSERT(WE_SHOULD_STOP_SEARCHING); + iBestScore = iScore; + goto end; + } + ASSERT(FALSE); + } +#endif + + if (TRUE == MakeMove(ctx, mv)) + { + uLegalMoves++; + ASSERT((IS_CHECKING_MOVE(mv) && InCheck(pos, pos->uToMove)) || + (!IS_CHECKING_MOVE(mv) && !InCheck(pos, pos->uToMove))); + + // Compute per-move extension (as opposed to per-position + // extensions which are represented by iOrigExtend). + iExtend = iOrigExtend; + ComputeMoveExtension(ctx, + iAlpha, + iBeta, + (x - 1), // Note: x==0 if doing mvHash + iRoughEval, + uDepth, + &iExtend); + + // Decide whether or not to do history pruning + if (TRUE == WeShouldDoHistoryPruning(iRoughEval, + iAlpha, + iBeta, + ctx, + uDepth, + uLegalMoves, + mv, + (x - 1), // Note: x==0 if hash + iExtend)) + { + ASSERT(iExtend == 0); + iExtend = -ONE_PLY; + pi->iExtensionAmount = -ONE_PLY; + } + + // Maybe even "futility prune" this move away. + if ((x != 0) && + (uLegalMoves > 1) && + (uFutilityMargin) && + (ComputeMoveScore(ctx, mv, (x - 1)) < uFutilityMargin) && + (iExtend <= 0) && + (!IS_ESCAPING_CHECK(mv))) + { + // TODO: test this more carefully + ASSERT(!IS_CHECKING_MOVE(mv)); + UnmakeMove(ctx, mv); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + } + else + { + // Compute the next search depth for this move/subtree. + uNextDepth = uDepth - ONE_PLY + iExtend; + if (uNextDepth >= MAX_DEPTH_PER_SEARCH) uNextDepth = 0; + ASSERT(pf->fAvoidNullmove == FALSE); + if (iBestScore == -INFINITY) + { + // First move, full a..b window. + ASSERT(uLegalMoves == 1); + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + else + { + // Moves 2..N, try a minimal window search + iScore = -Search(ctx, -iAlpha - 1, -iAlpha, uNextDepth); + if ((iAlpha < iScore) && (iScore < iBeta)) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + } + + // Research deeper if history pruning failed + if ((iExtend < 0) && (iScore >= iBeta)) + { + uNextDepth += ONE_PLY; + pi->iExtensionAmount = 0; + iScore = -Search(ctx, -iBeta, -iAlpha, uNextDepth); + } + UnmakeMove(ctx, mv); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + if (WE_SHOULD_STOP_SEARCHING) + { + iBestScore = iScore; + goto end; + } + + // Check results + ASSERT(iBestScore <= iAlpha); + ASSERT(iAlpha < iBeta); + if (iScore > iBestScore) + { + iBestScore = iScore; + mvBest = mv; + pi->mvBest = mv; + + if (iScore > iAlpha) + { + if (iScore >= iBeta) + { + // Update history and killers list and store in + // the transposition table. + UpdateDynamicMoveOrdering(ctx, + uDepth, + mv, + iScore, + x); + StoreLowerBound(mv, pos, iScore, uDepth, fThreat); + KEEP_TRACK_OF_FIRST_MOVE_FHs(uLegalMoves == 1); + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + goto end; + } + else + { + // PV move... + UpdatePV(ctx, mv); + iAlpha = iScore; + } + } + } + } + } + } + while(1); // foreach move + + no_more_moves: + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + + // Detect checkmates and stalemates + if (0 == uLegalMoves) + { + if (pi->fInCheck) + { + ASSERT(IS_CHECKING_MOVE(mvLast)); + ASSERT(InCheck(pos, pos->uToMove)); + iBestScore = MATED_SCORE(ctx->uPly); + ASSERT(iBestScore <= -NMATE); + goto end; + } + else + { + iBestScore = 0; + if ((iAlpha < iBestScore) && (iBestScore < iBeta)) + { + UpdatePV(ctx, DRAWMOVE); + } + goto end; + } + } + + // Not checkmate/stalemate; store the result of this search in the + // hash table. + if (iAlpha != iInitialAlpha) + { + ASSERT(mvBest.uMove != 0); + if (!IS_CAPTURE_OR_PROMOTION(mvBest)) + { + UpdateDynamicMoveOrdering(ctx, + uDepth, + mvBest, + iBestScore, + 0); + } + StoreExactScore(mvBest, pos, iBestScore, uDepth, fThreat, ctx->uPly); + } + else + { + // IDEA: "I am very well aware of the fact, that the scores + // you get back outside of the window, are not trustable at + // all. Still, I have mentioned the case, of all scores being + // losing mate scores, but one is not. This move will be good + // to try first. I have seen this, by investigating multi MB + // large tree dumps, so it is not only there in theory. Often, + // even with fail soft, I of course will also get multiple + // moves with the same score (alpha). But then one can see the + // "best" move as an additional killer move. It was most + // probably the killer move anyway, when this position was + // visited the last time. I cannot see a reason, why trying + // such a move early could hurt. And I do see reductions of + // tree sizes. I don't try upper-bound moves first. I try them + // (more or less) after the good captures, and together with + // the killer moves, but before history moves." + // --Ed Schroder + StoreUpperBound(pos, iBestScore, uDepth, fThreat); + } + + end: + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBestScore) || WE_SHOULD_STOP_SEARCHING); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + DTLeaveNode(ctx, FALSE, iBestScore, mvBest); + return(iBestScore); +} + + +/** + +Routine description: + + This routine is called by QSearch, the select part of the + recursive search code. Its job is to determine if a move + generated is worth searching. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : searcher context + ULONG uMoveNum : the move number we are considering + SCORE iFutility : the futility line + +Return value: + + FLAG : TRUE if the move is worth considering, + FALSE if it can be skipped + +**/ +static FLAG INLINE +_ShouldWeConsiderThisMove(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uMoveNum, + IN SCORE iFutility, + IN FLAG fGeneratedChecks) +{ + MOVE mvLast = ctx->sPlyInfo[ctx->uPly - 1].mv; + MOVE mv = ctx->sMoveStack.mvf[uMoveNum].mv; + ULONG uColor; + SCORE i; + + ASSERT(!IS_CHECKING_MOVE(mvLast)); + ASSERT(!InCheck(&(ctx->sPosition), ctx->sPosition.uToMove)); + + if (IS_CAPTURE_OR_PROMOTION(mv)) + { + // IDEA: if mvLast was a promotion, try everything here? + + // Don't consider promotions to anything but queens unless + // it's a knight and we are going for a knockout. + if ((mv.pPromoted) && (!IS_QUEEN(mv.pPromoted))) + { + if (!IS_KNIGHT(mv.pPromoted) || + !IS_CHECKING_MOVE(mv) || + (FALSE == fGeneratedChecks)) + { + return(FALSE); + } + } + + i = ctx->sMoveStack.mvf[uMoveNum].iValue; + if (i >= SORT_THESE_FIRST) + { + i &= STRIP_OFF_FLAGS; + ASSERT(i >= 0); + if (mv.pCaptured) + { + // If there are very few pieces left on the board, + // consider all captures because we could be, for + // example, taking the guy's last pawn and forcing a + // draw. Even though the cap looks futile the draw + // might save the game... + uColor = GET_COLOR(mv.pCaptured); + ASSERT(OPPOSITE_COLORS(ctx->sPosition.uToMove, uColor)); + if ((IS_PAWN(mv.pCaptured) && + ctx->sPosition.uPawnCount[uColor] == 1) || + (!IS_PAWN(mv.pCaptured) && + ctx->sPosition.uNonPawnCount[uColor][0] == 2)) + { + return(TRUE); + } + + // Also always consider "dangerous pawn" captures. + if (IS_PAWN(mv.pMoved) && + (((GET_COLOR(mv.pMoved) == WHITE) && RANK7(mv.cTo)) || + ((GET_COLOR(mv.pMoved) == BLACK) && RANK2(mv.cTo)))) + { + return(TRUE); + } + + // Don't trust the SEE alone for alpha pruning decisions. + i = MAXU(i, PIECE_VALUE(mv.pCaptured)); + + // Also try hard not to prune recaps, the bad trade + // penalty can make them look "futile" sometimes. + if ((PIECE_VALUE(mv.pCaptured) == + PIECE_VALUE(mvLast.pCaptured)) && + (i + 200 > iFutility)) + { + return(TRUE); + } + } + + // Otherwise, even if a move is even/winning, make sure it + // brings the score up to at least somewhere near alpha. + if (i > iFutility) + { + return(TRUE); + } + } + + // If we get here the move was either a losing capture/prom + // that checked or a "futile" winning capture/prom that may or + // may not check. Be more willing to play checking captures + // even if they look bad. + if (IS_CHECKING_MOVE(mv) && (TRUE == fGeneratedChecks)) + { + return(iFutility < +VALUE_ROOK); + } + } + else + { + // If we get here we have a checking move that does not + // capture anything or promote anything. We are interested in + // these to some depth. + ASSERT(IS_CHECKING_MOVE(mv)); + ASSERT(TRUE == fGeneratedChecks); + + // IDEA: don't play obviously losing checks if we are already + // way below alpha. + if (iFutility < +VALUE_BISHOP) + { + return(TRUE); + } + return(SEE(&ctx->sPosition, mv) >= 0); + } + return(FALSE); +} + + +/** + +Routine description: + + Side to move is in check and may or may not have had a chance to + stand pat at a qnode above this point. Search all legal check + evasions and return a mate-in-n score if this is checkmate. + Possibly extend the depth to which we generate checks under this + node. If there's a stand pat qnode above us the mate-in-n will be + weeded out. + +Parameters: + + IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta + +Return value: + + SCORE + +**/ +SCORE +QSearchFromCheckNoStandPat(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta) +{ + POSITION *pos = &ctx->sPosition; + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + ULONG x, uMoveCount; + SCORE iBestScore = MATED_SCORE(ctx->uPly); + SCORE iScore; + MOVE mv; + ULONG uLegalMoves = 0; + ULONG uQsearchCheckExtension = 0; + + ASSERT(InCheck(pos, pos->uToMove)); + GenerateMoves(ctx, NULLMOVE, GENERATE_ESCAPES); + uMoveCount = MOVE_COUNT(ctx, ctx->uPly); + if (uMoveCount > 0) + { + // Consider extending the number of qsearch plies we consider + // non-capture checks at during this line. + if ((pf->fCouldStandPat[pos->uToMove] == FALSE) && + (pf->uQsearchDepth < g_uIterateDepth / 2) && + (CountKingSafetyDefects(pos, pos->uToMove) > 1)) + { + if (uMoveCount == 1) { + uQsearchCheckExtension = 2; + INC(ctx->sCounters.extension.uQExtend); + } else if ((uMoveCount == 2) || + (NUM_KING_MOVES(ctx, ctx->uPly) == 0) || + (NUM_CHECKING_PIECES(ctx, ctx->uPly) > 1)) { + uQsearchCheckExtension = 1; + INC(ctx->sCounters.extension.uQExtend); + } + ctx->sPlyInfo[ctx->uPly].iExtensionAmount = uQsearchCheckExtension; + } + } + + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectBestNoHistory(ctx, x); + mv = ctx->sMoveStack.mvf[x].mv; + mv.bvFlags |= WouldGiveCheck(ctx, mv); +#ifdef DEBUG + ASSERT(0 == (ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED)); + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; +#endif + + // Note: no selectivity at in-check nodes; search every reply. + // IDEA: prune if the side in check could have stood pat before. + if (MakeMove(ctx, mv)) + { + uLegalMoves++; + pf->uQsearchNodes++; + pf->uQsearchDepth++; + ASSERT(uQsearchCheckExtension < 3); + pf->uQsearchCheckDepth += uQsearchCheckExtension; + ASSERT(pf->uQsearchDepth > 0); + iScore = -QSearch(ctx, + -iBeta, + -iAlpha); + pf->uQsearchCheckDepth -= uQsearchCheckExtension; + pf->uQsearchDepth--; + UnmakeMove(ctx, mv); + if (WE_SHOULD_STOP_SEARCHING) + { + iBestScore = iScore; + goto end; + } + + if (iScore > iBestScore) + { + iBestScore = iScore; + ctx->sPlyInfo[ctx->uPly].mvBest = mv; + if (iScore > iAlpha) + { + if (iScore >= iBeta) + { + KEEP_TRACK_OF_FIRST_MOVE_FHs(uLegalMoves == 1); + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + goto end; + } + else + { + UpdatePV(ctx, mv); + StoreExactScore(mv, pos, iScore, 0, FALSE, ctx->uPly); + iAlpha = iScore; + } + } + } + } + } + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + + end: + ASSERT((uLegalMoves > 0) || (iBestScore <= -NMATE)); + ASSERT(IS_VALID_SCORE(iBestScore) || WE_SHOULD_STOP_SEARCHING); + return(iBestScore); +} + + + +/** + +Routine description: + + The QSearch (Quiescence Search) is a selective search called when + there is no remaining depth in Search. Its job is to search only + moves that stabilize the position -- once it is quiescence (quiet) + we will run a static evaluation on it and return the score. + + This branch of the QSearch is called when the side to move is in + danger somehow -- either he has two pieces en prise on the board + or some piece that seems trapped. We do not allow him an + opportunity to stand pat in this position. + +Parameters: + + IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta + IN SCORE iEval + +Return value: + + SCORE + +**/ +SCORE +QSearchInDangerNoStandPat(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta) +{ + POSITION *pos = &ctx->sPosition; + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + ULONG x; + FLAG fIncludeChecks; + SCORE iBestScore = iAlpha; + SCORE iScore; + SCORE iFutility; + SCORE iEval = GetRoughEvalScore(ctx, iAlpha, iBeta, TRUE); + MOVE mv; + ULONG uLegalMoves = 0; + static ULONG _WhatToGen[] = + { + GENERATE_CAPTURES_PROMS, + GENERATE_CAPTURES_PROMS_CHECKS + }; + + + // Set futility: + // + // iEval + move_value + margin < alpha + // move_value < alpha - margin - iEval + iFutility = 0; + if (iAlpha < +NMATE) + { + iFutility = (iAlpha - + (FUTILITY_BASE_MARGIN + ctx->uPositional) - + iEval); + iFutility = MAX0(iFutility); + } + + // We suspect that the guy on move is in sad shape if we're + // here... he has more than one piece en prise or he seems to + // have a piece trapped. Allow him to play checks in order to try + // to save the situation. + ASSERT(!InCheck(pos, pos->uToMove)); + fIncludeChecks = (pf->uQsearchDepth < g_uIterateDepth / 3); + GenerateMoves(ctx, NULLMOVE, _WhatToGen[fIncludeChecks]); + + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectBestNoHistory(ctx, x); + mv = ctx->sMoveStack.mvf[x].mv; +#ifdef DEBUG + ASSERT(0 == (ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED)); + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; +#endif + + // Prune except when pruning all moves could cause us to return + // -INFINITY (mated) erroneously. + if (iAlpha > -INFINITY) + { + if (ctx->sMoveStack.mvf[x].iValue <= 0) + { + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE | VERIFY_AFTER)); + goto end; + } + if (FALSE == _ShouldWeConsiderThisMove(ctx, + x, + iFutility, + TRUE)) + { + continue; + } + } + + if (FALSE == fIncludeChecks) + { + mv.bvFlags |= WouldGiveCheck(ctx, mv); + } + + if (MakeMove(ctx, mv)) + { + uLegalMoves++; + pf->uQsearchNodes++; + pf->uQsearchDepth++; + iScore = -QSearch(ctx, + -iBeta, + -iAlpha); + pf->uQsearchDepth--; + UnmakeMove(ctx, mv); + + if (iScore > iBestScore) + { + iBestScore = iScore; + ctx->sPlyInfo[ctx->uPly].mvBest = mv; + if (iScore > iAlpha) + { + if (iScore >= iBeta) + { + KEEP_TRACK_OF_FIRST_MOVE_FHs(uLegalMoves == 1); + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + goto end; + } + else + { + UpdatePV(ctx, mv); + StoreExactScore(mv, pos, iScore, 0, FALSE, ctx->uPly); + iAlpha = iScore; + } + } + } + if (WE_SHOULD_STOP_SEARCHING) goto end; + } + } + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + + end: + // If iAlpha is -INFINITY and side on move has no captures, + // promotes or checks then we must make up a "stand pat" score + // here. We don't want to let him stand pat with iEval because + // the board looks dangerous. But we likewise don't want to say + // "mated" because he's not. + ASSERT((uLegalMoves > 0) || (iBestScore == iAlpha)); + if (iBestScore == -INFINITY) + { + ASSERT(iAlpha == -INFINITY); + iBestScore = iEval - VALUE_QUEEN; + } + ASSERT(IS_VALID_SCORE(iBestScore) || WE_SHOULD_STOP_SEARCHING); + return(iBestScore); +} + + +/** + +Routine description: + + The QSearch (Quiescence Search) is a selective search called when + there is no remaining depth in Search. Its job is to search only + moves that stabilize the position -- once it is quiescence (quiet) + we will run a static evaluation on it and return the score. + + TODO: experiment with probing and storing in the hash table here. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : the searcher context + SCORE iAlpha : lowerbound of search window + SCORE iBeta : upperbound of search window + +Return value: + + SCORE : a score + +**/ +SCORE FASTCALL +QSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta) +{ + POSITION *pos = &ctx->sPosition; + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + MOVE mvLast = (pi-1)->mv; + MOVE mv; + SCORE iBestScore; + SCORE iScore; + SCORE iEval; + SCORE iFutility; + ULONG x; + ULONG uLegalMoves; + FLAG fIncludeChecks; + FLAG fOrigStandPat = ctx->sSearchFlags.fCouldStandPat[pos->uToMove]; + static ULONG _WhatToGen[] = + { + GENERATE_CAPTURES_PROMS, + GENERATE_CAPTURES_PROMS_CHECKS + }; + +#ifdef DEBUG + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(ctx->uPly > 0); + ASSERT(TRUE == pi->fInQsearch); + memcpy(&pi->sPosition, pos, sizeof(POSITION)); +#endif + + INC(ctx->sCounters.tree.u64QNodeCount); + pi->iExtensionAmount = 0; + if (TRUE == CommonSearchInit(ctx, + &iAlpha, + &iBeta, + &iBestScore)) + { + goto end; + } + DTEnterNode(ctx, 0, TRUE, iAlpha, iBeta); + + // Probe interior node recognizers; do not allow probes into ondisk + // EGTB files since we are in qsearch. + switch(RecognLookup(ctx, &iScore, FALSE)) + { + case UNRECOGNIZED: + break; + case RECOGN_EXACT: + case RECOGN_EGTB: + if ((iAlpha < iScore) && (iScore < iBeta)) + { + UpdatePV(ctx, RECOGNMOVE); + } + iBestScore = iScore; + goto end; + case RECOGN_LOWER: + if (iScore >= iBeta) + { + iBestScore = iScore; + goto end; + } + break; + case RECOGN_UPPER: + if (iScore <= iAlpha) + { + iBestScore = iScore; + goto end; + } + break; +#ifdef DEBUG + default: + ASSERT(FALSE); +#endif + } + + // If the side is in check, don't let him stand pat. Search every + // reply to check and return a MATE score if applicable. If the + // side had a chance to stand pat above then the MATE score will + // be disregarded there since it's not forced. + if (IS_CHECKING_MOVE(mvLast)) + { + ASSERT(InCheck(pos, pos->uToMove)); + iBestScore = QSearchFromCheckNoStandPat(ctx, iAlpha, iBeta); + goto end; + } + ASSERT(!InCheck(pos, pos->uToMove)); + + // Even if the side is not in check, do not let him stand pat if + // his position looks dangerous (i.e. more than one piece en prise + // or a piece trapped). Fail low if there's nothing that looks + // good on this line. + if (SideCanStandPat(pos, pos->uToMove) == FALSE) + { + iBestScore = QSearchInDangerNoStandPat(ctx, iAlpha, iBeta); + goto end; + } + + // If we get here then side on move is not in check and this + // position looks ok enough to allow him the option to stand pat + // -or- we missed when we probed the dangerhash. Also remember + // that this side has had the option to stand pat when searching + // below this point. + uLegalMoves = 0; + iEval = iBestScore = Eval(ctx, iAlpha, iBeta); + if (iBestScore > iAlpha) + { + iAlpha = iBestScore; + ASSERT(ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly].uMove == 0); + ASSERT(pi->mvBest.uMove == 0); + if (iBestScore >= iBeta) + { + goto end; + } + } + ctx->sSearchFlags.fCouldStandPat[pos->uToMove] = TRUE; + + // He did not choose to stand pat here; we will be generating + // moves and searching recursively. Compute a futility score: + // any move less than this will not be searched because it will + // just cause a lazy eval answer; is has no shot to bring the + // score close enough to alpha to even consider. + // + // iEval + move_value + margin < alpha + // move_value < alpha - margin - iEval + iFutility = 0; + if (iAlpha < +NMATE) + { + iFutility = iAlpha - (FUTILITY_BASE_MARGIN + ctx->uPositional) - iEval; + iFutility = MAX0(iFutility); + } + + // We know we are not in check. Generate moves (including checks + // if we are below the threshold and the other side has never been + // allowed to stand pat). Recurse. + fIncludeChecks = ((pf->uQsearchDepth < pf->uQsearchCheckDepth) && + (pf->fCouldStandPat[FLIP(pos->uToMove)] == FALSE) && + (pos->uNonPawnMaterial[pos->uToMove] > + (VALUE_KING + VALUE_BISHOP))); + GenerateMoves(ctx, NULLMOVE, _WhatToGen[fIncludeChecks]); + for (x = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectBestNoHistory(ctx, x); + if (ctx->sMoveStack.mvf[x].iValue <= 0) + { + // We are only intersted in winning/even captures/promotions + // and (if fIncludeChecks is TRUE) some checking moves too. + // If we see a move whose value is zero, the rest of the moves + // in this ply can be tossed. + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE | VERIFY_AFTER)); + ASSERT(iBestScore > -NMATE); + goto end; + } + mv = ctx->sMoveStack.mvf[x].mv; +#ifdef DEBUG + ASSERT(0 == (ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED)); + ctx->sMoveStack.mvf[x].bvFlags |= MVF_MOVE_SEARCHED; +#endif + + if (FALSE == _ShouldWeConsiderThisMove(ctx, + x, + iFutility, + fIncludeChecks)) + { + continue; + } + + // If fIncludeChecks is FALSE then we still need to see if + // this move is going to check the opponent; GenerateMoves + // didn't do it for us to save time in the event of a fail + // high. + if (FALSE == fIncludeChecks) + { + mv.bvFlags |= WouldGiveCheck(ctx, mv); + } + + if (MakeMove(ctx, mv)) + { + uLegalMoves++; + pf->uQsearchNodes++; + pf->uQsearchDepth++; + ASSERT(pf->uQsearchDepth > 0); + iScore = -QSearch(ctx, + -iBeta, + -iAlpha); + pf->uQsearchDepth--; + UnmakeMove(ctx, mv); + + if (iScore > iBestScore) + { + iBestScore = iScore; + pi->mvBest = mv; + + if (iScore > iAlpha) + { + if (iScore >= iBeta) + { + KEEP_TRACK_OF_FIRST_MOVE_FHs(uLegalMoves == 1); + ASSERT(iBestScore > -NMATE); + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + goto end; + } + else + { + UpdatePV(ctx, mv); + StoreExactScore(mv, pos, iScore, 0, FALSE, ctx->uPly); + iAlpha = iScore; + + // Readjust futility margin here; it can be wider now. + if (iAlpha < +NMATE) + { + iFutility = (iAlpha - + (FUTILITY_BASE_MARGIN + + ctx->uPositional) - + iEval); + iFutility = MAX0(iFutility); + } + } + } + } + if (WE_SHOULD_STOP_SEARCHING) goto end; + } + } + ASSERT(iBestScore > -NMATE); + ASSERT(SanityCheckMoves(ctx, x, VERIFY_BEFORE)); + + end: + ctx->sSearchFlags.fCouldStandPat[pos->uToMove] = fOrigStandPat; + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + ASSERT(IS_VALID_SCORE(iBestScore) || WE_SHOULD_STOP_SEARCHING); + DTLeaveNode(ctx, TRUE, iBestScore, pi->mvBest); + return(iBestScore); +} diff --git a/src/searchsup.c b/src/searchsup.c new file mode 100644 index 0000000..9e842d4 --- /dev/null +++ b/src/searchsup.c @@ -0,0 +1,1182 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + searchsup.c + +Abstract: + + Search support routines. See also search.c, root.c, and split.c. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 06 Oct 2005 + +Revision History: + +**/ + +#include "chess.h" + +extern SCORE g_iRootScore[2]; +extern ULONG g_uHardExtendLimit; +extern ULONG g_uIterateDepth; + +void +UpdatePV(SEARCHER_THREAD_CONTEXT *ctx, MOVE mv) +/** + +Routine description: + + Update the principle variation at this depth. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + MOVE mv + +Return value: + + void + +**/ +{ + PLY_INFO *this = &(ctx->sPlyInfo[ctx->uPly]); + PLY_INFO *next = (this + 1); + ULONG u = ctx->uPly; + + ASSERT(u < MAX_PLY_PER_SEARCH); + this->PV[u] = mv; + u++; + while(u < MAX_PLY_PER_SEARCH) + { + this->PV[u] = next->PV[u]; + if (0 == this->PV[u].uMove) + { + break; + } + u++; + } +} + + +FLAG +CheckInputAndTimers(IN SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + This code is called from search when the total number of nodes + searched is a multiple of g_MoveTimer.uNodeCheckMask. Its job is + to check for user input waiting on the input queue and to check to + see if we are over a time limit. + +Parameters: + + void + +Return value: + + static FLAG : TRUE if the search should terminate and unroll, + FALSE if the search can continue + +**/ +{ + double dTimeStamp; + + // + // See if there's user input to process. + // + if ((ctx->uThreadNumber == 0) && (NumberOfPendingInputEvents() != 0)) + { + ParseUserInput(TRUE); + + // + // If the user input can be handled in the middle of the + // search then it will have been. If it cannot be handled + // without stopping the search then ParseUserInput will flip + // this bit in the MoveTimer to tell us (any any other + // searcher threads) to stop and unroll. + // + if (WE_SHOULD_STOP_SEARCHING) + { + return(TRUE); + } + } + + // + // Also check time limits now. + // + if (-1 != g_MoveTimer.dSoftTimeLimit) + { + dTimeStamp = SystemTimeStamp(); + if ((g_MoveTimer.bvFlags & TIMER_CURRENT_OBVIOUS) || + (g_MoveTimer.bvFlags & TIMER_CURRENT_WONT_UNBLOCK)) + { + Trace("OBVIOUS MOVE / WON'T UNBLOCK --> stop searching now\n"); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + return(TRUE); + } + + if (dTimeStamp > g_MoveTimer.dSoftTimeLimit) + { + // + // If we have exceeded the soft time limit, move now unless... + // + if ((!(g_MoveTimer.bvFlags & TIMER_JUST_OUT_OF_BOOK)) && + (!(g_MoveTimer.bvFlags & TIMER_ROOT_POSITION_CRITICAL)) && + (!(g_MoveTimer.bvFlags & TIMER_RESOLVING_ROOT_FL)) && + (!(g_MoveTimer.bvFlags & TIMER_RESOLVING_ROOT_FH)) && + (!(g_MoveTimer.bvFlags & TIMER_MANY_ROOT_FLS)) && + (g_MoveTimer.bvFlags & TIMER_SEARCHING_FIRST_MOVE)) + { + Trace("SOFT TIMER (%3.1f sec) --> " + "stop searching now\n", + dTimeStamp - g_MoveTimer.dStartTime); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + return(TRUE); + } + } + + // + // If we have exceeded the hard limit, we have to move no matter + // what. + // + if (dTimeStamp > g_MoveTimer.dHardTimeLimit) + { + Trace("HARD TIMER (%3.1f sec) --> " + "stop searching now\n", + dTimeStamp - g_MoveTimer.dStartTime); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + return(TRUE); + } + } + + // + // Also check raw node count limit here. + // + if (g_Options.u64MaxNodeCount != 0ULL && + ctx->sCounters.tree.u64TotalNodeCount > g_Options.u64MaxNodeCount) + { + Trace("NODE COUNT LIMIT (limit %llu, searched %llu) " + "--> stop searching now\n", g_Options.u64MaxNodeCount, + ctx->sCounters.tree.u64TotalNodeCount); + g_MoveTimer.bvFlags |= TIMER_STOPPING; + return(TRUE); + } + return(FALSE); +} + + +FLAG +ThreadUnderTerminatingSplit(IN SEARCHER_THREAD_CONTEXT *ctx) +{ + ULONG u; + + for (u = 0; u < NUM_SPLIT_PTRS_IN_CONTEXT; u++) + { + if (ctx->pSplitInfo[u] != NULL) + { + if (ctx->pSplitInfo[u]->fTerminate == TRUE) return(TRUE); + return(FALSE); + } + } + return(FALSE); +} + + +FLAG +WeShouldDoHistoryPruning(IN SCORE iRoughEval, + IN SCORE iAlpha, + IN SCORE iBeta, + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uRemainingDepth, + IN ULONG uLegalMoves, + IN MOVE mv, + IN ULONG uMoveNum, + IN INT iExtend) +/** + +Routine description: + + Decide whether or not to do history pruning at this node for the + given move. Note: this function is called after the move has + been played on the board. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG uRemainingDepth, + ULONG uLegalMoves, + MOVE mv, + INT iExtend + +Return value: + + FLAG + +**/ +{ + ASSERT(ctx->uPly > 0); + ASSERT(mv.uMove); + ASSERT((uMoveNum > 0) || (uLegalMoves == 0)); + if ((uRemainingDepth >= TWO_PLY) && + (iBeta == (iAlpha + 1)) && + (uLegalMoves > 5) && + (0 == iExtend) && +// (iRoughEval + ComputeMoveScore(ctx, mv, uMoveNum - 1) + 200 < iAlpha) && + (!IS_ESCAPING_CHECK(mv)) && + (!IS_CAPTURE_OR_PROMOTION(mv)) && + (!IS_CHECKING_MOVE(mv)) && + (!IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-1][0])) && + (!IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-1][1])) && + ((ctx->uPly < 3) || + (!IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-3][0]) && + !IS_SAME_MOVE(mv, ctx->mvKiller[ctx->uPly-3][1]))) && + (GetMoveFailHighPercentage(mv) <= 10)) + { + ASSERT(!InCheck(&ctx->sPosition, ctx->sPosition.uToMove)); + return(TRUE); + } + return(FALSE); +} + + +SCORE +ComputeMoveScore(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv, + IN ULONG uMoveNum) +{ + SCORE iMoveScore = (PIECE_VALUE(mv.pCaptured) + + PIECE_VALUE(mv.pPromoted)); + if (uMoveNum != (ULONG)-1) + { + ASSERT(uMoveNum < MAX_MOVE_STACK); + ASSERT(IS_SAME_MOVE(mv, ctx->sMoveStack.mvf[uMoveNum].mv)); + iMoveScore = ctx->sMoveStack.mvf[uMoveNum].iValue; + if (iMoveScore >= SORT_THESE_FIRST) + { + ASSERT(iMoveScore > 0); + iMoveScore &= STRIP_OFF_FLAGS; + } + else + { + iMoveScore = MIN0(iMoveScore); + } + } + return(iMoveScore); +} + + +void +ComputeMoveExtension(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta, + IN ULONG uMoveNum, + IN SCORE iRoughEval, + IN ULONG uDepth, + IN OUT INT *piExtend) +/** + +Routine description: + + This routine is called by Search and by HelpSearch (in split.c). + It's job is to assign a move-based extension for the move mv. + This extension should be between -ONE_PLY (reduction) and +ONE_PLY + (extension). + + Note: this code is executed after the move has already been played + on the board! + +Parameters: + + IN SEARCHER_THREAD_CONTEXT *ctx : the searcher thread's context + IN SCORE iAlpha : current alpha + IN SCORE iBeta : current beta + IN ULONG uMoveNum : move number in stack + IN ULONG uDepth : remaining depth + IN OUT INT *piExtend : extension amount (in/out) + +Return value: + + void + +**/ +{ + static const SCORE _window[MAX_PLY_PER_SEARCH] = { + -1, -1, 500, 500, 425, 425, 350, 350, 275, 275, 200, 200, // 0..11 + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, // 12..23 + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, // 24..35 + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, // 36..47 + 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, 150, // 48..59 + 150, 150, 150, 150 // 60..63 + }; + POSITION *pos = &ctx->sPosition; + MOVE mvLast = ctx->sPlyInfo[ctx->uPly-2].mv; + MOVE mv = ctx->sPlyInfo[ctx->uPly-1].mv; + ULONG uColor = GET_COLOR(mv.pMoved); + SCORE iMoveScore; +#ifdef DEBUG + int iM; + + // + // Preconditions + // + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(ctx->uPly >= 2); + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + ASSERT(mv.uMove); + ASSERT(*piExtend >= 0); +#endif + + // Checking move extension. + if (IS_CHECKING_MOVE(mv)) + { + ASSERT(InCheck(pos, pos->uToMove)); + INC(ctx->sCounters.extension.uCheck); + *piExtend += ONE_PLY; + if (pos->uNonPawnMaterial[FLIP(pos->uToMove)] > + (VALUE_KING + VALUE_BISHOP)) + { + goto enforce_ceiling; + } + *piExtend -= THREE_QUARTERS_PLY; + } + + // Pawn push extension + if (IS_PAWN(mv.pMoved)) + { + if (((GET_COLOR(mv.pMoved) == WHITE) && RANK7(mv.cTo)) || + ((GET_COLOR(mv.pMoved) == BLACK) && RANK2(mv.cTo))) + { + *piExtend += THREE_QUARTERS_PLY; + if (DISTANCE(pos->cNonPawns[GET_COLOR(mv.pMoved)][0], mv.cTo) < 3) + { + *piExtend += QUARTER_PLY; + } + INC(ctx->sCounters.extension.uPawnPush); + goto enforce_ceiling; + } + } + + // Responses to check extensions: + if (IS_CHECKING_MOVE(mvLast)) + { + ASSERT(IS_ESCAPING_CHECK(mv)); + iMoveScore = iRoughEval + ComputeMoveScore(ctx, mv, uMoveNum); + + // One legal move in reply to check... + if (ONE_LEGAL_MOVE(ctx, ctx->uPly - 1) && + CountKingSafetyDefects(&ctx->sPosition, uColor) > 1) + { + *piExtend += (QUARTER_PLY + + HALF_PLY * + (iMoveScore + VALUE_KNIGHT > iAlpha)); + INC(ctx->sCounters.extension.uOneLegalMove); + } + + // Singular response to check... + if ((mv.pCaptured) && + (iRoughEval + 225 < iAlpha) && + (iMoveScore + 75 > iAlpha)) + { + *piExtend += ONE_PLY; + INC(ctx->sCounters.extension.uSingularReplyToCheck); + goto enforce_ceiling; + } + } + + // These last ones only happen if we are close to the root score. + ASSERT(_window[ctx->uPly] > 0); + if ((iRoughEval >= (g_iRootScore[uColor] - _window[ctx->uPly] * 2)) && + (iRoughEval <= (g_iRootScore[uColor] + _window[ctx->uPly] * 2))) + { + // Endgame extension + if ((ctx->sPlyInfo[1].uTotalNonPawns > 2) && + ((pos->uNonPawnCount[BLACK][0] + + pos->uNonPawnCount[WHITE][0]) == 2)) + { + if ((mv.pCaptured && !IS_PAWN(mv.pCaptured)) || + (mvLast.pCaptured && !IS_PAWN(mvLast.pCaptured))) + { + *piExtend += HALF_PLY; + INC(ctx->sCounters.extension.uEndgame); + } + } + + // Recapture extension + if ((iRoughEval >= (g_iRootScore[uColor] - _window[ctx->uPly])) && + (iRoughEval <= (g_iRootScore[uColor] + _window[ctx->uPly]))) + { + if (uDepth <= THREE_PLY) + { + if ((mv.pCaptured) && !IS_PAWN(mv.pCaptured) && + ((PIECE_VALUE(mv.pCaptured) == + PIECE_VALUE(mvLast.pCaptured)) || + ((mvLast.pPromoted) && (mv.cTo == mvLast.cTo)))) + { + iMoveScore = ComputeMoveScore(ctx, mv, uMoveNum); + if (iMoveScore >= 0) + { + *piExtend += HALF_PLY; + INC(ctx->sCounters.extension.uRecapture); + } + } + } + } + } + + enforce_ceiling: + + // Don't let extensions add up to > 1 ply +#ifdef DEBUG + iM = MIN(ONE_PLY, *piExtend); +#endif + ASSERT(!(*piExtend & 0x80000000)); + *piExtend = MINU(ONE_PLY, *piExtend); + ASSERT(iM == *piExtend); + + // Scale back extensions that are very far from the root: + // + // Iterate g_Soft g_Hard + // | | | | | | | | | + // 0 1 2 3/2 3 4 (x Iterate) + // |-------------------|----|----|---------|----... + // |full full full full|-1/4|-1/2|-3/4 -3/4|none... + ASSERT(ctx->uPly != 0); + ASSERT(ctx->uPly <= MAX_PLY_PER_SEARCH); + *piExtend -= g_uExtensionReduction[ctx->uPly-1]; +#ifdef DEBUG + iM = MAX(0, *piExtend); +#endif + *piExtend = MAX0(*piExtend); + ASSERT(iM == *piExtend); + ctx->sPlyInfo[ctx->uPly-1].iExtensionAmount = *piExtend; + ASSERT((0 <= *piExtend) && (*piExtend <= ONE_PLY)); +} + + + + +#ifdef DO_IID +SCORE +RescoreMovesViaSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uDepth, + IN SCORE iAlpha, + IN SCORE iBeta) +/** + +Routine description: + + This is my implementation of "internal iterative deepening". It's + not really IID because it doesn't recurse on the same position. + This code is called when we are at a PV node and have no hash move + and no good capture from the generator. Instead of relying on + only history / killer heuristics to order the moves instead we + reduce the depth by two ply and search all the moves generated. + The scores that come out of the reduced-depth search are then used + to order the moves at the regular-depth search. This is somewhat + recursive because the first move considered by the reduced-depth + search may also have no hash move / good capture and invoke the + whole process again. + +Parameters: + + IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uDepth, + IN SCORE iAlpha, + IN SCORE iBeta + +Return value: + + SCORE + +**/ +{ + ULONG x; + MOVE mv; + SCORE iScore; + SCORE iBestScore = -INFINITY; + ULONG uBest; + + // + // Preconditions + // + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(uDepth >= (IID_R_FACTOR + ONE_PLY)); + + // + // Compute next depth, possibly recurse + // + uDepth -= (IID_R_FACTOR + ONE_PLY); + if (uDepth >= (IID_R_FACTOR + ONE_PLY)) + { + (void)RescoreMovesViaSearch(ctx, uDepth, iAlpha, iBeta); + } + ASSERT(uDepth < MAX_DEPTH_PER_SEARCH); + + // + // Search the moves and remember the scores + // + for (x = uBest = ctx->sMoveStack.uBegin[ctx->uPly]; + x < ctx->sMoveStack.uEnd[ctx->uPly]; + x++) + { + SelectBestNoHistory(ctx, x); + mv = ctx->sMoveStack.mvf[x].mv; + mv.bvFlags |= WouldGiveCheck(ctx, mv); + if (TRUE == MakeMove(ctx, mv)) + { + if (-INFINITY == iBestScore) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uDepth); + } + else + { + iScore = -Search(ctx, -iAlpha - 1, -iAlpha, uDepth); + if (iScore > iAlpha) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uDepth); + } + } + UnmakeMove(ctx, mv); + ctx->sMoveStack.mvf[x].iValue = iScore; + if (iScore > iBestScore) + { + uBest = x; + iBestScore = iScore; + if (iScore >= iBeta) + { + goto end; + } + } + } + } + + end: + // + // Clear the values from the current move to the end of the + // moves in the list so that if we failed high we don't have + // stale move values in the list for moves we did not search + // the subtrees for. + // + while(x < ctx->sMoveStack.uEnd[ctx->uPly]) + { + ctx->sMoveStack.mvf[x].iValue = -INFINITY; + x++; + } + ctx->sMoveStack.mvf[uBest].iValue |= SORT_THESE_FIRST; + ASSERT(IS_VALID_SCORE(iBestScore)); + return(iBestScore); +} +#endif + + +FLAG +MateDistancePruningCutoff(IN ULONG uPly, + IN FLAG fInCheck, + IN OUT SCORE *piBestScore, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta) +/** + +Routine description: + + This idea (shamelessly?) "borrowed" from Fruit. The idea is that + the worst score we can return from any node in the tree is if we + are in checkmate right now (indeed, if we're not in check right + now than the worst score we can return is mated-in-2-ply). + + Likewise the best score we can return from here is mate-in-1-ply. + Use these facts to attempt to narrow the alpha..beta window. + Indeed there are some cases where we can prune this entire tree + branch. + +Parameters: + + ULONG uPly : ply from root + FLAG InCheck : are we in check? + SCORE *piBestScore : pointer to bestscore + SCORE *piAlpha : pointer to alpha + SCORE *piBeta : pointer to beta + +Return value: + + FLAG : TRUE if we can prune the branch outright, FALSE otherwise + +**/ +{ + SCORE iScore = MATED_SCORE(uPly + 2 * !fInCheck); + + // + // Do the alpha side + // + if (*piAlpha < iScore) + { + *piAlpha = iScore; + if (iScore >= *piBeta) + { + *piBestScore = iScore; + return(TRUE); + } + } + + // + // Do the beta side + // + iScore = -1 * MATED_SCORE(uPly + 1); + if (iScore < *piBeta) + { + *piBeta = iScore; + if (iScore <= *piAlpha) + { + *piBestScore = iScore; + return(TRUE); + } + } + return(FALSE); +} + + +void +DumpPlyInfoStack(IN SEARCHER_THREAD_CONTEXT *ctx, + IN SCORE iAlpha, + IN SCORE iBeta) +/** + +Routine description: + + Dump some information about the current search line; mainly here as + a debugging aide. + + Note: this will not work on an MP searcher thread that is under a + split node. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : searcher context to dump + +Return value: + + void + +**/ +{ + ULONG u, v; + POSITION *pos = GetRootPosition(); + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + char *p = PositionToFen(pos); + PLY_INFO *q; + FLAG fSeenQ = FALSE; + SCORE iEval; + static SEARCHER_THREAD_CONTEXT temp; + + InitializeSearcherContext(pos, &temp); + + Trace("Iterate Depth: %2u\tCurrent Ply: %2u\n", g_uIterateDepth, + ctx->uPly); + Trace("Qsearch Check: %2u\tCurrent Qdepth: %2u\n", pf->uQsearchCheckDepth, + pf->uQsearchDepth); + Trace("Current a..b: %d .. %d\n", iAlpha, iBeta); + if (NULL != p) + { + Trace("Root: %s\n", p); + SystemFreeMemory(p); + } + Trace("\n"); + Trace("move\t number\t exten\t eval b.keval w.keval Danger Squares\n" + "----------------------------------------------------------------------------\n"); + + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + for (u = 0; u < ctx->uPly; u++) + { + q = &ctx->sPlyInfo[u]; + ASSERT(PositionsAreEquivalent(&q->sPosition, &temp.sPosition)); + + if ((FALSE == fSeenQ) && (q->fInQsearch == TRUE)) + { + p = PositionToFen(&temp.sPosition); + if (NULL != p) + { + Trace("\nHorizon: %s\n\n", p); + SystemFreeMemory(p); + } + fSeenQ = TRUE; + } + + Trace("%02u.%-6s ", u, MoveToSan(q->mv, &temp.sPosition)); + for (v = ctx->sMoveStack.uBegin[u]; + v < ctx->sMoveStack.uEnd[u]; + v++) + { + if (IS_SAME_MOVE(q->mv, ctx->sMoveStack.mvf[v].mv)) + { + Trace("%u/%u", v - ctx->sMoveStack.uBegin[u] + 1, + MOVE_COUNT(ctx, u)); + } + } + Trace("\t"); + + if (FALSE == MakeMove(&temp, q->mv)) + { + Trace("Illegal move?!\n"); + return; + } + + if (q->iExtensionAmount != 0) + { + Trace("%-3u\t", q->iExtensionAmount); + } + else + { + Trace(" \t"); + } + + iEval = Eval(&temp, -INFINITY, +INFINITY); + Trace("%5s (%+2d) | ", ScoreToString(iEval), + temp.sPosition.iMaterialBalance[temp.sPosition.uToMove] / 100); + Trace("%5s (%2u) | ", + ScoreToString(temp.sPlyInfo[temp.uPly].iKingScore[BLACK]), + CountKingSafetyDefects(&temp.sPosition, BLACK)); + Trace("%5s (%2u) ", + ScoreToString(temp.sPlyInfo[temp.uPly].iKingScore[WHITE]), + CountKingSafetyDefects(&temp.sPosition, WHITE)); + Trace("\n"); + } + + p = PositionToFen(&ctx->sPosition); + if (NULL != p) + { + Trace("\n"); + Trace("Now: %s\n", p); + SystemFreeMemory(p); + } +} + + +FLAG +CommonSearchInit(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta, + IN OUT SCORE *piScore) +/** + +Routine description: + + A set of common code that is called by Search and QSearch. It does + the following: + + 1. Increment the total node counter + 2. Clears pi->mvBest and cDanger squares + 3. Possibly check for user input or timer expiration + 4. Checks to see if the position is a draw + 5. Makes sure ctx->uPly is not too deep + 6. Sets pi->fInCheck + 7. Does mate-distance pruning + +Parameters: + + IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN OUT SCORE *piBeta, + IN OUT SCORE *piScore + +Return value: + + FLAG : TRUE if the search node should be aborted (return *piScore) + FALSE otherwise (*piAlpha, *piBeta possibly adjusted) + +**/ +{ + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + FLAG fRet = TRUE; + + ASSERT(*piAlpha < *piBeta); + + // + // Increment node count and see if we need to check input / timer + // + ctx->sCounters.tree.u64TotalNodeCount++; + ASSERT(ctx->sCounters.tree.u64TotalNodeCount > 0); + if ((ctx->sCounters.tree.u64TotalNodeCount & + g_MoveTimer.uNodeCheckMask) == 0) + { + (void)CheckInputAndTimers(ctx); + } + + // + // Make sure that the time allotted to search in has not expired + // and (if this is an MP search) that we are still doing relevant work. + // + if (WE_SHOULD_STOP_SEARCHING) + { + pi->mvBest.uMove = 0; + *piScore = INVALID_SCORE; + goto end; + } + + // + // Make sure we have not exceeded max ply; note that since this + // is checked at the beginning of search/qsearch and if we let + // the past they will call MakeMove this must cut off one ply + // before the hard limit. + // + if ((ctx->uPly >= (MAX_PLY_PER_SEARCH - 1)) || + (ctx->sSearchFlags.uQsearchDepth >= g_uHardExtendLimit)) + { + *piScore = *piBeta; + DTTRACE(""); + goto end; + } + + // + // Erase deeper killer moves + // + if (ctx->uPly + 2 < MAX_PLY_PER_SEARCH) + { + ctx->mvKiller[ctx->uPly + 2][0].uMove = 0; + ctx->mvKiller[ctx->uPly + 2][1].uMove = 0; + } + + // + // Set fInCheck in this ply info struct + // + pi->fInCheck = (IS_CHECKING_MOVE((pi-1)->mv) != 0); + ASSERT((pi->fInCheck && + (InCheck(&ctx->sPosition, ctx->sPosition.uToMove))) || + (!pi->fInCheck && + (!InCheck(&ctx->sPosition, ctx->sPosition.uToMove)))); + + // + // This code is for a debug option where I dump paths from root + // to leaf along with extensions and evals at each node in the + // path for debugging/brainstorming purposes. + // + pi->PV[ctx->uPly].uMove = 0; + pi->mvBest.uMove = 0; + pi->iExtensionAmount = 0; + pi->iEval = INVALID_SCORE; +#if 0 + if ((g_uIterateDepth > 5) && + (ctx->uPly > 2.5 * g_uIterateDepth)) + { + DumpPlyInfoStack(ctx, *piAlpha, *piBeta); + } +#endif + + // + // See if this position is a draw + // + if (TRUE == IsDraw(ctx)) + { + INC(ctx->sCounters.tree.u64LeafCount); + *piScore = 0; + if ((*piAlpha < *piScore) && (*piScore < *piBeta)) + { + UpdatePV(ctx, DRAWMOVE); + } + DTTRACE(""); + goto end; + } + + // + // Do mate-distance pruning + // + if (TRUE == MateDistancePruningCutoff(ctx->uPly, + pi->fInCheck, + piScore, + piAlpha, + piBeta)) + { + ASSERT(*piScore != -INFINITY); + ASSERT((*piScore <= *piAlpha) || (*piScore >= *piBeta)); + goto end; + } +#ifdef DEBUG + pi->iAlpha = *piAlpha; + pi->iBeta = *piBeta; +#endif + fRet = FALSE; + + end: + ASSERT(IS_VALID_FLAG(fRet)); + return(fRet); +} + + +ULONG +SelectNullmoveRFactor(SEARCHER_THREAD_CONTEXT *ctx, + INT uDepth) +{ + ULONG u = TWO_PLY; + ULONG uMaxPiecesPerSide = MAXU(ctx->sPosition.uNonPawnCount[WHITE][0], + ctx->sPosition.uNonPawnCount[BLACK][0]); + ASSERT(uMaxPiecesPerSide <= 16); + + if ((uDepth > 8 * ONE_PLY) || + ((uDepth > 6 * ONE_PLY) && (uMaxPiecesPerSide >= 3))) + { + u = THREE_PLY; + } + ASSERT((u == TWO_PLY) || (u == THREE_PLY)); + return(u); +} + + +FLAG +WeShouldTryNullmovePruning(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iRoughEval, + ULONG uNullDepth) +{ + static SCORE _iDistAlphaSkipNull[] = { + 700, 950, 1110, 1150, 1190, 1230, 1270, 0 + }; + POSITION *pos = &ctx->sPosition; + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + ULONG u; + + ASSERT(IS_VALID_SCORE(iAlpha) && IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(IS_VALID_SCORE(iRoughEval)); + ASSERT(uNullDepth < MAX_PLY_PER_SEARCH * ONE_PLY); + + if ((FALSE == pf->fAvoidNullmove) && + (pos->uNonPawnCount[pos->uToMove][0] > 2) && + (FALSE == pi->fInCheck) && + (iBeta != +INFINITY) && + (iBeta == iAlpha + 1)) // <--- TODO: test this one please... + { + if (uNullDepth <= 6 * ONE_PLY) + { + u = uNullDepth / ONE_PLY; + ASSERT(u <= 6); + if ((iRoughEval + _iDistAlphaSkipNull[u] <= iAlpha) || + ((iRoughEval + _iDistAlphaSkipNull[u] / 2 <= iAlpha) && + (ValueOfMaterialInTroubleAfterNull(pos, pos->uToMove)))) + { + return FALSE; + } + } + return TRUE; + } + return FALSE; +} + + +FLAG +TryNullmovePruning(SEARCHER_THREAD_CONTEXT *ctx, + FLAG *pfThreat, + SCORE iAlpha, + SCORE iBeta, + ULONG uNullDepth, + INT *piOrigExtend, + SCORE *piNullScore) +{ + static INT _bm_by_piece[7] = { + -1, -1, QUARTER_PLY, QUARTER_PLY, HALF_PLY, HALF_PLY, -1 + }; + POSITION *pos = &ctx->sPosition; + PLY_INFO *pi = &ctx->sPlyInfo[ctx->uPly]; + CUMULATIVE_SEARCH_FLAGS *pf = &ctx->sSearchFlags; + SCORE iVerifyScore; + MOVE mv; + MOVE mvRef; + + ASSERT(IS_VALID_SCORE(iAlpha) && IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + + // TODO: more experiments with quick null + + // Ok, do it. + ASSERT(!InCheck(pos, pos->uToMove)); + VERIFY(MakeMove(ctx, NULLMOVE)); + ASSERT(pos->u64NonPawnSig != pi->sPosition.u64NonPawnSig); + ASSERT(pos->uToMove != pi->sPosition.uToMove); + INC(ctx->sCounters.tree.u64NullMoves); + + // (Reduced depth) search under the nullmove; don't allow two + // nullmoves in a row. + ASSERT(pf->fAvoidNullmove == FALSE); + pf->fAvoidNullmove = TRUE; + *piNullScore = -Search(ctx, -iBeta, -iBeta + 1, uNullDepth); + pf->fAvoidNullmove = FALSE; + + // Check the results + if (*piNullScore >= iBeta) + { + UnmakeMove(ctx, NULLMOVE); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + + // If there are very few pieces on the board, launch a + // separate "verification search". + if ((pos->uNonPawnCount[pos->uToMove][0] < 4) && + (pf->fVerifyNullmove == TRUE)) + { + ASSERT(pf->fAvoidNullmove == FALSE); + uNullDepth -= ONE_PLY; + if (uNullDepth > MAX_DEPTH_PER_SEARCH) uNullDepth = 0; + pf->fVerifyNullmove = FALSE; + iVerifyScore = Search(ctx, iAlpha, iBeta, uNullDepth); + pf->fVerifyNullmove = TRUE; + if (iVerifyScore < iBeta) + { + // The nullmove failed high but the verify search + // did not; we are in zug so extend. + *piOrigExtend += ONE_PLY; + INC(ctx->sCounters.extension.uZugzwang); + return FALSE; + } + } + + // Nullmove succeeded and either no need to verify or verify + // succeeded too. + INC(ctx->sCounters.tree.u64NullMoveSuccess); + if (*piNullScore > +NMATE) *piNullScore = +NMATE; + return TRUE; + } + + // Nullmove failed... + mv = (pi+1)->mvBest; + if (mv.uMove) + { + // See what we can learn from the move that refuted our nullmove. + ASSERT(SanityCheckMove(pos, mv)); + ASSERT(GET_COLOR(mv.pMoved) == pos->uToMove); + ASSERT(ctx->uPly >= 2); + + // If we make a nullmove that fails because we lose a + // piece, remember that the piece in question is in danger. + if ((mv.pCaptured) && !IS_PAWN(mv.pCaptured)) + { + ASSERT(GET_COLOR(mv.pCaptured) == FLIP(pos->uToMove)); + ASSERT(mv.pCaptured == pos->rgSquare[mv.cTo].pPiece); + StoreEnprisePiece(pos, mv.cTo); + mvRef = ctx->mvNullmoveRefutations[ctx->uPly - 2]; + if ((mvRef.uMove) && + (mvRef.pCaptured == mv.pCaptured) && + (mvRef.pMoved == mv.pMoved) && + (mvRef.cTo != mv.cTo)) + { + ASSERT(GET_COLOR(mvRef.pCaptured) == FLIP(pos->uToMove)); + ASSERT(mvRef.pCaptured); + ASSERT(_bm_by_piece[PIECE_TYPE(mv.pCaptured)] > 0); + ASSERT(_bm_by_piece[PIECE_TYPE(mv.pCaptured)] <= + ONE_PLY); + *piOrigExtend += _bm_by_piece[PIECE_TYPE(mv.pCaptured)]; + INC(ctx->sCounters.extension.uBotvinnikMarkoff); + } + ctx->mvNullmoveRefutations[ctx->uPly] = mv; + } + + // This is an idea from Tord Romstad on ccc: if we are below a + // history reduced node and we try a nullmove and the nullmove + // fails low and the move that refuted the nullmove involves + // the same piece moved in the reduced move at ply-1 then bail + // out of the reduced depth search now and research at full + // depth. The move that was reduced had some tactical + // significance. + ASSERT(IS_ON_BOARD(mv.cFrom)); + if ((mv.cFrom == (pi-1)->mv.cTo) && ((pi-1)->iExtensionAmount < 0)) + { + ASSERT(GET_COLOR(mv.pMoved) == GET_COLOR((pi-1)->mv.pMoved)); + UnmakeMove(ctx, NULLMOVE); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + *piNullScore = iAlpha - 1; + return TRUE; + } + } + + // If we do nothing we are mated-in-n, therefore this is a + // dangerous position so extend. This is Bruce Moreland's idea + // originally. + if (*piNullScore <= -NMATE) + { + if (mv.uMove && !IS_CAPTURE_OR_PROMOTION(mv)) + { + ASSERT(SanityCheckMove(pos, mv)); + ASSERT(GET_COLOR(mv.pMoved) == pos->uToMove); + UpdateDynamicMoveOrdering(ctx, + uNullDepth + TWO_PLY, + mv, + *piNullScore, + 0); + } + *pfThreat = TRUE; + } + UnmakeMove(ctx, NULLMOVE); + ASSERT(PositionsAreEquivalent(pos, &pi->sPosition)); + return FALSE; +} + + +#ifdef DEBUG +FLAG +SanityCheckMoves(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG uCurrent, + IN ULONG uType) +/** + +Routine description: + + Support routine to sanity check that: + + 1. The moves before uCurrent on the move stack were all marked + as searched (or pruned) + 2. The moves after uCurrent on the move stack are all zero + value moves and not checking moves. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG uCurrent, + ULONG uType + +Return value: + + FLAG + +**/ +{ + ULONG x; + + if (WE_SHOULD_STOP_SEARCHING) + { + return(TRUE); + } + + // + // Check moves yet to be searched + // + if (uType & VERIFY_AFTER) + { + for (x = uCurrent; x < ctx->sMoveStack.uEnd[ctx->uPly]; x++) + { + ASSERT(ctx->sMoveStack.mvf[x].iValue <= 0); + ASSERT(!IS_CHECKING_MOVE(ctx->sMoveStack.mvf[x].mv)); + } + } + + // + // Check moves already searched + // + if (uType & VERIFY_BEFORE) + { + for (x = uCurrent - 1; + ((x >= ctx->sMoveStack.uBegin[ctx->uPly]) && (x != (ULONG)-1)); + x--) + { + ASSERT(ctx->sMoveStack.mvf[x].bvFlags & MVF_MOVE_SEARCHED); + } + } + return(TRUE); +} +#endif diff --git a/src/see.c b/src/see.c new file mode 100755 index 0000000..292cbf1 --- /dev/null +++ b/src/see.c @@ -0,0 +1,981 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + see.c + +Abstract: + + Static exchange evaluator and support code. See also x86.asm. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 11 Jun 2004 + +Revision History: + + $Id: see.c 348 2008-01-05 07:11:36Z scott $ + +**/ + +#include "chess.h" + +#define ADD_ATTACKER(p, c, v) \ + pList->data[pList->uCount].pPiece = (p); \ + pList->data[pList->uCount].cLoc = (c); \ + pList->data[pList->uCount].uVal = (v); \ + pList->uCount++; + +void CDECL +SlowGetAttacks(IN OUT SEE_LIST *pList, + IN POSITION *pos, + IN COOR cSquare, + IN ULONG uSide) +/*++ + +Routine description: + + SlowGetAttacks is the C version of GetAttacks; it should be + identical to the GetAttacks code in x86.asm. The job of the + function is, given a position, square and side, to populate the + SEE_LIST with the locations and types of enemy pieces attacking + the square. + +Parameters: + + SEE_LIST *pList : list to populate + POSITION *pos : the board + COOR cSquare : square in question + ULONG uSide : side we are looking for attacks from + +Return value: + + void + +--*/ +{ + register ULONG x; + PIECE p; + COOR c; + int iIndex; + COOR cBlockIndex; + int iDelta; + static PIECE pPawn[2] = { BLACK_PAWN, WHITE_PAWN }; + static int iSeeDelta[2] = { -17, +15 }; + +#ifdef DEBUG + ASSERT(IS_ON_BOARD(cSquare)); + ASSERT(IS_VALID_COLOR(uSide)); + VerifyPositionConsistency(pos, FALSE); +#endif + pList->uCount = 0; + + // + // Check for pawns attacking cSquare + // + c = cSquare + (iSeeDelta[uSide]); + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (p == pPawn[uSide]) + { + // + // N.B. Don't use ADD_ATTACKER here because we know we're + // at element zero. + // + pList->data[0].pPiece = p; + pList->data[0].cLoc = c; + pList->data[0].uVal = VALUE_PAWN; + pList->uCount = 1; + } + } + + c += 2; + if (IS_ON_BOARD(c)) + { + p = pos->rgSquare[c].pPiece; + if (p == pPawn[uSide]) + { + ADD_ATTACKER(p, c, VALUE_PAWN); + } + } + + // + // Check for pieces attacking cSquare + // + for (x = pos->uNonPawnCount[uSide][0] - 1; + x != (ULONG)-1; + x--) + { + c = pos->cNonPawns[uSide][x]; + ASSERT(IS_ON_BOARD(c)); + + p = pos->rgSquare[c].pPiece; + ASSERT(p && !IS_PAWN(p)); + ASSERT(GET_COLOR(p) == uSide); + + iIndex = (int)c - (int)cSquare; + if (0 == (CHECK_VECTOR_WITH_INDEX(iIndex, GET_COLOR(p)) & + (1 << PIECE_TYPE(p)))) + { + continue; + } + + if (IS_KNIGHT_OR_KING(p)) + { + ASSERT(IS_KNIGHT(p) || IS_KING(p)); + ADD_ATTACKER(p, c, PIECE_VALUE(p)); + continue; + } + + // + // Check to see if there is a piece in the path from cSquare + // to c that blocks the attack. + // + iDelta = NEG_DELTA_WITH_INDEX(iIndex); + ASSERT(iDelta == -1 * CHECK_DELTA_WITH_INDEX(iIndex)); + ASSERT(iDelta != 0); + for (cBlockIndex = cSquare + iDelta; + cBlockIndex != c; + cBlockIndex += iDelta) + { + if (!IS_EMPTY(pos->rgSquare[cBlockIndex].pPiece)) + { + goto done; + } + } + + // + // Nothing in the way. + // + ADD_ATTACKER(p, c, PIECE_VALUE(p)); + + done: + ; + } +} + +#ifdef SEE_HEAPS +// +// SEE_HEAPS works great in principle but makes MinLegalPiece +// inaccurate if the top of the heap is not a legal move (i.e. the +// piece is pinned etc...) When tested the result of this was minimal +// and the use of a heap instead of a sorted list sped up the SEE +// code. +// +#define PARENT(x) ((x - 1) / 2) +#define LEFT_CHILD(x) (((x) * 2) + 1) +#define RIGHT_CHILD(x) (((x) * 2) + 2) + +#ifdef DEBUG +static FLAG +_IsValidHeap(IN SEE_LIST *p) +/** + +Routine description: + + Is the minheap in SEE_LIST p->data[] valid (i.e. does it satisfy + the minheap property?) + +Parameters: + + SEE_LIST *p : SEE_LIST to check + +Return value: + + static FLAG : TRUE if valid, FALSE otherwise + +**/ +{ + ULONG u, l, r; + + for (u = 0; u < p->uCount; u++) + { + l = LEFT_CHILD(u); + if ((l < p->uCount) && (p->data[l].uVal < p->data[u].uVal)) + { + return(FALSE); + } + + r = RIGHT_CHILD(u); + if ((r < p->uCount) && (p->data[r].uVal < p->data[u].uVal)) + { + return(FALSE); + } + } + return(TRUE); +} +#endif // DEBUG + + +static void +_PushDown(IN OUT SEE_LIST *p, + IN ULONG u) +/** + +Routine description: + + Take heap node number u and compare its value with the value of + its children. Swap smallest value into position u and continue + the push-down process if warranted. + +Parameters: + + SEE_LIST *p : SEE_LIST/minheap + ULONG u : node number in consideration + +Return value: + + static void + +**/ +{ + ULONG l = LEFT_CHILD(u); + ULONG r; + ULONG uSmallest; + SEE_THREESOME temp; + + // + // The heap is a complete tree -- if there's no left child of this + // node then there's no right child either. If this is a leaf node + // then our work is done. + // + ASSERT(p->uCount > 0); + if (l >= p->uCount) + { + return; + } + ASSERT(PARENT(l) == u); + + // + // Otherwise, find the smallest of u, l and r. + // + r = l + 1; + ASSERT(r == RIGHT_CHILD(u)); + ASSERT(PARENT(r) == u); + ASSERT((r != u) && (r != l) && (l != u)); + uSmallest = u; + if (p->data[l].uVal < p->data[u].uVal) + { + uSmallest = l; + } + if ((r < p->uCount) && (p->data[r].uVal < p->data[uSmallest].uVal)) + { + uSmallest = r; + } + + // + // If it's anything other than u, swap them and continue to push. + // + if (uSmallest != u) + { + ASSERT((uSmallest == l) || (uSmallest == r)); + temp = p->data[uSmallest]; + p->data[uSmallest] = p->data[u]; + p->data[u] = temp; + _PushDown(p, uSmallest); + } +} + +static void +_BuildHeap(IN OUT SEE_LIST *p) +/** + +Routine description: + + Convert a random array into a minheap. Start at the first + internal node and push it down into place. Continue to work + backwards until we get to the root (index 0). + +Parameters: + + SEE_LIST *p : list to heapify + +Return value: + + static void + +**/ +{ + int iStart = (p->uCount / 2) - 1; + int i; + + ASSERT(iStart < (int)p->uCount); + for (i = iStart; i > -1; i--) + { + ASSERT(i >= 0); + _PushDown(p, (ULONG)i); + } + ASSERT(_IsValidHeap(p)); +} + + +static void +_BubbleUp(IN OUT SEE_LIST *p, IN ULONG u) +/** + +Routine description: + + Take a node and bubble it up into place to re-create a minheap. + +Parameters: + + SEE_LIST *p : heap + ULONG u : index of node to bubble up + +Return value: + + static void + +**/ +{ + ULONG uParent; + SEE_THREESOME temp; + + ASSERT(p->uCount > 0); + if (u == 0) return; + + uParent = PARENT(u); + ASSERT((LEFT_CHILD(uParent) == u) || + (RIGHT_CHILD(uParent) == u)); + ASSERT(uParent < u); + if (p->data[uParent].uVal > p->data[u].uVal) + { + temp = p->data[uParent]; + p->data[uParent] = p->data[u]; + p->data[u] = temp; + _BubbleUp(p, uParent); + } +} + +#else // !SEE_HEAPS + +static void +_SortList(IN OUT SEE_LIST *pList) +/** + +Routine description: + + Sort the SEE list by piece value with a selection sort. + +Parameters: + + SEE_LIST *pList + +Return value: + + static void + +**/ +{ + ULONG x; + ULONG y; + register ULONG uMaxVal; + register ULONG uMaxLoc; + SEE_THREESOME sTemp; + + for (x = 0; + x < pList->uCount; + x++) + { + // + // Assume index X is the largest value item in the list + // + uMaxVal = pList->data[x].uVal; + uMaxLoc = x; + + // + // Look for others with a larger value + // + for (y = x + 1; + y < pList->uCount; + y++) + { + if (pList->data[y].uVal > uMaxVal) + { + uMaxVal = pList->data[y].uVal; + uMaxLoc = y; + } + } + + sTemp = pList->data[uMaxLoc]; + pList->data[uMaxLoc] = pList->data[x]; + pList->data[x] = sTemp; + } +} + +#endif + +static void INLINE +_RemoveItem(IN OUT SEE_LIST *pList, + IN ULONG x) +/** + +Routine description: + + Delete item x from the list. + +Parameters: + + SEE_LIST *pList, + ULONG x + +Return value: + + static void INLINE + +**/ +{ +#ifndef SEE_HEAPS + ULONG y; +#endif + + ASSERT(x < pList->uCount); + ASSERT(pList->uCount > 0); + +#ifdef SEE_HEAPS + // + // Swap item x with the last thing on the heap and then push the + // node back down. + // + if (x != (pList->uCount - 1)) + { + pList->data[x] = pList->data[pList->uCount - 1]; + pList->uCount--; + _PushDown(pList, 0); + } + else + { + pList->uCount--; + } + +#else // !SEE_HEAPS + + // + // If X is not the last thing in the list we will have to ripple + // shift to close the hole. This is rare. + // + for (y = x + 1; + y < pList->uCount; + y++) + { + pList->data[y - 1] = pList->data[y]; + } + pList->uCount--; + +#endif // SEE_HEAPS +} + + +static void +_ClearPieceByLocation(IN OUT SEE_LIST *pList, + IN COOR cLoc) +/** + +Routine description: + + Find a piece on the SEE list at COOR cLoc and delete it. + +Parameters: + + SEE_LIST *pList, + COOR cLoc + +Return value: + + static void + +**/ +{ + ULONG x = 0; + + while (x < pList->uCount) + { + if (pList->data[x].cLoc == cLoc) + { + _RemoveItem(pList, x); + return; + } + x++; + } + + // + // This can happen if, for example, the SEE move was a passed pawn push + // +} + + +#ifdef SEE_HEAPS +static PIECE +_MinLegalPiece(IN POSITION *pos, + IN ULONG uColor, + IN SEE_LIST *pList, + IN SEE_LIST *pOther, + IN COOR *pc, + IN COOR cIgnore) +/** + +Routine description: + + Return the piece from the SEE list with the lowest value that is + not pinned to its own king. Because we are storing the SEE_LISTS + as heaps, this is only an approximate value in the event that the + real min value piece is indeed pinned to its own king. I + considered sorting the list in this case but it seems like (in + tests) this inaccuracy really has little or no impact on the + search tree size. The speedup with heaps instead of sorted lists + seems worth the price. + +Parameters: + + POSITION *pos : the board + ULONG uColor : the color on move + SEE_LIST *pList : the list we're selecting from + SEE_LIST *pOther : the other side's list + COOR *pc, + COOR cIgnore + +Return value: + + static PIECE + +**/ +{ + COOR cKing; + PIECE p; + register ULONG x; + COOR c; + + // + // The list is a minheap with the min value piece at index 0. + // + for (x = 0; + x < pList->uCount; + x++) + { + p = pList->data[x].pPiece; + + // + // If this piece is the king, then no need to see if the move + // exposes the king to check.. just play the move as long as + // it's legal (i.e. no defenders to the square) + // + if (IS_KING(p)) + { + if (pOther->uCount == 0) + { + *pc = pList->data[0].cLoc; + + // + // Note: if p is a king and we allow them to play it then + // by definition the other side has nothing to counter + // with... otherwise we'd be moving into check here. So + // even if we had other pieces that were pinned to the + // king, empty out the list because we're done in the next + // SEE loop. + // + pList->uCount = 0; + return(p); + } + } + else + { + // + // Otherwise... consider pins. If the least valuable + // defender of the square cannot move because doing so + // would exposes his king to check, skip it and try the + // next least valuable. + // + cKing = pos->cNonPawns[uColor][0]; + c = ExposesCheck(pos, pList->data[x].cLoc, cKing); + + // + // cIgnore is the coordinate of the last piece the other + // side "moved" in this capture sequence. This is a hack + // to ignore pins based on a piece that has already moved + // in the computation but is already on the board. This + // of course does not work for positions where the piece + // you expose check to was "moved" two turns ago but these + // are pretty rare. + // + if (!IS_ON_BOARD(c) || (c == cIgnore)) + { + *pc = pList->data[x].cLoc; + _RemoveItem(pList, x); + return(p); + } + } + } + + // + // There are no legal pieces to move to square + // + return(0); +} + +#else // !SEE_HEAPS + +static PIECE +_MinLegalPiece(IN POSITION *pos, + IN ULONG uColor, + IN SEE_LIST *pList, + IN SEE_LIST *pOther, + IN COOR *pc, + IN COOR cIgnore) +/** + +Routine description: + + Return the piece from the SEE list with the lowest value that is + not pinned to its own king. + +Parameters: + + POSITION *pos : the board + ULONG uColor : the color on move + SEE_LIST *pList : the list we're selecting from + SEE_LIST *pOther : the other side's list + COOR *pc, + COOR cIgnore + +Return value: + + static PIECE + +**/ +{ + COOR cKing; + PIECE p; + register ULONG x; + COOR c; + + // + // The list is sorted from most valuable (index 0) to least valuable + // (index N). Begin at the least valuable and work up. + // + for (x = pList->uCount - 1; + x != (ULONG)-1; + x--) + { + p = pList->data[x].pPiece; + // + // If this piece is the king, then no need to see if the move + // exposes the king to check.. just play the move as long as + // it's legal (i.e. no defenders to the square) + // + if ((IS_KING(p)) && (pOther->uCount == 0)) + { + ASSERT(x == 0); + *pc = pList->data[0].cLoc; + pList->uCount = 0; + return(p); + } + else + { + // + // Otherwise... consider pins. If the least valuable + // defender of the square cannot move because doing so + // would exposes his king to check, skip it and try the + // next least valuable. + // + cKing = pos->cNonPawns[uColor][0]; + c = ExposesCheck(pos, pList->data[x].cLoc, cKing); + + // + // cIgnore is the coordinate of the last piece the other + // side "moved" in this capture sequence. This is a hack + // to ignore pins based on a piece that has already moved + // in the computation but is already on the board. This + // of course does not work for positions where the piece + // you expose check to was "moved" two turns ago but these + // are pretty rare. + // + if (!IS_ON_BOARD(c) || (c == cIgnore)) + { + *pc = pList->data[x].cLoc; + _RemoveItem(pList, x); + return(p); + } + } + } + + // + // There are no legal pieces to move to square + // + return(0); +} +#endif // SEE_HEAPS + +static void _AddXRays(IN POSITION *pos, + IN INT iAttackerColor, + IN COOR cTarget, + IN COOR cObstacle, + IN OUT SEE_LIST *pAttacks, + IN OUT SEE_LIST *pDefends) +/** + +Routine description: + + We just "moved" a piece in the SEE sequence... add any xray + attacks that it exposed to the SEE list to be take part as the + sequence plays out. + +Parameters: + + POSITION *pos, + INT iAttackerColor, + COOR cTarget, + COOR cObstacle, + SEE_LIST *pAttacks, + SEE_LIST *pDefends + +Return value: + + static void + +**/ +{ + int iDelta; + COOR cIndex; + PIECE xPiece; + int iIndex; + + iIndex = (int)cTarget - (int)cObstacle; + + // + // If there is no way for a queen sitting on the target square to + // reach the obsticle square then there is no discovered attack. + // (This could happen, for instance, if a knight captured. It + // can't uncover a new attack on the square where it took. + // + if (0 == (CHECK_VECTOR_WITH_INDEX(iIndex, BLACK) & (1 << QUEEN))) + { + return; + } + + // + // The squares are on the same rank, file or diagonal. iDelta is + // the way to move from target towards obstacle. + // + iDelta = CHECK_DELTA_WITH_INDEX(iIndex); + + // + // Search for a piece that moves the right way to attack the target + // square starting at the obstacle square + delta. + // + for (cIndex = cObstacle + iDelta; + IS_ON_BOARD(cIndex); + cIndex += iDelta) + { + xPiece = pos->rgSquare[cIndex].pPiece; + if (!IS_EMPTY(xPiece)) + { + // + // Does it move the right way to hit cTarget? TODO: can this + // be optimized? Remember pawns though... + // + if (0 != (CHECK_VECTOR_WITH_INDEX((int)cIndex - (int)cTarget, + GET_COLOR(xPiece)) & + (1 << PIECE_TYPE(xPiece)))) + { + // + // Add this attacker to the proper SEE_LIST + // + if (GET_COLOR(xPiece) == iAttackerColor) + { + pAttacks->data[pAttacks->uCount].pPiece = xPiece; + pAttacks->data[pAttacks->uCount].cLoc = cIndex; + pAttacks->data[pAttacks->uCount].uVal = + PIECE_VALUE(xPiece); + pAttacks->uCount++; + ASSERT(pAttacks->uCount > 0); +#ifdef SEE_HEAPS + _BubbleUp(pAttacks, pAttacks->uCount - 1); +#else + _SortList(pAttacks); +#endif + } + else + { + pDefends->data[pDefends->uCount].pPiece = xPiece; + pDefends->data[pDefends->uCount].cLoc = cIndex; + pDefends->data[pDefends->uCount].uVal = + PIECE_VALUE(xPiece); + pDefends->uCount++; + ASSERT(pDefends->uCount > 0); +#ifdef SEE_HEAPS + _BubbleUp(pDefends, pDefends->uCount - 1); +#else + _SortList(pDefends); +#endif + } + } + return; + } + } +} + + +SCORE +SEE(IN POSITION *pos, + IN MOVE mv) +/** + +Routine description: + + Given a board and a move on the board, estimate the value of the + move by considering the friend/enemy pieces that attack the move's + destination square. + +Parameters: + + POSITION *pos, + MOVE mv + +Return value: + + SCORE : the estimate of the move's score + +**/ +{ + SEE_LIST rgPieces[2]; + PIECE pPiece; + ULONG uInPeril; + SCORE rgiList[32]; + ULONG uListIndex; + ULONG uWhoseTurn = GET_COLOR(mv.pMoved); + ULONG uOrig = uWhoseTurn; + int iSign = 1; + ULONG uPromValue; + ULONG uVal; + COOR cFrom = mv.cFrom; + static FLAG _Table[2][3] = { + // ab + { FALSE, FALSE, TRUE }, // uVal==0 + { TRUE, FALSE, FALSE }, // uVal==1 + }; + +#ifdef DEBUG + ASSERT(mv.uMove != 0); + memset(rgiList, 0xFF, sizeof(rgiList)); + memset(rgPieces, 0xFF, sizeof(rgPieces)); +#endif + + // + // Create a sorted list of pieces attacking and defending the + // square. + // + GetAttacks(&(rgPieces[uWhoseTurn]), pos, mv.cTo, uWhoseTurn); + GetAttacks(&(rgPieces[FLIP(uWhoseTurn)]), pos, mv.cTo, FLIP(uWhoseTurn)); +#ifdef SEE_HEAPS + _BuildHeap(&(rgPieces[FLIP(uWhoseTurn)])); + _BuildHeap(&(rgPieces[uWhoseTurn])); +#else + _SortList(&(rgPieces[FLIP(uWhoseTurn)])); + _SortList(&(rgPieces[uWhoseTurn])); +#endif + + // + // Play the first move -- TODO: the first move may be illegal... + // fix this? + // + rgiList[0] = (PIECE_VALUE(mv.pCaptured) + + PIECE_VALUE(mv.pPromoted)); + uInPeril = (PIECE_VALUE(mv.pMoved) + + PIECE_VALUE(mv.pPromoted)); + uListIndex = 1; + + _ClearPieceByLocation(&(rgPieces[uWhoseTurn]), mv.cFrom); + _AddXRays(pos, + uWhoseTurn, + mv.cTo, + mv.cFrom, + &(rgPieces[uWhoseTurn]), + &(rgPieces[FLIP(uWhoseTurn)])); + + // + // Play moves 2..n + // + do + { + // + // Other side's turn now... + // + uWhoseTurn = FLIP(uWhoseTurn); + iSign = -iSign; + pPiece = _MinLegalPiece(pos, + uWhoseTurn, + &(rgPieces[uWhoseTurn]), + &(rgPieces[FLIP(uWhoseTurn)]), + &cFrom, + cFrom); + if (0 == pPiece) break; // no legal piece + // + // If this is a pawn capturing and it ends on the queening + // rank, set uPromValue appropriately. Bitwise operators are + // correct here, done for speed and branch removal; this loop + // is pretty heavily used. + // + uPromValue = IS_PAWN(pPiece) & (RANK1(mv.cTo) | RANK8(mv.cTo)); + uPromValue *= VALUE_QUEEN; + ASSERT((uPromValue == 0) || (uPromValue == VALUE_QUEEN)); + + ASSERT(uListIndex != 0); + rgiList[uListIndex] = rgiList[uListIndex - 1] + + iSign * (uInPeril + uPromValue); + uListIndex++; + ASSERT(uListIndex < ARRAY_LENGTH(rgiList)); + uInPeril = PIECE_VALUE(pPiece) + uPromValue; + + _AddXRays(pos, + GET_COLOR(mv.pMoved), + mv.cTo, + cFrom, + &(rgPieces[uOrig]), // These must be rgAttacks and + &(rgPieces[FLIP(uOrig)])); // rgDefends. Not based on tomove + } + while(1); + + // + // The swaplist is now complete but we still must consider that either + // side has the option of not taking (not continuing the exchange). + // + ASSERT(uListIndex >= 1); + uListIndex--; + + while (uListIndex > 0) + { + uVal = (uListIndex & 1); + iSign = ((rgiList[uListIndex] > rgiList[uListIndex - 1]) - + (rgiList[uListIndex] < rgiList[uListIndex - 1])) + 1; + ASSERT((iSign >= 0) && (iSign <= 2)); + if (TRUE == _Table[uVal][iSign]) + { + rgiList[uListIndex - 1] = rgiList[uListIndex]; + } + uListIndex--; + } + +#ifdef TEST_BROKEN + iSign = DebugSEE(pos, mv); + + if ((rgiList[0] != iSign) && + (iSign != INVALID_SCORE)) + { + DumpPosition(pos); + DumpMove(mv.uMove); + Trace("Real SEE says: %d\n" + "Test SEE says: %d\n", + rgiList[0], iSign); + UtilPanic(TESTCASE_FAILURE, + NULL, + "See mismatch", + rgiList[0], + iSign, + __FILE__, __LINE__); + } +#endif + return(rgiList[0]); +} diff --git a/src/see.s b/src/see.s new file mode 100644 index 0000000..72c63f5 --- /dev/null +++ b/src/see.s @@ -0,0 +1,1538 @@ +# GNU C version 4.0.1 (Apple Inc. build 5465) (i686-apple-darwin9) +# compiled by GNU C version 4.0.1 (Apple Inc. build 5465). +# GGC heuristics: --param ggc-min-expand=100 --param ggc-min-heapsize=131072 +# options passed: -D__DYNAMIC__ -fPIC -mmacosx-version-min=10.5.1 -m64 +# -mtune=generic -march=apple -auxbase -fverbose-asm +# options enabled: -fPIC -falign-jumps-max-skip -falign-loops +# -falign-loops-max-skip -fargument-alias -fasynchronous-unwind-tables +# -fbranch-count-reg -fcommon -feliminate-unused-debug-types -ffunction-cse +# -fgcse-lm -fident -fivopts -fkeep-static-consts -fleading-underscore +# -flocal-alloc -floop-optimize2 -fpeephole -freg-struct-return +# -fsched-interblock -fsched-spec -fsched-stalled-insns-dep +# -fsplit-ivs-in-unroller -ftree-loop-im -ftree-loop-ivcanon +# -ftree-loop-optimize -funwind-tables -fverbose-asm +# -fzero-initialized-in-bss -m80387 -mhard-float -mno-soft-float -mieee-fp +# -mfp-ret-in-387 -maccumulate-outgoing-args -mmmx -msse -msse2 -msse3 +# -m128bit-long-double -m64 -mtune=generic64 -march=apple +# -mmacosx-version-min=10.5.1 + +# Compiler executable checksum: 0a7d9e41e786877ed5cbeb90e063cdab + + .data + .align 2 +_iSeeDelta.5028: + .long -17 + .long 15 + .align 2 +_pPawn.5027: + .long 2 + .long 3 + .text +.globl _SlowGetAttacks +_SlowGetAttacks: +LFB33: + pushq %rbp # +LCFI0: + movq %rsp, %rbp #, +LCFI1: + movq %rdi, -40(%rbp) # pList, pList + movq %rsi, -48(%rbp) # pos, pos + movl %edx, -52(%rbp) # cSquare, cSquare + movl %ecx, -56(%rbp) # uSide, uSide + movq -40(%rbp), %rax # pList, pList + movl $0, (%rax) #, .uCount + movl -56(%rbp), %eax # uSide, uSide.5 + mov %eax, %eax # uSide.5, uSide.5 + leaq 0(,%rax,4), %rdx #, tmp125 + leaq _iSeeDelta.5028(%rip), %rax #, tmp126 + movl (%rdx,%rax), %eax # iSeeDelta, D.5038 + addl -52(%rbp), %eax # cSquare, tmp127 + movl %eax, -16(%rbp) # tmp127, c + movl -16(%rbp), %eax # c, D.5040 + andl $136, %eax #, D.5040 + testl %eax, %eax # D.5040 + jne L2 #, + movl -16(%rbp), %eax # c, c.6 + movq -48(%rbp), %rdx # pos, pos + mov %eax, %eax # c.6, c.6 + movl (%rdx,%rax,8), %eax # .D.2182.pPiece, .D.2182.pPiece + movl %eax, -20(%rbp) # .D.2182.pPiece, p + movl -56(%rbp), %eax # uSide, uSide.7 + mov %eax, %eax # uSide.7, uSide.7 + leaq 0(,%rax,4), %rdx #, tmp132 + leaq _pPawn.5027(%rip), %rax #, tmp133 + movl (%rdx,%rax), %eax # pPawn, D.5043 + cmpl -20(%rbp), %eax # p, D.5043 + jne L2 #, + movq -40(%rbp), %rdx # pList, pList + movl -20(%rbp), %eax # p, p + movl %eax, 4(%rdx) # p, .pPiece + movq -40(%rbp), %rdx # pList, pList + movl -16(%rbp), %eax # c, c + movl %eax, 8(%rdx) # c, .cLoc + movq -40(%rbp), %rax # pList, pList + movl $100, 12(%rax) #, .uVal + movq -40(%rbp), %rax # pList, pList + movl $1, (%rax) #, .uCount +L2: + leaq -16(%rbp), %rax #, tmp258 + addl $2, (%rax) #, c + movl -16(%rbp), %eax # c, D.5044 + andl $136, %eax #, D.5044 + testl %eax, %eax # D.5044 + jne L5 #, + movl -16(%rbp), %eax # c, c.8 + movq -48(%rbp), %rdx # pos, pos + mov %eax, %eax # c.8, c.8 + movl (%rdx,%rax,8), %eax # .D.2182.pPiece, .D.2182.pPiece + movl %eax, -20(%rbp) # .D.2182.pPiece, p + movl -56(%rbp), %eax # uSide, uSide.9 + mov %eax, %eax # uSide.9, uSide.9 + leaq 0(,%rax,4), %rdx #, tmp144 + leaq _pPawn.5027(%rip), %rax #, tmp145 + movl (%rdx,%rax), %eax # pPawn, D.5047 + cmpl -20(%rbp), %eax # p, D.5047 + jne L5 #, + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5048 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5048, D.5048 + movq %rdx, %rax # D.5048, D.5048 + addq %rax, %rax # D.5048 + addq %rdx, %rax # D.5048, D.5048 + salq $2, %rax #, tmp150 + addq %rcx, %rax # pList, tmp151 + leaq 4(%rax), %rdx #, tmp152 + movl -20(%rbp), %eax # p, p + movl %eax, (%rdx) # p, .pPiece + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5049 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5049, D.5049 + movq %rdx, %rax # D.5049, D.5049 + addq %rax, %rax # D.5049 + addq %rdx, %rax # D.5049, D.5049 + salq $2, %rax #, tmp158 + addq %rcx, %rax # pList, tmp159 + leaq 8(%rax), %rdx #, tmp160 + movl -16(%rbp), %eax # c, c + movl %eax, (%rdx) # c, .cLoc + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5050 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5050, D.5050 + movq %rdx, %rax # D.5050, D.5050 + addq %rax, %rax # D.5050 + addq %rdx, %rax # D.5050, D.5050 + salq $2, %rax #, tmp166 + addq %rcx, %rax # pList, tmp167 + addq $12, %rax #, tmp168 + movl $100, (%rax) #, .uVal + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5051 + leal 1(%rax), %edx #, D.5052 + movq -40(%rbp), %rax # pList, pList + movl %edx, (%rax) # D.5052, .uCount +L5: + movl -56(%rbp), %eax # uSide, uSide.10 + movq -48(%rbp), %rdx # pos, pos + mov %eax, %eax # uSide.10, uSide.10 + salq $5, %rax #, tmp173 + addq %rdx, %rax # pos, tmp174 + addq $1280, %rax #, tmp175 + movl (%rax), %eax # .uNonPawnCount, D.5054 + decl %eax # + movl %eax, -60(%rbp) #, x + jmp L8 # +L9: + movl -56(%rbp), %eax # uSide, uSide.11 + movl -60(%rbp), %edx # x, x.12 + movq -48(%rbp), %rcx # pos, pos + mov %eax, %eax # uSide.11, uSide.11 + mov %edx, %edx # x.12, x.12 + salq $4, %rax #, tmp179 + addq %rdx, %rax # x.12, tmp180 + movl 1144(%rcx,%rax,4), %eax # .cNonPawns, tmp181 + movl %eax, -16(%rbp) # tmp181, c + movl -16(%rbp), %eax # c, c.13 + movq -48(%rbp), %rdx # pos, pos + mov %eax, %eax # c.13, c.13 + movl (%rdx,%rax,8), %eax # .D.2182.pPiece, .D.2182.pPiece + movl %eax, -20(%rbp) # .D.2182.pPiece, p + movl -16(%rbp), %edx # c, c.14 + movl -52(%rbp), %eax # cSquare, cSquare.15 + movl %edx, %ecx # c.14, + subl %eax, %ecx # cSquare.15, + movl %ecx, %eax #, tmp185 + movl %eax, -12(%rbp) # tmp185, iIndex + movl -12(%rbp), %eax # iIndex, iIndex + cltq + salq $2, %rax #, D.5061 + movq %rax, %rdx # D.5061, D.5062 + movq _g_pVectorDelta@GOTPCREL(%rip), %rax #, tmp187 + movq (%rax), %rax # g_pVectorDelta, g_pVectorDelta.16 + addq %rax, %rdx # g_pVectorDelta.16, D.5064 + movl -20(%rbp), %eax # p, D.5065 + andl $1, %eax #, D.5065 + mov %eax, %eax # D.5065, D.5065 + movzbl (%rdx,%rax), %eax # .iVector, D.5066 + movzbl %al, %edx # D.5066, D.5067 + movl -20(%rbp), %eax # p, p + shrl %eax # D.5068 + movl %eax, %ecx # D.5068, D.5069 + movl %edx, %eax # D.5067, D.5070 + sarl %cl, %eax # D.5069, D.5070 + xorl $1, %eax #, D.5072 + andl $1, %eax #, D.5074 + testb %al, %al # D.5075 + jne L10 #, + movl -20(%rbp), %eax # p, D.5076 + andl $6, %eax #, D.5076 + cmpl $4, %eax #, D.5076 + jne L12 #, + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5077 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5077, D.5077 + movq %rdx, %rax # D.5077, D.5077 + addq %rax, %rax # D.5077 + addq %rdx, %rax # D.5077, D.5077 + salq $2, %rax #, tmp194 + addq %rcx, %rax # pList, tmp195 + leaq 4(%rax), %rdx #, tmp196 + movl -20(%rbp), %eax # p, p + movl %eax, (%rdx) # p, .pPiece + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5078 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5078, D.5078 + movq %rdx, %rax # D.5078, D.5078 + addq %rax, %rax # D.5078 + addq %rdx, %rax # D.5078, D.5078 + salq $2, %rax #, tmp202 + addq %rcx, %rax # pList, tmp203 + leaq 8(%rax), %rdx #, tmp204 + movl -16(%rbp), %eax # c, c + movl %eax, (%rdx) # c, .cLoc + movq -40(%rbp), %rax # pList, pList + movl (%rax), %edi # .uCount, D.5079 + movl -20(%rbp), %eax # p, p + shrl %eax # D.5080 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp208 + mov %eax, %edx # D.5080, D.5080 + movq %rdx, %rax # D.5080, D.5080 + addq %rax, %rax # D.5080 + addq %rdx, %rax # D.5080, D.5080 + salq $3, %rax #, tmp211 + movl (%rax,%rcx), %ecx # .uValue, D.5081 + movq -40(%rbp), %rsi # pList, pList + mov %edi, %edx # D.5079, D.5079 + movq %rdx, %rax # D.5079, D.5079 + addq %rax, %rax # D.5079 + addq %rdx, %rax # D.5079, D.5079 + salq $2, %rax #, tmp215 + addq %rsi, %rax # pList, tmp216 + addq $12, %rax #, tmp217 + movl %ecx, (%rax) # D.5081, .uVal + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5082 + leal 1(%rax), %edx #, D.5083 + movq -40(%rbp), %rax # pList, pList + movl %edx, (%rax) # D.5083, .uCount + jmp L10 # +L12: + movl -12(%rbp), %eax # iIndex, iIndex + cltq + salq $2, %rax #, D.5085 + movq %rax, %rdx # D.5085, D.5086 + movq _g_pVectorDelta@GOTPCREL(%rip), %rax #, tmp221 + movq (%rax), %rax # g_pVectorDelta, g_pVectorDelta.17 + leaq (%rdx,%rax), %rax #, D.5088 + movzbl 3(%rax), %eax # .iNegDelta, D.5089 + movsbl %al,%eax # D.5089, D.5089 + movl %eax, -4(%rbp) # D.5089, iDelta + movl -4(%rbp), %eax # iDelta, iDelta.18 + addl -52(%rbp), %eax # cSquare, tmp223 + movl %eax, -8(%rbp) # tmp223, cBlockIndex + jmp L14 # +L15: + movl -8(%rbp), %eax # cBlockIndex, cBlockIndex.19 + movq -48(%rbp), %rdx # pos, pos + mov %eax, %eax # cBlockIndex.19, cBlockIndex.19 + movl (%rdx,%rax,8), %eax # .D.2182.pPiece, D.5092 + testl %eax, %eax # D.5092 + jne L10 #, + movl -4(%rbp), %edx # iDelta, iDelta.20 + leaq -8(%rbp), %rax #, tmp260 + addl %edx, (%rax) # iDelta.20, cBlockIndex +L14: + movl -8(%rbp), %eax # cBlockIndex, cBlockIndex + cmpl -16(%rbp), %eax # c, cBlockIndex + jne L15 #, + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5094 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5094, D.5094 + movq %rdx, %rax # D.5094, D.5094 + addq %rax, %rax # D.5094 + addq %rdx, %rax # D.5094, D.5094 + salq $2, %rax #, tmp231 + addq %rcx, %rax # pList, tmp232 + leaq 4(%rax), %rdx #, tmp233 + movl -20(%rbp), %eax # p, p + movl %eax, (%rdx) # p, .pPiece + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5095 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # D.5095, D.5095 + movq %rdx, %rax # D.5095, D.5095 + addq %rax, %rax # D.5095 + addq %rdx, %rax # D.5095, D.5095 + salq $2, %rax #, tmp239 + addq %rcx, %rax # pList, tmp240 + leaq 8(%rax), %rdx #, tmp241 + movl -16(%rbp), %eax # c, c + movl %eax, (%rdx) # c, .cLoc + movq -40(%rbp), %rax # pList, pList + movl (%rax), %edi # .uCount, D.5096 + movl -20(%rbp), %eax # p, p + shrl %eax # D.5097 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp245 + mov %eax, %edx # D.5097, D.5097 + movq %rdx, %rax # D.5097, D.5097 + addq %rax, %rax # D.5097 + addq %rdx, %rax # D.5097, D.5097 + salq $3, %rax #, tmp248 + movl (%rax,%rcx), %ecx # .uValue, D.5098 + movq -40(%rbp), %rsi # pList, pList + mov %edi, %edx # D.5096, D.5096 + movq %rdx, %rax # D.5096, D.5096 + addq %rax, %rax # D.5096 + addq %rdx, %rax # D.5096, D.5096 + salq $2, %rax #, tmp252 + addq %rsi, %rax # pList, tmp253 + addq $12, %rax #, tmp254 + movl %ecx, (%rax) # D.5098, .uVal + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5099 + leal 1(%rax), %edx #, D.5100 + movq -40(%rbp), %rax # pList, pList + movl %edx, (%rax) # D.5100, .uCount +L10: + decl -60(%rbp) # x +L8: + cmpl $-1, -60(%rbp) #, x + jne L9 #, + leave + ret +LFE33: +__PushDown: +LFB34: + pushq %rbp # +LCFI2: + movq %rsp, %rbp #, +LCFI3: + subq $48, %rsp #, +LCFI4: + movq %rdi, -40(%rbp) # p, p + movl %esi, -44(%rbp) # u, u + movl -44(%rbp), %eax # u, u + addl %eax, %eax # D.5121 + incl %eax # tmp74 + movl %eax, -12(%rbp) # tmp74, l + movq -40(%rbp), %rax # p, p + movl (%rax), %eax # .uCount, D.5122 + cmpl -12(%rbp), %eax # l, D.5122 + jbe L29 #, + movl -12(%rbp), %eax # l, tmp76 + incl %eax # tmp76 + movl %eax, -8(%rbp) # tmp76, r + movl -44(%rbp), %eax # u, u + movl %eax, -4(%rbp) # u, uSmallest + movl -12(%rbp), %eax # l, l.21 + movq -40(%rbp), %rcx # p, p + mov %eax, %edx # l.21, l.21 + movq %rdx, %rax # l.21, l.21 + addq %rax, %rax # l.21 + addq %rdx, %rax # l.21, l.21 + salq $2, %rax #, tmp81 + addq %rcx, %rax # p, tmp82 + addq $12, %rax #, tmp83 + movl (%rax), %esi # .uVal, D.5124 + movl -44(%rbp), %eax # u, u.22 + movq -40(%rbp), %rcx # p, p + mov %eax, %edx # u.22, u.22 + movq %rdx, %rax # u.22, u.22 + addq %rax, %rax # u.22 + addq %rdx, %rax # u.22, u.22 + salq $2, %rax #, tmp87 + addq %rcx, %rax # p, tmp88 + addq $12, %rax #, tmp89 + movl (%rax), %eax # .uVal, D.5126 + cmpl %eax, %esi # D.5126, D.5124 + jae L23 #, + movl -12(%rbp), %eax # l, l + movl %eax, -4(%rbp) # l, uSmallest +L23: + movq -40(%rbp), %rax # p, p + movl (%rax), %eax # .uCount, D.5127 + cmpl -8(%rbp), %eax # r, D.5127 + jbe L25 #, + movl -8(%rbp), %eax # r, r.23 + movq -40(%rbp), %rcx # p, p + mov %eax, %edx # r.23, r.23 + movq %rdx, %rax # r.23, r.23 + addq %rax, %rax # r.23 + addq %rdx, %rax # r.23, r.23 + salq $2, %rax #, tmp95 + addq %rcx, %rax # p, tmp96 + addq $12, %rax #, tmp97 + movl (%rax), %esi # .uVal, D.5129 + movl -4(%rbp), %eax # uSmallest, uSmallest.24 + movq -40(%rbp), %rcx # p, p + mov %eax, %edx # uSmallest.24, uSmallest.24 + movq %rdx, %rax # uSmallest.24, uSmallest.24 + addq %rax, %rax # uSmallest.24 + addq %rdx, %rax # uSmallest.24, uSmallest.24 + salq $2, %rax #, tmp101 + addq %rcx, %rax # p, tmp102 + addq $12, %rax #, tmp103 + movl (%rax), %eax # .uVal, D.5131 + cmpl %eax, %esi # D.5131, D.5129 + jae L25 #, + movl -8(%rbp), %eax # r, r + movl %eax, -4(%rbp) # r, uSmallest +L25: + movl -4(%rbp), %eax # uSmallest, uSmallest + cmpl -44(%rbp), %eax # u, uSmallest + je L29 #, + movl -4(%rbp), %eax # uSmallest, uSmallest.25 + movq -40(%rbp), %rcx # p, p + mov %eax, %edx # uSmallest.25, uSmallest.25 + movq %rdx, %rax # uSmallest.25, uSmallest.25 + addq %rax, %rax # uSmallest.25 + addq %rdx, %rax # uSmallest.25, uSmallest.25 + leaq 0(,%rax,4), %rdx #, tmp109 + movq 4(%rdx,%rcx), %rax # .data, tmp110 + movq %rax, -32(%rbp) # tmp110, temp + movl 12(%rdx,%rcx), %eax # .data, tmp111 + movl %eax, -24(%rbp) # tmp111, temp + movl -4(%rbp), %eax # uSmallest, uSmallest.26 + movl -44(%rbp), %ecx # u, u.27 + movq -40(%rbp), %rsi # p, p + mov %eax, %edx # uSmallest.26, uSmallest.26 + movq %rdx, %rax # uSmallest.26, uSmallest.26 + addq %rax, %rax # uSmallest.26 + addq %rdx, %rax # uSmallest.26, uSmallest.26 + leaq 0(,%rax,4), %rdi #, tmp115 + movq -40(%rbp), %r8 # p, p + mov %ecx, %edx # u.27, u.27 + movq %rdx, %rax # u.27, u.27 + addq %rax, %rax # u.27 + addq %rdx, %rax # u.27, u.27 + leaq 0(,%rax,4), %rdx #, tmp119 + movq 4(%rdx,%r8), %rax # .data, tmp120 + movq %rax, 4(%rdi,%rsi) # tmp120, .data + movl 12(%rdx,%r8), %eax # .data, tmp121 + movl %eax, 12(%rdi,%rsi) # tmp121, .data + movl -44(%rbp), %eax # u, u.28 + movq -40(%rbp), %rcx # p, p + mov %eax, %edx # u.28, u.28 + movq %rdx, %rax # u.28, u.28 + addq %rax, %rax # u.28 + addq %rdx, %rax # u.28, u.28 + leaq 0(,%rax,4), %rdx #, tmp125 + movq -32(%rbp), %rax # temp, temp + movq %rax, 4(%rdx,%rcx) # temp, .data + movl -24(%rbp), %eax # temp, temp + movl %eax, 12(%rdx,%rcx) # temp, .data + movl -4(%rbp), %esi # uSmallest, uSmallest + movq -40(%rbp), %rdi # p, p + call __PushDown # +L29: + leave + ret +LFE34: +__BuildHeap: +LFB35: + pushq %rbp # +LCFI5: + movq %rsp, %rbp #, +LCFI6: + subq $32, %rsp #, +LCFI7: + movq %rdi, -24(%rbp) # p, p + movq -24(%rbp), %rax # p, p + movl (%rax), %eax # .uCount, D.5154 + shrl %eax # D.5155 + decl %eax # D.5156 + movl %eax, -8(%rbp) # D.5156, iStart + movl -8(%rbp), %eax # iStart, iStart + movl %eax, -4(%rbp) # iStart, i + jmp L31 # +L32: + movl -4(%rbp), %esi # i, i.29 + movq -24(%rbp), %rdi # p, p + call __PushDown # + leaq -4(%rbp), %rax #, tmp66 + decl (%rax) # i +L31: + cmpl $-1, -4(%rbp) #, i + jg L32 #, + leave + ret +LFE35: +__BubbleUp: +LFB36: + pushq %rbp # +LCFI8: + movq %rsp, %rbp #, +LCFI9: + subq $32, %rsp #, +LCFI10: + movq %rdi, -24(%rbp) # p, p + movl %esi, -28(%rbp) # u, u + cmpl $0, -28(%rbp) #, u + je L39 #, + movl -28(%rbp), %eax # u, D.5164 + decl %eax # D.5164 + shrl %eax # tmp67 + movl %eax, -4(%rbp) # tmp67, uParent + movl -4(%rbp), %eax # uParent, uParent.30 + movq -24(%rbp), %rcx # p, p + mov %eax, %edx # uParent.30, uParent.30 + movq %rdx, %rax # uParent.30, uParent.30 + addq %rax, %rax # uParent.30 + addq %rdx, %rax # uParent.30, uParent.30 + salq $2, %rax #, tmp71 + addq %rcx, %rax # p, tmp72 + addq $12, %rax #, tmp73 + movl (%rax), %esi # .uVal, D.5166 + movl -28(%rbp), %eax # u, u.31 + movq -24(%rbp), %rcx # p, p + mov %eax, %edx # u.31, u.31 + movq %rdx, %rax # u.31, u.31 + addq %rax, %rax # u.31 + addq %rdx, %rax # u.31, u.31 + salq $2, %rax #, tmp77 + addq %rcx, %rax # p, tmp78 + addq $12, %rax #, tmp79 + movl (%rax), %eax # .uVal, D.5168 + cmpl %eax, %esi # D.5168, D.5166 + jbe L39 #, + movl -4(%rbp), %eax # uParent, uParent.32 + movq -24(%rbp), %rcx # p, p + mov %eax, %edx # uParent.32, uParent.32 + movq %rdx, %rax # uParent.32, uParent.32 + addq %rax, %rax # uParent.32 + addq %rdx, %rax # uParent.32, uParent.32 + leaq 0(,%rax,4), %rdx #, tmp83 + movq 4(%rdx,%rcx), %rax # .data, tmp84 + movq %rax, -16(%rbp) # tmp84, temp + movl 12(%rdx,%rcx), %eax # .data, tmp85 + movl %eax, -8(%rbp) # tmp85, temp + movl -4(%rbp), %eax # uParent, uParent.33 + movl -28(%rbp), %ecx # u, u.34 + movq -24(%rbp), %rsi # p, p + mov %eax, %edx # uParent.33, uParent.33 + movq %rdx, %rax # uParent.33, uParent.33 + addq %rax, %rax # uParent.33 + addq %rdx, %rax # uParent.33, uParent.33 + leaq 0(,%rax,4), %rdi #, tmp89 + movq -24(%rbp), %r8 # p, p + mov %ecx, %edx # u.34, u.34 + movq %rdx, %rax # u.34, u.34 + addq %rax, %rax # u.34 + addq %rdx, %rax # u.34, u.34 + leaq 0(,%rax,4), %rdx #, tmp93 + movq 4(%rdx,%r8), %rax # .data, tmp94 + movq %rax, 4(%rdi,%rsi) # tmp94, .data + movl 12(%rdx,%r8), %eax # .data, tmp95 + movl %eax, 12(%rdi,%rsi) # tmp95, .data + movl -28(%rbp), %eax # u, u.35 + movq -24(%rbp), %rcx # p, p + mov %eax, %edx # u.35, u.35 + movq %rdx, %rax # u.35, u.35 + addq %rax, %rax # u.35 + addq %rdx, %rax # u.35, u.35 + leaq 0(,%rax,4), %rdx #, tmp99 + movq -16(%rbp), %rax # temp, temp + movq %rax, 4(%rdx,%rcx) # temp, .data + movl -8(%rbp), %eax # temp, temp + movl %eax, 12(%rdx,%rcx) # temp, .data + movl -4(%rbp), %esi # uParent, uParent + movq -24(%rbp), %rdi # p, p + call __BubbleUp # +L39: + leave + ret +LFE36: +__ClearPieceByLocation: +LFB38: + pushq %rbp # +LCFI11: + movq %rsp, %rbp #, +LCFI12: + subq $32, %rsp #, +LCFI13: + movq %rdi, -24(%rbp) # pList, pList + movl %esi, -28(%rbp) # cLoc, cLoc + movl $0, -4(%rbp) #, x + jmp L41 # +L42: + movl -4(%rbp), %eax # x, x.37 + movq -24(%rbp), %rcx # pList, pList + mov %eax, %edx # x.37, x.37 + movq %rdx, %rax # x.37, x.37 + addq %rax, %rax # x.37 + addq %rdx, %rax # x.37, x.37 + salq $2, %rax #, tmp64 + addq %rcx, %rax # pList, tmp65 + addq $8, %rax #, tmp66 + movl (%rax), %eax # .cLoc, D.5199 + cmpl -28(%rbp), %eax # cLoc, D.5199 + jne L43 #, + movl -4(%rbp), %esi # x, x + movq -24(%rbp), %rdi # pList, pList + call __RemoveItem # + jmp L46 # +L43: + leaq -4(%rbp), %rax #, tmp71 + incl (%rax) # x +L41: + movq -24(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5200 + cmpl -4(%rbp), %eax # x, D.5200 + ja L42 #, +L46: + leave + ret +LFE38: +__RemoveItem: +LFB37: + pushq %rbp # +LCFI14: + movq %rsp, %rbp #, +LCFI15: + subq $16, %rsp #, +LCFI16: + movq %rdi, -8(%rbp) # pList, pList + movl %esi, -12(%rbp) # x, x + movq -8(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5181 + decl %eax # D.5182 + cmpl -12(%rbp), %eax # x, D.5182 + je L48 #, + movl -12(%rbp), %edx # x, x.36 + movq -8(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5184 + leal -1(%rax), %ecx #, D.5185 + movq -8(%rbp), %rsi # pList, pList + mov %edx, %edx # x.36, x.36 + movq %rdx, %rax # x.36, x.36 + addq %rax, %rax # x.36 + addq %rdx, %rax # x.36, x.36 + leaq 0(,%rax,4), %rdi #, tmp72 + movq -8(%rbp), %r8 # pList, pList + mov %ecx, %edx # D.5185, D.5185 + movq %rdx, %rax # D.5185, D.5185 + addq %rax, %rax # D.5185 + addq %rdx, %rax # D.5185, D.5185 + leaq 0(,%rax,4), %rdx #, tmp76 + movq 4(%rdx,%r8), %rax # .data, tmp77 + movq %rax, 4(%rdi,%rsi) # tmp77, .data + movl 12(%rdx,%r8), %eax # .data, tmp78 + movl %eax, 12(%rdi,%rsi) # tmp78, .data + movq -8(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5186 + leal -1(%rax), %edx #, D.5187 + movq -8(%rbp), %rax # pList, pList + movl %edx, (%rax) # D.5187, .uCount + movq -8(%rbp), %rdi # pList, pList + movl $0, %esi #, + call __PushDown # + jmp L51 # +L48: + movq -8(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5188 + leal -1(%rax), %edx #, D.5189 + movq -8(%rbp), %rax # pList, pList + movl %edx, (%rax) # D.5189, .uCount +L51: + leave + ret +LFE37: +__MinLegalPiece: +LFB39: + pushq %rbp # +LCFI17: + movq %rsp, %rbp #, +LCFI18: + subq $80, %rsp #, +LCFI19: + movq %rdi, -24(%rbp) # pos, pos + movl %esi, -28(%rbp) # uColor, uColor + movq %rdx, -40(%rbp) # pList, pList + movq %rcx, -48(%rbp) # pOther, pOther + movq %r8, -56(%rbp) # pc, pc + movl %r9d, -60(%rbp) # cIgnore, cIgnore + movl $0, -64(%rbp) #, x + jmp L53 # +L54: + movl -64(%rbp), %eax # x, x.38 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # x.38, x.38 + movq %rdx, %rax # x.38, x.38 + addq %rax, %rax # x.38 + addq %rdx, %rax # x.38, x.38 + salq $2, %rax #, tmp76 + addq %rcx, %rax # pList, tmp77 + addq $4, %rax #, tmp78 + movl (%rax), %eax # .pPiece, .pPiece + movl %eax, -8(%rbp) # .pPiece, p + movl -8(%rbp), %eax # p, D.5223 + andl $14, %eax #, D.5223 + cmpl $12, %eax #, D.5223 + jne L55 #, + movq -48(%rbp), %rax # pOther, pOther + movl (%rax), %eax # .uCount, D.5224 + testl %eax, %eax # D.5224 + jne L57 #, + movq -40(%rbp), %rax # pList, pList + movl 8(%rax), %edx # .cLoc, D.5225 + movq -56(%rbp), %rax # pc, pc + movl %edx, (%rax) # D.5225,* pc + movq -40(%rbp), %rax # pList, pList + movl $0, (%rax) #, .uCount + movl -8(%rbp), %eax # p, + movl %eax, -68(%rbp) #, D.5226 + jmp L59 # +L55: + movl -28(%rbp), %eax # uColor, uColor.39 + movq -24(%rbp), %rdx # pos, pos + mov %eax, %eax # uColor.39, uColor.39 + salq $6, %rax #, tmp86 + addq %rdx, %rax # pos, tmp87 + addq $1136, %rax #, tmp88 + movl 8(%rax), %eax # .cNonPawns, tmp89 + movl %eax, -12(%rbp) # tmp89, cKing + movl -64(%rbp), %eax # x, x.40 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # x.40, x.40 + movq %rdx, %rax # x.40, x.40 + addq %rax, %rax # x.40 + addq %rdx, %rax # x.40, x.40 + salq $2, %rax #, tmp93 + addq %rcx, %rax # pList, tmp94 + addq $8, %rax #, tmp95 + movl (%rax), %esi # .cLoc, D.5229 + movl -12(%rbp), %edx # cKing, cKing + movq -24(%rbp), %rdi # pos, pos + call _ExposesCheck # + movl %eax, -4(%rbp) # D.5230, c + movl -4(%rbp), %eax # c, D.5233 + andl $136, %eax #, D.5233 + testl %eax, %eax # D.5233 + jne L60 #, + movl -4(%rbp), %eax # c, c + cmpl -60(%rbp), %eax # cIgnore, c + jne L57 #, +L60: + movl -64(%rbp), %eax # x, x.41 + movq -40(%rbp), %rcx # pList, pList + mov %eax, %edx # x.41, x.41 + movq %rdx, %rax # x.41, x.41 + addq %rax, %rax # x.41 + addq %rdx, %rax # x.41, x.41 + salq $2, %rax #, tmp102 + addq %rcx, %rax # pList, tmp103 + addq $8, %rax #, tmp104 + movl (%rax), %edx # .cLoc, D.5235 + movq -56(%rbp), %rax # pc, pc + movl %edx, (%rax) # D.5235,* pc + movq -40(%rbp), %rdi # pList, pList + movl -64(%rbp), %esi # x, x + call __RemoveItem # + movl -8(%rbp), %eax # p, + movl %eax, -68(%rbp) #, D.5226 + jmp L59 # +L57: + incl -64(%rbp) # x +L53: + movq -40(%rbp), %rax # pList, pList + movl (%rax), %eax # .uCount, D.5236 + cmpl -64(%rbp), %eax # x, D.5236 + ja L54 #, + movl $0, -68(%rbp) #, D.5226 +L59: + movl -68(%rbp), %eax # D.5226, + leave + ret +LFE39: +__AddXRays: +LFB40: + pushq %rbp # +LCFI20: + movq %rsp, %rbp #, +LCFI21: + subq $64, %rsp #, +LCFI22: + movq %rdi, -24(%rbp) # pos, pos + movl %esi, -28(%rbp) # iAttackerColor, iAttackerColor + movl %edx, -32(%rbp) # cTarget, cTarget + movl %ecx, -36(%rbp) # cObstacle, cObstacle + movq %r8, -48(%rbp) # pAttacks, pAttacks + movq %r9, -56(%rbp) # pDefends, pDefends + movl -32(%rbp), %edx # cTarget, cTarget.42 + movl -36(%rbp), %eax # cObstacle, cObstacle.43 + movl %edx, %ecx # cTarget.42, + subl %eax, %ecx # cObstacle.43, + movl %ecx, %eax #, tmp118 + movl %eax, -4(%rbp) # tmp118, iIndex + movl -4(%rbp), %eax # iIndex, iIndex + cltq + salq $2, %rax #, D.5262 + movq %rax, %rdx # D.5262, D.5263 + movq _g_pVectorDelta@GOTPCREL(%rip), %rax #, tmp120 + movq (%rax), %rax # g_pVectorDelta, g_pVectorDelta.44 + leaq (%rdx,%rax), %rax #, D.5265 + movzbl (%rax), %eax # .iVector, D.5266 + movzbl %al, %eax # D.5266, D.5267 + shrl $5, %eax #, D.5268 + xorl $1, %eax #, D.5269 + andl $1, %eax #, D.5271 + testb %al, %al # D.5272 + jne L74 #, + movl -4(%rbp), %eax # iIndex, iIndex + cltq + salq $2, %rax #, D.5274 + movq %rax, %rdx # D.5274, D.5275 + movq _g_pVectorDelta@GOTPCREL(%rip), %rax #, tmp122 + movq (%rax), %rax # g_pVectorDelta, g_pVectorDelta.45 + leaq (%rdx,%rax), %rax #, D.5277 + movzbl 2(%rax), %eax # .iDelta, D.5278 + movsbl %al,%eax # D.5278, D.5278 + movl %eax, -16(%rbp) # D.5278, iDelta + movl -16(%rbp), %eax # iDelta, iDelta.46 + addl -36(%rbp), %eax # cObstacle, tmp124 + movl %eax, -12(%rbp) # tmp124, cIndex + jmp L67 # +L68: + movl -12(%rbp), %eax # cIndex, cIndex.47 + movq -24(%rbp), %rdx # pos, pos + mov %eax, %eax # cIndex.47, cIndex.47 + movl (%rdx,%rax,8), %eax # .D.2182.pPiece, .D.2182.pPiece + movl %eax, -8(%rbp) # .D.2182.pPiece, xPiece + cmpl $0, -8(%rbp) #, xPiece + je L69 #, + movl -12(%rbp), %edx # cIndex, cIndex.48 + movl -32(%rbp), %eax # cTarget, cTarget.49 + movl %edx, %ecx # cIndex.48, + subl %eax, %ecx # cTarget.49, + movl %ecx, %eax #, D.5283 + cltq + salq $2, %rax #, D.5285 + movq %rax, %rdx # D.5285, D.5286 + movq _g_pVectorDelta@GOTPCREL(%rip), %rax #, tmp128 + movq (%rax), %rax # g_pVectorDelta, g_pVectorDelta.50 + addq %rax, %rdx # g_pVectorDelta.50, D.5288 + movl -8(%rbp), %eax # xPiece, D.5289 + andl $1, %eax #, D.5289 + mov %eax, %eax # D.5289, D.5289 + movzbl (%rdx,%rax), %eax # .iVector, D.5290 + movzbl %al, %edx # D.5290, D.5291 + movl -8(%rbp), %eax # xPiece, xPiece + shrl %eax # D.5292 + movl %eax, %ecx # D.5292, D.5293 + movl %edx, %eax # D.5291, D.5294 + sarl %cl, %eax # D.5293, D.5294 + andl $1, %eax #, D.5295 + testb %al, %al # D.5296 + je L74 #, + movl -8(%rbp), %edx # xPiece, D.5297 + andl $1, %edx #, D.5297 + movl -28(%rbp), %eax # iAttackerColor, iAttackerColor.51 + cmpl %eax, %edx # iAttackerColor.51, D.5297 + jne L72 #, + movq -48(%rbp), %rax # pAttacks, pAttacks + movl (%rax), %eax # .uCount, D.5299 + movq -48(%rbp), %rcx # pAttacks, pAttacks + mov %eax, %edx # D.5299, D.5299 + movq %rdx, %rax # D.5299, D.5299 + addq %rax, %rax # D.5299 + addq %rdx, %rax # D.5299, D.5299 + salq $2, %rax #, tmp135 + addq %rcx, %rax # pAttacks, tmp136 + leaq 4(%rax), %rdx #, tmp137 + movl -8(%rbp), %eax # xPiece, xPiece + movl %eax, (%rdx) # xPiece, .pPiece + movq -48(%rbp), %rax # pAttacks, pAttacks + movl (%rax), %eax # .uCount, D.5300 + movq -48(%rbp), %rcx # pAttacks, pAttacks + mov %eax, %edx # D.5300, D.5300 + movq %rdx, %rax # D.5300, D.5300 + addq %rax, %rax # D.5300 + addq %rdx, %rax # D.5300, D.5300 + salq $2, %rax #, tmp143 + addq %rcx, %rax # pAttacks, tmp144 + leaq 8(%rax), %rdx #, tmp145 + movl -12(%rbp), %eax # cIndex, cIndex + movl %eax, (%rdx) # cIndex, .cLoc + movq -48(%rbp), %rax # pAttacks, pAttacks + movl (%rax), %edi # .uCount, D.5301 + movl -8(%rbp), %eax # xPiece, xPiece + shrl %eax # D.5302 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp149 + mov %eax, %edx # D.5302, D.5302 + movq %rdx, %rax # D.5302, D.5302 + addq %rax, %rax # D.5302 + addq %rdx, %rax # D.5302, D.5302 + salq $3, %rax #, tmp152 + movl (%rax,%rcx), %ecx # .uValue, D.5303 + movq -48(%rbp), %rsi # pAttacks, pAttacks + mov %edi, %edx # D.5301, D.5301 + movq %rdx, %rax # D.5301, D.5301 + addq %rax, %rax # D.5301 + addq %rdx, %rax # D.5301, D.5301 + salq $2, %rax #, tmp156 + addq %rsi, %rax # pAttacks, tmp157 + addq $12, %rax #, tmp158 + movl %ecx, (%rax) # D.5303, .uVal + movq -48(%rbp), %rax # pAttacks, pAttacks + movl (%rax), %eax # .uCount, D.5304 + leal 1(%rax), %edx #, D.5305 + movq -48(%rbp), %rax # pAttacks, pAttacks + movl %edx, (%rax) # D.5305, .uCount + movq -48(%rbp), %rax # pAttacks, pAttacks + movl (%rax), %eax # .uCount, D.5306 + leal -1(%rax), %esi #, D.5307 + movq -48(%rbp), %rdi # pAttacks, pAttacks + call __BubbleUp # + jmp L74 # +L72: + movq -56(%rbp), %rax # pDefends, pDefends + movl (%rax), %eax # .uCount, D.5308 + movq -56(%rbp), %rcx # pDefends, pDefends + mov %eax, %edx # D.5308, D.5308 + movq %rdx, %rax # D.5308, D.5308 + addq %rax, %rax # D.5308 + addq %rdx, %rax # D.5308, D.5308 + salq $2, %rax #, tmp167 + addq %rcx, %rax # pDefends, tmp168 + leaq 4(%rax), %rdx #, tmp169 + movl -8(%rbp), %eax # xPiece, xPiece + movl %eax, (%rdx) # xPiece, .pPiece + movq -56(%rbp), %rax # pDefends, pDefends + movl (%rax), %eax # .uCount, D.5309 + movq -56(%rbp), %rcx # pDefends, pDefends + mov %eax, %edx # D.5309, D.5309 + movq %rdx, %rax # D.5309, D.5309 + addq %rax, %rax # D.5309 + addq %rdx, %rax # D.5309, D.5309 + salq $2, %rax #, tmp175 + addq %rcx, %rax # pDefends, tmp176 + leaq 8(%rax), %rdx #, tmp177 + movl -12(%rbp), %eax # cIndex, cIndex + movl %eax, (%rdx) # cIndex, .cLoc + movq -56(%rbp), %rax # pDefends, pDefends + movl (%rax), %edi # .uCount, D.5310 + movl -8(%rbp), %eax # xPiece, xPiece + shrl %eax # D.5311 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp181 + mov %eax, %edx # D.5311, D.5311 + movq %rdx, %rax # D.5311, D.5311 + addq %rax, %rax # D.5311 + addq %rdx, %rax # D.5311, D.5311 + salq $3, %rax #, tmp184 + movl (%rax,%rcx), %ecx # .uValue, D.5312 + movq -56(%rbp), %rsi # pDefends, pDefends + mov %edi, %edx # D.5310, D.5310 + movq %rdx, %rax # D.5310, D.5310 + addq %rax, %rax # D.5310 + addq %rdx, %rax # D.5310, D.5310 + salq $2, %rax #, tmp188 + addq %rsi, %rax # pDefends, tmp189 + addq $12, %rax #, tmp190 + movl %ecx, (%rax) # D.5312, .uVal + movq -56(%rbp), %rax # pDefends, pDefends + movl (%rax), %eax # .uCount, D.5313 + leal 1(%rax), %edx #, D.5314 + movq -56(%rbp), %rax # pDefends, pDefends + movl %edx, (%rax) # D.5314, .uCount + movq -56(%rbp), %rax # pDefends, pDefends + movl (%rax), %eax # .uCount, D.5315 + leal -1(%rax), %esi #, D.5316 + movq -56(%rbp), %rdi # pDefends, pDefends + call __BubbleUp # + jmp L74 # +L69: + movl -16(%rbp), %edx # iDelta, iDelta.52 + leaq -12(%rbp), %rax #, tmp196 + addl %edx, (%rax) # iDelta.52, cIndex +L67: + movl -12(%rbp), %eax # cIndex, D.5318 + andl $136, %eax #, D.5318 + testl %eax, %eax # D.5318 + je L68 #, +L74: + leave + ret +LFE40: + .data + .align 4 +__Table.5343: + .long 0 + .long 0 + .long 1 + .long 1 + .long 0 + .long 0 + .text +.globl _SEE +_SEE: +LFB41: + pushq %rbp # +LCFI23: + movq %rsp, %rbp #, +LCFI24: + subq $592, %rsp #, +LCFI25: + movq %rdi, -584(%rbp) # pos, pos + movl %esi, -588(%rbp) # mv, mv + movl -588(%rbp), %eax #, tmp194 + shrl $16, %eax #, tmp193 + andl $15, %eax #, D.5349 + movzbl %al, %eax # D.5349, D.5350 + andl $1, %eax #, tmp195 + movl %eax, -20(%rbp) # tmp195, uWhoseTurn + movl -20(%rbp), %eax # uWhoseTurn, uWhoseTurn + movl %eax, -16(%rbp) # uWhoseTurn, uOrig + movl $1, -12(%rbp) #, iSign + movzbl -588(%rbp), %eax # mv.D.2138.cFrom, D.5351 + movzbl %al, %eax # D.5351, D.5352 + movl %eax, -564(%rbp) # D.5352, cFrom + movzbl -587(%rbp), %eax # mv.D.2138.cTo, D.5353 + movzbl %al, %edx # D.5353, D.5354 + mov -20(%rbp), %eax # uWhoseTurn, D.5355 + imulq $196, %rax, %rax #, D.5355, D.5356 + leaq -432(%rbp), %rdi #, D.5358 + addq %rax, %rdi # D.5357, D.5358 + movl -20(%rbp), %ecx # uWhoseTurn, uWhoseTurn + movq -584(%rbp), %rsi # pos, pos + call _GetAttacks # + movl -20(%rbp), %ecx # uWhoseTurn, D.5359 + xorl $1, %ecx #, D.5359 + movzbl -587(%rbp), %eax # mv.D.2138.cTo, D.5360 + movzbl %al, %edx # D.5360, D.5361 + movl -20(%rbp), %eax # uWhoseTurn, D.5362 + xorl $1, %eax #, D.5362 + mov %eax, %eax # D.5362, D.5363 + imulq $196, %rax, %rax #, D.5363, D.5364 + leaq -432(%rbp), %rdi #, D.5366 + addq %rax, %rdi # D.5365, D.5366 + movq -584(%rbp), %rsi # pos, pos + call _GetAttacks # + movl -20(%rbp), %eax # uWhoseTurn, D.5367 + xorl $1, %eax #, D.5367 + mov %eax, %eax # D.5367, D.5368 + imulq $196, %rax, %rax #, D.5368, D.5369 + leaq -432(%rbp), %rdi #, D.5371 + addq %rax, %rdi # D.5370, D.5371 + call __BuildHeap # + mov -20(%rbp), %eax # uWhoseTurn, D.5372 + imulq $196, %rax, %rax #, D.5372, D.5373 + leaq -432(%rbp), %rdi #, D.5375 + addq %rax, %rdi # D.5374, D.5375 + call __BuildHeap # + movl -588(%rbp), %eax #, tmp202 + shrl $20, %eax #, tmp201 + andl $15, %eax #, D.5376 + movzbl %al, %eax # D.5376, D.5377 + sarl %eax # D.5378 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp203 + movslq %eax,%rdx # D.5378, D.5378 + movq %rdx, %rax # D.5378, D.5378 + addq %rax, %rax # D.5378 + addq %rdx, %rax # D.5378, D.5378 + salq $3, %rax #, tmp206 + movl (%rax,%rcx), %esi # .uValue, D.5379 + movl -588(%rbp), %eax #, tmp209 + shrl $24, %eax #, tmp208 + andl $15, %eax #, D.5380 + movzbl %al, %eax # D.5380, D.5381 + sarl %eax # D.5382 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp210 + movslq %eax,%rdx # D.5382, D.5382 + movq %rdx, %rax # D.5382, D.5382 + addq %rax, %rax # D.5382 + addq %rdx, %rax # D.5382, D.5382 + salq $3, %rax #, tmp213 + movl (%rax,%rcx), %eax # .uValue, D.5383 + leal (%rsi,%rax), %eax #, D.5384 + movl %eax, -560(%rbp) # D.5385, rgiList + movl -588(%rbp), %eax #, tmp216 + shrl $16, %eax #, tmp215 + andl $15, %eax #, D.5386 + movzbl %al, %eax # D.5386, D.5387 + sarl %eax # D.5388 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp217 + movslq %eax,%rdx # D.5388, D.5388 + movq %rdx, %rax # D.5388, D.5388 + addq %rax, %rax # D.5388 + addq %rdx, %rax # D.5388, D.5388 + salq $3, %rax #, tmp220 + movl (%rax,%rcx), %esi # .uValue, D.5389 + movl -588(%rbp), %eax #, tmp223 + shrl $24, %eax #, tmp222 + andl $15, %eax #, D.5390 + movzbl %al, %eax # D.5390, D.5391 + sarl %eax # D.5392 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp224 + movslq %eax,%rdx # D.5392, D.5392 + movq %rdx, %rax # D.5392, D.5392 + addq %rax, %rax # D.5392 + addq %rdx, %rax # D.5392, D.5392 + salq $3, %rax #, tmp227 + movl (%rax,%rcx), %eax # .uValue, D.5393 + leal (%rsi,%rax), %eax #, tmp228 + movl %eax, -28(%rbp) # tmp228, uInPeril + movl $1, -24(%rbp) #, uListIndex + movzbl -588(%rbp), %eax # mv.D.2138.cFrom, D.5394 + movzbl %al, %esi # D.5394, D.5395 + mov -20(%rbp), %eax # uWhoseTurn, D.5396 + imulq $196, %rax, %rax #, D.5396, D.5397 + leaq -432(%rbp), %rdi #, D.5399 + addq %rax, %rdi # D.5398, D.5399 + call __ClearPieceByLocation # + movl -20(%rbp), %eax # uWhoseTurn, D.5400 + xorl $1, %eax #, D.5400 + mov %eax, %eax # D.5400, D.5401 + imulq $196, %rax, %rax #, D.5401, D.5402 + leaq -432(%rbp), %rcx #, D.5404 + addq %rax, %rcx # D.5403, D.5404 + mov -20(%rbp), %eax # uWhoseTurn, D.5405 + imulq $196, %rax, %rax #, D.5405, D.5406 + leaq -432(%rbp), %rdx #, D.5408 + addq %rax, %rdx # D.5407, D.5408 + movzbl -588(%rbp), %eax # mv.D.2138.cFrom, D.5409 + movzbl %al, %esi # D.5409, D.5410 + movzbl -587(%rbp), %eax # mv.D.2138.cTo, D.5411 + movzbl %al, %eax # D.5411, D.5412 + movl -20(%rbp), %edi # uWhoseTurn, uWhoseTurn.53 + movq -584(%rbp), %r10 # pos, pos + movq %rcx, %r9 # D.5404, D.5404 + movq %rdx, %r8 # D.5408, D.5408 + movl %esi, %ecx # D.5410, D.5410 + movl %eax, %edx # D.5412, D.5412 + movl %edi, %esi # uWhoseTurn.53, uWhoseTurn.53 + movq %r10, %rdi # pos, pos + call __AddXRays # + jmp L76 # +L85: + movl -32(%rbp), %eax # pPiece, D.5425 + andl $14, %eax #, D.5425 + cmpl $2, %eax #, D.5425 + sete %al #, tmp233 + movzbl %al, %ecx # tmp233, D.5426 + movzbl -587(%rbp), %eax # mv.D.2138.cTo, D.5427 + movzbl %al, %eax # D.5427, D.5428 + andl $240, %eax #, D.5429 + cmpl $112, %eax #, D.5429 + sete %dl #, D.5430 + movzbl -587(%rbp), %eax # mv.D.2138.cTo, D.5431 + movzbl %al, %eax # D.5431, D.5432 + andl $240, %eax #, D.5433 + testl %eax, %eax # D.5433 + sete %al #, D.5434 + orl %edx, %eax # D.5430, D.5435 + movzbl %al, %eax # D.5435, D.5436 + andl %ecx, %eax # D.5426, D.5437 + movl %eax, -8(%rbp) # D.5437, uPromValue + movl -8(%rbp), %edx # uPromValue, uPromValue + movl %edx, %eax # uPromValue, uPromValue + sall $4, %eax #, tmp236 + subl %edx, %eax # uPromValue, tmp236 + movl %eax, %edx # tmp236, tmp237 + sall $6, %edx #, tmp237 + addl %edx, %eax # tmp237, tmp238 + movl %eax, -8(%rbp) # tmp238, uPromValue + movl -24(%rbp), %esi # uListIndex, uListIndex.55 + movl -24(%rbp), %eax # uListIndex, D.5439 + decl %eax # D.5439 + mov %eax, %eax # D.5439, D.5439 + movl -560(%rbp,%rax,4), %eax # rgiList, D.5440 + movl %eax, %ecx # D.5440, D.5441 + movl -8(%rbp), %eax # uPromValue, uPromValue + movl -28(%rbp), %edx # uInPeril, D.5442 + addl %eax, %edx # uPromValue, D.5442 + movl -12(%rbp), %eax # iSign, iSign.56 + imull %edx, %eax # D.5442, D.5444 + leal (%rcx,%rax), %eax #, D.5445 + movl %eax, %edx # D.5445, D.5446 + mov %esi, %eax # uListIndex.55, uListIndex.55 + movl %edx, -560(%rbp,%rax,4) # D.5446, rgiList + leaq -24(%rbp), %rax #, tmp274 + incl (%rax) # uListIndex + movl -32(%rbp), %eax # pPiece, pPiece + shrl %eax # D.5447 + movq _g_PieceData@GOTPCREL(%rip), %rcx #, tmp243 + mov %eax, %edx # D.5447, D.5447 + movq %rdx, %rax # D.5447, D.5447 + addq %rax, %rax # D.5447 + addq %rdx, %rax # D.5447, D.5447 + salq $3, %rax #, tmp246 + movl (%rax,%rcx), %eax # .uValue, D.5448 + addl -8(%rbp), %eax # uPromValue, tmp247 + movl %eax, -28(%rbp) # tmp247, uInPeril + movl -16(%rbp), %eax # uOrig, D.5449 + xorl $1, %eax #, D.5449 + mov %eax, %eax # D.5449, D.5450 + imulq $196, %rax, %rax #, D.5450, D.5451 + leaq -432(%rbp), %rcx #, D.5453 + addq %rax, %rcx # D.5452, D.5453 + mov -16(%rbp), %eax # uOrig, D.5454 + imulq $196, %rax, %rax #, D.5454, D.5455 + leaq -432(%rbp), %rdx #, D.5457 + addq %rax, %rdx # D.5456, D.5457 + movl -564(%rbp), %r10d # cFrom, cFrom.57 + movzbl -587(%rbp), %eax # mv.D.2138.cTo, D.5459 + movzbl %al, %esi # D.5459, D.5460 + movl -588(%rbp), %eax #, tmp250 + shrl $16, %eax #, tmp249 + andl $15, %eax #, D.5461 + movzbl %al, %eax # D.5461, D.5462 + andl $1, %eax #, D.5463 + movq -584(%rbp), %rdi # pos, pos + movq %rcx, %r9 # D.5453, D.5453 + movq %rdx, %r8 # D.5457, D.5457 + movl %r10d, %ecx # cFrom.57, cFrom.57 + movl %esi, %edx # D.5460, D.5460 + movl %eax, %esi # D.5463, D.5463 + call __AddXRays # +L76: + leaq -20(%rbp), %rax #, tmp270 + xorl $1, (%rax) #, uWhoseTurn + leaq -12(%rbp), %rax #, tmp272 + negl (%rax) # iSign + movl -564(%rbp), %r8d # cFrom, cFrom.54 + movl -20(%rbp), %eax # uWhoseTurn, D.5415 + xorl $1, %eax #, D.5415 + mov %eax, %eax # D.5415, D.5416 + imulq $196, %rax, %rax #, D.5416, D.5417 + leaq -432(%rbp), %rcx #, D.5419 + addq %rax, %rcx # D.5418, D.5419 + mov -20(%rbp), %eax # uWhoseTurn, D.5420 + imulq $196, %rax, %rax #, D.5420, D.5421 + leaq -432(%rbp), %rdx #, D.5423 + addq %rax, %rdx # D.5422, D.5423 + leaq -564(%rbp), %rax #, tmp230 + movl -20(%rbp), %esi # uWhoseTurn, uWhoseTurn + movq -584(%rbp), %rdi # pos, pos + movl %r8d, %r9d # cFrom.54, cFrom.54 + movq %rax, %r8 # tmp230, + call __MinLegalPiece # + movl %eax, -32(%rbp) # D.5424, pPiece + cmpl $0, -32(%rbp) #, pPiece + jne L85 #, +L77: + leaq -24(%rbp), %rax #, tmp276 + decl (%rax) # uListIndex + jmp L79 # +L80: + movl -24(%rbp), %eax # uListIndex, tmp252 + andl $1, %eax #, tmp252 + movl %eax, -4(%rbp) # tmp252, uVal + movl -24(%rbp), %eax # uListIndex, uListIndex.58 + mov %eax, %eax # uListIndex.58, uListIndex.58 + movl -560(%rbp,%rax,4), %edx # rgiList, D.5465 + movl -24(%rbp), %eax # uListIndex, D.5466 + decl %eax # D.5466 + mov %eax, %eax # D.5466, D.5466 + movl -560(%rbp,%rax,4), %eax # rgiList, D.5467 + cmpl %eax, %edx # D.5467, D.5465 + setg %al #, tmp255 + movzbl %al, %ecx # tmp255, D.5468 + movl -24(%rbp), %eax # uListIndex, uListIndex.59 + mov %eax, %eax # uListIndex.59, uListIndex.59 + movl -560(%rbp,%rax,4), %edx # rgiList, D.5470 + movl -24(%rbp), %eax # uListIndex, D.5471 + decl %eax # D.5471 + mov %eax, %eax # D.5471, D.5471 + movl -560(%rbp,%rax,4), %eax # rgiList, D.5472 + cmpl %eax, %edx # D.5472, D.5470 + setl %al #, tmp258 + movzbl %al, %eax # tmp258, D.5473 + movl %ecx, %edx # D.5468, + subl %eax, %edx # D.5473, + movl %edx, %eax #, D.5474 + incl %eax # tmp259 + movl %eax, -12(%rbp) # tmp259, iSign + movl -4(%rbp), %eax # uVal, uVal.60 + movl -12(%rbp), %edx # iSign, iSign.61 + mov %eax, %ecx # uVal.60, uVal.60 + movslq %edx,%rdx # iSign.61, iSign.61 + movq %rcx, %rax # uVal.60, uVal.60 + addq %rax, %rax # uVal.60 + addq %rcx, %rax # uVal.60, uVal.60 + addq %rdx, %rax # iSign.61, tmp263 + leaq 0(,%rax,4), %rdx #, tmp264 + leaq __Table.5343(%rip), %rax #, tmp265 + movl (%rdx,%rax), %eax # _Table, D.5477 + cmpl $1, %eax #, D.5477 + jne L81 #, + movl -24(%rbp), %ecx # uListIndex, D.5478 + decl %ecx # D.5478 + movl -24(%rbp), %eax # uListIndex, uListIndex.62 + mov %eax, %eax # uListIndex.62, uListIndex.62 + movl -560(%rbp,%rax,4), %edx # rgiList, D.5480 + mov %ecx, %eax # D.5478, D.5478 + movl %edx, -560(%rbp,%rax,4) # D.5480, rgiList +L81: + leaq -24(%rbp), %rax #, tmp278 + decl (%rax) # uListIndex +L79: + cmpl $0, -24(%rbp) #, uListIndex + jne L80 #, + movl -560(%rbp), %eax # rgiList, D.5481 + leave + ret +LFE41: + .section __TEXT,__eh_frame,coalesced,no_toc+strip_static_syms+live_support +EH_frame1: + .set L$set$0,LECIE1-LSCIE1 + .long L$set$0 +LSCIE1: + .long 0x0 + .byte 0x1 + .ascii "zR\0" + .byte 0x1 + .byte 0x78 + .byte 0x10 + .byte 0x1 + .byte 0x10 + .byte 0xc + .byte 0x7 + .byte 0x8 + .byte 0x90 + .byte 0x1 + .align 3 +LECIE1: + .globl _SlowGetAttacks.eh +_SlowGetAttacks.eh: +LSFDE1: + .set L$set$1,LEFDE1-LASFDE1 + .long L$set$1 +LASFDE1: + .long LASFDE1-EH_frame1 + .quad LFB33-. + .set L$set$2,LFE33-LFB33 + .quad L$set$2 + .byte 0x0 + .byte 0x4 + .set L$set$3,LCFI0-LFB33 + .long L$set$3 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$4,LCFI1-LCFI0 + .long L$set$4 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE1: +__PushDown.eh: +LSFDE3: + .set L$set$5,LEFDE3-LASFDE3 + .long L$set$5 +LASFDE3: + .long LASFDE3-EH_frame1 + .quad LFB34-. + .set L$set$6,LFE34-LFB34 + .quad L$set$6 + .byte 0x0 + .byte 0x4 + .set L$set$7,LCFI2-LFB34 + .long L$set$7 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$8,LCFI3-LCFI2 + .long L$set$8 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE3: +__BuildHeap.eh: +LSFDE5: + .set L$set$9,LEFDE5-LASFDE5 + .long L$set$9 +LASFDE5: + .long LASFDE5-EH_frame1 + .quad LFB35-. + .set L$set$10,LFE35-LFB35 + .quad L$set$10 + .byte 0x0 + .byte 0x4 + .set L$set$11,LCFI5-LFB35 + .long L$set$11 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$12,LCFI6-LCFI5 + .long L$set$12 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE5: +__BubbleUp.eh: +LSFDE7: + .set L$set$13,LEFDE7-LASFDE7 + .long L$set$13 +LASFDE7: + .long LASFDE7-EH_frame1 + .quad LFB36-. + .set L$set$14,LFE36-LFB36 + .quad L$set$14 + .byte 0x0 + .byte 0x4 + .set L$set$15,LCFI8-LFB36 + .long L$set$15 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$16,LCFI9-LCFI8 + .long L$set$16 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE7: +__ClearPieceByLocation.eh: +LSFDE9: + .set L$set$17,LEFDE9-LASFDE9 + .long L$set$17 +LASFDE9: + .long LASFDE9-EH_frame1 + .quad LFB38-. + .set L$set$18,LFE38-LFB38 + .quad L$set$18 + .byte 0x0 + .byte 0x4 + .set L$set$19,LCFI11-LFB38 + .long L$set$19 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$20,LCFI12-LCFI11 + .long L$set$20 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE9: +__RemoveItem.eh: +LSFDE11: + .set L$set$21,LEFDE11-LASFDE11 + .long L$set$21 +LASFDE11: + .long LASFDE11-EH_frame1 + .quad LFB37-. + .set L$set$22,LFE37-LFB37 + .quad L$set$22 + .byte 0x0 + .byte 0x4 + .set L$set$23,LCFI14-LFB37 + .long L$set$23 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$24,LCFI15-LCFI14 + .long L$set$24 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE11: +__MinLegalPiece.eh: +LSFDE13: + .set L$set$25,LEFDE13-LASFDE13 + .long L$set$25 +LASFDE13: + .long LASFDE13-EH_frame1 + .quad LFB39-. + .set L$set$26,LFE39-LFB39 + .quad L$set$26 + .byte 0x0 + .byte 0x4 + .set L$set$27,LCFI17-LFB39 + .long L$set$27 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$28,LCFI18-LCFI17 + .long L$set$28 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE13: +__AddXRays.eh: +LSFDE15: + .set L$set$29,LEFDE15-LASFDE15 + .long L$set$29 +LASFDE15: + .long LASFDE15-EH_frame1 + .quad LFB40-. + .set L$set$30,LFE40-LFB40 + .quad L$set$30 + .byte 0x0 + .byte 0x4 + .set L$set$31,LCFI20-LFB40 + .long L$set$31 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$32,LCFI21-LCFI20 + .long L$set$32 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE15: + .globl _SEE.eh +_SEE.eh: +LSFDE17: + .set L$set$33,LEFDE17-LASFDE17 + .long L$set$33 +LASFDE17: + .long LASFDE17-EH_frame1 + .quad LFB41-. + .set L$set$34,LFE41-LFB41 + .quad L$set$34 + .byte 0x0 + .byte 0x4 + .set L$set$35,LCFI23-LFB41 + .long L$set$35 + .byte 0xe + .byte 0x10 + .byte 0x86 + .byte 0x2 + .byte 0x4 + .set L$set$36,LCFI24-LCFI23 + .long L$set$36 + .byte 0xd + .byte 0x6 + .align 3 +LEFDE17: + .subsections_via_symbols diff --git a/src/sig.c b/src/sig.c new file mode 100755 index 0000000..7c6c521 --- /dev/null +++ b/src/sig.c @@ -0,0 +1,244 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + sig.c + +Abstract: + + Position signature code... the algorithm is a Zobrist hash scheme. + Every piece has a different 64-bit "seed" for every different + square. Plus some non-piece/location features of a position (such + as legal castling rights or the en passant location) have 64-bit + "seed" keys. The position's signature is the xor sum of all these + seeds. A position's pawn hash signature is the xor sum of all + pawn-related seeds. These signatures, once computed, can be + incrementally maintained by just xoring off the seed of a moving + piece's from location and xoring on the seed of its to location. + These signatures are used as the basis for the pawn hash and main + transposition table code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 09 May 2004 + +Revision History: + + $Id: sig.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" + +UINT64 g_u64SigSeeds[128][7][2]; +UINT64 g_u64PawnSigSeeds[128][2]; +UINT64 g_u64CastleSigSeeds[16]; +UINT64 g_u64EpSigSeeds[9]; + +void +InitializeSigSystem(void) +/** + +Routine description: + + Populate the arrays of signature keys (see above) used to generate + normal and pawn signatures for POSITIONs. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG x, y, z; + UINT uChecksum = 0; + ULONG uRandom; + + memset(g_u64SigSeeds, 0, sizeof(g_u64SigSeeds)); + memset(g_u64PawnSigSeeds, 0, sizeof(g_u64PawnSigSeeds)); + memset(g_u64CastleSigSeeds, 0, sizeof(g_u64CastleSigSeeds)); + memset(g_u64EpSigSeeds, 0, sizeof(g_u64EpSigSeeds)); + seedMT(2222); + + for (x = A; x <= H+1; x++) + { + // + // Do en-passant sig + // + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64EpSigSeeds[x] = (UINT64)uRandom << 32; + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64EpSigSeeds[x] |= uRandom; + g_u64EpSigSeeds[x] &= ~1; + } + + // + // Foreach square on the board. + // + for (x = 0; x < 128; x++) + { + // + // For both colors + // + FOREACH_COLOR(z) + { + // + // Do the pawn sigs + // + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64PawnSigSeeds[x][z] = (UINT64)uRandom << 32; + + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64PawnSigSeeds[x][z] |= uRandom; + g_u64PawnSigSeeds[x][z] &= ~1; + + // + // Do the piece sigs + // + for (y = 0; y < 7; y++) + { + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64SigSeeds[x][y][z] = (UINT64)uRandom << 32; + + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64SigSeeds[x][y][z] |= uRandom; + g_u64SigSeeds[x][y][z] &= ~1; + } + } + } + + // + // For all castle permissions + // + for (x = 0; x < 16; x++) + { + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64CastleSigSeeds[x] = (UINT64)uRandom << 32; + + uRandom = randomMT(); + uChecksum ^= uRandom; + g_u64CastleSigSeeds[x] |= uRandom; + g_u64CastleSigSeeds[x] &= ~1; + } + + // + // Make sure we got what we expected. + // + if (uChecksum != 0xac19ab2b) + { + UtilPanic(DETECTED_INCORRECT_INITIALIZATION, + NULL, + "signature system", + (void *)uChecksum, + (void *)0xac19ab2b, + __FILE__, __LINE__); + } +} + + +UINT64 +ComputePawnSig(POSITION *pos) +/** + +Routine description: + + Given a board, recompute the pawn signature from scratch. + +Parameters: + + POSITION *pos + +Return value: + + UINT64 + +**/ +{ + register COOR c; + PIECE p; + UINT64 u64Sum = 0; + + FOREACH_SQUARE(c) + { + if (!IS_ON_BOARD(c)) continue; + + p = pos->rgSquare[c].pPiece; + if (IS_PAWN(p)) + { + u64Sum ^= g_u64PawnSigSeeds[c][GET_COLOR(p)]; + } + } + return(u64Sum); +} + + +UINT64 +ComputeSig(POSITION *pos) +/** + +Routine description: + + Given a board, recompute the main signature from scratch. + +Parameters: + + POSITION *pos + +Return value: + + UINT64 + +**/ +{ + register COOR c; + UINT64 u64Sum = 0; + PIECE p; + + FOREACH_SQUARE(c) + { + if (!IS_ON_BOARD(c)) continue; + + p = pos->rgSquare[c].pPiece; + + if (!IS_EMPTY(p) && !IS_PAWN(p)) + { + ASSERT(IS_VALID_PIECE(p)); + u64Sum ^= g_u64SigSeeds[c][PIECE_TYPE(p)][GET_COLOR(p)]; + } + } + + // + // Update the signature to reflect the castle permissions and ep + // square at this point. + // + u64Sum ^= g_u64CastleSigSeeds[pos->bvCastleInfo]; + u64Sum ^= g_u64EpSigSeeds[FILE(pos->cEpSquare)]; + + // + // Update the low order bit to reflect the side to move. + // + if (pos->uToMove == WHITE) + { + u64Sum |= 1; + } + else + { + u64Sum &= ~1; + } + ASSERT((u64Sum & 1) == pos->uToMove); + + return(u64Sum); +} diff --git a/src/split.c b/src/split.c new file mode 100755 index 0000000..714d77b --- /dev/null +++ b/src/split.c @@ -0,0 +1,1154 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + split.c + +Abstract: + + This code is the glue needed to run a parallel search. Let me + encourage other chess programmers to read this code carefully. + Implementing a parallel search is pretty easy and I procrastinated + doing it for WAY too long because I was afraid to sink multiple + months into coding it up. It's not as hard as you think. If you + have a good handle on multi-threaded programming then you can do + something that works pretty well in a week. + + Here's my system (which is not original -- I believe this is the + same idea that Bruce Moreland used for Ferret and I've been told + it's simiar to what Bob Hyatt does in Crafty). You want to split + the search on all-nodes. There is some overhead involved in + splitting the tree and, after you paid the price, you do not want + one of the moves failing high... because then you have to abort + the split and return a fail high. + + Once my search has one of these nodes, it calls in here to split + the tree. What's involved with splitting the tree is: + + 1. populating a "split node" with data about the position + we are splitting in. + 2. grabbing zero or more idle "worker threads" to come help + with the split. + 3. all threads searching under the split grab a move from + the move list and search that move's subtree in parallel. + 4. when a subtree is evaluated... all threads update the + split node with new information (i.e. raise alpha or, in + the undesirable case that a thread failed high, toggles + a flag in the split node to inform the rest of the + searchers). + 5. before grabbing the next move, each thread updates its + local alpha to pick up window-narrowing information + encountered by other threads. + 6. goto step 3, stop when there are no more moves or + thread finds a fail high. + + ------------------------------------------------------------------ + + This is a quote from some win32 blog about the x86 memory model + which I found helpful to read while I was thinking about + multithreaded code in this module: + + "The most familiar model is X86. It's a relatively strong model. + Stores are never reordered with respect to other stores. But, in + the absence of data dependence, loads can be reordered with + respect to other loads and stores. Many X86 developers don't + realize that this reordering is possible, though it can lead to + some nasty failures under stress on big MP machines. + + In terms of the above, the memory model for X86 can be described as: + + 1. All stores are actually store.release (upward memory fence). + This means that normal loads can be moved above the + store.release but nothing can be moved below it. + 2. All loads are normal loads. + 3. Any use of the LOCK prefix (e.g. LOCK CMPXCHG or LOCK INC) + creates a full memory fence." + +Author: + + Scott Gasch (scott.gasch@gmail.com) 25 Jun 2004 + +Revision History: + + $Id: split.c 345 2007-12-02 22:56:42Z scott $ + +**/ +#ifdef MP + +#include "chess.h" + +extern ULONG g_uIterateDepth; +ULONG g_uNumHelperThreads = 0; +#define MAX_SPLITS (20) +#define IDLE ((ULONG)-1) + +void +HelpSearch(SEARCHER_THREAD_CONTEXT *ctx, ULONG u); + +// +// A struct that holds information about helper threads. +// +typedef struct _HELPER_THREAD +{ + ULONG uHandle; + volatile ULONG uAssignment; + SEARCHER_THREAD_CONTEXT ctx; +#ifdef PERF_COUNTERS + UINT64 u64IdleCycles; + UINT64 u64BusyCycles; +#endif +} HELPER_THREAD; + +// +// An array of these structs that is alloced dynamically so that N +// cpus is not a hardcoded thing, the engine can scale N based on +// where it is running. +// +static HELPER_THREAD *g_HelperThreads = NULL; + +// +// An array of structs that hold information about where we have split +// the search tree. +// +static SPLIT_INFO g_SplitInfo[MAX_SPLITS]; + +// +// In addition to this main split database lock each split entry has +// its own private lock. This way contention between searcher threads +// operating on different split nodes is eliminated. +// +volatile static ULONG g_uSplitLock = 0; +#define SPLITS_LOCKED (g_uSplitLock != 0) +#define LOCK_SPLITS \ + AcquireSpinLock(&g_uSplitLock); \ + ASSERT(SPLITS_LOCKED); +#define UNLOCK_SPLITS \ + ASSERT(SPLITS_LOCKED); \ + ReleaseSpinLock(&g_uSplitLock); + +static ULONG g_uNumSplitsAvailable; +volatile ULONG g_uNumHelpersAvailable; + + +ULONG +HelperThreadIdleLoop(IN ULONG uMyId) +/** + +Routine description: + + The entry point of a helper thread. It will spin in the idle loop + here until another thread splits the search tree, sees that it is + idle, and notifies it to come help by changing the assignment + field in its struct. + +Parameters: + + ULONG uMyId : this thread's index in g_HelperThreads + +Return value: + + ULONG + +**/ +{ + SEARCHER_THREAD_CONTEXT *ctx = &(g_HelperThreads[uMyId].ctx); + ULONG u, v; + MOVE mv; + ULONG uIdleLoops = 0; +#ifdef PERF_COUNTERS + UINT64 u64Then; + UINT64 u64Now; +#endif +#ifdef DEBUG + POSITION board; +#endif + InitializeSearcherContext(NULL, ctx); + ctx->uThreadNumber = uMyId + 1; + do + { +#ifdef PERF_COUNTERS + if (uIdleLoops == 0) u64Then = SystemReadTimeStampCounter(); +#endif + // + // Did someone tell us to come help? + // + if ((u = g_HelperThreads[uMyId].uAssignment) != IDLE) + { + // + // By now the split info is populated. + // + uIdleLoops = 0; + ReInitializeSearcherContext(&(g_SplitInfo[u].sRootPosition), ctx); + ctx->pSplitInfo[0] = &(g_SplitInfo[u]); + ctx->uPositional = g_SplitInfo[u].uSplitPositional; + + // + // Note: the main thread could have already exhausted the + // split and decremented it from 3->2. When we leave it + // will fall to 1 and allow the main thread to continue. + // + ASSERT(g_SplitInfo[u].uNumThreadsHelping >= 2); + + // + // Get from the root of the search to the split position. + // We do this instead of just initializing the searcher + // context at the split node so that historic things like + // draw detection still work in the helper threads. + // + v = 0; + do + { + ASSERT(v < MAX_PLY_PER_SEARCH); + mv.uMove = g_SplitInfo[u].mvPathToHere[v].uMove; + if (ILLEGALMOVE == mv.uMove) break; +#ifdef DEBUG + if (mv.uMove) + { + ASSERT(SanityCheckMove(&ctx->sPosition, mv)); + } +#endif + if (FALSE == MakeMove(ctx, mv)) + { + UtilPanic(CANNOT_INITIALIZE_SPLIT, + &ctx->sPosition, + (void *)mv.uMove, + &g_SplitInfo[u], + (void *)v, + __FILE__, __LINE__); + } + v++; + } + while(1); +#ifdef DEBUG + ASSERT(g_SplitInfo[u].uSplitPly == ctx->uPly); + ASSERT(v > 0); + ASSERT(IS_SAME_MOVE(g_SplitInfo[u].mvPathToHere[v-1], + g_SplitInfo[u].mvLast)); + ASSERT(PositionsAreEquivalent(&(ctx->sPosition), + &(g_SplitInfo[u].sSplitPosition))); + VerifyPositionConsistency(&(ctx->sPosition), FALSE); + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + // + // Populate the move stack of this helper context to make + // it look like it generated to moves at the split. The + // reason I do this is so that ComputeMoveExtension (which + // looks at the move stack) will work at a split node even + // if the context it gets is a helper thread's. + // + ctx->sMoveStack.uBegin[ctx->uPly] = 0; + ctx->sMoveStack.uBegin[ctx->uPly + 1] = + ctx->sMoveStack.uEnd[ctx->uPly] = g_SplitInfo[u].uNumMoves; + + for (v = 0; + v < g_SplitInfo[u].uNumMoves; + v++) + { + ctx->sMoveStack.mvf[v] = g_SplitInfo[u].mvf[v]; + ASSERT(SanityCheckMove(&ctx->sPosition, + g_SplitInfo[u].mvf[v].mv)); + } + + // + // Go help with the search + // + HelpSearch(ctx, u); + ASSERT(PositionsAreEquivalent(&board, &(ctx->sPosition))); + + // + // Done with this assignment, wrap up and go back to idle state + // + LOCK_SPLITS; + g_HelperThreads[uMyId].uAssignment = IDLE; + g_uNumHelpersAvailable++; + UNLOCK_SPLITS; +#ifdef PERF_COUNTERS + u64Now = SystemReadTimeStampCounter(); + g_HelperThreads[uMyId].u64BusyCycles += (u64Now - u64Then); +#endif + } +#if PERF_COUNTERS + // + // There was nothing for us to do, if that happens often + // enough remember the idle cycles. + // + else + { + uIdleLoops++; + if (uIdleLoops > 1000) + { + u64Now = SystemReadTimeStampCounter(); + LOCK_SPLITS; + g_HelperThreads[uMyId].u64IdleCycles += (u64Now - u64Then); + UNLOCK_SPLITS; + uIdleLoops = 0; +#ifdef DEBUG + SystemDeferExecution(1); +#endif + } + } +#endif + } + while(FALSE == g_fExitProgram); + Trace("HELPER THREAD: thread terminating.\n"); + + return(0); // ExitThread +} + + +FLAG +InitializeParallelSearch(void) +/** + +Routine description: + + This routine must be called before any thread can split the search + tree because it sets up the parallel search system. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + ULONG u; + + if (g_Options.uNumProcessors < 2) return(FALSE); + + // + // Initialize split entries + // + g_uSplitLock = 0; + for (u = 0; u < MAX_SPLITS; u++) + { + memset(&(g_SplitInfo[u]), 0, sizeof(g_SplitInfo[u])); + } + g_uNumSplitsAvailable = MAX_SPLITS; + ASSERT(NUM_SPLIT_PTRS_IN_CONTEXT <= MAX_SPLITS); + + // + // Create and initialize helper threads + // + g_uNumHelperThreads = g_Options.uNumProcessors - 1; + ASSERT(g_uNumHelperThreads >= 1); + g_HelperThreads = SystemAllocateMemory(sizeof(HELPER_THREAD) * + g_uNumHelperThreads); + ASSERT(g_HelperThreads != NULL); + for (u = 0; u < g_uNumHelperThreads; u++) + { + memset(&(g_HelperThreads[u]), 0, sizeof(g_HelperThreads[u])); + g_HelperThreads[u].uAssignment = IDLE; + if (FALSE == SystemCreateThread(HelperThreadIdleLoop, + u, + &(g_HelperThreads[u].uHandle))) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, + "creating a thread", + 0, + NULL, + __FILE__, __LINE__); + } + } + g_uNumHelpersAvailable = g_uNumHelperThreads; + return(TRUE); +} + + +#ifdef PERF_COUNTERS +void +ClearHelperThreadIdleness(void) +/** + +Routine description: + + Called at the start of a search, if PERF_COUNTERS is + defined... this function's job is to reset the idleness counter + for all helper threads. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG u; + + LOCK_SPLITS; + for (u = 0; u < g_uNumHelperThreads; u++) + { + g_HelperThreads[u].u64BusyCycles = + g_HelperThreads[u].u64IdleCycles = 0ULL; + } + UNLOCK_SPLITS; +} + + +void +DumpHelperIdlenessReport(void) +/** + +Routine description: + + Called at the end of a search, this function's job is to print + out a report of how busy/idle each helper threads was. + +Parameters: + + void + +Return value: + + void + +**/ +{ + ULONG u; + double n, d; + + for (u = 0; + u < g_uNumHelperThreads; + u++) + { + n = (double)g_HelperThreads[u].u64BusyCycles; + d = (double)g_HelperThreads[u].u64IdleCycles; + d += n; + Trace("Helper thread %u: %5.2f percent busy.\n", u, (n / d) * 100.0); + } +} +#endif + + +FLAG +CleanupParallelSearch(void) +/** + +Routine description: + + Cleanup parallel search system before program shutdown. + +Parameters: + + void + +Return value: + + FLAG + +**/ +{ + if (g_HelperThreads != NULL ) + { + SystemFreeMemory(g_HelperThreads); + } + g_uNumHelperThreads = 0; + return(TRUE); +} + + +SCORE +StartParallelSearch(IN SEARCHER_THREAD_CONTEXT *ctx, + IN OUT SCORE *piAlpha, + IN SCORE iBeta, + IN OUT SCORE *piBestScore, + IN OUT MOVE *pmvBest, + IN ULONG uMoveNum, + IN INT iPositionExtend, + IN ULONG uDepth) +{ +/** + +Routine description: + + This routine is called from the main Search (not RootSearch or QSearch) + when: + + 1. it thinks the current search tree node looks like it could + be searched in parallel -and- + + 2. it's likely that there are idle helper thread(s) to help. + + It job is to find a free split node, populate it, find idle helper + threads, assign them to help, and search this node in parallel. + It _must_ be called after generating moves at this node. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : context of thread requesting split + SCORE *piAlpha : in/out alpha of split node + SCORE iBeta : in only (beta doesn't change) beta of split node + SCORE *piBestScore : in/out best score seen so far at split node + MOVE *pmvBest : in/out best move seen so far at split node + ULONG uMoveNum : in next move number in ctx->sMoveStack + INT iPositionExtend : in position based extensions for split node + ULONG uDepth : in the depth we need to search to + +Return value: + + SCORE : the score of this split subtree, along with out params above + +**/ + SCORE iScore; + ULONG u, v; + ULONG uSplitNum; + ULONG uOldStart; +#ifdef DEBUG + POSITION board; + + ASSERT(IS_VALID_SCORE(*piAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(IS_VALID_SCORE(*piBestScore)); + ASSERT(*piBestScore > -INFINITY); + ASSERT(pmvBest->uMove); + ASSERT(*piAlpha < iBeta); + + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); + VerifyPositionConsistency(&board, FALSE); +#endif + + // + // Note: This is a lazy lock construction: search.c has peeked at + // g_uNumHelperThreads before calling us and only calls when it + // thinks there's a helper available. (1) We could find that + // there is no helper available now because of the race condition. + // (2) On IA64 memory model this type of construct is + // _not_supported_ (my understanding is that this is supported on + // X86 and AMD64, though). + // + LOCK_SPLITS; + for (u = 0; u < MAX_SPLITS; u++) + { + // + // Try to find a vacant split + // + if (g_SplitInfo[u].uNumThreadsHelping == 0) + { + // + // Found one, populate it. + // + ASSERT(g_uNumSplitsAvailable > 0); + g_uNumSplitsAvailable--; + + // + // We initialize this to two to double-reference this + // split node. This guarantees we are the last ones + // holding a reference to it (since we want to be the last + // one out of this split node) + // + g_SplitInfo[u].uNumThreadsHelping = 2; + + // + // Store the path from the root to the split node and the + // root position to start at. This is done so that + // ponders that convert into searches don't crash us and + // so that helper threads can detect repeated positions + // before the split point. + // + ASSERT(ctx->uPly >= 1); + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + for (v = 0; v < ctx->uPly; v++) + { + g_SplitInfo[u].mvPathToHere[v] = ctx->sPlyInfo[v].mv; + } + g_SplitInfo[u].mvPathToHere[v].uMove = ILLEGALMOVE; + ASSERT(v >= 1); + g_SplitInfo[u].mvLast = g_SplitInfo[u].mvPathToHere[v-1]; + memcpy(&(g_SplitInfo[u].sRootPosition), + GetRootPosition(), + sizeof(POSITION)); +#if DEBUG + g_SplitInfo[u].uSplitPly = ctx->uPly; + memcpy(&(g_SplitInfo[u].sSplitPosition), + &(ctx->sPosition), + sizeof(POSITION)); +#endif + // + // What has happened here is that another thread has + // triggered the "stop searching" bit in the move timer. + // This also means that the root position may have changed + // and therefore the split we just populated can be + // useless. Before we grab any helper threads, see if we + // need to bail out of this split. + // + if (g_MoveTimer.bvFlags & TIMER_STOPPING) + { + g_uNumSplitsAvailable++; + g_SplitInfo[u].uNumThreadsHelping = 0; + UNLOCK_SPLITS; + return(INVALID_SCORE); + } + + // + // More split node initialization + // + g_SplitInfo[u].uLock = 0; + g_SplitInfo[u].fTerminate = FALSE; + g_SplitInfo[u].uDepth = uDepth; + g_SplitInfo[u].iPositionExtend = iPositionExtend; + g_SplitInfo[u].iAlpha = *piAlpha; + g_SplitInfo[u].iBeta = iBeta; + g_SplitInfo[u].uSplitPositional = ctx->uPositional; + g_SplitInfo[u].sSearchFlags = ctx->sSearchFlags; + ASSERT(FALSE == ctx->sSearchFlags.fAvoidNullmove); + g_SplitInfo[u].mvBest = *pmvBest; + g_SplitInfo[u].iBestScore = *piBestScore; + ASSERT(g_SplitInfo[u].iBestScore <= g_SplitInfo[u].iAlpha); + g_SplitInfo[u].sCounters.tree.u64TotalNodeCount = 0; + g_SplitInfo[u].sCounters.tree.u64BetaCutoffs = 0; + g_SplitInfo[u].sCounters.tree.u64BetaCutoffsOnFirstMove = 0; + g_SplitInfo[u].PV[0] = NULLMOVE; + + // + // Copy the remaining moves to be searched from the + // searcher context that called us into the split node. + // Note: this thread must have already called + // GenerateMoves at the split node! + // + uOldStart = ctx->sMoveStack.uBegin[ctx->uPly]; + g_SplitInfo[u].uAlreadyDone = uMoveNum - uOldStart + 1; + ASSERT(g_SplitInfo[u].uAlreadyDone >= 1); + ctx->sMoveStack.uBegin[ctx->uPly] = uMoveNum; + for (v = uMoveNum, g_SplitInfo[u].uRemainingMoves = 0; + (v < ctx->sMoveStack.uEnd[ctx->uPly]); + v++, g_SplitInfo[u].uRemainingMoves++) + { + ASSERT(g_SplitInfo[u].uRemainingMoves >= 0); + ASSERT(g_SplitInfo[u].uRemainingMoves < MAX_MOVES_PER_PLY); + + // + // If we fail high at this node we have done a lot of + // work for naught. We also want to know as soon as + // possible so that we can vacate this split point, + // free up a worker thread and get back to the main + // search. So forget about the SEARCH_SORT_LIMIT + // stuff here and sort the whole list of moves from + // best..worst. + // + SelectBestWithHistory(ctx, v); + ctx->sMoveStack.mvf[v].mv.bvFlags |= + WouldGiveCheck(ctx, ctx->sMoveStack.mvf[v].mv); + ASSERT(!(ctx->sMoveStack.mvf[v].bvFlags & MVF_MOVE_SEARCHED)); + g_SplitInfo[u].mvf[g_SplitInfo[u].uRemainingMoves] = + ctx->sMoveStack.mvf[v]; +#ifdef DEBUG + ctx->sMoveStack.mvf[v].bvFlags |= MVF_MOVE_SEARCHED; +#endif + } + g_SplitInfo[u].uOnDeckMove = 0; + g_SplitInfo[u].uNumMoves = g_SplitInfo[u].uRemainingMoves; +#ifdef DEBUG + for (v = uMoveNum; + v < ctx->sMoveStack.uEnd[ctx->uPly]; + v++) + { + ASSERT(ctx->sMoveStack.mvf[v].bvFlags & MVF_MOVE_SEARCHED); + ASSERT(SanityCheckMove(&ctx->sPosition, + ctx->sMoveStack.mvf[v].mv)); + } +#endif + + // + // See if we can get some help here or we have to go it + // alone. Note: past this point the split we are using + // may have threads under it -- be careful. + // + for (v = 0; v < g_uNumHelperThreads; v++) + { + if (g_HelperThreads[v].uAssignment == IDLE) + { + // + // Note: there could already be a thread searching + // this split; we must obtain its lock now to mess + // with the helper count. + // + AcquireSpinLock(&(g_SplitInfo[u].uLock)); + g_SplitInfo[u].uNumThreadsHelping += 1; + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); + ASSERT(g_SplitInfo[u].uNumThreadsHelping > 2); + ASSERT(g_uNumHelpersAvailable > 0); + g_uNumHelpersAvailable -= 1; + ASSERT(g_uNumHelpersAvailable >= 0); + ASSERT(g_uNumHelpersAvailable < g_uNumHelperThreads); + g_HelperThreads[v].uAssignment = u; + } + } + UNLOCK_SPLITS; + + // + // Update the context of the thread that is initiating the + // split with a pointer to the split info node we are using. + // + for (uSplitNum = 0; + uSplitNum < NUM_SPLIT_PTRS_IN_CONTEXT; + uSplitNum++) + { + if (ctx->pSplitInfo[uSplitNum] == NULL) + { + ctx->pSplitInfo[uSplitNum] = &(g_SplitInfo[u]); + break; + } + } + if (uSplitNum >= NUM_SPLIT_PTRS_IN_CONTEXT) + { + ASSERT(FALSE); + return(INVALID_SCORE); + } + ASSERT(ctx->pSplitInfo[uSplitNum] == &(g_SplitInfo[u])); + + // + // Go search it + // + INC(ctx->sCounters.parallel.uNumSplits); + HelpSearch(ctx, u); + + // + // We are done searching under this node... make sure all + // helpers are done too. When everyone is finished the + // refcount on this split node will be one because every + // thread decremented it once and we double referenced + // it initially. + // + while(g_SplitInfo[u].uNumThreadsHelping != 1) + { + ASSERT(g_SplitInfo[u].uNumThreadsHelping != 0); + if (g_fExitProgram) break; + } + + // + // Note: past this point we are the only ones using the + // split until we return it to the pool by making its + // refcount zero again. + // +#ifdef DEBUG + ASSERT((g_SplitInfo[u].uNumThreadsHelping == 1) || + (g_fExitProgram)); + SystemDeferExecution(rand() % 2); + ASSERT((g_SplitInfo[u].uNumThreadsHelping == 1) || + (g_fExitProgram)); + if (g_SplitInfo[u].iBestScore < g_SplitInfo[u].iBeta) + { + for (v = 0; + v < g_SplitInfo[u].uRemainingMoves; + v++) + { + ASSERT(g_SplitInfo[u].mvf[v].mv.uMove); + ASSERT(g_SplitInfo[u].mvf[v].bvFlags & MVF_MOVE_SEARCHED); + } + } +#endif +#ifdef PERF_COUNTERS + // + // Grab counters. Technically we should do with under a + // lock b/c we want to ensure that any pending memory + // operations from other cpus are flushed. But I don't + // really care too much about these counters and am trying + // to reduce lock contention. + // + if (TRUE == g_SplitInfo[u].fTerminate) + { + ASSERT(g_SplitInfo[u].iBestScore >= g_SplitInfo[u].iBeta); + INC(ctx->sCounters.parallel.uNumSplitsTerminated); + } + ctx->sCounters.tree.u64BetaCutoffs = + g_SplitInfo[u].sCounters.tree.u64BetaCutoffs; + ctx->sCounters.tree.u64BetaCutoffsOnFirstMove = + g_SplitInfo[u].sCounters.tree.u64BetaCutoffsOnFirstMove; +#endif + // + // Pop off the split info ptr from the stack in the thread's + // context. + // + ASSERT(ctx->pSplitInfo[uSplitNum] == &(g_SplitInfo[u])); + ctx->pSplitInfo[uSplitNum] = NULL; + + // + // Grab alpha, bestscore, bestmove, PV etc... The lock + // needs to be here to flush any pending memory writes + // from other processors. + // + LOCK_SPLITS; + ctx->sCounters.tree.u64TotalNodeCount = + g_SplitInfo[u].sCounters.tree.u64TotalNodeCount; + iScore = *piBestScore = g_SplitInfo[u].iBestScore; + *pmvBest = g_SplitInfo[u].mvBest; + if ((*piAlpha < iScore) && (iScore < iBeta)) + { + ASSERT(IS_SAME_MOVE(*pmvBest, g_SplitInfo[u].PV[0])); + ASSERT((*pmvBest).uMove != 0); + v = 0; + do + { + ASSERT((ctx->uPly + v) < MAX_PLY_PER_SEARCH); + ASSERT(v < MAX_PLY_PER_SEARCH); + ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly+v] = + g_SplitInfo[u].PV[v]; + if (0 == g_SplitInfo[u].PV[v].uMove) break; + v++; + } + while(1); + } + *piAlpha = g_SplitInfo[u].iAlpha; + ASSERT(iBeta == g_SplitInfo[u].iBeta); + g_uNumSplitsAvailable++; + g_SplitInfo[u].uNumThreadsHelping = 0; + UNLOCK_SPLITS; + ctx->sMoveStack.uBegin[ctx->uPly] = uOldStart; + +#ifdef DEBUG + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); + VerifyPositionConsistency(&ctx->sPosition, FALSE); + ASSERT(IS_VALID_SCORE(iScore) || WE_SHOULD_STOP_SEARCHING); +#endif + return(iScore); + } + } + + // + // There was no split available for us; unlock and continue in + // search. + // + UNLOCK_SPLITS; + return(INVALID_SCORE); +} + + +static void +_UpdateSplitInfo(IN SEARCHER_THREAD_CONTEXT *ctx, + IN MOVE mv, + IN SCORE iScore, + IN ULONG u) +/** + +Routine description: + + We think we have some information learned from search to store in + the split node. Take the lock and see if we really do. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : context of thread updating split + MOVE mv : move it just searched + SCORE iScore : score of the move's subtree + ULONG u : split node number + +Return value: + + static void + +**/ +{ + ULONG v; + + AcquireSpinLock(&(g_SplitInfo[u].uLock)); + + // + // See if this split is shutting down + // + if (TRUE == g_SplitInfo[u].fTerminate) + { + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); + return; + } + + if (iScore > g_SplitInfo[u].iBestScore) + { + // + // We found a move better than the best so far, so we want to + // update the split node and possibly raise alpha. + // + g_SplitInfo[u].iBestScore = iScore; + g_SplitInfo[u].mvBest = mv; + if (iScore > g_SplitInfo[u].iAlpha) + { + if (iScore >= g_SplitInfo[u].iBeta) + { + // + // We failed high so we want to update the split node + // + g_SplitInfo[u].fTerminate = TRUE; + g_SplitInfo[u].PV[0] = NULLMOVE; + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); + return; + } + + // + // Normal PV move, update the split's PV. + // + g_SplitInfo[u].iAlpha = iScore; + UpdatePV(ctx, mv); + ASSERT(ctx->uPly < MAX_PLY_PER_SEARCH); + ASSERT(ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly].uMove); + for (v = 0; v < MAX_PLY_PER_SEARCH; v++) + { + ASSERT((ctx->uPly + v) < MAX_PLY_PER_SEARCH); + mv = ctx->sPlyInfo[ctx->uPly].PV[ctx->uPly + v]; + g_SplitInfo[u].PV[v] = mv; + if (0 == mv.uMove) break; + } + } + } + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); +} + + +static void +_SetFinalStats(IN SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG u) +/** + +Routine description: + + We are exiting the split node (because it ran out of moves or + because someone failed high). Update some stats on the way out. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + ULONG u + +Return value: + + static void + +**/ +{ + // + // Before we stop searching this node, update some stuff. + // + AcquireSpinLock(&(g_SplitInfo[u].uLock)); + + // + // Counters to persist in the main counter struct via the split. + // + g_SplitInfo[u].sCounters.tree.u64TotalNodeCount += + ctx->sCounters.tree.u64TotalNodeCount; + g_SplitInfo[u].sCounters.tree.u64BetaCutoffs += + ctx->sCounters.tree.u64BetaCutoffs; + g_SplitInfo[u].sCounters.tree.u64BetaCutoffsOnFirstMove += + ctx->sCounters.tree.u64BetaCutoffsOnFirstMove; + + // + // TODO: Any other counters we care about? + // + + // + // IDEA: Save the killers from this context to bring back to main + // + + // + // Decrement threadcount in this split. Note: the main thread + // incremented it by two. + // + ASSERT((g_SplitInfo[u].uNumThreadsHelping > 1) || (g_fExitProgram)); + g_SplitInfo[u].uNumThreadsHelping -= 1; + ASSERT((g_SplitInfo[u].uNumThreadsHelping >= 1) || (g_fExitProgram)); + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); +} + + +static MOVE +_GetNextParallelMove(OUT SCORE *piAlpha, + OUT SCORE *piBestScore, + OUT ULONG *puMoveNumber, + IN ULONG u) +/** + +Routine description: + + Retrieve the next parallel move to search at the split node. Also + update alpha and bestscore. + +Parameters: + + SCORE *piAlpha : current alpha + SCORE *piBestScore : current bestscore + ULONG u : split number + +Return value: + + static MOVE + +**/ +{ + MOVE mv = {0}; + + AcquireSpinLock(&(g_SplitInfo[u].uLock)); + if (g_SplitInfo[u].fTerminate) + { + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); + return(mv); + } + + if (g_SplitInfo[u].uRemainingMoves != 0) + { + // + // There is another move to search, get it. + // + mv = g_SplitInfo[u].mvf[g_SplitInfo[u].uOnDeckMove].mv; +#ifdef DEBUG + ASSERT(!(g_SplitInfo[u].mvf[g_SplitInfo[u].uOnDeckMove].bvFlags & + MVF_MOVE_SEARCHED)); + g_SplitInfo[u].mvf[g_SplitInfo[u].uOnDeckMove].bvFlags |= + MVF_MOVE_SEARCHED; + ASSERT(mv.uMove); + ASSERT(SanityCheckMove(&g_SplitInfo[u].sSplitPosition, mv)); +#endif + g_SplitInfo[u].uRemainingMoves--; + *puMoveNumber = g_SplitInfo[u].uOnDeckMove; + g_SplitInfo[u].uOnDeckMove++; + } + *piAlpha = g_SplitInfo[u].iAlpha; + *piBestScore = g_SplitInfo[u].iBestScore; + ReleaseSpinLock(&(g_SplitInfo[u].uLock)); + ASSERT(*piBestScore <= *piAlpha); + return(mv); +} + + +void +HelpSearch(IN OUT SEARCHER_THREAD_CONTEXT *ctx, + IN ULONG u) +/** + +Routine description: + + Help search the split position. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx : thread context + ULONG u : the split index to help search + +Return value: + + void + +**/ +{ + SCORE iScore; + SCORE iAlpha = 0; + SCORE iBeta; + SCORE iBestScore = 0; + SCORE iRoughEval; + ULONG uOrigDepth; + ULONG uDepth; + ULONG uMoveNum = 0; + INT iOrigExtend; + INT iExtend; + MOVE mv; +#ifdef DEBUG + POSITION board; + + memcpy(&board, &ctx->sPosition, sizeof(POSITION)); + ASSERT(PositionsAreEquivalent(&board, &g_SplitInfo[u].sSplitPosition)); +#endif + + iOrigExtend = g_SplitInfo[u].iPositionExtend; + iBeta = g_SplitInfo[u].iBeta; + uOrigDepth = g_SplitInfo[u].uDepth; + ctx->sSearchFlags = g_SplitInfo[u].sSearchFlags; + do + { + iExtend = iOrigExtend; + uDepth = uOrigDepth; + ASSERT(ctx->uPly == g_SplitInfo[u].uSplitPly); + + mv = _GetNextParallelMove(&iAlpha, + &iBestScore, + &uMoveNum, + u); + if (mv.uMove == 0) break; // Split is terminating + + ASSERT(IS_VALID_SCORE(iBestScore)); + ASSERT(uMoveNum < MAX_MOVES_PER_PLY); + ASSERT(IS_SAME_MOVE(mv, + ctx->sMoveStack.mvf[ctx->sMoveStack.uBegin[ctx->uPly]+uMoveNum].mv)); + ASSERT(uDepth <= MAX_DEPTH_PER_SEARCH); + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(iExtend >= -ONE_PLY); + ASSERT(iExtend <= +ONE_PLY); + + if (MakeMove(ctx, mv)) + { + ASSERT((IS_CHECKING_MOVE(mv) && + InCheck(&ctx->sPosition, ctx->sPosition.uToMove)) || + (!IS_CHECKING_MOVE(mv) && + !InCheck(&ctx->sPosition, ctx->sPosition.uToMove))); + iRoughEval = GetRoughEvalScore(ctx, iAlpha, iBeta, TRUE); + + // Compute extension + ComputeMoveExtension(ctx, + iAlpha, + iBeta, + (ctx->sMoveStack.uBegin[ctx->uPly - 1] + + uMoveNum), + iRoughEval, + uDepth, + &iExtend); + + // + // Decide whether to history prune + // + if (TRUE == WeShouldDoHistoryPruning(iRoughEval, + iAlpha, + iBeta, + ctx, + uDepth, + (g_SplitInfo[u].uAlreadyDone + + uMoveNum + 1), + mv, + (g_SplitInfo[u].uAlreadyDone + + uMoveNum + 1), + iExtend)) + { + ASSERT(iExtend == 0); + iExtend = -ONE_PLY; + ctx->sPlyInfo[ctx->uPly].iExtensionAmount = -ONE_PLY; + } + + // + // Compute next depth + // + uDepth = uDepth - ONE_PLY + iExtend; + if (uDepth >= MAX_DEPTH_PER_SEARCH) uDepth = 0; + + iScore = -Search(ctx, -iAlpha - 1, -iAlpha, uDepth); + if ((iAlpha < iScore) && (iScore < iBeta)) + { + iScore = -Search(ctx, -iBeta, -iAlpha, uDepth); + } + + // + // Decide whether to research reduced branches to full depth. + // + if ((iExtend < 0) && (iScore >= iBeta)) + { + uDepth += ONE_PLY; + ctx->sPlyInfo[ctx->uPly].iExtensionAmount = 0; + iScore = -Search(ctx, -iBeta, -iAlpha, uDepth); + } + UnmakeMove(ctx, mv); + ASSERT(PositionsAreEquivalent(&ctx->sPosition, &board)); + if (TRUE == g_SplitInfo[u].fTerminate) break; + if (iScore > iBestScore) + { + _UpdateSplitInfo(ctx, mv, iScore, u); + } + } + } + while(1); + _SetFinalStats(ctx, u); +} +#endif diff --git a/src/suite_diff.pl b/src/suite_diff.pl new file mode 100755 index 0000000..6749f07 --- /dev/null +++ b/src/suite_diff.pl @@ -0,0 +1,225 @@ +#!/usr/bin/perl + +$verbose = 0; +for $arg (@ARGV) { + $verbose = 1 if ($arg eq "-v"); +} + +$one_correct = $two_correct = 0; +$one_beta = $two_beta = 0.0; +$one_null = $two_null = 0.0; +$one_time = $two_time = 0.0; +$one_nodes = $two_nodes = 0.0; +$one_depth = $two_depth = 0.0; +$one_extends = $two_extends = 0; +$one_hash = $two_hash = 0; +$one_useful = $two_useful = 0; + +open(LOG, $ARGV[0]) || die "Can't open $ARGV[0], $!\n"; +while() +{ + if (/^Problem \"([^\"]+)\" solved in (\d+\.\d+)/) + { + $one_correct++; + $name = $1; + $time = $2; + } + elsif (/^>>>>> Problem \"([^\"]+)\" was not solved\. <<<<) +{ + if ($_ =~ /^Problem \"([^\"]+)\" solved in (\d+\.\d+)/) + { + $name = $1; + $time = $2; + if ($name =~ /[^\.]+\.(\d+)/) + { + $name = $1; + } + $two_correct++ if (defined($one{$name})); + } + elsif ($_ =~ /^>>>>> Problem \"([^\"]+)\" was not solved\. <<<< 0) +{ + printf "$ARGV[1] by %6.2f sec\n", $sigma_diff; +} +else +{ + print "even.\n"; +} + +@x = keys(%one); +$one_count = $#x; +@x = keys(%two); +$two_count = $#x; + +printf "1st mv betas:\t%6.3f\t%6.3f\n", + ($one_beta / $one_count), ($two_beta / $two_count); +printf "nullmv cutoff:\t%6.3f\t%6.3f\n", + ($one_null / $one_count), ($two_null / $two_count); +printf "avg depth:\t%6.3f\t%6.3f\n", + ($one_depth / $one_count), ($two_depth / $two_count); +printf "total hash:\t%6.3f\t%6.3f\n", + ($one_hash / $one_count), ($two_hash / $two_count); +printf "useful hash:\t%6.3f\t%6.3f\n", + ($one_useful / $one_count), ($two_useful / $two_count); +printf "k-avg.extend:\t%6.3f\t%6.3f\n", + ($one_extends / $one_count) / 1024, ($two_extends / $two_count) / 1024; +printf "k-extends:\t%6u\t%6u\n", + ($one_extends / 1024), ($two_extends / 1024); +printf "overall nps:\t%6u\t%6u\n", + ($one_nodes / $one_time), ($two_nodes / $two_time); diff --git a/src/suite_null.pl b/src/suite_null.pl new file mode 100755 index 0000000..4d7f64b --- /dev/null +++ b/src/suite_null.pl @@ -0,0 +1,24 @@ +#!/usr/bin/perl + +$correct[0] = $correct[1] = 0; +$total[0] = $total[1] = 0; + +while(<>) +{ + #if (/Avoid null move heuristic was (\d+)\s*\/\s*(\d+)./) + #{ + # $correct[0] += $1; + # $total[0] += $2; + #} + if (/ick null move heuristic rate was (\d+)\s*\((\d+)\)\s*\/\s*(\d+)./) + { + $correct[1] += ($1 + $2); + $total[1] += $3; + } +} + +#print "Avoid null move tried $total[0] times, succeeded $correct[0] times.\n"; +#printf "Avoid null move success rate %5.2f percent.\n", $correct[0] / $total[0] * 100.0; +print "Quick null move tried $total[1] times, succeeded $correct[1] times.\n"; +printf "Quick null move success rate %5.2f percent.\n", $correct[1] / $total[1] * 100.0; + diff --git a/src/suite_picker.pl b/src/suite_picker.pl new file mode 100755 index 0000000..9433679 --- /dev/null +++ b/src/suite_picker.pl @@ -0,0 +1,25 @@ +#!/usr/bin/perl + +$max = 0; +while(<>) +{ + if ($_ =~ /^Problem \"([^\"]+)\" solved in/) + { + $k = $1; + $k =~ s/[^\.]*\.//; + $solved[$k]++; + $max = $solved[$k] if ($solved[$k] > $max); + } +} + +for ($k = 0; $k < 880; $k++) +{ + if ($solved[$k] >= ($max - 3)) + { + print "drop ecm.$k\n"; + } + else + { + printf "keep ecm.$k (%u solution(s))\n", $solved[$k]; + } +} diff --git a/src/suite_rep.pl b/src/suite_rep.pl new file mode 100755 index 0000000..4294394 --- /dev/null +++ b/src/suite_rep.pl @@ -0,0 +1,70 @@ +#!/usr/bin/perl + +$NUM_BINS = 20; + + +$max_bin = 0; +open(LOG, $ARGV[0]) || die "Can't open $ARGV[0], $!\n"; +while() +{ + if ($_ =~ /^Problem \"([^\"]+)\" solved in (\d+\.\d+)/) + { + $name = $1; + $time = $2; + } + elsif ($_ =~ /^>>>>> Problem \"([^\"]+)\" was not solved\. <<<< $max_bin) + { + $max_bin = $bin[$bin_num]; + } + $name = ""; + $time = 0; + } +} +close(LOG); + + +for ($x = 1; + $x < $NUM_BINS + 1; + $x++) +{ + $num_star = $bin[$x] / $max_bin * 60; + $num_star = int($num_star); + printf "%02u..%02u sec: %s ($bin[$x])\n", $x-1, $x, "#" x $num_star; + print "\n ids: $ids[$x]\n\n"; +} +$num_star = $bin[0] / $max_bin * 60; +$num_star = int($num_star); +printf "not solved: %s ($bin[0])\n", "#" x $num_star; +print "\n ids: $ids[0]\n\n"; + + diff --git a/src/tbdecode.h b/src/tbdecode.h new file mode 100644 index 0000000..22bd5a0 --- /dev/null +++ b/src/tbdecode.h @@ -0,0 +1,1038 @@ +#ifndef TBDECODE +#define TBDECODE + +#include +#include +#include +#include +#ifndef CLOCKS_PER_SEC +#define CLOCKS_PER_SEC CLK_TCK +#endif + +/* ---------------------------- Error codes --------------------------- */ +/* ----------- */ + +#define COMP_ERR_NONE 0 /* everything is OK */ +#define COMP_ERR_READ 2 /* input file read error */ +#define COMP_ERR_NOMEM 5 /* no enough memory */ +#define COMP_ERR_BROKEN 6 /* damaged compressed data */ +#define COMP_ERR_PARAM 7 /* incorrect function parameter */ +#define COMP_ERR_INTERNAL 9 /* everything else is internal error */ + /* hopefully it should never happen */ + +/* Almost all functions listed further return one as its result on of */ +/* codes given above: if no error occured then COMP_ERR_NONE (i.e. 0) */ +/* is returned, otherwise functions return error code plus number of */ +/* line in "comp.c" where the error was detected multiplied by 256; */ +/* line number may be used for exact specification of a place where */ +/* error was detected thus making debugging slightly simpler. */ +/* */ +/* Thus, "(code & 0xff)" gives proper error code, and "(code >> 8)" */ +/* gives number of line where the error was raised. */ + +/* -------------------------------------------------------------------- */ +/* */ +/* Compress/decompress some chess tables */ +/* */ +/* Copyright (c) 1991--1998 Andrew Kadatch */ +/* */ +/* The Limited-Reference variant of Lempel-Ziv algorithm implemented */ +/* here was first described in my B.Sc. thesis "Efficient algorithms */ +/* for image compression", Novosibirsk State University, 1992, and */ +/* cannot be used in any product distributed in Russia or CIS without */ +/* written permission from the author. */ +/* */ +/* Most of the code listed below is significantly simplified code from */ +/* the PRS data compression library and therefore it should not be used */ +/* in any product (software or hardware, commercial or not, and so on) */ +/* without written permission from the author. */ +/* */ +/* -------------------------------------------------------------------- */ + +/* ---------------------------- Debugging ----------------------------- */ +/* --------- */ + +#ifndef DEBUG +#define DEBUG 0 +#endif + +#if DEBUG +#define assert(cond) ((cond) ? (void) 0 : _local_assert (__LINE__)) +static void _local_assert(int lineno) +{ + fprintf(stderr, "assertion at line %u failed\n", lineno); + exit(33); +} + +#define debug(x) x +#define dprintf(x) printf x +#else +#if !defined (assert) +#define assert(cond) ((void) 0) +#endif +#define debug(x) ((void) 0) +#define dprintf(x) ((void) 0) +#endif + +/* mob_pach */ +#ifndef __cplusplus +int cbEGTBCompBytes = 0; +#else +extern "C" { + int cbEGTBCompBytes = 0; +} +#endif +/* --------------------- Constants, types, etc. ----------------------- */ +/* ---------------------- */ +#define MIN_BLOCK_BITS 8 /* LOG2 (min size of block to compress) */ +#define MAX_BLOCK_BITS 16 /* LOG2 (max size of block to compress) */ + /* max. integer we can take LOG2 by table */ +#define MAX_BITS_HALF ((MAX_BLOCK_BITS + 1) >> 1) +#define MAX_BITS (MAX_BITS_HALF * 2) +/* assume that integer is at least 32 bits wide */ +#ifndef uint +#define uint unsigned +#endif +#ifndef uchar +#define uchar unsigned char +#endif +#define HEADER_SIZE 80 /* number of reserved bytes */ +#define STOP_SEARCH_LENGTH 256 /* terminate search if match */ + /* length exceeds that value */ +#define MAX_LENGTH_BITS 5 +#define MAX_LENGTH (1 << MAX_LENGTH_BITS) +#define LONG_BITS 1 +#define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS) +#define LONG_QUICK (MAX_LENGTH - LONG_LENGTH) +#if LONG_LENGTH > (MAX_BLOCK_BITS - LONG_BITS) +# undef LONG_LENGTH +# define LONG_LENGTH (MAX_BLOCK_BITS - LONG_BITS) +#endif +#if LONG_LENGTH >= MAX_LENGTH || LONG_LENGTH <= 0 +#error LONG_LENGTH is out of range +#endif +#if LONG_BITS <= 0 +#error LONG_BITS must be positive +#endif +#define DELTA (LONG_BITS + LONG_QUICK - 1) +#if (MAX_LENGTH - 1) - (LONG_LENGTH - LONG_BITS) != DELTA +#error Hmmm +#endif +#define MAX_DISTANCES 24 +#define LOG_MAX_DISTANCES 6 /* see check below */ +#if MAX_DISTANCES > (1 << LOG_MAX_DISTANCES) +#error MAX_DISTANCES should not exceed (1 << LOG_MAX_DISTANCES) +#endif +#define ALPHABET_SIZE (256 + (MAX_DISTANCES << MAX_LENGTH_BITS)) +#define MAX_ALPHABET ALPHABET_SIZE /* max. alphabet handled by */ + /* Huffman coding routines */ +#define USE_CRC32 1 +/* 0 - use Fletcher's checksum, != 0 - use proper CRC32 */ + static uchar header_title[64] = + "Compressed by DATACOMP v 1.0 (c) 1991--1998 Andrew Kadatch\r\n\0"; + +#define RET(n) ((n) + __LINE__ * 256) + +/* ------------------------- CRC32 routines --------------------------- */ +/* -------------- */ + +#if USE_CRC32 + +static unsigned CRC32_table[256]; +static int CRC32_initialized = 0; + +static void CRC32_init(void) +{ + int i, j; + unsigned k, m = (unsigned) 0xedb88320L; + + if (CRC32_initialized) + return; + for (i = 0; i < 256; ++i) { + k = i; + j = 8; + do { + if ((k & 1) != 0) + k >>= 1; + else { + k >>= 1; + k ^= m; + }; + } + while (--j); + CRC32_table[i] = k; + } + CRC32_initialized = 1; +} + +static unsigned CRC32(uchar * p, int n, unsigned k) +{ + unsigned *table = CRC32_table; + uchar *e = p + n; + + while (p + 16 < e) { +# define X(i) k = table[((uchar) k) ^ p[i]] ^ (k >> 8) + X(0); + X(1); + X(2); + X(3); + X(4); + X(5); + X(6); + X(7); + X(8); + X(9); + X(10); + X(11); + X(12); + X(13); + X(14); + X(15); +# undef X + p += 16; + } + while (p < e) + k = table[((uchar) k) ^ *p++] ^ (k >> 8); + return (k); +} + +#else + +#define CRC32_init() + +static unsigned CRC32(uchar * p, int n, unsigned k1) +{ + unsigned k0 = k1 & 0xffff; + uchar *e = p + n; + + k1 = (k1 >> 16) & 0xffff; + while (p + 16 < e) { +# define X(i) k0 += p[i]; k1 += k0; + X(0); + X(1); + X(2); + X(3); + X(4); + X(5); + X(6); + X(7); + X(8); + X(9); + X(10); + X(11); + X(12); + X(13); + X(14); + X(15); +# undef X + k0 = (k0 & 0xffff) + (k0 >> 16); + k1 = (k1 & 0xffff) + (k1 >> 16); + p += 16; + } + while (p < e) { + k0 += *p++; + k1 += k0; + } + k0 = (k0 & 0xffff) + (k0 >> 16); + k1 = (k1 & 0xffff) + (k1 >> 16); + k0 = (k0 & 0xffff) + (k0 >> 16); + k1 = (k1 & 0xffff) + (k1 >> 16); + assert(((k0 | k1) >> 16) == 0); + return (k0 + (k1 << 16)); +} + +#endif /* USE_CRC32 */ + +/* ------------------------ Bit IO interface -------------------------- */ +/* ---------------- */ + +#define BITIO_LOCALS \ + uint _mask; \ + int _bits; \ + uchar *_ptr + +typedef struct { + BITIO_LOCALS; +} bitio_t; + +#define BITIO_ENTER(p) do { \ + _mask = (p)._mask; \ + _bits = (p)._bits; \ + _ptr = (p)._ptr; \ +} while (0) + +#define BITIO_LEAVE(p) do { \ + (p)._mask = _mask; \ + (p)._bits = _bits; \ + (p)._ptr = _ptr; \ +} while (0) + +#define BIORD_START(from) do { \ + _ptr = (uchar *) (from); \ + _bits = sizeof (_mask); \ + _mask = 0; \ + do \ + _mask = (_mask << 8) | *_ptr++; \ + while (--_bits != 0); \ + _bits = 16; \ +} while (0) + +/* read [1, 17] bits at once */ +#define BIORD(bits) \ + (_mask >> (8 * sizeof (_mask) - (bits))) + +#define BIORD_MORE(bits) do { \ + _mask <<= (bits); \ + if ((_bits -= (bits)) <= 0) \ + { \ + _mask |= ((_ptr[0] << 8) + _ptr[1]) << (-_bits); \ + _ptr += 2; _bits += 16; \ + } \ +} while (0) + +/* ------------------------ Huffman coding ---------------------------- */ +/* -------------- */ + +#if MAX_ALPHABET <= 0xffff +# if MAX_ALPHABET <= 1024 +/* positive value takes 15 bits => symbol number occupies <= 10 bits */ +# define huffman_decode_t short +# else +# define huffman_decode_t int +# endif +#else +# define huffman_decode_t int +#endif + +#define HUFFMAN_DECODE(ch,table,start_bits) do { \ + (ch) = table[BIORD (start_bits)]; \ + if (((int) (ch)) >= 0) \ + { \ + BIORD_MORE ((ch) & 31); \ + (ch) >>= 5; \ + break; \ + } \ + BIORD_MORE (start_bits); \ + do \ + { \ + (ch) = table[BIORD (1) - (ch)]; \ + BIORD_MORE (1); \ + } \ + while (((int) (ch)) < 0); \ +} while (0) + +#define HUFFMAN_TABLE_SIZE(n,start_bits) \ + ((1 << (start_bits)) + ((n) << 1)) + +static int huffman_decode_create(huffman_decode_t * table, uchar * length, + int n, int start_bits) +{ + int i, j, k, last, freq[32], sum[32]; + + /* calculate number of codewords */ + memset(freq, 0, sizeof(freq)); + for (i = 0; i < n; ++i) { + if ((k = length[i]) > 31) + return RET(COMP_ERR_BROKEN); + ++freq[k]; + } + + /* handle special case(s) -- 0 and 1 symbols in alphabet */ + if (freq[0] == n) { + memset(table, 0, sizeof(table[0]) << start_bits); + return (0); + } + if (freq[0] == n - 1) { + if (freq[1] != 1) + return RET(COMP_ERR_BROKEN); + for (i = 0; length[i] == 0;) + ++i; + i <<= 5; + for (k = 1 << start_bits; --k >= 0;) + *table++ = (huffman_decode_t) i; + return (0); + } + + /* save frequences */ + memcpy(sum, freq, sizeof(sum)); + + /* check code correctness */ + k = 0; + for (i = 32; --i != 0;) { + if ((k += freq[i]) & 1) + return RET(COMP_ERR_BROKEN); + k >>= 1; + } + if (k != 1) + return RET(COMP_ERR_BROKEN); + + /* sort symbols */ + k = 0; + for (i = 1; i < 32; ++i) + freq[i] = (k += freq[i]); + last = freq[31]; /* preserve number of symbols in alphabet */ + for (i = n; --i >= 0;) { + if ((k = length[i]) != 0) + table[--freq[k]] = (huffman_decode_t) i; + } + + /* now create decoding table */ + k = i = (1 << start_bits) + (n << 1); + for (n = 32; --n > start_bits;) { + j = i; + while (k > j) + table[--i] = (huffman_decode_t) - (k -= 2); + for (k = sum[n]; --k >= 0;) + table[--i] = table[--last]; + k = j; + } + + j = i; + i = 1 << start_bits; + while (k > j) + table[--i] = (huffman_decode_t) - (k -= 2); + + for (; n > 0; --n) { + for (k = sum[n]; --k >= 0;) { + assert(last <= i && last > 0); + j = i - (1 << (start_bits - n)); + n |= table[--last] << 5; + do + table[--i] = (huffman_decode_t) n; + while (i != j); + n &= 31; + } + } + assert((i | last) == 0); + + return (0); +} + +/* -------------------- Read/write Huffman code ----------------------- */ +/* ----------------------- */ + +#define MIN_REPT 2 + +#if MIN_REPT <= 1 +#error MIN_REPT must exceed 1 +#endif + +#define TEMP_TABLE_BITS 8 + +static int huffman_read_length(bitio_t * bitio, uchar * length, int n) +{ + BITIO_LOCALS; + huffman_decode_t table[2][HUFFMAN_TABLE_SIZE(64, TEMP_TABLE_BITS)]; + uchar bits[128]; + int i, j, k; + + BITIO_ENTER(*bitio); + k = BIORD(1); + BIORD_MORE(1); + if (k != 0) { + memset(length, 0, n); + goto ret; + } + + if (n <= 128) { + k = BIORD(5); + BIORD_MORE(5); + for (i = 0; i < n;) { + length[i] = (uchar) BIORD(k); + BIORD_MORE(k); + if (length[i++] == 0) { + j = i + BIORD(4); + BIORD_MORE(4); + if (j > n) + return RET(COMP_ERR_BROKEN); + while (i != j) + length[i++] = 0; + } + } + goto ret; + } + + BITIO_LEAVE(*bitio); + i = huffman_read_length(bitio, bits, 128); + if (i != 0) + return (i); + i = huffman_decode_create(table[0], bits, 64, TEMP_TABLE_BITS); + if (i != 0) + return (i); + i = huffman_decode_create(table[1], bits + 64, 64, TEMP_TABLE_BITS); + if (i != 0) + return (i); + BITIO_ENTER(*bitio); + + for (i = 0; i < n;) { + HUFFMAN_DECODE(k, table[0], TEMP_TABLE_BITS); + if (k <= 31) { + length[i++] = (uchar) k; + continue; + } + k &= 31; + HUFFMAN_DECODE(j, table[1], TEMP_TABLE_BITS); + if (j > 31) { + int jj = j - 32; + + j = 1 << jj; + if (jj != 0) { + if (jj > 16) { + j += BIORD(16) << (jj - 16); + BIORD_MORE(16); + } + j += BIORD(jj); + BIORD_MORE(jj); + } + j += 31; + } + j += MIN_REPT + i; + if (j > n) + return RET(COMP_ERR_BROKEN); + do + length[i] = (uchar) k; + while (++i != j); + } + +ret: + BITIO_LEAVE(*bitio); + return (0); +} + +/* ----------------------- Proper compression ------------------------- */ +/* ------------------ */ + +#if MIN_BLOCK_BITS > MAX_BLOCK_BITS || MAX_BLOCK_BITS > MAX_BITS_HALF*2 +#error condition MIN_BLOCK_BITS <= MAX_BLOCK_BITS <= MAX_BITS_HALF*2 failed +#endif + +#define DECODE_MAGIC ((int) 0x5abc947fL) +#define BLOCK_MAGIC ((int) 0x79a3f29dL) + +#define START_BITS 13 + +#define SHORT_INDEX 8u + +typedef struct { + huffman_decode_t table[HUFFMAN_TABLE_SIZE(ALPHABET_SIZE, START_BITS)]; + int distance[MAX_DISTANCES]; + unsigned *crc, *blk_u; + unsigned short *blk_s; + int block_size_log, /* block_size is integral power of 2 */ + block_size, /* 1 << block_size_log */ + last_block_size, /* [original] size of last block */ + n_blk, /* total number of blocks */ + comp_block_size, /* size of largest compressed block+32 */ + check_crc; /* check CRC32? */ + uchar *comp; + int magic; +} decode_info; + +typedef struct { + unsigned char *ptr; /* pointer to the first decoded byte */ + int decoded; /* number of bytes decoded so far */ + int total; /* total number of bytes in block */ + int number; /* number of this block */ +} COMP_BLOCK_T; + +/* Pointer to compressed data block */ + +typedef struct { + COMP_BLOCK_T b; + struct { + uchar *first; + int size; + } orig , comp; + struct { + uchar *ptr, *src; + int rept; + } emit; + bitio_t bitio; + int n; + int magic; +} decode_block; + +static int calculate_offset(decode_info * info, unsigned n) +{ + unsigned i; + + i = n / (2 * SHORT_INDEX); + if (n & SHORT_INDEX) + return info->blk_u[i + 1] - info->blk_s[n]; + else + return info->blk_u[i] + info->blk_s[n]; +} + +static void do_decode(decode_info * info, decode_block * block, uchar * e) +{ + BITIO_LOCALS; + uchar *p, *s = 0; + int ch; + + if ((p = block->emit.ptr) >= e) + return; + if (p == block->orig.first) { + BIORD_START(block->comp.first); + block->emit.rept = 0; + } else { + BITIO_ENTER(block->bitio); + if ((ch = block->emit.rept) != 0) { + block->emit.rept = 0; + s = block->emit.src; + goto copy; + } + } +#define OVER if (p < e) goto over; break + do { + over: + HUFFMAN_DECODE(ch, info->table, START_BITS); + if ((ch -= 256) < 0) { + *p++ = (uchar) ch; + OVER; + } + + s = p + info->distance[ch >> MAX_LENGTH_BITS]; + + ch &= MAX_LENGTH - 1; + if (ch <= 3) { + p[0] = s[0]; + p[1] = s[1]; + p[2] = s[2]; + p[3] = s[3]; + p += ch + 1; + OVER; + } else if (ch >= LONG_LENGTH) { + ch -= LONG_LENGTH - LONG_BITS; +#if (MAX_BLOCK_BITS - 1) + (LONG_LENGTH - LONG_BITS) >= MAX_LENGTH + if (ch == DELTA) { + ch = BIORD(5); + BIORD_MORE(5); + ch += DELTA; + } +#endif + { + int n = 1 << ch; + + if (ch > 16) { + n += BIORD(16) << (ch -= 16); + BIORD_MORE(16); + } + n += BIORD(ch); + BIORD_MORE(ch); + ch = n; + } + ch += LONG_LENGTH - (1 << LONG_BITS); + } + ++ch; + copy: + if (ch > 16) { + if (p + ch > e) { + block->emit.rept = ch - (int) (e - p); + ch = (int) (e - p); + goto copy; + } + do { +# define X(i) p[i] = s[i] + X(0); + X(1); + X(2); + X(3); + X(4); + X(5); + X(6); + X(7); + X(8); + X(9); + X(10); + X(11); + X(12); + X(13); + X(14); + X(15); +# undef X + p += 16; + s += 16; + } + while ((ch -= 16) > 16); + } + p += ch; + s += ch; + switch (ch) { +# define X(i) case i: p[-i] = s[-i] + X(16); + X(15); + X(14); + X(13); + X(12); + X(11); + X(10); + X(9); + X(8); + X(7); + X(6); + X(5); + X(4); + X(3); + X(2); +# undef X + } + p[-1] = s[-1]; + } + while (p < e); +#undef OVER + block->emit.ptr = p; + block->emit.src = s; + BITIO_LEAVE(block->bitio); +} + +/* pretty ugly */ +static int comp_open_file(decode_info ** res, FILE * fd, int check_crc) +{ + BITIO_LOCALS; + bitio_t Bitio; + uchar temp[ALPHABET_SIZE >= HEADER_SIZE ? ALPHABET_SIZE : HEADER_SIZE]; + uchar *ptr; + int header_size, block_size, block_size_log, n_blk, i, n, n_s, n_u; + unsigned *blk_u, *blk; + unsigned short *blk_s; + decode_info *info; + + if (res == 0) + return RET(COMP_ERR_PARAM); + + CRC32_init(); + + *res = 0; + + if (fread(temp, 1, HEADER_SIZE, fd) != HEADER_SIZE) + return RET(COMP_ERR_READ); + + if (memcmp(temp, header_title, 64) != 0) + return RET(COMP_ERR_READ); + + ptr = temp; +#define R4(i) \ + ((ptr[i] << 24) + (ptr[(i) + 1] << 16) + (ptr[(i) + 2] << 8) + (ptr[(i) + 3])) + + header_size = R4(64); + block_size_log = ptr[70]; + if (block_size_log > MAX_BITS || header_size < 84) + return RET(COMP_ERR_BROKEN); + block_size = 1 << block_size_log; + if (ptr[71] != MAX_DISTANCES) + return RET(COMP_ERR_BROKEN); + n_blk = R4(72); + if (R4(76) != + (ALPHABET_SIZE << 12) + (LONG_BITS << 8) + (LONG_LENGTH << 4) + + MAX_LENGTH_BITS) + return RET(COMP_ERR_BROKEN); + + if ((ptr = (uchar *) malloc(header_size)) == 0) + return RET(COMP_ERR_NOMEM); + + if (fread(ptr + HEADER_SIZE, 1, header_size - HEADER_SIZE, fd) != + (size_t) (header_size - HEADER_SIZE)) { + free(ptr); + return RET(COMP_ERR_NOMEM); + } + memcpy(ptr, temp, HEADER_SIZE); + header_size -= 4; + if (CRC32(ptr, header_size, 0) != (unsigned) R4(header_size)) { + free(ptr); + return RET(COMP_ERR_BROKEN); + } + header_size += 4; + + /* + blk = (unsigned *) malloc (sizeof (unsigned) * (1 + n_blk)); + */ + n = sizeof(unsigned) * (1 + n_blk); + if (n < 4 * 1024 * 1024) + n = 4 * 1024 * 1024; + blk = (unsigned *) malloc(n); + + if (blk == 0) { + free(ptr); + return RET(COMP_ERR_NOMEM); + } + n = sizeof(info->crc[0]) * (1 + (check_crc ? (2 * n_blk) : 0)); + n_u = sizeof(unsigned) * (2 + n_blk / (2 * SHORT_INDEX)); + n_s = sizeof(unsigned short) * (1 + n_blk); + if ((info = (decode_info *) malloc(sizeof(*info) + n + n_u + n_s)) == 0) { + free(ptr); + free(blk); + return RET(COMP_ERR_NOMEM); + } + cbEGTBCompBytes += sizeof(*info) + n + n_s + n_u; + info->crc = (unsigned *) (info + 1); + if (check_crc) + blk_u = info->blk_u = info->crc + 2 * n_blk; + else + blk_u = info->blk_u = info->crc; + blk_s = info->blk_s = + (unsigned short *) (blk_u + 2 + n_blk / (2 * SHORT_INDEX)); + + info->check_crc = check_crc; + info->block_size_log = block_size_log; + info->block_size = block_size; + info->n_blk = n_blk; + + if (check_crc) { + n_blk <<= 1; + i = HEADER_SIZE; + for (n = 0; n < n_blk; ++n) { + info->crc[n] = R4(i); + i += 4; + } + n_blk >>= 1; + } + + i = HEADER_SIZE + (n_blk << 3); + BIORD_START(ptr + i); + + info->comp_block_size = 0; + for (n = 0; n <= n_blk; ++n) { + if ((blk[n] = BIORD(block_size_log)) == 0) + blk[n] = block_size; + if (info->comp_block_size < (int) (blk[n])) + info->comp_block_size = (int) (blk[n]); + BIORD_MORE(block_size_log); + } + info->comp_block_size += 32; + + for (n = 0; n < MAX_DISTANCES; ++n) { + info->distance[n] = -((int) BIORD(block_size_log)); + BIORD_MORE(block_size_log); + } + + i += ((n_blk + 1 + MAX_DISTANCES) * block_size_log + 7) >> 3; + BIORD_START(ptr + i); + BITIO_LEAVE(Bitio); + if (huffman_read_length(&Bitio, temp, ALPHABET_SIZE) != 0) { + free(blk); + free(info); + free(ptr); + return RET(COMP_ERR_BROKEN); + } + + if (huffman_decode_create(info->table, temp, ALPHABET_SIZE, START_BITS) != 0) { + free(blk); + free(info); + free(ptr); + return RET(COMP_ERR_BROKEN); + } + + info->last_block_size = blk[n_blk]; + blk[n_blk] = 0; + for (n = 0; n <= n_blk; ++n) { + i = blk[n]; + blk[n] = header_size; + header_size += i; + if (0 == n % (2 * SHORT_INDEX)) + blk_u[n / (2 * SHORT_INDEX)] = blk[n]; + } + blk_u[n_blk / (2 * SHORT_INDEX) + 1] = blk[n_blk]; + + for (n = 0; n <= n_blk; ++n) { + i = n / (2 * SHORT_INDEX); + if (n & SHORT_INDEX) + blk_s[n] = blk_u[i + 1] - blk[n]; + else + blk_s[n] = blk[n] - blk_u[i]; + } + + free(blk); + free(ptr); + info->comp = 0; + info->magic = DECODE_MAGIC; + *res = info; + + return (COMP_ERR_NONE); +} + +static int comp_tell_blocks(decode_info * info) +{ + if (info == 0 || info->magic != DECODE_MAGIC) + return (-1); + return (info->n_blk); +} + +static int comp_init_block(decode_block * block, int block_size, uchar * orig) +{ + if (block == 0) + return RET(COMP_ERR_PARAM); + block->orig.first = orig; + block->comp.first = (uchar *) (block + 1); + block->b.ptr = 0; + block->b.decoded = -1; + block->b.total = -1; + block->b.number = -1; + block->n = -1; + block->magic = BLOCK_MAGIC; + return (COMP_ERR_NONE); +} + +static int comp_alloc_block(decode_block ** ret_block, int block_size) +{ + decode_block *block; + + if (ret_block == 0) + return RET(COMP_ERR_PARAM); + *ret_block = 0; + if ((block = (decode_block *) malloc(sizeof(*block) + block_size)) == 0) + return RET(COMP_ERR_NOMEM); + cbEGTBCompBytes += sizeof(*block) + block_size; + if (0 != comp_init_block(block, block_size, NULL)) + return RET(COMP_ERR_PARAM); + *ret_block = block; + return (COMP_ERR_NONE); +} + +#define RETURN(n) \ + return ((n) == COMP_ERR_NONE ? COMP_ERR_NONE : RET (n)); + +static int comp_read_block(decode_block * block, decode_info * info, FILE * fd, + int n) +{ + int comp_size, orig_size, comp_start; + uchar *comp, *orig; + + if (block == 0 || block->magic != BLOCK_MAGIC) + return RET(COMP_ERR_PARAM); + assert(info->magic == DECODE_MAGIC); + if ((unsigned) n >= (unsigned) info->n_blk) + RETURN(COMP_ERR_PARAM); + comp = block->comp.first; + block->n = n; + orig = block->orig.first; + orig_size = info->block_size; + if (n == info->n_blk - 1) + orig_size = info->last_block_size; + block->orig.size = orig_size; + comp_start = calculate_offset(info, n); + block->comp.size = comp_size = calculate_offset(info, n + 1) - comp_start; + if (fseek(fd, comp_start, SEEK_SET) != 0) + RETURN(COMP_ERR_READ); + if (fread(comp, 1, comp_size, fd) != (size_t) comp_size) + RETURN(COMP_ERR_READ); + if (info->check_crc + && info->crc[(n << 1) + 1] != CRC32(block->comp.first, comp_size, 0)) + RETURN(COMP_ERR_BROKEN); + block->emit.rept = 0; + if (comp_size == orig_size) { + memcpy(orig, comp, comp_size); + block->emit.ptr = orig + comp_size; + block->b.decoded = comp_size; + } else { + block->emit.ptr = orig; + block->b.decoded = 0; + } + block->b.number = n; + block->b.ptr = orig; + block->b.total = orig_size; + + RETURN(COMP_ERR_NONE); +} + +static int comp_decode_and_check_crc(decode_block * block, decode_info * info, + int n, int check_crc) +{ + if (block == 0 || block->magic != BLOCK_MAGIC) + return RET(COMP_ERR_PARAM); + assert(info->magic == DECODE_MAGIC); + if ((unsigned) (n - 1) > (unsigned) (block->orig.size - 1)) + RETURN(COMP_ERR_PARAM); + if (check_crc) + n = block->orig.size; + do_decode(info, block, block->orig.first + n); + block->b.ptr = block->orig.first; + block->b.total = block->orig.size; + if (block->b.decoded >= block->b.total) { + if (block->b.decoded > block->b.total) + RETURN(COMP_ERR_BROKEN); + if (block->emit.rept != 0) + RETURN(COMP_ERR_BROKEN); + } + if (check_crc && info->check_crc + && info->crc[block->n << 1] != CRC32(block->orig.first, block->orig.size, + 0)) + RETURN(COMP_ERR_BROKEN); + + RETURN(COMP_ERR_NONE); +} + +#if !defined (COLOR_DECLARED) + +/* + Test driver + */ + +#define CRC_CHECK 1 + +int main(int argc, char *argv[]) +{ + int i; + int size; + int result; + FILE *fp; + decode_info *comp_info; + decode_block *comp_block; + clock_t tStart, tEnd; + double dSeconds; + uchar rgbBuf[8192 + 32]; + + if (2 != argc) { + printf("Invalid arguments\n"); + exit(1); + } + fp = fopen(argv[1], "rb"); + if (0 == fp) { + printf("Unable to open file\n"); + exit(1); + } + result = comp_open_file(&comp_info, fp, CRC_CHECK); + if (0 != result) { + printf("Unable to read file (1): %d\n", result); + exit(1); + } + if (8192 != comp_info->block_size) { + printf("Invalid block size: %d\n", comp_info->block_size); + exit(1); + } + result = comp_alloc_block(&comp_block, comp_info->block_size); + if (0 != result) { + printf("Unable to allocate block: %d\n", result); + exit(1); + } + + size = 0; + tStart = clock(); + for (i = 0; i < comp_info->n_blk; i++) { + if (0 != + (result = comp_init_block(comp_block, comp_info->block_size, rgbBuf))) { + printf("Unable to init block: %d\n", result); + exit(1); + } + if (0 != (result = comp_read_block(comp_block, comp_info, fp, i))) { + printf("Unable to read block: %d\n", result); + exit(1); + } + size += comp_block->orig.size; + if (0 != + (result = + comp_decode_and_check_crc(comp_block, comp_info, comp_block->orig.size, + CRC_CHECK))) { + printf("Unable to decode block: %d\n", result); + exit(1); + } + } + tEnd = clock(); + dSeconds = (double) (tEnd - tStart) / CLOCKS_PER_SEC; + printf("Total memory allocated: %dKb\n", (cbEGTBCompBytes + 1023) / 1024); + printf("%g seconds, %dMb, %gMb/sec)\n", dSeconds, size / (1024 * 1024), + size / (1024 * 1024) / dSeconds); + return 0; +} + +#endif +#endif diff --git a/src/test.sh b/src/test.sh new file mode 100755 index 0000000..2109112 --- /dev/null +++ b/src/test.sh @@ -0,0 +1,12 @@ +#!/bin/sh + +opts='--cpus 1 --hash 256m --egtbpath /egtb/three;/egtb/four;/egtb/five' + +if [ $# -ne 2 ]; then + echo "Usage: ${0} +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define SYS_MAX_HEAP_ALLOC_SIZE_BYTES 0xfff +#define HEAP 0x48656170 +#define MMAP 0x4d6d6170 + +pthread_mutex_t g_SystemLock; +#define LOCK_SYSTEM pthread_mutex_lock(&g_SystemLock) +#define UNLOCK_SYSTEM pthread_mutex_unlock(&g_SystemLock) + +#ifdef DEBUG +ULONG g_uTotalAlloced = 0; + +#define ALLOC_HASH_SIZE 0x4000 + +typedef struct _ALLOC_RECORD +{ + void *p; + ULONG uSize; +} ALLOC_RECORD; +ALLOC_RECORD g_AllocHash[ALLOC_HASH_SIZE]; + +#define PTR_TO_ALLOC_HASH(x) ((((ULONG)(x)) >> 3) & (ALLOC_HASH_SIZE - 1)) + +ULONG +GetHeapMemoryUsage(void) +{ + Trace("There are now %u bytes outstanding.\n", g_uTotalAlloced); + return(g_uTotalAlloced); +} + +static void +ReleaseAllocHashEntry(void *p) +{ + ULONG u = PTR_TO_ALLOC_HASH(p); + ULONG v = u; + + LOCK_SYSTEM; + while(g_AllocHash[u].p != p) + { + u++; + u &= (ALLOC_HASH_SIZE - 1); + if (v == u) return; + } + g_AllocHash[u].p = NULL; + g_uTotalAlloced -= g_AllocHash[u].uSize; + UNLOCK_SYSTEM; + +// Trace("Freed %u bytes at %p.\n", g_AllocHash[u].uSize, p); +} + +static void +MarkAllocHashEntry(void *p, ULONG uSize) +{ + ULONG u = PTR_TO_ALLOC_HASH(p); + + if (uSize > (1024 * 1024 * 30)) return; + + LOCK_SYSTEM; + while(g_AllocHash[u].p != NULL) + { + u++; + u &= (ALLOC_HASH_SIZE - 1); + } + g_AllocHash[u].p = p; + g_AllocHash[u].uSize = uSize; + g_uTotalAlloced += uSize; + UNLOCK_SYSTEM; + +// Trace("Alloc %u bytes at %p.\n", g_AllocHash[u].uSize, p); +} +#endif // DEBUG + +// +// Thread table +// +typedef struct _SYSTEM_THREAD_TABLE_ENTRY +{ + DLIST_ENTRY links; + ULONG uWrapperHandle; + ULONG uTid; + ULONG uThreadParam; + pthread_t thread; + THREAD_ENTRYPOINT *pEntry; + ULONG uExitCode; +} +SYSTEM_THREAD_TABLE_ENTRY; +DLIST_ENTRY g_SystemThreadList; +ULONG g_uNextThreadHandle = 6000; + +CHAR * +SystemGetTimeString(void) +/** + +Routine description: + + Get the current time string from the OS. Not thread safe. + +Parameters: + + void + +Return value: + + CHAR + +**/ +{ + static CHAR buf[32]; + time_t t = time(NULL); + struct tm *p; + + p = localtime(&t); + snprintf(buf, ARRAY_LENGTH(buf), + "%u:%02u:%02u", p->tm_hour, p->tm_min, p->tm_sec); + return(buf); +} + +CHAR * +SystemGetDateString(void) +/** + +Routine description: + + Get the current date string from the OS. Not thread safe. + +Parameters: + + void + +Return value: + + CHAR + +**/ +{ + static CHAR buf[32]; + time_t t = time(NULL); + struct tm *p; + + p = localtime(&t); + snprintf(buf, ARRAY_LENGTH(buf), + "%u.%02u.%02u", p->tm_year + 1900, p->tm_mon + 1, p->tm_mday); + return(buf); +} + +// +// Thread code +// + +static SYSTEM_THREAD_TABLE_ENTRY * +_SystemGetThreadTableEntry(ULONG uThreadHandle) +/** + +Routine description: + + Support routine for thread functionality wrapper. Given a + uThreadHandle look up its entry in the global table. + +Parameters: + + ULONG uThreadHandle + +Return value: + + SYSTEM_THREAD_TABLE_ENTRY * + +**/ +{ + DLIST_ENTRY *p; + SYSTEM_THREAD_TABLE_ENTRY *q; + + LOCK_SYSTEM; + p = g_SystemThreadList.pFlink; + while(p != &g_SystemThreadList) + { + q = CONTAINING_STRUCT(p, SYSTEM_THREAD_TABLE_ENTRY, links); + if (q->uWrapperHandle == uThreadHandle) + { + goto end; + } + p = p->pFlink; + } + q = NULL; + end: + UNLOCK_SYSTEM; + return(q); +} + +void * +SystemThreadEntryPoint(void *pParam) +/** + +Routine description: + + The first code that any newly created thread executes. + +Parameters: + + void *pParam + +Return value: + + void + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *p = (SYSTEM_THREAD_TABLE_ENTRY *)pParam; + ULONG uParam; + int i; + + LOCK_SYSTEM; + UNLOCK_SYSTEM; + + uParam = p->uThreadParam; + i = (int)(*(p->pEntry))(uParam); // call thread's user-supplied entry + return((void *)i); +} + +FLAG +SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle) +/** + +Routine description: + + Wraps the OS/Library dependent thread creation call. + +Parameters: + + THREAD_ENTRYPOINT *pEntry : where should the new thread start? + ULONG uParam : parameter to pass to the new thread + ULONG *puHandle : "handle" to the new thread + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *p; + + p = malloc(sizeof(SYSTEM_THREAD_TABLE_ENTRY)); + if (NULL == p) + { + *puHandle = 0; + return(FALSE); + } + + LOCK_SYSTEM; + p->pEntry = pEntry; + p->uThreadParam = uParam; + if (0 != pthread_create(&(p->thread), + NULL, + SystemThreadEntryPoint, + p)) + { + free(p); + return(FALSE); + } + *puHandle = p->uWrapperHandle = g_uNextThreadHandle; + g_uNextThreadHandle++; + InsertHeadList(&g_SystemThreadList, &(p->links)); + UNLOCK_SYSTEM; + return(TRUE); +} + + +FLAG +SystemWaitForThreadToExit(ULONG uThreadHandle) +/** + +Routine description: + + Blocks until the thread whose handle is provieded exits. + +Parameters: + + ULONG uThreadHandle + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *q = _SystemGetThreadTableEntry(uThreadHandle); + + pthread_join(q->thread, NULL); + return(TRUE); +} + + +FLAG +SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode) +/** + +Routine description: + + Get the exit value of an already-exited thread. + +Parameters: + + ULONG uThreadHandle, + ULONG *puCode + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *q = _SystemGetThreadTableEntry(uThreadHandle); + void *p; + + pthread_join(q->thread, &p); + *puCode = ((ULONG)p); + return(TRUE); +} + + +FLAG +SystemDeleteThread(ULONG uThreadHandle) +/** + +Routine description: + + Kill a thread. + +Parameters: + + ULONG uThreadHandle + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *q = _SystemGetThreadTableEntry(uThreadHandle); + + if (NULL != q) + { + pthread_kill(q->thread, SIGKILL); + LOCK_SYSTEM; + RemoveEntryList(&(q->links)); + free(q); + UNLOCK_SYSTEM; + return(TRUE); + } + return(FALSE); +} + + + +void FORCEINLINE +SystemDebugBreakpoint(void) +/** + +Routine description: + + A hardcoded breakpoint. + +Parameters: + + void + +Return value: + + void + +**/ +{ + __asm__("int3\n"); +} + +UINT64 FASTCALL +SystemReadTimeStampCounter(void) +/** + +Routine description: + + Read the processor's timestamp counter. + +Parameters: + + void + +Return value: + + UINT64 FASTCALL + +**/ +{ + __asm__("rdtsc;" + : + : + : "%eax", "%edx"); +} + + +double INLINE +SystemTimeStamp(void) +/** + +Routine description: + + Return a timestamp to the caller. + +Parameters: + + void + +Return value: + + double + +**/ +{ + struct timeval tv; + + // + // Number of seconds and microseconds since the Epoch. + // + if (0 != gettimeofday(&tv, NULL)) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "gettimeofday", (void *)errno, NULL, + __FILE__, __LINE__); + } + return((double)tv.tv_sec + (double)tv.tv_usec * 1.0e-6); +} + + +FLAG +SystemDoesFileExist(CHAR *szFilename) +/** + +Routine description: + + Determine if a file exists (non-atomically). + +Parameters: + + CHAR *szFilename + +Return value: + + FLAG + +**/ +{ + struct stat sb; + int i = stat(szFilename, &sb); + + if ((i == -1) && (errno == ENOENT)) return(FALSE); + return(TRUE); +} + + +static FLAG +_SystemIsRoot(void) +/** + +Routine description: + + This code is called by SystemDependentInitialization. Its job is to + determine whether this process is running with administrative powers. + +Parameters: + + void + +Return value: + + static FLAG + +**/ +{ + if (0 == geteuid()) + { + return(TRUE); + } + return(FALSE); +} + + +void FORCEINLINE +SystemDeferExecution(ULONG dwMs) +/** + +Routine description: + + Sleep for a few ms. + +Parameters: + + ULONG dwMs + +Return value: + + void FORCEINLINE + +**/ +{ + struct timeval t = { 0, dwMs * 1000 }; + if (select(0, (fd_set *)NULL, (fd_set *)NULL, (fd_set *)NULL, &t) < 0) + { + if (usleep(dwMs * 1000) < 0) + { + Bug("SystemDeferExecution: I have insomnia...\n"); + } + } +} + + +static void * +_SystemCallMmap(ULONG dwSizeBytes) +/** + +Routine description: + + Wrapper around mmap. + +Parameters: + + ULONG dwSizeBytes + +Return value: + + static void + +**/ +{ + void *pMem = mmap(0, + (size_t)dwSizeBytes, + PROT_READ | PROT_WRITE, + MAP_ANON, + -1, + 0); + if (MAP_FAILED == pMem) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "mmap", (void *)errno, (void *)dwSizeBytes, + __FILE__, __LINE__); + } + (void)madvise(pMem, dwSizeBytes, MADV_RANDOM | MADV_WILLNEED); + return(pMem); +} + + +static void +_SystemCallMunmap(void *pMem) +/** + +Routine description: + + Wrapper around munmap + +Parameters: + + void *pMem + +Return value: + + static void + +**/ +{ + if (0 != munmap(pMem, (size_t)-1)) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "munmap", (void *)errno, pMem, + __FILE__, __LINE__); + } +} + + +static void *_SystemCallMalloc(ULONG dwSizeBytes) +/** + +Routine description: + + Wrapper around malloc. + +Parameters: + + ULONG dwSizeBytes + +Return value: + + static void + +**/ +{ + void *p = malloc(dwSizeBytes); + if (NULL == p) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "malloc", (void *)errno, (void *)dwSizeBytes, + __FILE__, __LINE__); + } + memset(p, 0, dwSizeBytes); + return(p); +} + + +static void +_SystemCallFree(void *p) +/** + +Routine description: + + Wrapper around free. + +Parameters: + + void *p + +Return value: + + static void + +**/ +{ + free(p); +} + +char * +SystemStrDup(char *p) +/** + +Routine description: + + Implements strdup functionality. + +Parameters: + + char *p + +Return value: + + char + +**/ +{ + char *q = SystemAllocateMemory(strlen(p) + 1); + strcpy(q, p); + return(q); +} + +void * +SystemAllocateMemory(ULONG dwSizeBytes) +/** + +Routine description: + + Allocate some memory. + +Parameters: + + ULONG dwSizeBytes + +Return value: + + void + +**/ +{ + DWORD *p; + + if (0) // (dwSizeBytes > SYS_MAX_HEAP_ALLOC_SIZE_BYTES) + { + p = _SystemCallMmap(dwSizeBytes + sizeof(DWORD)); + if (NULL == p) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "mmap", (void *)errno, NULL, + __FILE__, __LINE__); + } + *p = MMAP; + p += 1; + } + else + { + p = _SystemCallMalloc(dwSizeBytes + sizeof(DWORD)); + if (NULL == p) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "malloc", (void *)errno, NULL, + __FILE__, __LINE__); + } + *p = HEAP; + p += 1; + } +#ifdef DEBUG + MarkAllocHashEntry(p, dwSizeBytes); +#endif + ASSERT(NULL != p); + return(p); +} + +void +SystemFreeMemory(void *pMemory) +/** + +Routine description: + + Free an allocation previously allocated by SystemAllocMemory. + +Parameters: + + void *pMemory + +Return value: + + void + +**/ +{ + DWORD *p = pMemory; + + p -= 1; +#ifdef DEBUG + ReleaseAllocHashEntry(pMemory); +#endif + if (*p == HEAP) + { + _SystemCallFree(p); + } + else if (*p == MMAP) + { + _SystemCallMunmap(p); + } +#ifdef DEBUG + else + { + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); + } +#endif +} + + +void * +SystemAllocateLockedMemory(ULONG dwSizeBytes) +/** + +Routine description: + + Allocate non-pagable memory (if possible). + +Parameters: + + ULONG dwSizeBytes + +Return value: + + void + +**/ +{ + void *p = SystemAllocateMemory(dwSizeBytes); + if (NULL != p) + { + if (0 != mlock(p, dwSizeBytes)) + { + // + // Note: don't panic the program over this... do dump a + // warning though as it should not happen. + // + Bug("WARNING: mlock for buffer at 0x%p (%u bytes) failed, " + "errno=%d\n\n", p, dwSizeBytes, errno); + } + } + return(p); +} + + +FLAG +SystemMakeMemoryReadOnly(void *pMemory, + ULONG dwSizeBytes) +/** + +Routine description: + + Make some memory region read-only (if possible). + +Parameters: + + void *pMemory, + ULONG dwSizeBytes + +Return value: + + FLAG + +**/ +{ + if (0 != mprotect(pMemory, dwSizeBytes, PROT_READ)) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "mprotect", (void *)errno, (void *)PROT_READ, + __FILE__, __LINE__); + } + return(TRUE); +} + + + +FLAG +SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes) +/** + +Routine description: + + Make a region of memory read/write. + +Parameters: + + void *pMemory, + ULONG dwSizeBytes + +Return value: + + FLAG + +**/ +{ + if (0 != mprotect(pMemory, dwSizeBytes, PROT_READ | PROT_WRITE)) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, + "mprotect", + (void *)errno, + (void *)(PROT_READ | PROT_WRITE), + __FILE__, __LINE__); + } + return(TRUE); +} + + + +FLAG +SystemCopyFile(CHAR *szSource, CHAR *szDest) +/** + +Routine description: + + Make a copy of a file. + +Parameters: + + CHAR *szSource, + CHAR *szDest + +Return value: + + FLAG + +**/ +{ + CHAR *buf = NULL; + CHAR *x = "/bin/cp -f "; + ULONG uLen = strlen(szSource) + strlen(szDest) + strlen(x) + 2; + + buf = SystemAllocateMemory(uLen); + snprintf(buf, uLen, + "%s%s %s", x, szSource, szDest); + if (0 == system(buf)) + { + SystemFreeMemory(buf); + return(TRUE); + } + SystemFreeMemory(buf); + return(FALSE); +} + + +FLAG +SystemDeleteFile(CHAR *szFile) +/** + +Routine description: + + Delete a file. + +Parameters: + + CHAR *szFile + +Return value: + + FLAG + +**/ +{ + if (0 == unlink(szFile)) + { + return(TRUE); + } + return(FALSE); +} + + +#define MAX_LOCKS (8) +typedef struct _UNIX_LOCK_ENTRY +{ + pthread_mutex_t lock; + FLAG fInUse; +} UNIX_LOCK_ENTRY; +UNIX_LOCK_ENTRY g_rgLockTable[MAX_LOCKS]; + +ULONG +SystemCreateLock(void) +{ + ULONG u; + + LOCK_SYSTEM; + for (u = 0; u < MAX_LOCKS; u++) + { + if (FALSE == g_rgLockTable[u].fInUse) + { + pthread_mutex_init(&(g_rgLockTable[u].lock), NULL); + g_rgLockTable[u].fInUse = TRUE; + goto end; + } + } + u = (ULONG)-1; // no free slot + + end: + UNLOCK_SYSTEM; + return(u); +} + +FLAG +SystemDeleteLock(ULONG u) +{ + LOCK_SYSTEM; + if ((u < MAX_LOCKS) && (g_rgLockTable[u].fInUse == TRUE)) + { + pthread_mutex_destroy(&(g_rgLockTable[u].lock)); + g_rgLockTable[u].fInUse = FALSE; + UNLOCK_SYSTEM; + return(TRUE); + } + UNLOCK_SYSTEM; + return(FALSE); +} + +FLAG +SystemBlockingWaitForLock(ULONG u) +{ + pthread_mutex_t *p = NULL; + LOCK_SYSTEM; + if ((u < MAX_LOCKS) && (g_rgLockTable[u].fInUse == TRUE)) + { + p = &(g_rgLockTable[u].lock); + } + UNLOCK_SYSTEM; + if (p != NULL) + { + pthread_mutex_lock(p); + return(TRUE); + } + return(FALSE); +} + + +FLAG +SystemReleaseLock(ULONG u) +{ + pthread_mutex_t *p = NULL; + LOCK_SYSTEM; + if ((u < MAX_LOCKS) && (g_rgLockTable[u].fInUse == TRUE)) + { + p = &(g_rgLockTable[u].lock); + } + UNLOCK_SYSTEM; + if (p != NULL) + { + pthread_mutex_unlock(p); + return(TRUE); + } + return(FALSE); +} + + +#define MAX_SEM (8) +int g_rgSemaphores[MAX_SEM]; +#ifdef DEBUG +ULONG g_rgSemValues[MAX_SEM]; +#endif + +ULONG +SystemCreateSemaphore(ULONG uValue) +{ + ULONG u; + union semun { + int val; + struct semid_ds *buf; + unsigned short *array; + } value; + + if (uValue > MAX_USHORT) return((ULONG)-1); + LOCK_SYSTEM; + for (u = 0; u < MAX_SEM; u++) + { + if (g_rgSemaphores[u] < 0) + { + g_rgSemaphores[u] = semget(IPC_PRIVATE, 1, IPC_CREAT | 0600); + if (g_rgSemaphores[u] < 0) + { + u = (ULONG)-1; + goto end; + } + value.val = uValue; + if (semctl(g_rgSemaphores[u], 0, SETVAL, value) < 0) + { + (void)SystemDeleteSemaphore(u); + u = (ULONG)-1; + goto end; + } +#ifdef DEBUG + g_rgSemValues[u] = uValue; + Trace("Semaphore #%u created, initial value is %u\n", + u, uValue); +#endif + goto end; + } + } + u = (ULONG)-1; + end: + UNLOCK_SYSTEM; + return(u); +} + +FLAG +SystemDeleteSemaphore(ULONG u) { + union semun { + int val; + struct semid_ds *buf; + unsigned short *array; + } value; + + LOCK_SYSTEM; + if ((u < MAX_SEM) && (g_rgSemaphores[u] >= 0)) + { + if (semctl(g_rgSemaphores[u], 0, IPC_RMID, value) < 0) + { + return(FALSE); + } + g_rgSemaphores[u] = -1; + } + UNLOCK_SYSTEM; + return(TRUE); +} + +void +SystemReleaseSemaphoreResource(ULONG u) +{ + struct sembuf operation; + + LOCK_SYSTEM; + if ((u < MAX_SEM) && (g_rgSemaphores[u] >= 0)) + { + operation.sem_num = u; + operation.sem_op = +1; + operation.sem_flg = 0; + if (semop(g_rgSemaphores[u], &operation, 1) < 0) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "semop", (void *)errno, (void *)0, + __FILE__, __LINE__); + } +#ifdef DEBUG + g_rgSemValues[u] += 1; + Trace("Semaphore #%u value incremented to %u\n", u, + g_rgSemValues[u]); +#endif + } + UNLOCK_SYSTEM; +} + +void +SystemObtainSemaphoreResource(ULONG u) +{ + struct sembuf operation; + + LOCK_SYSTEM; + if ((u < MAX_SEM) && (g_rgSemaphores[u] >= 0)) + { + operation.sem_num = u; + operation.sem_op = -1; + operation.sem_flg = 0; + UNLOCK_SYSTEM; + if (semop(g_rgSemaphores[u], &operation, 1) < 0) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "semop", (void *)errno, (void *)1, + __FILE__, __LINE__); + } +#ifdef DEBUG + if (g_rgSemValues[u] > 0) + { + g_rgSemValues[u] -= 1; + Trace("Semaphore #%u value decremented to %u\n", u, + g_rgSemValues[u]); + } +#endif + return; + } + UNLOCK_SYSTEM; +} + + +FLAG +SystemDependentInitialization(void) +/** + +Routine description: + + This code is called to initialize operating system dependent code. + It is unsynchronized. It should only ever be called once. It + should definitely never be called by two threads at once! + +Parameters: + + void + +Return value: + + FLAG : TRUE on success, FALSE otherwise + +**/ +{ + ULONG u; +#ifdef DEBUG + static FLAG fInit = FALSE; + + if (TRUE == fInit) + { + Bug("SystemDependentInitialization code called more than once!\n"); + ASSERT(FALSE); + return(FALSE); + } + fInit = TRUE; + + memset(g_AllocHash, 0, sizeof(g_AllocHash)); +#endif + for (u = 0; u < MAX_SEM; u++) + { + g_rgSemaphores[u] = -1; + } + InitializeListHead(&g_SystemThreadList); + pthread_mutex_init(&g_SystemLock, NULL); + return(TRUE); +} diff --git a/src/util.c b/src/util.c new file mode 100755 index 0000000..599c16d --- /dev/null +++ b/src/util.c @@ -0,0 +1,1252 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + util.c + +Abstract: + + General purpose utility code to support the engine. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 8 Apr 2004 + +Revision History: + + $Id: util.c 355 2008-07-01 15:46:43Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uIterateDepth; +extern ULONG g_uFullWidthDepth; + +#define STATE_UNKNOWN (0) +#define STATE_HEADER (1) +#define STATE_MOVELIST (2) + +CHAR * +ReadNextGameFromPgnFile(FILE *pf) +/** + +Routine description: + + Reads the next game in a PGN file and returns a pointer to it. + +Parameters: + + FILE *pf : open file pointer + +Return value: + + CHAR * : NULL on error, else caller must free via SystemFreeMemory. + +**/ +{ + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + CHAR *p; + long lStartOfGame = -1; + long lEndOfGame = -1; + long lBefore; + ULONG uBytes; + ULONG uState = STATE_UNKNOWN; + + while(1) + { + lBefore = ftell(pf); + if (fgets(buf, ARRAY_LENGTH(buf), pf) <= 0) + { + //Trace("fgets failed, errno=%u.\n", errno); + break; + } + + // + // Skip leading whitespace on this line... + // + p = buf; + while(*p && isspace(*p)) p++; + + if (*p == '\0') + { + // + // We just read a blank line + // + switch(uState) + { + case STATE_UNKNOWN: + break; + + case STATE_HEADER: + uState = STATE_MOVELIST; + break; + + case STATE_MOVELIST: + lEndOfGame = lBefore; + uBytes = lEndOfGame - lStartOfGame; + if (uBytes <= 0) + { + return(NULL); + } + + p = SystemAllocateMemory(uBytes + 1); + ASSERT(p); + fseek(pf, lStartOfGame, SEEK_SET); + if (1 != fread(p, uBytes, 1, pf)) + { + SystemFreeMemory(p); + return(NULL); + } + p[uBytes] = '\0'; + return(p); + } + } + else + { + // + // We saw a non-blank line + // + switch(uState) + { + case STATE_HEADER: + case STATE_MOVELIST: + break; + + case STATE_UNKNOWN: + if (*p == '[') + { + uState = STATE_HEADER; + lStartOfGame = lBefore; + } + break; + } + } + } + return(NULL); +} + + +COMMAND(LearnPsqtFromPgn) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + +Return value: + + FLAG + +**/ +{ + CHAR *szFilename; + ULONG uPSQT[12][128]; + CHAR *pPGN; + FILE *pf = NULL; + DLIST_ENTRY *p; + GAME_MOVE *q; + ULONG x, y, z; + double d; + struct stat s; +#ifdef DEBUG + ULONG uHeap; +#endif + + if (argc < 2) + { + Trace("Error (missing filename)\n"); + return; + } + szFilename = argv[1]; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPsqtFromPgn: file \"%s\" doesn't exist.\n", + szFilename); + return; + } + + if (0 != stat(szFilename, &s)) + { + Trace("Stat failed.\n"); + return; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPsqtFromPgn: error reading file \"%s\".\n", + szFilename); + return; + } + + memset(uPSQT, 0, sizeof(uPSQT)); +#ifdef DEBUG + ResetGameList(); + uHeap = GetHeapMemoryUsage(); +#endif + while((pPGN = ReadNextGameFromPgnFile(pf)) != NULL) + { + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("(%5.2f%% done)\r", d); + + if (TRUE == LoadPgn(pPGN)) + { + p = g_GameData.sMoveList.pFlink; + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if ((q->uNumber > 10) && + (q->uNumber < 50) && + (!q->mv.pCaptured)) + { + uPSQT[q->mv.pMoved - 2][q->mv.cTo] += 1; + } + p = p->pFlink; + } + } + SystemFreeMemory(pPGN); +#ifdef DEBUG + ResetGameList(); + ASSERT(uHeap == GetHeapMemoryUsage()); +#endif + } + fclose(pf); + + z = 0; + for (x = 0; x < 12; x++) + { + for (y = 0; y < 128; y++) + { + if (uPSQT[x][y] > z) + { + z = uPSQT[x][y]; + } + } + } + + Trace("ULONG g_PSQT[12][128] = {\n"); + for (x = 0; x < 12; x++) + { + Trace("// Piece 0x%x (%s)\n", x + 2, PieceAbbrev((PIECE)(x + 2))); + Trace("{\n"); + + for (y = 0; y < 128; y++) + { + if (y % 16 == 0) Trace("\n"); + d = (double)uPSQT[x][y]; + d /= (double)z; + d *= (double)1000.0; + Trace("%4u,", (ULONG)d); + } + Trace("},\n"); + } + Trace("};\n"); +} + + +COMMAND(GeneratePositionAndBestMoveSuite) +/** + +Routine description: + +Parameters: + + CHAR *szFilename, + +Return value: + + FLAG + +**/ +{ + CHAR *szFilename; + CHAR *pPGN; + FILE *pf = NULL; + DLIST_ENTRY *p; + GAME_MOVE *q; + SEARCHER_THREAD_CONTEXT *ctx = NULL; + FLAG fPost = g_Options.fShouldPost; + struct stat s; + double d; + POSITION board; + + if (argc < 2) + { + Trace("Error (missing filename)\n"); + goto end; + } + szFilename = argv[1]; + + if (FALSE == SystemDoesFileExist(szFilename)) + { + Trace("LearnPsqtFromPgn: file \"%s\" doesn't exist.\n", + szFilename); + goto end; + } + + if (0 != stat(szFilename, &s)) + { + Trace("Stat failed.\n"); + goto end; + } + + pf = fopen(szFilename, "rb"); + if (NULL == pf) + { + Trace("LearnPsqtFromPgn: error reading file \"%s\".\n", + szFilename); + goto end; + } + + ctx = SystemAllocateMemory(sizeof(SEARCHER_THREAD_CONTEXT)); + if (NULL == ctx) + { + Trace("Out of memory.\n"); + goto end; + } + + g_Options.fShouldPost = FALSE; + while((pPGN = ReadNextGameFromPgnFile(pf)) != NULL) + { + d = (double)ftell(pf); + d /= (double)s.st_size; + d *= 100.0; + printf("(%5.2f%% done)\r", d); + + if (TRUE == LoadPgn(pPGN)) + { + p = g_GameData.sMoveList.pFlink; + while(p != &(g_GameData.sMoveList)) + { + q = CONTAINING_STRUCT(p, GAME_MOVE, links); + if ((q->uNumber > 20) && (q->uNumber < 60)) + { + if (FenToPosition(&board, q->szUndoPositionFen)) + { + InitializeSearcherContext(&board, ctx); + g_MoveTimer.bvFlags = 0; + g_Options.fPondering = FALSE; + g_Options.fThinking = TRUE; + g_Options.fSuccessfulPonder = FALSE; + + MaintainDynamicMoveOrdering(); + DirtyHashTable(); + + g_MoveTimer.uNodeCheckMask = 0x1000 - 1; + g_MoveTimer.dStartTime = SystemTimeStamp(); + g_MoveTimer.bvFlags = 0; + g_MoveTimer.dSoftTimeLimit = + g_MoveTimer.dStartTime + 3.0; + g_MoveTimer.dHardTimeLimit = + g_MoveTimer.dStartTime + 3.0; + g_Options.uMaxDepth = MAX_DEPTH_PER_SEARCH - 1; + + // + // TODO: Set draw value + // +#if (PERF_COUNTERS && MP) + ClearHelperThreadIdleness(); +#endif + GAME_RESULT result = Iterate(ctx); + if (result.eResult == RESULT_IN_PROGRESS) { + ASSERT(SanityCheckMove(&board, + ctx->sPlyInfo[0].PV[0])); + Trace("setboard %s\n", q->szUndoPositionFen); + Trace("gmmove %s\n", q->szMoveInSan); + Trace("solution %s\n", + MoveToSan(ctx->sPlyInfo[0].PV[0], &board)); + } + } + } + p = p->pFlink; + } + } + SystemFreeMemory(pPGN); + } + + end: + if (NULL != pf) + { + fclose(pf); + } + + if (NULL != ctx) + { + SystemFreeMemory(ctx); + } + + g_Options.fShouldPost = fPost; +} + + +char * +FindChunk(char *sz, ULONG uTargetChunk) +/** + +Routine description: + + A support routine used by FenToPosition. Used to parse apart a + string and return the Nth chunk of text (delimited by whitespace) + +Parameters: + + char *sz, + ULONG uTargetChunk + +Return value: + + char * + +**/ +{ + char *p = sz; + ULONG u = 0; + + if (0 == uTargetChunk) return(p); + + do + { + // + // Skip whitespace between chunks + // + while(isspace(*p) && *p) p++; + if (!*p) return(NULL); + + u++; + if (u == uTargetChunk) return(p); + + // + // Skip chunks + // + while(!isspace(*p) && &p) p++; + if (!*p) return(NULL); + } + while(1); + +#ifdef DEBUG + UtilPanic(SHOULD_NOT_GET_HERE, + NULL, NULL, NULL, NULL, + __FILE__, __LINE__); +#endif + return(NULL); +} + + + +CHAR * +ScoreToString(SCORE iScore) +/** + +Routine description: + + Format a chess score as a string that looks like: + + +0.100 + -4.951 + +MATE20 + -MATE4 + +0.000 + + etc... + + Note: NOT thread safe. + +Parameters: + + SCORE iScore + +Return value: + + CHAR * + +**/ +{ + static char szBuf[10]; + ULONG uDist; + + if (abs(iScore) < +NMATE) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), + "%c%u.%02u", + (iScore < 0) ? '-' : '+', + abs(iScore / 100), + abs(iScore % 100)); + return(szBuf); + } + + if (iScore > 0) + { + uDist = +INFINITY - iScore; + uDist /= 2; + if (uDist) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "+MATE%u", uDist); + } + else + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "+MATE"); + } + } + else + { + uDist = +INFINITY + iScore; + uDist /= 2; + if (uDist) + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "-MATE%u", uDist); + } + else + { + snprintf(szBuf, ARRAY_LENGTH(szBuf), "-MATE"); + } + } + return(szBuf); +} + + + +CHAR * +CoorToString(COOR c) +/** + +Routine description: + + Take a chessboard coordinate and convert it into a string. Note: + NOT thread safe. + +Parameters: + + COOR c + +Return value: + + CHAR * + +**/ +{ + static char buf[3]; + + if (IS_ON_BOARD(c)) + { + buf[0] = 'a' + FILE(c); + buf[1] = '0' + RANK(c); + buf[2] = '\0'; + } + else + { + buf[0] = '-'; + buf[1] = '\0'; + } + return(buf); +} + + +CHAR * +ColorToString(ULONG u) +/** + +Routine description: + + Convert a color into a string ("WHITE" or "BLACK"). Callers + should not mess with the contents of the buffer returned! + +Parameters: + + ULONG u + +Return value: + + char + +**/ +{ + static CHAR *szColor[2] = + { + "BLACK", + "WHITE" + }; + ASSERT(IS_VALID_COLOR(u)); + return(szColor[u]); +} + + +CHAR * +TimeToString(double d) +/** + +Routine description: + + Convert a time value into a string. e.g. + + 00:00:01.021 // seconds with ms + 00:15:21.998 // minutes+seconds + 01:59:23.232 // hours+minutes+sec + 27:08:11:103 // we don't do days + + Note: NOT thread safe. The caller should not mess with the + buffer returned. + +Parameters: + + double d + +Return value: + + CHAR * + +**/ +{ + ULONG uTotalSecs = (ULONG)d; + double dFract = d - (double)uTotalSecs; + ULONG uHours; + ULONG uMinutes; + ULONG uFract; + static char buf[13]; + + dFract *= 1000; + uFract = (int)dFract; + uHours = uTotalSecs / 60 / 60; + uTotalSecs -= uHours * 60 * 60; + uMinutes = uTotalSecs / 60; + uTotalSecs -= uMinutes * 60; + ASSERT(uTotalSecs < 60); + + if (uHours != 0) + { + snprintf(buf, ARRAY_LENGTH(buf), + "%2u:%02u:%02u.%03u", + uHours, uMinutes, uTotalSecs, uFract); + } + else + { + snprintf(buf, ARRAY_LENGTH(buf), + "%02u:%02u.%03u", + uMinutes, uTotalSecs, uFract); + } + return(buf); +} + + +FLAG +BufferIsZeroed(BYTE *p, ULONG u) +/** + +Routine description: + + Verify that a buffer is zeroed out. + +Parameters: + + BYTE *p : buffer start + ULONG u : buffer length + +Return value: + + FLAG + +**/ +{ + while(u) + { + if (*p != (BYTE)0) + { + return(FALSE); + } + p++; + u--; + } + return(TRUE); +} + + +void CDECL +Trace(CHAR *szMessage, ...) +/** + +Routine description: + + Trace a logging message on stdout and to the logfile + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send to logfile + // + if (NULL != g_pfLogfile) { + fprintf(g_pfLogfile, buf); + } + + // + // Send to stdout + // + fprintf(stdout, buf); + fflush(stdout); +} + + +void CDECL +Log(CHAR *szMessage, ...) +/** + +Routine description: + + Trace a logging message to the logfile only + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send to logfile + // + if (NULL != g_pfLogfile) { + fprintf(g_pfLogfile, buf); + fflush(g_pfLogfile); + } +} + + +void CDECL +Bug(CHAR *szMessage, ...) +/** + +Routine description: + + Trace an error message to stderr and the logfile + +Parameters: + + CHAR *szMessage, + ... + +Return value: + + void + +**/ +{ + va_list ap; // Variable argument list + CHAR buf[MEDIUM_STRING_LEN_CHAR]; + + memset(buf, 0, sizeof(buf)); + + // + // Populate buffer + // + va_start(ap, szMessage); + COMPILER_VSNPRINTF(buf, MEDIUM_STRING_LEN_CHAR - 1, szMessage, ap); + va_end(ap); + + // + // Send it to logfile + // + if (NULL != g_pfLogfile) { + fprintf(g_pfLogfile, buf); + fflush(g_pfLogfile); + } + + // + // Send it to stderr + // + fprintf(stderr, buf); + fflush(stderr); +} + + +#ifdef DEBUG +void +_assert(CHAR *szFile, ULONG uLine) +/** + +Routine description: + + An assertion handler + +Parameters: + + CHAR *szFile, + UINT uLine + +Return value: + + void + +**/ +{ + Bug("Assertion failure in %s, line %u.\n", szFile, uLine); + BREAKPOINT; +} +#endif + + +ULONG +AcquireSpinLock(volatile ULONG *pSpinlock) +/** + +Routine description: + + Atomically acquire a lock or spin trying. + +Parameters: + + ULONG *pSpinlock : a pointer to the lock + +Return value: + + ULONG : the number of times we had to spin + +**/ +{ + ULONG uLoops = 0; + while(0 != LockCompareExchange(pSpinlock, 1, 0)) + { + uLoops++; + } + ASSERT(*pSpinlock == 1); + return(uLoops); +} + +FLAG +TryAcquireSpinLock(volatile ULONG *pSpinlock) +{ + return(0 != LockCompareExchange(pSpinlock, 1, 0)); +} + +void +ReleaseSpinLock(volatile ULONG *pSpinlock) +/** + +Routine description: + + Release a lock so someone else can acquire it. + +Parameters: + + ULONG *pSpinlock : a pointer to the lock + +Return value: + + void + +**/ +{ + ULONG u; + ASSERT(*pSpinlock == 1); + u = LockCompareExchange(pSpinlock, 0, 1); + ASSERT(u == 1); +} + + +FLAG +BackupFile(CHAR *szFile) +/** + +Routine description: + + Backup a file to file.000. If file.000 already exists, back it up + to file.001 etc... + + Note: this function is recursive and can require quite a lot of + stack space. Also it is full of race conditions and should not be + used when some other code may be accessing the filesystem at the + same time. + +Parameters: + + CHAR *szFile : the file to backup + +Return value: + + FLAG + +**/ +{ + ULONG u; + CHAR buf[SMALL_STRING_LEN_CHAR]; + CHAR *p; + + if (TRUE == SystemDoesFileExist(szFile)) + { + if ((strlen(szFile) > 3) && + (isdigit(szFile[0])) && + (isdigit(szFile[1])) && + (isdigit(szFile[2]))) + { + u = (szFile[0] - '0') * 100; + u += (szFile[1] - '0') * 10; + u += szFile[2] - '0' + 1; + p = &(szFile[3]); + } + else + { + u = 0; + p = szFile; + } + snprintf(buf, ARRAY_LENGTH(buf), "%03u%s", u, p); + if (TRUE == SystemDoesFileExist(buf)) + { + BackupFile(buf); + } + return(SystemCopyFile(szFile, buf) && SystemDeleteFile(szFile)); + } + return(FALSE); +} + + +BYTE +Checksum(BYTE *p, ULONG uSize) +/** + +Routine description: + + Compute the checksum of a buffer. + +Parameters: + + BYTE *p, + ULONG uSize + +Return value: + + BYTE + +**/ +{ + BYTE b = 0; + while(uSize) + { + b ^= *p; + p++; + uSize--; + } + return(b); +} + +void +FinishPVTailFromHash(SEARCHER_THREAD_CONTEXT *ctx, + CHAR *buf, + ULONG uLenRemain) +{ + MOVE PV[MAX_PLY_PER_SEARCH]; + MOVE mv; + ULONG uPly = ctx->uPly; + ULONG uLen; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + + if (NULL == g_pHashTable) return; + do + { + mv = GetPonderMove(&ctx->sPosition); + if (mv.uMove == 0) break; + PV[ctx->uPly] = mv; + + uLen = (ULONG)strlen(MoveToSan(mv, &ctx->sPosition)) + 1; + ASSERT(uLen <= 11); + if (uLenRemain <= uLen) break; + strcat(buf, MoveToSan(PV[ctx->uPly], &ctx->sPosition)); + strcat(buf, " "); + uLenRemain -= uLen; + + if (FALSE == MakeMove(ctx, mv)) break; + } + while(1); + + // + // Unmake the moves + // + while(ctx->uPly > uPly) + { + UnmakeMove(ctx, PV[ctx->uPly - 1]); + } + ASSERT(ctx->uPly == uPly); + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); +} + + + +char * +WalkPV(SEARCHER_THREAD_CONTEXT *ctx) +/** + +Routine description: + + Return a string buffer representing the principle variation. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx + +Return value: + + CHAR * + +**/ +{ + static CHAR buf[SMALL_STRING_LEN_CHAR]; + ULONG u = ctx->uPly; + ULONG v = u; + MOVE mv; +#ifdef DEBUG + POSITION board; + memcpy(&board, &(ctx->sPosition), sizeof(POSITION)); +#endif + + buf[0] = '\0'; + while((mv.uMove = ctx->sPlyInfo[v].PV[u].uMove) != 0) + { + if (mv.uMove == HASHMOVE.uMove) + { + strncat(buf, " ", ARRAY_LENGTH(buf) - strlen(buf) - 1); + FinishPVTailFromHash(ctx, buf, ARRAY_LENGTH(buf) - strlen(buf)); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else if (mv.uMove == RECOGNMOVE.uMove) + { + strncat(buf, "", ARRAY_LENGTH(buf) - strlen(buf) - 1); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else if (mv.uMove == DRAWMOVE.uMove) + { + strncat(buf, "<=>", ARRAY_LENGTH(buf) - strlen(buf) - 1); + ASSERT(ctx->sPlyInfo[v].PV[u+1].uMove == 0); + break; + } + else + { + strncat(buf, MoveToSan(mv, &ctx->sPosition), + ARRAY_LENGTH(buf) - strlen(buf)); + strncat(buf, " ", ARRAY_LENGTH(buf) - strlen(buf) - 1); + } + + if (FALSE == MakeMove(ctx, mv)) break; + u++; + + if (strlen(buf) > (SMALL_STRING_LEN_CHAR - 10)) break; + } + + // + // Unmake the moves + // + u--; + while(ctx->uPly > v) + { + UnmakeMove(ctx, ctx->sPlyInfo[v].PV[u]); + u--; + } + ASSERT(ctx->uPly == v); + ASSERT(PositionsAreEquivalent(&board, &ctx->sPosition)); + return(buf); +} + + +void +UtilPanic(ULONG uPanicCode, + POSITION *pos, + void *arg1, void *arg2, void *arg3, + char *szFile, ULONG uLine) +{ + Bug("Typhoon PANIC 0x%x (%p, %p, %p, %p)\n" + "Location: %s at line %u\n\n", + uPanicCode, pos, arg1, arg2, arg3, szFile, uLine); + Banner(); + Bug("----------------------------------------------------------------\n"); + switch(uPanicCode) { + case CANNOT_INITIALIZE_SPLIT: + case GOT_ILLEGAL_MOVE_WHILE_PONDERING: + case CANNOT_OFFICIALLY_MAKE_MOVE: + DumpPosition(pos); + DumpMove((ULONG)arg1); + break; + case INITIALIZATION_FAILURE: + Bug("%s\n", (char *)arg1); + break; + default: + break; + } + fflush(stdout); + fflush(g_pfLogfile); + BREAKPOINT; + exit(-1); +} + +void +UtilPrintPV(SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv) +/** + +Routine description: + + Print a PV out to stdout and the log. + +Parameters: + + SEARCHER_THREAD_CONTEXT *ctx, + SCORE iAlpha, + SCORE iBeta, + SCORE iScore, + MOVE mv + +Return value: + + void + +**/ +{ + double dNow = SystemTimeStamp(); + + ASSERT(ctx->uThreadNumber == 0); + ASSERT(IS_VALID_SCORE(iAlpha)); + ASSERT(IS_VALID_SCORE(iBeta)); + ASSERT(iAlpha < iBeta); + ASSERT(IS_VALID_SCORE(iScore)); + + dNow -= g_MoveTimer.dStartTime; + + // + // Set the last PV in the context if we have a root PV or a root + // fail high. + // + if ((iAlpha < iScore) && (iScore < iBeta)) + { + strncpy(ctx->szLastPV, WalkPV(ctx), SMALL_STRING_LEN_CHAR); + } + else if (iScore > iBeta) + { + strncpy(ctx->szLastPV, MoveToSan(mv, &(ctx->sPosition)), + SMALL_STRING_LEN_CHAR); + } + + if ((TRUE == g_Options.fThinking) && (TRUE == g_Options.fShouldPost)) + { + // + // Maybe output the PV. Note: xboard gets confused by PV + // lines that don't match its requirements exactly; if we are + // running under xboard, match its expected format. Otherwise + // be more helpful / verbose. + // + if ((dNow > 0.35) || ((dNow > 0.15) && (g_Options.fVerbosePosting))) + { + if (TRUE == g_Options.fRunningUnderXboard) + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + else if (iScore <= iAlpha) + { + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" FL --\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount); + } + else + { + ASSERT(iScore >= iBeta); + Trace("%2u %6d %5u %-12" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s ++\n", + g_uIterateDepth, + iScore, + (ULONG)(dNow * 100), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + } + else // !running under xboard + { + if ((iAlpha < iScore) && (iScore < iBeta)) + { + Trace("%2u %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + else if (iScore <= iAlpha) + { + Trace("%2u- %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" FL --\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount); + } + else + { + ASSERT(iScore >= iBeta); + Trace("%2u+ %5s %-9s %-11" + COMPILER_LONGLONG_UNSIGNED_FORMAT" %s ++\n", + g_uIterateDepth, + ScoreToString(iScore), + TimeToString(dNow), + ctx->sCounters.tree.u64TotalNodeCount, + ctx->szLastPV); + } + } + } + } +} diff --git a/src/vars.c b/src/vars.c new file mode 100644 index 0000000..9d736ab --- /dev/null +++ b/src/vars.c @@ -0,0 +1,483 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + vars.c + +Abstract: + + This is code that implements variables in the engine. Some of + these variables are read only but others can be set by the engine + user to affect certain aspects of engine operation. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 18 May 2004 + +Revision History: + + $Id: vars.c 354 2008-06-30 05:10:08Z scott $ + +**/ + +#include "chess.h" + +extern ULONG g_uNumInputEvents; + +typedef void(PUSERVARFUN)(void); + +// +// Here's how we expose engine variables to the user. +// +typedef struct _USER_VARIABLE +{ + char *szName; // variable name + char *szType; // variable type: + // * - char *, strdup/free + // H - hash size + // B - boolean + // U - unsigned + // I - int + // M - move + // D - double + // S - string buffer + void *pValue; // pointer to value + PUSERVARFUN *pFunction; // funct to call when it changes +} USER_VARIABLE; + +extern ULONG g_uBookProbeFailures; + +USER_VARIABLE g_UserVarList[] = +{ + { "AnnounceOpening", + "B", + (void *)&(g_Options.fShouldAnnounceOpening), + NULL }, + { "BatchMode", + "b", + (void *)&(g_Options.fNoInputThread), + NULL }, + { "BlackPlayer", + "*", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].szName), + NULL }, + { "BlackRating", + "U", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].uRating), + NULL }, + { "BlackDescription", + "*", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].szDescription), + NULL }, + { "BlackIsComputer", + "B", + (void *)&(g_GameData.sHeader.sPlayer[BLACK].fIsComputer), + NULL }, + { "BookFileName", + "S", + (void *)&(g_Options.szBookName), + NULL }, + { "BookProbeFailures", + "u", + (void *)&(g_uBookProbeFailures), + NULL }, + { "ComputerTimeRemainingSec", + "U", + (void *)&(g_Options.uOpponentsClock), + NULL }, //&DoVerifyClocks }, + { "EGTBPath", + "S", + (void *)&(g_Options.szEGTBPath), + InitializeEGTB }, + { "FastScript", + "B", + (void *)&(g_Options.fFastScript), + NULL }, + { "GameDescription", + "*", + (void *)&(g_GameData.sHeader.szGameDescription), + NULL }, + { "GameLocation", + "*", + (void *)&(g_GameData.sHeader.szLocation), + NULL }, + { "GameIsRated", + "B", + (void *)&(g_GameData.sHeader.fGameIsRated), + NULL }, + { "GameResultComment", + "*", + (void *)&(g_GameData.sHeader.result.szDescription), + NULL }, + { "LastEval", + "I", + (void *)&(g_Options.iLastEvalScore), + NULL }, + { "LogfileName", + "S", + (void *)&(g_Options.szLogfile), + NULL }, + { "MoveToPonder", + "m", + (void *)&(g_Options.mvPonder), + NULL }, + { "MovesPerTimePeriod", + "U", + (void *)&(g_Options.uMovesPerTimePeriod), + NULL }, + { "OpponentTimeRemainingSec", + "U", + (void *)&(g_Options.uMyClock), + NULL }, //&DoVerifyClocks }, + { "PendingInputEvents", + "u", + (void *)&(g_uNumInputEvents), + NULL }, + { "PonderingNow", + "b", + (void *)&(g_Options.fPondering), + NULL }, + { "PostLines", + "B", + (void *)&(g_Options.fShouldPost), + NULL }, + { "ResignThreshold", + "I", + (void *)&(g_Options.iResignThreshold), + NULL }, + { "SearchDepthLimit", + "U", + (void *)&(g_Options.uMaxDepth), + NULL }, //&DoVerifySearchDepth }, + { "SearchTimeLimit", + "U", + (void *)&(g_Options.uMyIncrement), + NULL }, //&DoVerifySearchTime }, + { "SearchStartedTime", + "d", + (void *)&(g_MoveTimer.dStartTime), + NULL }, + { "SearchSoftTimeLimit", + "d", + (void *)&(g_MoveTimer.dSoftTimeLimit), + NULL }, + { "SearchHardTimeLimit", + "d", + (void *)&(g_MoveTimer.dHardTimeLimit), + NULL }, + { "SearchNodesBetweenTimeCheck", + "u", + (void *)&(g_MoveTimer.uNodeCheckMask), + NULL }, + { "StatusLine", + "B", + (void *)&(g_Options.fStatusLine), + NULL }, + { "ThinkOnOpponentsTime", + "B", + (void *)&(g_Options.fShouldPonder), + NULL }, + { "ThinkingNow", + "b", + (void *)&(g_Options.fThinking), + NULL }, + { "TournamentMode", + "B", + (void *)&(g_fTournamentMode), + NULL }, + { "VerbosePosting", + "B", + (void *)&(g_Options.fVerbosePosting), + NULL }, + { "WhitePlayer", + "*", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].szName), + NULL }, + { "WhiteRating", + "U", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].uRating), + NULL }, + { "WhiteDescription", + "*", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].szDescription), + NULL }, + { "WhiteIsComputer", + "B", + (void *)&(g_GameData.sHeader.sPlayer[WHITE].fIsComputer), + NULL }, + { "Xboard", + "B", + (void *)&(g_Options.fRunningUnderXboard), + NULL } +}; + + + + +COMMAND(SetCommand) +/** + +Routine description: + + This function implements the 'set' engine command. + + Usage: + + set [variable name [value]] + + With no arguments, set dumps a list of all variables and their + current values. + + With one argument, set displays the specified variable's value. + + With two arguments, set changes the value of the specified + variable to the given value. + +Parameters: + + The COMMAND macro hides four arguments from the input parser: + + CHAR *szInput : the full line of input + ULONG argc : number of argument chunks + CHAR *argv[] : array of ptrs to each argument chunk + POSITION *pos : a POSITION pointer to operate on + +Return value: + + void + +**/ +{ + ULONG x, y; + FLAG fFound; + + if (argc == 1) + { + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + switch(toupper(g_UserVarList[x].szType[0])) + { + case 'H': + case 'U': + Trace("%-28s => %u\n", + g_UserVarList[x].szName, + *((unsigned int *)g_UserVarList[x].pValue)); + break; + case 'I': + Trace("%-28s => %d\n", + g_UserVarList[x].szName, + *((int *)g_UserVarList[x].pValue)); + break; + case 'S': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (char *)g_UserVarList[x].pValue); + break; + case 'M': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + MoveToIcs(*((MOVE *)g_UserVarList[x].pValue))); + break; + case 'B': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (*((FLAG *)g_UserVarList[x].pValue) == TRUE) ? + "TRUE" : "FALSE"); + break; + case 'D': + Trace("%-28s => %f\n", + g_UserVarList[x].szName, + *((double *)g_UserVarList[x].pValue)); + break; + case '*': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + *((char **)g_UserVarList[x].pValue)); + break; + default: + Trace("%-28s => ???\n", + g_UserVarList[x].szName); + // ASSERT(FALSE); + break; + } + } + return; + } + else if (argc == 2) + { + fFound = FALSE; + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + if (!STRNCMPI(argv[1], + g_UserVarList[x].szName, + strlen(argv[1]))) + { + fFound = TRUE; + switch(toupper(g_UserVarList[x].szType[0])) + { + case 'H': + case 'U': + Trace("%-28s => %u\n", + g_UserVarList[x].szName, + *((unsigned int *)g_UserVarList[x].pValue)); + break; + case 'I': + Trace("%-28s => %d\n", + g_UserVarList[x].szName, + *((int *)g_UserVarList[x].pValue)); + break; + case 'S': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (char *)g_UserVarList[x].pValue); + break; + case 'M': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + MoveToIcs(*((MOVE *)g_UserVarList[x].pValue))); + break; + case 'B': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + (*((FLAG *)g_UserVarList[x].pValue) == TRUE) ? + "TRUE" : "FALSE"); + break; + case 'D': + Trace("%-28s => %f\n", + g_UserVarList[x].szName, + *((double *)g_UserVarList[x].pValue)); + break; + case '*': + Trace("%-28s => \"%s\"\n", + g_UserVarList[x].szName, + *((char **)g_UserVarList[x].pValue)); + break; + default: + Trace("%-28s => ???\n", + g_UserVarList[x].szName); + // ASSERT(FALSE); + break; + } + } + } + + if (FALSE == fFound) + { + Trace("Error (invalid variable): %s\n", argv[1]); + } + return; + } + else + { + ASSERT(argc > 2); + + fFound = FALSE; + + for (x = 0; + x < ARRAY_SIZE(g_UserVarList); + x++) + { + if (!STRNCMPI(argv[1], + g_UserVarList[x].szName, + strlen(argv[1]))) + { + fFound = TRUE; + + if (islower(g_UserVarList[x].szType[0])) + { + Trace("Error (variable is read only): %s\n", + argv[1]); + } + + switch(g_UserVarList[x].szType[0]) + { + case 'H': + y = atoi(argv[2]); + if ((y < 0) || (y & (y - 1))) + { + Trace("Error (invalid size): %d\n", y); + } + else + { + *((int *)g_UserVarList[x].pValue) = y; + } + break; + + case '*': + if (NULL != *((char **)g_UserVarList[x].pValue)) + { + SystemFreeMemory( *((char **)g_UserVarList[x].pValue ) ); + } + *((char **)g_UserVarList[x].pValue) = STRDUP(argv[2]); + if (NULL == *((char **)g_UserVarList[x].pValue)) + { + Trace("Error (out of memory)\n"); + return; + } + break; + + case 'S': + strncpy(((char *)g_UserVarList[x].pValue), + argv[2], + 127); + break; + + case 'U': + y = atoi(argv[2]); + if (y < 0) + { + Trace("Error (invalid value): %d\n", y); + return; + } + *((unsigned *)g_UserVarList[x].pValue) = y; + break; + + case 'I': + y = atoi(argv[2]); + *((int *)g_UserVarList[x].pValue) = y; + break; + + case 'B': + if (toupper(*(argv[2])) == 'T') + { + *((FLAG *)g_UserVarList[x].pValue) = TRUE; + } + else if (toupper(*(argv[2])) == 'F') + { + *((FLAG *)g_UserVarList[x].pValue) = FALSE; + } + else + { + Trace("Error (invalid value, must be TRUE or " + "FALSE): %s\n", argv[2]); + } + break; + + default: + ASSERT(FALSE); + break; + } + + if (NULL != g_UserVarList[x].pFunction) + { + (void)(g_UserVarList[x].pFunction)(); + } + } + } + + if (FALSE == fFound) + { + Trace("Error (invalid variable): %s\n", argv[1]); + } + } +} + +// +// TODO: unset? +// diff --git a/src/win32.c b/src/win32.c new file mode 100755 index 0000000..3b65779 --- /dev/null +++ b/src/win32.c @@ -0,0 +1,1448 @@ +/** + +Copyright (c) Scott Gasch + +Module Name: + + win32.c + +Abstract: + + Windows(R) operating system dependent code. + +Author: + + Scott Gasch (scott.gasch@gmail.com) 7 Apr 2004 + +Revision History: + + $Id: win32.c 345 2007-12-02 22:56:42Z scott $ + +**/ + +#include "chess.h" +#define _WIN32_WINNT 0x403 + +#pragma warning(disable:4142) // benign redefinition of type +#include +#pragma warning(default:4142) + +#define SYS_MAX_HEAP_ALLOC_SIZE_BYTES 0xfff + +// +// Global system lock +// +CRITICAL_SECTION g_SystemLock; +#define LOCK_SYSTEM EnterCriticalSection(&g_SystemLock) +#define UNLOCK_SYSTEM LeaveCriticalSection(&g_SystemLock) + +// +// Thread table +// +typedef struct _SYSTEM_THREAD_TABLE_ENTRY +{ + DLIST_ENTRY links; + ULONG uWrapperHandle; + ULONG uTid; + ULONG uThreadParam; + THREAD_ENTRYPOINT *pEntry; + ULONG uExitCode; + HANDLE hThread; +} +SYSTEM_THREAD_TABLE_ENTRY; +DLIST_ENTRY g_SystemThreadList; + +// +// Global buffer to hold a bunch of system dependent numbers / settings +// +typedef struct _SYS_INFORMATION_BUFFER +{ + FLAG fPopulated; + SYSTEM_INFO si; + OSVERSIONINFOEX vi; + MEMORYSTATUS ms; +} +SYS_INFORMATION_BUFFER; +SYS_INFORMATION_BUFFER g_SystemInfoBuffer; + +// +// The frequency and type of our TimeStamp timer +// +double g_dTimeStampFrequency = 0.0; +ULONG g_uTimeStampType = 0; +ULONG g_uMaxHeapAllocationSize = 0; + +// +// A history of allocations +// +#ifdef DEBUG +ULONG g_uTotalAlloced = 0; + +#define ALLOC_HASH_SIZE 0x4000 + +typedef struct _ALLOC_RECORD +{ + void *p; + ULONG uSize; +} ALLOC_RECORD; +ALLOC_RECORD g_AllocHash[ALLOC_HASH_SIZE]; + +#define PTR_TO_ALLOC_HASH(x) ((((ULONG_PTR)(x)) >> 3) & (ALLOC_HASH_SIZE - 1)) + +ULONG +GetHeapMemoryUsage(void) +{ + Trace("There are now %u bytes outstanding.\n", g_uTotalAlloced); + return(g_uTotalAlloced); +} + +static void +ReleaseAllocHashEntry(void *p) +{ + ULONG u = PTR_TO_ALLOC_HASH(p); + ULONG v = u; + + LOCK_SYSTEM; + while(g_AllocHash[u].p != p) + { + u++; + u &= (ALLOC_HASH_SIZE - 1); + if (v == u) return; + } + g_AllocHash[u].p = NULL; + g_uTotalAlloced -= g_AllocHash[u].uSize; + UNLOCK_SYSTEM; + +// Trace("Freed %u bytes at 0x%p.\n", g_AllocHash[u].uSize, p); +} + +static void +MarkAllocHashEntry(void *p, ULONG uSize) +{ + ULONG u = PTR_TO_ALLOC_HASH(p); + + if (uSize > (1024 * 1024 * 30)) return; + + LOCK_SYSTEM; + while(g_AllocHash[u].p != NULL) + { + u++; + u &= (ALLOC_HASH_SIZE - 1); + } + g_AllocHash[u].p = p; + g_AllocHash[u].uSize = uSize; + g_uTotalAlloced += uSize; + UNLOCK_SYSTEM; + +// Trace("Alloc %u bytes at 0x%p.\n", g_AllocHash[u].uSize, p); +} +#endif + + +CHAR * +SystemStrDup(CHAR *p) +/** + +Routine description: + + Local implementation of strdup + +Parameters: + + CHAR *p + +Return value: + + CHAR + +**/ +{ + CHAR *q = SystemAllocateMemory((ULONG)strlen(p) + 1); + + ASSERT(strlen(p) < (size_t)MAX_ULONG); + strcpy(q, p); + return(q); +} + + +CHAR * +SystemGetDateString(void) +/** + +Routine description: + + Get the current date as a string. + +Parameters: + + void + +Return value: + + CHAR + +**/ +{ + static CHAR buf[32]; + SYSTEMTIME st; + + GetSystemTime(&st); + + snprintf(buf, ARRAY_LENGTH(buf), + "%u.%02u.%02u", st.wYear, st.wMonth, st.wDay); + return(buf); +} + + +CHAR * +SystemGetTimeString(void) +/** + +Routine description: + + Get the current time as a string. + +Parameters: + + void + +Return value: + + CHAR + +**/ +{ + static CHAR buf[32]; + SYSTEMTIME st; + + GetSystemTime(&st); + + snprintf(buf, ARRAY_LENGTH(buf), + "%u:%02u:%02u", st.wHour, st.wMinute, st.wSecond); + return(buf); +} + + +void +SystemDeferExecution(ULONG uMs) +/** + +Routine description: + + Sleep for some number of milliseconds. + +Parameters: + + ULONG uMs + +Return value: + + void + +**/ +{ + Sleep(uMs); +} + +static SYSTEM_THREAD_TABLE_ENTRY * +_SystemGetThreadTableEntry(ULONG uThreadHandle) +/** + +Routine description: + + Support code for the thread functionality wrapper. Given a thread + "handle" return its thread table struct. + +Parameters: + + ULONG uThreadHandle + +Return value: + + SYSTEM_THREAD_TABLE_ENTRY * + +**/ +{ + DLIST_ENTRY *p; + SYSTEM_THREAD_TABLE_ENTRY *q; + + LOCK_SYSTEM; + p = g_SystemThreadList.pFlink; + while(p != &g_SystemThreadList) + { + q = CONTAINING_STRUCT(p, SYSTEM_THREAD_TABLE_ENTRY, links); + if (q->uWrapperHandle == uThreadHandle) + { + goto end; + } + p = p->pFlink; + } + q = NULL; + end: + UNLOCK_SYSTEM; + return(q); +} + +int WINAPI +SystemThreadEntryPoint(VOID *pParam) +/** + +Routine description: + + The real entry point of all new threads. It calls into the user + specified entry point. + +Parameters: + + VOID *pParam + +Return value: + + int WINAPI + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *p = (SYSTEM_THREAD_TABLE_ENTRY *)pParam; + ULONG uParam; + int i; + + LOCK_SYSTEM; + UNLOCK_SYSTEM; + + uParam = p->uThreadParam; + i = (int)(*(p->pEntry))(uParam); + return(i); +} + +FLAG +SystemCreateThread(THREAD_ENTRYPOINT *pEntry, ULONG uParam, ULONG *puHandle) +/** + +Routine description: + + Wrapper function to expose create thread functionality. + +Parameters: + + THREAD_ENTRYPOINT *pEntry, + ULONG uParam, + ULONG *puHandle + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *p; + + p = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + sizeof(SYSTEM_THREAD_TABLE_ENTRY)); + if (NULL == p) + { + *puHandle = 0; + return(FALSE); + } + + LOCK_SYSTEM; + p->pEntry = pEntry; + p->uThreadParam = uParam; + p->hThread = CreateThread(NULL, + 0x6000, + SystemThreadEntryPoint, + (VOID *)p, + 0, + &(p->uTid)); + if (NULL == p->hThread) + { + (void)HeapFree(GetProcessHeap(), 0, p); + return(FALSE); + } + *puHandle = p->uWrapperHandle = p->uTid; + InsertHeadList(&g_SystemThreadList, &(p->links)); + UNLOCK_SYSTEM; + return(TRUE); +} + + +FLAG +SystemWaitForThreadToExit(ULONG uThreadHandle) +/** + +Routine description: + + Wait for the specified thread to exit. + +Parameters: + + ULONG uThreadHandle + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *q = _SystemGetThreadTableEntry(uThreadHandle); + + if (WAIT_OBJECT_0 != WaitForSingleObject(q->hThread, INFINITE)) + { + ASSERT(FALSE); + return(FALSE); + } + return(TRUE); +} + + +FLAG +SystemGetThreadExitCode(ULONG uThreadHandle, ULONG *puCode) +/** + +Routine description: + + Get the specified thread's exit value. + +Parameters: + + ULONG uThreadHandle, + ULONG *puCode + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *q = _SystemGetThreadTableEntry(uThreadHandle); + ULONG uCode; + + if (FALSE == GetExitCodeThread(q->hThread, &uCode)) + { + return(FALSE); + } + if (STILL_ACTIVE == uCode) + { + return(FALSE); + } + *puCode = uCode; + return(TRUE); +} + + +FLAG +SystemDeleteThread(ULONG uThreadHandle) +/** + +Routine description: + + Terminate a thread. + +Parameters: + + ULONG uThreadHandle + +Return value: + + FLAG + +**/ +{ + SYSTEM_THREAD_TABLE_ENTRY *q = _SystemGetThreadTableEntry(uThreadHandle); + ULONG u; + + if (NULL != q) + { + if (FALSE == SystemGetThreadExitCode(uThreadHandle, &u)) + { + SystemWaitForThreadToExit(uThreadHandle); + } + CloseHandle(q->hThread); + LOCK_SYSTEM; + RemoveEntryList(&(q->links)); + HeapFree(GetProcessHeap(), 0, q); + UNLOCK_SYSTEM; + return(TRUE); + } + return(FALSE); +} + + +static void +_SystemPopulateSystemInformationBuffer(void) +/** + +Routine description: + + Populates global structure SYS_INFORMATION_BUFFER. This code should + be called only once from SystemDependentInitialization. It should + definitely never be called by more than one thread at a time. + +Parameters: + + void + +Return value: + + void + +**/ +{ +#ifdef DEBUG + static FLAG fInit = FALSE; + + if (TRUE == fInit) + { + Bug("_SystemPopulateSystemInformationBuffer: This code should " + "not be called more than once!\n"); + ASSERT(FALSE); + } + fInit = TRUE; +#endif + + // + // Make some calls to populate the global buffer + // + GetSystemInfo(&(g_SystemInfoBuffer.si)); + + // + // Note: This API is not present on Win9x + // + g_SystemInfoBuffer.vi.dwOSVersionInfoSize = sizeof(OSVERSIONINFOEX); + if (FALSE == GetVersionEx((OSVERSIONINFO *)&(g_SystemInfoBuffer.vi))) + { + Bug("_SystemPopulateSystemInformationBuffer: GetVersionEx " + "call failed, error=%u.\n", GetLastError()); + ASSERT(FALSE); + } + + GlobalMemoryStatus(&(g_SystemInfoBuffer.ms)); + + g_SystemInfoBuffer.fPopulated = TRUE; +} + + +static FLAG +_SystemEnablePrivilege(TCHAR *szPrivilegeName, + FLAG fEnable) +/** + +Routine description: + + This code is called by SystemDependentInitialization to add some + privileges to our process' security token. + +Parameters: + + TCHAR *szPrivilegeName, + FLAG fEnable + +Return value: + + FLAG + +**/ +{ + FLAG fMyRetVal = FALSE; // our return value + HANDLE hToken = INVALID_HANDLE_VALUE; // handle to process token + PTOKEN_PRIVILEGES pNewPrivileges; // privs to enable/disable + LUID Luid; // priv as a LUID + BYTE buf[sizeof(TOKEN_PRIVILEGES)+ + ((1 - ANYSIZE_ARRAY) * sizeof(LUID_AND_ATTRIBUTES))]; + + pNewPrivileges = (PTOKEN_PRIVILEGES)buf; + + // + // Try to open the thread's security token first. + // + if (FALSE == OpenThreadToken(GetCurrentThread(), + TOKEN_ADJUST_PRIVILEGES, + FALSE, + &hToken)) + { + // + // Well that failed. If it is because there is no thread token then + // try to open the process' security token. + // + if (ERROR_NO_TOKEN == GetLastError()) + { + if (FALSE == OpenProcessToken(GetCurrentProcess(), + TOKEN_ADJUST_PRIVILEGES, + &hToken)) + { + // + // Can't open the process token either. Fail. + // + goto end; + } + } + else + { + // + // Failed to open the thread token for some other reason. Fail. + // + goto end; + } + } + + // + // Convert priv name to an LUID. + // + if (FALSE == LookupPrivilegeValue(NULL, + szPrivilegeName, + &Luid)) + { + goto end; + } + + // + // Construct new data struct to enable / disable the privi. + // + pNewPrivileges->PrivilegeCount = 1; + pNewPrivileges->Privileges[0].Luid = Luid; + pNewPrivileges->Privileges[0].Attributes = + fEnable ? SE_PRIVILEGE_ENABLED : 0; + + // + // Adjust the privileges on the token. + // + fMyRetVal = AdjustTokenPrivileges(hToken, + FALSE, + pNewPrivileges, + 0, + NULL, + NULL); + if (TRUE == fMyRetVal) + { + // + // This boneheaded API returns TRUE and then expects the + // caller to test GetLastError to see if it really worked. + // + if (ERROR_SUCCESS != GetLastError()) + { + fMyRetVal = FALSE; + } + } + + end: + if (INVALID_HANDLE_VALUE != hToken) + { + CloseHandle(hToken); + } + return(fMyRetVal); +} + + +void FORCEINLINE +SystemDebugBreakpoint(void) +/** + +Routine description: + + A hardcoded breakpoint. + +Parameters: + + void + +Return value: + + void + +**/ +{ + DebugBreak(); +} + +#define SYS_HIGH_PERFORMANCE_TIMER (1) +#define SYS_GET_TICK_COUNT (2) +#define SYS_MS_PER_SECOND (1000) + +double +SystemTimeStamp(void) +/** + +Routine description: + + Return a timestamp to the caller. The precision of this timestamp + is based on whether the machine supports a high resolution timer. + If not, this code rolls back to use GetTickCount(). + + This code relies on some initialization code in SystemDependent- + Initialization. Once that code has executed, this code is thread + safe. + +Parameters: + + void + +Return value: + + double + +**/ +{ + double dRetVal; + UINT64 u64; + + switch(g_uTimeStampType) + { + case SYS_HIGH_PERFORMANCE_TIMER: + QueryPerformanceCounter((LARGE_INTEGER *)&u64); + dRetVal = u64 * g_dTimeStampFrequency; + break; + case SYS_GET_TICK_COUNT: + dRetVal = GetTickCount() / SYS_MS_PER_SECOND; + break; + default: + dRetVal = 0.0; + Bug("SystemTimeStamp: You have to call SystemDependent" + "Initialization before you can call this code.\n"); + ASSERT(FALSE); + break; + } + return(dRetVal); +} + + +FLAG +SystemDoesFileExist(CHAR *szFilename) +/** + +Routine description: + + Determine if a file exists (non-atomically). + +Parameters: + + CHAR *szFilename + +Return value: + + FLAG + +**/ +{ + if (INVALID_FILE_ATTRIBUTES == GetFileAttributesA(szFilename)) + { + if (GetLastError() == ERROR_FILE_NOT_FOUND) + { + return(FALSE); + } + } + return(TRUE); +} + + +static FLAG +_SystemIsAdministrator(void) +/** + +Routine description: + + This code is called by SystemDependentInitialization. Its job is to + determine whether this process is running with administrative powers. + +Parameters: + + void + +Return value: + + static FLAG + +**/ +{ + BOOL fIsMember = FALSE; // our return value + SID *pAdminSid = NULL; // ptr to admin sid + SID_IDENTIFIER_AUTHORITY NtAuthority = // used to create admin sid + SECURITY_NT_AUTHORITY; + + // + // Allocate and initialize a SID for the admin group. + // + if (FALSE == AllocateAndInitializeSid(&NtAuthority, + 2, + SECURITY_BUILTIN_DOMAIN_RID, + DOMAIN_ALIAS_RID_ADMINS, + 0, 0, 0, 0, 0, 0, + &pAdminSid)) + { + goto end; + } + + // + // SID allocation succeeded, check this thread or process token + // for membership in the admin group. + // + if (FALSE == CheckTokenMembership(NULL, + pAdminSid, + &fIsMember)) + { + fIsMember = FALSE; + } + + end: + if (NULL != pAdminSid) + { + FreeSid(pAdminSid); + } + + return(fIsMember); +} + + +static void * +_SystemCallVirtualAlloc(ULONG dwSizeBytes) +/** + +Routine description: + + Wrapper around VirtualAlloc + +Parameters: + + ULONG dwSizeBytes + +Return value: + + static void + +**/ +{ + SIZE_T size = dwSizeBytes; + void *pMem = NULL; + + pMem = VirtualAlloc(NULL, + size, + MEM_RESERVE | MEM_COMMIT, + PAGE_READWRITE); + if (NULL == pMem) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "VirtualAlloc", GetLastError(), size, + __FILE__, __LINE__); + } + return(pMem); +} + +static void +_SystemCallVirtualFree(void *pMem) +/** + +Routine description: + + Wrapper around VirtualFree + +Parameters: + + void *pMem + +Return value: + + static void + +**/ +{ + BOOL fRetVal = FALSE; + + if (NULL != pMem) + { + fRetVal = VirtualFree(pMem, 0, MEM_RELEASE); + if (FALSE == fRetVal) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "VirtualFree", GetLastError(), pMem, + __FILE__, __LINE__); + } + } +} + +static void * +_SystemCallHeapAlloc(ULONG dwSizeBytes) +/** + +Routine description: + + Wrapper around HeapAlloc. Returns a zeroed buffer from the heap. + While on the subject of heaps, let me take a moment to extol the + value of the Win32 Application Verifier / PageHeap code. This is + code that sanity checks the actions of an app. It is especially + good at finding heap misuse (double frees, reuse after free, + buffer overruns, etc...) It also catches things like + CRITICAL_SECTION abuse and HANDLE abuse. To enable it, use + appverif.exe. + +Parameters: + + ULONG dwSizeBytes + +Return value: + + static void + +**/ +{ + void *p = HeapAlloc(GetProcessHeap(), + HEAP_ZERO_MEMORY, + dwSizeBytes); + if (NULL == p) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "HeapAlloc", GetLastError(), dwSizeBytes, + __FILE__, __LINE__); + } + return(p); +} + +static void +_SystemCallHeapFree(void *pMem) +/** + +Routine description: + + Wrapper around HeapFree + +Parameters: + + void *pMem + +Return value: + + static void + +**/ +{ + if (FALSE == HeapFree(GetProcessHeap(), + 0, + pMem)) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "HeapFree", GetLastError(), pMem, + __FILE__, __LINE__); + } +} + +void +SystemFreeMemory(void *pMem) +/** + +Routine description: + + Free memory + +Parameters: + + void *pMem + +Return value: + + static void + +**/ +{ + _SystemCallHeapFree(pMem); +#ifdef DEBUG + ReleaseAllocHashEntry(pMem); +#endif +} + +void * +SystemAllocateMemory(ULONG dwSizeBytes) +/** + +Routine description: + + Allocate some memory, either from the heap or from VirtualAlloc + depending on the size of the request. The buffer returned by + this call is guaranteed to be zeroed out. Buffers allocated by + this call should be freed via a call to SystemFreeMemory when + they are no longer needed. + +Parameters: + + ULONG dwSizeBytes : size of the buffer needed in bytes + +Return value: + + void + +**/ +{ + BYTE *p; + + p = _SystemCallHeapAlloc(dwSizeBytes); +#ifdef DEBUG + MarkAllocHashEntry(p, dwSizeBytes); +#endif + return(p); +} + + +void * +SystemAllocateLockedMemory(ULONG dwSizeBytes) +/** + +Routine description: + + Allocate a buffer that is locked in memory (i.e. non-pagable). + +Parameters: + + ULONG dwSizeBytes + +Return value: + + void + +**/ +{ + void *p = _SystemCallVirtualAlloc(dwSizeBytes); + + if (NULL != p) + { + if (FALSE == VirtualLock(p, dwSizeBytes)) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "VirtualLock", GetLastError(), p, + __FILE__, __LINE__); + } + } +#ifdef DEBUG + MarkAllocHashEntry(p, dwSizeBytes); +#endif + return(p); +} + + +FLAG +SystemMakeMemoryReadOnly(void *pMemory, + ULONG dwSizeBytes) +/** + +Routine description: + +Parameters: + + void *pMemory, + ULONG dwSizeBytes + +Return value: + + FLAG + +**/ +{ + BOOL fRetVal = FALSE; + ULONG dwJunk; + + fRetVal = VirtualProtect(pMemory, + dwSizeBytes, + PAGE_READONLY, + &dwJunk); + if (FALSE == fRetVal) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "VirtualProtect", GetLastError(), pMemory, + __FILE__, __LINE__); + } + return((FLAG)fRetVal); +} + +FLAG +SystemMakeMemoryNoAccess(void *pMemory, + ULONG dwSizeBytes) +/** + +Routine description: + +Parameters: + + void *pMemory, + ULONG dwSizeBytes + +Return value: + + FLAG + +**/ +{ + BOOL fRetVal = FALSE; + ULONG dwJunk; + + fRetVal = VirtualProtect(pMemory, + dwSizeBytes, + PAGE_NOACCESS, + &dwJunk); + if (FALSE == fRetVal) + { + UtilPanic(UNEXPECTED_SYSTEM_CALL_FAILURE, + NULL, "VirtualProtect", GetLastError(), pMemory, + __FILE__, __LINE__); + } + return((FLAG)fRetVal); +} + + +FLAG +SystemCopyFile(CHAR *szSource, CHAR *szDest) +/** + +Routine description: + +Parameters: + + CHAR *szSource, + CHAR *szDest + +Return value: + + FLAG + +**/ +{ + return(CopyFileA(szSource, szDest, TRUE)); +} + + +FLAG +SystemDeleteFile(CHAR *szFile) +/** + +Routine description: + +Parameters: + + CHAR *szFile + +Return value: + + FLAG + +**/ +{ + return(DeleteFileA(szFile)); +} + + +FLAG +SystemMakeMemoryReadWrite(void *pMemory, ULONG dwSizeBytes) +/** + +Routine description: + +Parameters: + + void *pMemory, + ULONG dwSizeBytes + +Return value: + + FLAG + +**/ +{ + BOOL fRetVal = FALSE; + ULONG dwJunk; + + fRetVal = VirtualProtect(pMemory, + dwSizeBytes, + PAGE_READWRITE, + &dwJunk); + if (FALSE == fRetVal) + { + Bug("SystemMakeMemoryReadWrite: VirtualProtect for buffer at %p " + "(size %u) failed, error=%u.\n", pMemory, dwSizeBytes, + GetLastError()); + } + return(fRetVal); +} + + +UINT64 FASTCALL +SystemReadTimeStampCounter(void) +/** + +Routine description: + +Parameters: + + void + +Return value: + + UINT64 FASTCALL + +**/ +{ +#if defined(_X86_) + _asm { + rdtsc + } +#elif defined(_AMD64_) + UINT64 itc; + itc = __rdtsc(); + return itc; +#elif defined(_IA64_) + UINT64 itc; + itc = __getReg(CV_IA64_ApITC); + return itc; +#else +#error Unknown architecture +#endif +} + +#define MAX_LOCKS (8) +typedef struct _WIN32_LOCK_ENTRY +{ + CRITICAL_SECTION lock; + FLAG fInUse; +} WIN32_LOCK_ENTRY; +WIN32_LOCK_ENTRY g_rgLockTable[MAX_LOCKS]; + +ULONG +SystemCreateLock(void) +{ + ULONG u; + + LOCK_SYSTEM; + for (u = 0; u < MAX_LOCKS; u++) + { + if (FALSE == g_rgLockTable[u].fInUse) + { + InitializeCriticalSection(&(g_rgLockTable[u].lock)); + g_rgLockTable[u].fInUse = TRUE; + goto end; + } + } + u = (ULONG)-1; // no free slot + + end: + UNLOCK_SYSTEM; + return(u); +} + +FLAG +SystemDeleteLock(ULONG u) +{ + LOCK_SYSTEM; + if ((u < MAX_LOCKS) && (g_rgLockTable[u].fInUse == TRUE)) + { + DeleteCriticalSection(&(g_rgLockTable[u].lock)); + g_rgLockTable[u].fInUse = FALSE; + UNLOCK_SYSTEM; + return(TRUE); + } + UNLOCK_SYSTEM; + return(FALSE); +} + +FLAG +SystemBlockingWaitForLock(ULONG u) +{ + CRITICAL_SECTION *p = NULL; + LOCK_SYSTEM; + if ((u < MAX_LOCKS) && (g_rgLockTable[u].fInUse == TRUE)) + { + p = &(g_rgLockTable[u].lock); + } + UNLOCK_SYSTEM; + if (p != NULL) + { + EnterCriticalSection(p); + Trace("lock at %p is obtained.\n", p); + return(TRUE); + } + return(FALSE); +} + + +FLAG +SystemReleaseLock(ULONG u) +{ + CRITICAL_SECTION *p = NULL; + LOCK_SYSTEM; + if ((u < MAX_LOCKS) && (g_rgLockTable[u].fInUse == TRUE)) + { + p = &(g_rgLockTable[u].lock); + } + UNLOCK_SYSTEM; + if (p != NULL) + { + LeaveCriticalSection(p); + Trace("lock at %p is released.\n", p); + return(TRUE); + } + return(FALSE); +} + + +#define MAX_SEMS (8) +HANDLE g_rgSemHandles[MAX_SEMS]; + +ULONG +SystemCreateSemaphore(ULONG uValue) +{ + ULONG u; + LOCK_SYSTEM; + for (u = 0; u < MAX_SEMS; u++) + { + if (g_rgSemHandles[u] == (HANDLE)NULL) + { + g_rgSemHandles[u] = CreateSemaphore(NULL, uValue, uValue, NULL); + if (NULL == g_rgSemHandles[u]) + { + u = (ULONG)-1; + } + goto end; + } + } + u = (ULONG)-1; + + end: + UNLOCK_SYSTEM; + return(u); +} + +FLAG +SystemDeleteSemaphore(ULONG u) +{ + LOCK_SYSTEM; + if ((u < MAX_SEMS) && (g_rgSemHandles[u] != (HANDLE)NULL)) + { + (void)CloseHandle(g_rgSemHandles[u]); + g_rgSemHandles[u] = (HANDLE)NULL; + UNLOCK_SYSTEM; + return(TRUE); + } + UNLOCK_SYSTEM; + return(FALSE); +} + +void +SystemReleaseSemaphoreResource(ULONG u) +{ + LOCK_SYSTEM; + if ((u < MAX_SEMS) && (g_rgSemHandles[u] != (HANDLE)NULL)) + { + ReleaseSemaphore(g_rgSemHandles[u], +1, NULL); + } + UNLOCK_SYSTEM; +} + +void +SystemObtainSemaphoreResource(ULONG u) +{ + HANDLE h; + LOCK_SYSTEM; + if ((u < MAX_SEMS) && (g_rgSemHandles[u] != (HANDLE)NULL)) + { + h = g_rgSemHandles[u]; + UNLOCK_SYSTEM; + (void)WaitForSingleObject(h, INFINITE); + return; + } + UNLOCK_SYSTEM; +} + + + +FLAG +SystemDependentInitialization(void) +/** + +Routine description: + + This code is called to initialize operating system dependent code. + It is unsynchronized. It should only ever be called once. It + should definitely never be called by two threads at once! + +Parameters: + + void + +Return value: + + FLAG : TRUE on success, FALSE otherwise + +**/ +{ + UINT64 u64; +#ifdef DEBUG + static FLAG fInit = FALSE; + + if (TRUE == fInit) + { + Bug("SystemDependentInitialization code called more than once!\n"); + ASSERT(FALSE); + return(FALSE); + } + fInit = TRUE; +#endif + + // + // Initialize the system dependent lock + // + __try + { + InitializeCriticalSection(&g_SystemLock); + } + __except(EXCEPTION_EXECUTE_HANDLER) + { + Bug("SystemDependentInitialization: InitializeCriticalSection " + "raised an exception, bailing out.\n"); + return(FALSE); + } + + // + // Clear a pool of handles + // + memset(g_rgLockTable, 0, sizeof(g_rgLockTable)); + memset(g_rgSemHandles, 0, sizeof(g_rgSemHandles)); + + // + // Populate global system info buffer + // + _SystemPopulateSystemInformationBuffer(); + + // + // Enable some privileges in this process' security token + // + if (FALSE == _SystemEnablePrivilege(SE_INC_BASE_PRIORITY_NAME, TRUE)) + { + Trace("NOTICE: Can't enable SE_INC_BASE_PRIORITY_NAME privilege, " + "error=%u\n", GetLastError()); + } + if (FALSE == _SystemEnablePrivilege(SE_LOCK_MEMORY_NAME, TRUE)) + { + Trace("NOTICE: Can't enable SE_LOCK_MEMORY_NAME privilege, " + "error=%u\n", GetLastError()); + } + + // + // Don't let the system hibernate/suspend while the chess program + // is running. + // + (void)SetThreadExecutionState(ES_CONTINUOUS | ES_SYSTEM_REQUIRED); + + // + // Determine the precision of our SystemTimeStamp() code + // + ASSERT(g_uTimeStampType == 0); + if (FALSE != QueryPerformanceFrequency((LARGE_INTEGER *)&u64)) + { + g_dTimeStampFrequency = 1.0 / u64; + g_uTimeStampType = SYS_HIGH_PERFORMANCE_TIMER; + } + else + { + g_dTimeStampFrequency = 1.0 / 1000.0; + g_uTimeStampType = SYS_GET_TICK_COUNT; + } + ASSERT(g_dTimeStampFrequency > 0.0); + + g_uMaxHeapAllocationSize = 0x1000; + InitializeListHead(&g_SystemThreadList); + + return(TRUE); +} diff --git a/src/x64.asm b/src/x64.asm new file mode 100644 index 0000000..e80dc67 --- /dev/null +++ b/src/x64.asm @@ -0,0 +1,176 @@ +%ifdef _X64_ +[BITS 64] + +[SEGMENT .data] + +[EXTERN _g_VectorDelta] +[EXTERN _g_PieceData] + +%ifdef OSX +;;; Note: The reason for this OSX stuff is that there is a bug in the mac +;;; version of nasm. See comments in data.c for more details. + +[GLOBAL g_NasmVectorDelta] +[GLOBAL _g_NasmVectorDelta] +g_NasmVectorDelta: +_g_NasmVectorDelta: + alignb 32, db 0 + times 256 * 4 db 0 + +[GLOBAL g_NasmPieceData] +[GLOBAL _g_NasmPieceData] +g_NasmPieceData: +_g_NasmPieceData: + alignb 32, db 0 + times 4 * 4 * 8 db 0 +%else +[EXTERN _g_VectorDelta] +[EXTERN _g_PieceData] +%endif + +[SEGMENT .text] + +%ifndef CROUTINES +[GLOBAL LastBit] +[GLOBAL _LastBit] + ;; + ;; ULONGLONG CDECL + ;; LastBit(BITBOARD bb) + ;; +LastBit: +_LastBit: + int 3 + bsr rax, rcx + jnz .found + xor rax, rax + ret +.found: add rax, 1 + ret + int 3 + +[GLOBAL FirstBit] +[GLOBAL _FirstBit] + ;; + ;; ULONGLONG CDECL + ;; FirstBit(BITBOARD bb) + ;; +FirstBit: +_FirstBit: + ;movq rcx, [rsp+8] + bsf rax, rcx + jnz .found + xor rax, rax + ret +.found: add rax, 1 + ret + int 3 + +[GLOBAL CountBits] +[GLOBAL _CountBits] + ;; + ;; ULONGLONG CDECL + ;; CountBits(BITBOARD bb) + ;; +CountBits: +_CountBits: + xor rax, rax + mov rcx, [esp+8] + test rcx, rcx + jz .done +.again: add rax, 1 + mov rdx, rcx + sub rdx, 1 + and rcx, rdx + jnz .again +.done: ret + int 3 + +[GLOBAL GetAttacks] +[GLOBAL _GetAttacks] + + db 43h,30h,50h,56h,72h,31h,47h,34h,54h,20h,32h,30h,30h + db 36h,20h,53h,63h,30h,74h,74h,20h,47h,61h,73h,63h,34h + +iDelta dd -17 + dd +15 + +%define uSide ebp+0x14 +%define cSquare ebp+0x10 +%define pos ebp+0xC +%define pList ebp+8 +;; retaddr ebp+4 +;; old ebp ebp +;; old ebx ebp-4 +;; old esi ebp-8 +;; old edi ebp-0xC +%define pOldList ebp-0x10 +%define c ebp-0x14 +%define x ebp-0x18 + +%define _cNonPawns 0x478 +%define _uNonPawnCount 0x500 +%define _rgSquare 0x0 + + ;; + ;; void CDECL + ;; GetAttacks(SEE_LIST *pList, ; ebp + 8 + ;; POSITION *pos, ; ebp + 0xC + ;; COOR cSquare, ; ebp + 0x10 + ;; ULONG uSide) ; ebp + 0x14 + ;; +GetAttacks: +_GetAttacks: + int 3 +%endif ; !CROUTINES + +[GLOBAL LockCompareExchange] +[GLOBAL _LockCompareExchange] +%define uComp esp+0xC +%define uExch esp+8 +%define pDest esp+4 + ;; + ;; ULONG CDECL + ;; LockCompareExchange(void *dest, ; esp + 4 + ;; ULONG exch, ; esp + 8 + ;; ULONG comp) ; esp + C + ;; +LockCompareExchange: +_LockCompareExchange: + mov ecx, [pDest] + mov edx, [uExch] + mov eax, [uComp] + lock cmpxchg dword [ecx], edx + ret + int 3 + +[GLOBAL LockIncrement] +[GLOBAL _LockIncrement] + ;; + ;; ULONG CDECL + ;; LockIncrement(ULONG *pDest) + ;; +LockIncrement: +_LockIncrement: + mov ecx, [pDest] + mov eax, 1 + lock xadd [ecx], eax + add eax, 1 + ret + int 3 + +[GLOBAL LockDecrement] +[GLOBAL _LockDecrement] + ;; + ;; ULONG CDECL + ;; LockDecrement(ULONG *pDest) + ;; +LockDecrement: +_LockDecrement: + mov ecx, [pDest] + mov eax, -1 + lock xadd [ecx], eax + add eax, -1 + ret + int 3 + +%endif ; X64 diff --git a/src/x86.asm b/src/x86.asm new file mode 100644 index 0000000..8a3f51a --- /dev/null +++ b/src/x86.asm @@ -0,0 +1,422 @@ +%ifdef _X86_ +[BITS 32] + +;;; +;;; For some reason MSVC like to put an extra underscore in front of +;;; global identifer names. If this is gcc, compensate. +;;; +%ifdef __GNUC__ +%define _g_VectorDelta g_VectorDelta +%define _g_PieceData g_PieceData +%endif + +[SEGMENT .data] +ParallelScratch: +_ParallelScratch: + db 43h,30h,50h,56h, 72h,31h,47h,34h, 54h,20h,32h,30h + db 30h,36h,20h,53h, 63h,30h,74h,74h, 20h,47h,61h,73h + db 63h,34h,00h,01h, 22h,15h,48h,35h, 31h,21h,55h,46h + +%ifdef OSX +;;; Note: The reason for this OSX stuff is that there is a bug in the mac +;;; version of nasm. See comments in data.c for more details. + +[GLOBAL g_NasmVectorDelta] +[GLOBAL _g_NasmVectorDelta] +g_NasmVectorDelta: +_g_NasmVectorDelta: + alignb 32, db 0 + times 256 * 4 db 0 + +[GLOBAL g_NasmPieceData] +[GLOBAL _g_NasmPieceData] +g_NasmPieceData: +_g_NasmPieceData: + alignb 32, db 0 + times 4 * 4 * 8 db 0 +%else +[EXTERN _g_VectorDelta] +[EXTERN _g_PieceData] +%endif + +[SEGMENT .text] + +%ifndef CROUTINES +[GLOBAL LastBit] +[GLOBAL _LastBit] + ;; + ;; ULONG CDECL + ;; LastBit(BITBOARD bb) + ;; +LastBit: +_LastBit: + mov ecx, [esp+8] + mov edx, [esp+4] + bsr eax, ecx + jnz .lone + bsr eax, edx + jnz .ltwo + xor eax, eax + jmp .ldone +.lone: add eax, 32 +.ltwo: add eax, 1 +.ldone: ret + + int 3 + +[GLOBAL FirstBit] +[GLOBAL _FirstBit] + ;; + ;; ULONG CDECL + ;; FirstBit(BITBOARD bb) + ;; +FirstBit: +_FirstBit: + mov ecx, [esp+8] ; half of bb + mov edx, [esp+4] ; the other half + bsf eax, edx + jnz .low + bsf eax, ecx + jnz .hi + xor eax, eax + ret +.hi: add eax, 32 +.low: add eax, 1 + ret + + int 3 + +[GLOBAL CountBits] +[GLOBAL _CountBits] + ;; + ;; ULONG CDECL + ;; CountBits(BITBOARD bb) + ;; +CountBits: +_CountBits: + xor eax, eax ; eax is the count + mov ecx, [esp+4] ; half of bb + test ecx, ecx + jz .c2 ; skip first loop? +.c1: add eax, 1 + mov edx, ecx + sub edx, 1 + and ecx, edx + jnz .c1 +.c2: mov ecx, [esp+8] ; the other half of bb + test ecx, ecx + jz .cdone ; skip second loop? +.c3: add eax, 1 + mov edx, ecx + sub edx, 1 + and ecx, edx + jnz .c3 +.cdone: ret + + int 3 +%endif + +[GLOBAL LockCompareExchange] +[GLOBAL _LockCompareExchange] + +%define uComp esp+0xC +%define uExch esp+8 +%define pDest esp+4 + + ;; + ;; ULONG CDECL + ;; LockCompareExchange(void *dest, ; esp + 4 + ;; ULONG exch, ; esp + 8 + ;; ULONG comp) ; esp + C + ;; +LockCompareExchange: +_LockCompareExchange: + mov ecx, [pDest] + mov edx, [uExch] + mov eax, [uComp] + lock cmpxchg dword [ecx], edx + ret + + int 3 + +[GLOBAL LockIncrement] +[GLOBAL _LockIncrement] + ;; + ;; ULONG CDECL + ;; LockIncrement(ULONG *pDest) + ;; +LockIncrement: +_LockIncrement: + mov ecx, [pDest] + mov eax, 1 + lock xadd [ecx], eax + add eax, 1 + ret + + int 3 + +[GLOBAL LockDecrement] +[GLOBAL _LockDecrement] + ;; + ;; ULONG CDECL + ;; LockDecrement(ULONG *pDest) + ;; +LockDecrement: +_LockDecrement: + mov ecx, [pDest] + mov eax, -1 + lock xadd [ecx], eax + add eax, -1 + ret + + int 3 + +%ifndef CROUTINES +[GLOBAL GetAttacks] +[GLOBAL _GetAttacks] + + db 43h,30h,50h,56h,72h,31h,47h,34h,54h,20h,32h,30h,30h + db 36h,20h,53h,63h,30h,74h,74h,20h,47h,61h,73h,63h,34h + +iDelta dd -17 + dd +15 + +%define uSide ebp+0x14 +%define cSquare ebp+0x10 +%define pos ebp+0xC +%define pList ebp+8 +;; retaddr ebp+4 +;; old ebp ebp +;; old ebx ebp-4 +;; old esi ebp-8 +;; old edi ebp-0xC +%define pOldList ebp-0x10 +%define c ebp-0x14 +%define x ebp-0x18 + +%define _cNonPawns 0x478 +%define _uNonPawnCount 0x500 +%define _rgSquare 0x0 + + ;; + ;; void CDECL + ;; GetAttacks(SEE_LIST *pList, ; ebp + 8 + ;; POSITION *pos, ; ebp + 0xC + ;; COOR cSquare, ; ebp + 0x10 + ;; ULONG uSide) ; ebp + 0x14 + ;; +GetAttacks: +_GetAttacks: + push ebp + mov ebp, esp + push ebx + push esi + push edi + + ;; SEE_LIST *pOldList + ;; COOR c + ;; int x + sub esp, 0xC + + mov ecx, [pList] + mov edx, [pos] + + ;; pOldList = pList; + mov dword [pOldList], ecx + + ;; pList.uCount = 0; + mov dword [ecx], 0 + + ;; pList = &(pList.data[0]); + add ecx, 4 + mov edi, ecx + + ;; c = cSquare + iDelta[uColor] + mov esi, dword [uSide] + mov ebx, dword [cSquare] + mov eax, dword [iDelta+esi*4] + add ebx, eax + + ;; pPawn = BLACK_PAWN | uColor + mov ecx, esi + or ecx, 2 + + ;; + ;; Check the pawns + ;; + + ;; if (!IS_ON_BOARD(c)) goto try other pawn + test ebx, 0x88 + jnz .try_other_pawn + + ;; p = pos->pSquare[c]; + mov eax, dword [edx+ebx*8+_rgSquare] + + ;; if (p != pPawn) then goto try other pawn + cmp eax, ecx + jne .try_other_pawn + + ;; pOldList->uCount = 1 + mov dword [edi-4], 1 + + ;; pList->pPiece = p; + mov dword [edi], ecx + + ;; pList->cLoc = c; + mov dword [edi+4], ebx + + ;; pList->iVal = VALUE_PAWN; + mov dword [edi+8], 100 + + ;; pList++ + add edi, 12 + +.try_other_pawn: + ;; c = c + 2 + add ebx, 2 + + ;; if (!IS_ON_BOARD(c)) goto done pawns + test ebx, 0x88 + jnz .done_pawns + + ;; p = pos->pSquare[c]; + mov eax, dword [edx+ebx*8+_rgSquare] + + ;; if (p != pPawn) then goto done pawns + cmp eax, ecx + jne .done_pawns + + ;; pList->pPiece = p; + mov dword [edi], ecx + + ;; pList->cLoc = c; + mov dword [edi+4], ebx + + ;; pList->iVal = VALUE_PAWN; + mov dword [edi+8], 100 + + ;; pOldList->uCount++ + ;; pList++ + mov eax, [pOldList] + add edi, 12 + add dword [eax], 1 + +.done_pawns: + + ;; + ;; Do pieces + ;; + + ;; for (x = pos->uNonPawnCount[uSide][0] - 1; + ;; x >= 0; + ;; x--) + ;; { + lea eax, [esi*8] + mov ecx, dword [edx+eax*4+_uNonPawnCount] + mov dword [x], ecx + +.loop_continue: + mov ecx, dword [x] + sub ecx, 1 + cmp ecx, 0 + jl near .done + mov esi, dword [uSide] + mov dword [x], ecx + + ;; c = pos->cNonPawns[uSide][x]; + mov eax, esi + shl eax, 4 + add eax, ecx + mov eax, dword [edx+eax*4+_cNonPawns] + mov dword [c], eax + + ;; p = pos->pSquare[c]; + mov ecx, dword [edx+eax*8+_rgSquare] + + ;; iIndex = c - cSquare; + sub eax, dword [cSquare] + + ;; + ;; If there is no way for that kind of piece to get to this + ;; square then keep looking. + ;; + ;; if (0 == (g_VectorDeltaTable[iIndex].iVector[iSide] & + ;; (1 << (PIECE_PIECE(p) >> 1)))) continue; + mov ebx, 1 + mov esi, ecx + shr ecx, 1 + shl ebx, cl +%ifdef OSX + test byte [_g_NasmVectorDelta+eax*4+512], bl +%else + test byte [_g_VectorDelta+eax*4+512], bl +%endif + jz .loop_continue + + ;; if (IS_KNIGHT_OR_KING(p)) goto nothing_blocks + and ecx, 3 + cmp ecx, 2 + mov ecx, dword [c] + je .nothing_blocks + + ;; + ;; Not a knight or king. Check to see if there is a piece in + ;; the path from cSquare to c that blocks the attack. + ;; + ;; iDelta = g_VectorDeltaTable[iIndex].iNegDelta; +%ifdef OSX + movsx ebx, byte [_g_NasmVectorDelta+eax*4+515] +%else + movsx ebx, byte [_g_VectorDelta+eax*4+515] +%endif + + ;; cBlockIndex = cSquare + iDelta + mov eax, dword [cSquare] +.block_loop: + add eax, ebx + + ;; if (cBlockIndex != c) + ;; { + cmp eax, ecx + je .nothing_blocks + + ;; if (IS_EMPTY(pos->pSquare[cBlockIndex])) + ;; { + cmp dword [edx+eax*8], 0 + jne .loop_continue + + ;; goto cond + jmp .block_loop + +.nothing_blocks: + ;; pList->pPiece[pList->iCount] = p; + mov dword [edi], esi + + ;; pList->cLoc[pList->iCount] = c; + mov dword [edi+4], ecx + + ;; pList->iVal[pList->iCount] = PIECE_VALUE(p) + mov ecx, esi + shr ecx, 1 + shl ecx, 4 +%ifdef OSX + mov ebx, dword [_g_NasmPieceData+ecx] +%else + mov ebx, dword [_g_PieceData+ecx] +%endif + mov dword [edi+8], ebx + + ;; uCount++ + mov eax, dword [pOldList] + add edi, 12 + add dword [eax], 1 + jmp .loop_continue + +.done: add esp, 0xC + pop edi ; restore saved registers + pop esi + pop ebx + leave + ret +%endif ; CROUTINES +%endif ; X86 diff --git a/tests/LCT2.ep_ b/tests/LCT2.ep_ new file mode 100644 index 0000000..46d2806 --- /dev/null +++ b/tests/LCT2.ep_ @@ -0,0 +1,140 @@ +setboard r3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq - +id "POS-01" +solution d6 +go +setboard r3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq - +id "POS-02" +solution d6 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-03" +solution Qc5 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-04" +solution Qc5 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-05" +solution Qc5 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-06" +solution Qc5 +go +setboard r1b2r1k/pp2q1pp/2p2p2/2p1n2N/4P3/1PNP2QP/1PP2RP1/5RK1 w - - +id "POS-07" +solution Nd1 +go +setboard r2qrnk1/pp3ppb/3b1n1p/1Pp1p3/2P1P2N/P5P1/1B1NQPBP/R4RK1 w - - +id "POS-08" +solution Bh3 +go +setboard 5nk1/Q4bpp/5p2/8/P1n1PN2/q4P2/6PP/1R4K1 w - - +id "POS-09" +solution Qd4 +go +setboard 5nk1/Q4bpp/5p2/8/P1n1PN2/q4P2/6PP/1R4K1 w - - +id "POS-10" +solution Qd4 +go +setboard bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - +id "POS-11" +solution h4 +go +setboard bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - +id "POS-12" +solution h4 +go +setboard bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - +id "POS-13" +solution h4 +go +setboard r2qkb1r/1b3ppp/p3pn2/1p6/1n1P4/1BN2N2/PP2QPPP/R1BR2K1 w kq - +id "POS-14" +solution d5 +go +setboard 8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - +id "FIN-01" +solution f6 +go +setboard 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - +id "FIN-02" +solution f5 +go +setboard 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - +id "FIN-03" +solution f5 +go +setboard 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - +id "FIN-04" +solution f5 +go +setboard 6k1/6p1/7p/P1N5/1r3p2/7P/1b3PP1/3bR1K1 w - - +id "FIN-05" +solution a6 +go +setboard 6k1/6p1/7p/P1N5/1r3p2/7P/1b3PP1/3bR1K1 w - - +id "FIN-06" +solution a6 +go +setboard 6k1/4pp1p/3p2p1/P1pPb3/R7/1r2P1PP/3B1P2/6K1 w - - +id "FIN-07" +solution Bb4 +go +setboard 2k5/p7/Pp1p1b2/1P1P1p2/2P2P1p/3K3P/5B2/8 w - - +id "FIN-08" +solution c5 +go +setboard 8/5Bp1/4P3/6pP/1b1k1P2/5K2/8/8 w - - +id "FIN-09" +solution Kg4 +go +setboard 1r4k1/1q2bp2/3p2p1/2pP4/p1N4R/2P2QP1/1P3PK1/8 w - - +id "CMB-01" +solution Nd6 +go +setboard rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - +id "CMB-02" +solution Qh7 +go +setboard rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - +id "CMB-03" +solution Qh7 +go +setboard 2k2b1r/1pq3p1/2p1pp2/p1n1PnNp/2P2B2/2N4P/PP2QPP1/3R2K1 w - - +id "CMB-04" +solution ef6 +go +setboard 2r2r2/3qbpkp/p3n1p1/2ppP3/6Q1/1P1B3R/PBP3PP/5R1K w - - +id "CMB-05" +solution Rh7 +go +setboard 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - +id "CMB-06" +solution ef6 +go +setboard 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - +id "CMB-07" +solution ef6 +go +setboard 2b1r1k1/r4ppp/p7/2pNP3/4Q3/q6P/2P2PP1/3RR1K1 w - - +id "CMB-08" +solution Nf6 +go +setboard 2b1r1k1/r4ppp/p7/2pNP3/4Q3/q6P/2P2PP1/3RR1K1 w - - +id "CMB-09" +solution Nf6 +go +setboard rq2rbk1/6p1/p2p2Pp/1p1Rn3/4PB2/6Q1/PPP1B3/2K3R1 w - - +id "CMB-10" +solution Bh6 +go +setboard rnbq2k1/p1r2p1p/1p1p1Pp1/1BpPn1N1/P7/2P5/6PP/R1B1QRK1 w - - +id "CMB-11" +solution Nh7 +go +setboard r2qrb1k/1p1b2p1/p2ppn1p/8/3NP3/1BN5/PPP3QP/1K3RR1 w - - +id "CMB-12" +solution e5 +go diff --git a/tests/arasan.ep_ b/tests/arasan.ep_ new file mode 100644 index 0000000..24340ec --- /dev/null +++ b/tests/arasan.ep_ @@ -0,0 +1,564 @@ +setboard +id "arasan4.1" + +go +setboard 8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - +id "arasan4.2" +avoid Rxb6 +go +setboard 8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - +id "arasan4.3" +avoid Rxb6 +go +setboard 8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - +id "arasan4.4" +avoid Rxb6 +go +setboard 2r3k1/1b1nqppp/p3p3/8/1pQPn3/4PNP1/PP3PBP/RN4K1 w - - +id "arasan4.5" +solution Qf1 +go +setboard r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - +id "arasan4.6" +solution f6 +go +setboard r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - +id "arasan4.7" +solution f6 +go +setboard r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - +id "arasan4.8" +solution f6 +go +setboard 4k3/5ppQ/1n3b2/3bp3/1B6/1P1R2NP/5PPK/1qr5 w - - +id "arasan4.9" +solution Ba5 +go +setboard r3r1k1/pb1n1p2/1p1p1n1p/q1pPpN2/2P4p/2PBPP2/P1Q3PP/1R3RK1 w - - +id "arasan4.10" +solution Qf2 +go +setboard r3r1k1/pb1n1p2/1p1p1n1p/q1pPpN2/2P4p/2PBPP2/P1Q3PP/1R3RK1 w - - +id "arasan4.11" +solution Qf2 +go +setboard q2r2k1/1bpn1ppp/1p1bp3/8/r2PP3/P4NP1/1BQ2PBP/3RR1K1 w - - +id "arasan4.12" +solution e5 +go +setboard q2r2k1/1bpn1ppp/1p1bp3/8/r2PP3/P4NP1/1BQ2PBP/3RR1K1 w - - +id "arasan4.13" +solution e5 +go +setboard rnbq1rk1/p3nppp/1p2p3/2ppP3/3P4/P1PB1N2/2P2PPP/R1BQK2R w KQ - +id "arasan4.14" +solution Bxh7+ +go +setboard 4nr1k/r4p1p/2bq4/pp1pNP2/3P3Q/2P5/4PPB1/RR4K1 w - - +id "arasan4.15" +solution c4 +go +setboard 4nr1k/r4p1p/2bq4/pp1pNP2/3P3Q/2P5/4PPB1/RR4K1 w - - +id "arasan4.16" +solution c4 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.17" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.18" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.19" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.20" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.21" +solution Bh6 +go +setboard 2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - +id "arasan4.22" +solution Rxd7 +go +setboard 2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - +id "arasan4.23" +solution Rxd7 +go +setboard 2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - +id "arasan4.24" +solution Rxd7 +go +setboard 5q2/3Q1N1p/r4kp1/4p3/3nb3/1B5P/5PP1/1R4K1 w - - +id "arasan4.25" +solution f4 +go +setboard 5rk1/1p1P1ppp/pBn1p1r1/3p4/6P1/RPP4K/7P/4R3 w - - +id "arasan4.26" +solution Ra5 +go +setboard 5rk1/1p1P1ppp/pBn1p1r1/3p4/6P1/RPP4K/7P/4R3 w - - +id "arasan4.27" +solution Ra5 +go +setboard 3r2k1/2qn1ppp/8/1pbrp3/pP1N4/P2P2P1/RB2RP1P/4QK2 w - - +id "arasan4.28" +solution Nxb5 +go +setboard 3r2k1/2qn1ppp/8/1pbrp3/pP1N4/P2P2P1/RB2RP1P/4QK2 w - - +id "arasan4.29" +solution Nxb5 +go +setboard 2Q5/8/8/8/3kbP1N/2pq3P/6PK/8 w - - +id "arasan4.30" +solution f5 +go +setboard 2Q5/8/8/8/3kbP1N/2pq3P/6PK/8 w - - +id "arasan4.31" +solution f5 +go +setboard r1b2rk1/pp3pp1/4p2p/2ppP1b1/3Pq3/2P1PNP1/PP2Q2P/R3KB1R w KQ - +id "arasan4.32" +solution Nxg5 +go +setboard Qn3rk1/p5p1/1pnqp3/6p1/6P1/2P5/P4P1P/R1B2RK1 w - - +id "arasan4.33" +solution Qb7 +go +setboard Qn3rk1/p5p1/1pnqp3/6p1/6P1/2P5/P4P1P/R1B2RK1 w - - +id "arasan4.34" +solution Qb7 +go +setboard r1b2r2/pp3p1p/1q1p3k/2p1n2N/3N4/4P1P1/P1PP2BP/R4QK1 w - - +id "arasan4.35" +solution Qf6+ +go +setboard r1bq2k1/1p1n1r1p/3Qppp1/pP5N/2P1B3/8/P4P1P/2KR2R1 w - - +id "arasan4.36" +solution Bxg6 +go +setboard r1bq2k1/1p1n1r1p/3Qppp1/pP5N/2P1B3/8/P4P1P/2KR2R1 w - - +id "arasan4.37" +solution Bxg6 +go +setboard r4rk1/2qbbpp1/7p/2pPp3/ppN1P3/4Q1P1/PPPN4/2K3RR w - - +id "arasan4.38" +solution Rxh6 +go +setboard r2q1r1k/1p2bppp/pnb1p3/4P3/6R1/2N5/PPB1QPPP/R1B3K1 w - - +id "arasan4.39" +solution Rxg7 +go +setboard 1r3k2/4q3/2Pp3b/3Bp3/2Q2p2/1p1P2P1/1P2KP2/3N4 w - - +id "arasan4.40" +solution Be6 +go +setboard r4rk1/pp1nqppp/2b1p3/6N1/4N3/6Q1/PPP2PPP/1K1RR3 w - - +id "arasan4.41" +solution Rxd7 +go +setboard r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - +id "arasan4.42" +solution Qg3 +go +setboard r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - +id "arasan4.43" +solution Qg3 +go +setboard r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - +id "arasan4.44" +solution Qg3 +go +setboard r1bk2nr/ppp2ppp/2np1b2/1N6/N4P1q/P3B3/1PP1B1PP/R2QR1K1 w - - +id "arasan4.45" +solution Nxd6 +go +setboard r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - +id "arasan4.46" +solution Rxe6 +go +setboard r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - +id "arasan4.47" +solution Rxe6 +go +setboard r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - +id "arasan4.48" +solution Rxe6 +go +setboard 2r1k1nr/p1Pq4/1p3p2/4pn1p/1B1p4/1N3Q2/PP2P1RP/2R4K w - - +id "arasan4.49" +solution Nd2 +go +setboard r2qr1k1/pp1b2pp/2nBpp1n/6NQ/2B1N3/P3b3/1PP3PP/R4R1K w - - +id "arasan4.50" +solution Nxf6+ +go +setboard 1n3rn1/3b4/rq1P1pkp/1p4p1/p1p1N1N1/2Q2B1P/1P3PP1/R3R1K1 w - - +id "arasan4.51" +solution Nexf6 Ngxf6 +go +setboard r1bq1rk1/ppp1bpp1/2np3p/3N3n/2P1PB2/3BQN2/PP3PPP/R3K2R w KQ - +id "arasan4.52" +solution Bxh6 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.53" +solution Qd4 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.54" +solution Qd4 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.55" +solution Qd4 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.56" +solution Qd4 +go +setboard r2r2k1/pbpq1ppp/1pn1pn2/8/P2PP3/B1R2NP1/P1Q2PBP/3R2K1 w - - +id "arasan4.57" +solution d5 +go +setboard r2r2k1/pbpq1ppp/1pn1pn2/8/P2PP3/B1R2NP1/P1Q2PBP/3R2K1 w - - +id "arasan4.58" +solution d5 +go +setboard 1b6/4kPp1/Pp6/2p2K1B/2P5/3p4/8/8 w - - +id "arasan4.59" +solution Ke4 +go +setboard 4r1k1/pppb3p/1n4p1/3P4/1bP2p2/qN3PPP/P1Q3B1/2R3KR w - - +id "arasan4.60" +solution g4 +go +setboard 2r3k1/2r1b1p1/p1q3Pp/3pP3/1p6/1P2B2Q/2PR4/1K4R1 w - - +id "arasan4.61" +solution Bxh6 +go +setboard 4R3/1k4p1/8/pp4P1/8/3K4/1b5P/8 w - - +id "arasan4.62" +solution Re2 +go +setboard r3k2r/pb3ppp/1p2pn2/1Nb1q3/4P3/P2B4/1PQ2PPP/R1B2RK1 w kq - +id "arasan4.63" +solution b4 +go +setboard 2r1r1k1/1pn3qp/2pbn1p1/p2pN3/3P1P2/3BP1BP/PPQ3K1/2R2R2 w - - +id "arasan4.64" +solution f5 +go +setboard 5Nk1/1p2n3/p2q1rp1/3p1pQP/5P2/2P2B2/b1PK2P1/4R3 w - - +id "arasan4.65" +solution Nd7 +go +setboard 5Nk1/1p2n3/p2q1rp1/3p1pQP/5P2/2P2B2/b1PK2P1/4R3 w - - +id "arasan4.66" +solution Nd7 +go +setboard 8/1B1r1b1k/3N2pp/p3Qp2/3P1P2/7P/1P1b1K2/2r5 w - - +id "arasan4.67" +solution Nxf5 +go +setboard 8/1B1r1b1k/3N2pp/p3Qp2/3P1P2/7P/1P1b1K2/2r5 w - - +id "arasan4.68" +solution Nxf5 +go +setboard 2kb4/r7/4p1r1/1RNn2p1/8/6P1/pB3PK1/7R w - - +id "arasan4.69" +solution Be5 +go +setboard 2kb4/r7/4p1r1/1RNn2p1/8/6P1/pB3PK1/7R w - - +id "arasan4.70" +solution Be5 +go +setboard 4rrk1/1bpn1qp1/1p1b3p/pP1Ppn2/4N3/P2Q1N1P/1BB2PP1/2R1R1K1 w - - +id "arasan4.71" +solution g4 +go +setboard 4rrk1/1bpn1qp1/1p1b3p/pP1Ppn2/4N3/P2Q1N1P/1BB2PP1/2R1R1K1 w - - +id "arasan4.72" +solution g4 +go +setboard 1r5k/pp5p/3Nn1p1/3R4/3b4/BP3rPP/P4P2/1R4K1 w - - +id "arasan4.73" +solution Rxd4 +go +setboard rn1r2k1/p4p2/1pp1pqp1/6Rp/3PB2P/8/PPPQ1P2/2KR4 w - - +id "arasan4.74" +solution Bxg6 +go +setboard r4rk1/1pp3q1/2np3p/p2Npb1B/2PbN1p1/3P2P1/PP4PP/R2Q1R1K w - - +id "arasan4.75" +solution Ndf6+ Nef6+ +go +setboard r5k1/p6r/1n2p2p/2BbPpp1/8/P2B4/5PPP/2RR2K1 w - - +id "arasan4.76" +solution Bxf5 +go +setboard 5rk1/q4ppp/pp1bp1n1/6N1/4QP2/P3P3/1P1B2PP/2R3K1 w - - +id "arasan4.77" +solution Nxe6 +go +setboard r3kb1r/2R2bpp/p2p1p2/1p2pPP1/3qP3/5Q2/1PPB3P/2K2B1R w kq - +id "arasan4.78" +solution Bc4 +go +setboard r3kb1r/2R2bpp/p2p1p2/1p2pPP1/3qP3/5Q2/1PPB3P/2K2B1R w kq - +id "arasan4.79" +solution Bc4 +go +setboard 6k1/3p2p1/1p1Npq2/3n3r/1P6/5PQ1/P4KP1/RNBR3r w - - +id "arasan4.80" +solution Ne4 +go +setboard 6k1/3p2p1/1p1Npq2/3n3r/1P6/5PQ1/P4KP1/RNBR3r w - - +id "arasan4.81" +solution Ne4 +go +setboard 2k4r/1q1bBQ2/2p1p3/1p2P2p/6r1/8/5PP1/R1R3K1 w - - +id "arasan4.82" +solution Bf8 +go +setboard 2r2k1r/p1q3pp/1p3p2/3Bp3/2Pb2b1/P1Q5/1B1R1PPP/4R1K1 w - - +id "arasan4.83" +solution Rxd4 +go +setboard 2r2k1r/p1q3pp/1p3p2/3Bp3/2Pb2b1/P1Q5/1B1R1PPP/4R1K1 w - - +id "arasan4.84" +solution Rxd4 +go +setboard 3q1k2/8/1p1b1r1p/p2R2p1/P1BQ2P1/1P3P2/8/3K4 w - - +id "arasan4.85" +solution f4 +go +setboard 2r2rk1/5qp1/1pN2p1p/pPnRp3/P1P5/5PP1/2Q1R1KP/8 w - - +id "arasan4.86" +solution Rxc5 +go +setboard 3r1r2/pb3pkp/1pn1qNp1/2p1P3/5P2/P2BQ3/1P4PP/3R1R1K w - - +id "arasan4.87" +solution f5 +go +setboard r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - +id "arasan4.88" +solution N3h4 +go +setboard r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - +id "arasan4.89" +solution N3h4 +go +setboard r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - +id "4.90" +solution N3h4 +go +setboard r3rk2/ppq2pbQ/2p1b1p1/4p1B1/2P3P1/3P1B2/P3PPK1/1R5R w - - +id "4.91" +solution Qxg7+ Qh8+ +go +setboard r1b2rk1/1pqp1p1p/p3nBpQ/4p3/4P3/1N4P1/PbP2PBP/R4RK1 w - - +id "4.92" +solution Nd2 +go +setboard 4r1k1/2P3pp/1n2q3/2pn1p2/8/6B1/1P1QBP1P/4R1K1 w - - +id "arasan4.93" +solution Rd1 +go +setboard r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - +id "arasan4.94" +solution Nxg5 +go +setboard r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - +id "arasan4.95" +solution Nxg5 +go +setboard r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - +id "arasan4.96" +solution Nxg5 +go +setboard 5rk1/3R1p2/ppp3r1/b1p1P2p/2P2B1q/2P2Q2/P5PP/3R3K w - - +id "arasan4.97" +solution h3 +go +setboard 2r1r1k1/5p1p/p3qBp1/1ppbP3/2n5/2PB3P/P3QPP1/3RR1K1 w - - +id "arasan4.98" +solution Bxc4 +go +setboard r1br3k/pp2qn1p/4p2P/4Ppp1/2B5/P4NQ1/1P3PP1/3R1RK1 w - - +id "arasan4.99" +solution Nxg5 +go +setboard 2r2rk1/3bq1p1/4p1Pp/3pP3/1p1N1PQ1/pP5R/P1P4R/4K3 w - - +id "arasan4.100" +solution Rxh6 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.101" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.102" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.103" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.104" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.105" +solution Qf2 +go +setboard 4r1k1/p5qp/Pp1Rbb2/4pp1r/2P1p1p1/1PB1P3/1Q2BPPP/3R2K1 w - - +id "arasan4.106" +solution c5 +go +setboard 8/4k1p1/8/5P1p/b1N4P/5PP1/1p1K4/1B1n4 w - - +id "arasan4.107" +solution g4 +go +setboard 3q1r1k/1P1n2p1/4R2p/2QBp2P/3pPb2/R1p2P2/5P2/5K2 w - - +id "arasan4.108" +solution Qxf8+ +go +setboard 3q1r1k/1P1n2p1/4R2p/2QBp2P/3pPb2/R1p2P2/5P2/5K2 w - - +id "arasan4.109" +solution Qxf8+ +go +setboard 2rbk1r1/7R/p1n3p1/1p3q2/2n2N2/4pQ2/PP2B1PP/3R2K1 w - - +id "arasan4.110" +solution g4 +go +setboard 8/8/3k4/1p1npP1p/pP2B2P/P7/5K2/8 w - - +id "arasan4.111" +solution Bxd5 +go +setboard 5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - +id "arasan4.112" +solution f5 +go +setboard 5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - +id "arasan4.113" +solution f5 +go +setboard 5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - +id "arasan4.114" +solution f5 +go +setboard 2kr3r/Rbpnq3/1p1pp3/2P3p1/3P4/2P1P1p1/Q2N1PP1/4KB2 w - - +id "arasan4.115" +solution Rxb7 +go +setboard 2R2b1r/3nkp2/B2pp1p1/1N4Pn/P3P3/4BP2/1r5q/3QK1R1 w - - +id "arasan4.116" +solution Nd4 Na7 +go +setboard r3r1k1/1p1b2pp/p2qpp2/3n4/Pn1P4/1BN2Q2/1P1B1PPP/R2R2K1 w - - +id "arasan5.1" +solution Ne4 +go +setboard r3r1k1/1p1b2pp/p2qpp2/3n4/Pn1P4/1BN2Q2/1P1B1PPP/R2R2K1 w - - +id "arasan5.2" +solution Ne4 +go +setboard 8/6p1/1b4k1/1p1KP3/1p3PP1/pB6/8/8 w - - +id "arasan5.3" +solution e6 +go +setboard r4rk1/1bq2p2/p3p1p1/n3P2p/3NpP2/2P1B2R/2P3PP/R3Q1K1 w - - +id "arasan5.4" +solution g4 +go +setboard 2rq1rk1/pb1n1p2/1p2pn1p/6p1/2BP3B/1QR2N2/PP3PPP/4R1K1 w - - +id "arasan5.5" +solution Nxg5 +go +setboard 2r1qrk1/1b1nbppp/4p3/pB1nP1B1/Pp2N3/5N1P/1P1Q1PP1/R2R2K1 w - - +id "arasan5.6" +solution Nf6+ +go +setboard 1q4k1/r4p1p/6p1/1p1Q3n/p3N3/P7/1P3PPP/4R1K1 w - - +id "arasan5.7" +solution g4 +go +setboard 3rr1k1/1pq2p1p/p1n3p1/3Bb3/P7/2P1BQ2/1P3PKP/3RR3 w - - +id "arasan5.8" +solution Bb6 +go +setboard 3rr1k1/1pq2p1p/p1n3p1/3Bb3/P7/2P1BQ2/1P3PKP/3RR3 w - - +id "arasan5.9" +solution Bb6 +go +setboard r2qr1k1/pb4b1/1pnP2pp/5p2/5PB1/B4NQ1/P5PP/2R1R1K1 w - - +id "arasan5.10" +solution Bxf5 +go +setboard r1b2rk1/p1q4p/1p4p1/2NP1p2/1PPB4/6P1/P6P/Q3R1K1 w - - +id "arasan5.11" +solution Qc1 +go +setboard 8/3k4/1p4b1/3p1p1p/K2P1PpP/3B2P1/1P6/8 w - - +id "arasan5.12" +solution Kb5 +go +setboard r1bn1rk1/2q2ppN/7p/p2p4/R7/2PB4/3B1PPb/3QRK2 w - - +id "arasan5.13" +solution Nf6+ +go +setboard 4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - +id "arasan5.14" +solution g5 +go +setboard 4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - +id "arasan5.15" +solution g5 +go +setboard 4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - +id "arasan5.16" +solution g5 +go +setboard r1bq1rk1/4ppbp/p2p1n1B/2p5/1p2p2Q/3P1N2/PPP1N1PP/R4RK1 w - - +id "arasan5.17" +solution Ng5 +go +setboard 4rrk1/p2n2pp/npbp4/2p1p3/2P2P1q/PNB1P3/1P2B1PP/1R1Q1RK1 w - - +id "arasan5.18" +avoid Qxd6 +go +setboard 4rrk1/p2n2pp/npbp4/2p1p3/2P2P1q/PNB1P3/1P2B1PP/1R1Q1RK1 w - - +id "arasan5.19" +avoid Qxd6 +go +setboard 8/B3r1p1/8/P4k1p/1P6/5P2/5K2/8 w - - +id "arasan5.21" +solution Bc5 +go +setboard b2rn1k1/3r1ppp/3N2n1/1pB1P3/p5P1/P3KP2/B6P/1RR5 w - - +id "arasan5.24" +solution e6 +go +setboard 8/4rq2/2Q1N1pk/p3R2p/3p1P2/2n4P/6P1/7K w - - +id "arasan5.25" +solution g4 +go +setboard 4kb1r/3n1p1p/p1q1p1p1/1p1nP3/1prPN3/4BB2/P2Q1PPP/3R1RK1 w - - +id "arasan5.26" +solution Bh6 +go +setboard 3q2k1/rbp2r1p/1p1p1pp1/p1nN4/2P1PP2/1P2QBPP/1P5K/3RR3 w - - +id "arasan5.27" +solution e5 +go +setboard 3q2k1/rbp2r1p/1p1p1pp1/p1nN4/2P1PP2/1P2QBPP/1P5K/3RR3 w - - +id "arasan5.28" +solution e5 +go diff --git a/tests/bench.ep_ b/tests/bench.ep_ new file mode 100644 index 0000000..9f501a1 --- /dev/null +++ b/tests/bench.ep_ @@ -0,0 +1,14 @@ +sd 9 +setboard 3r1k2/4npp1/1ppr3p/p6P/P2PPPP1/1NR5/5K2/2R5 w - - 0 0 +go +setboard rnbqkb1r/p3pppp/1p6/2ppP3/3N4/2P5/PPP1QPPP/R1B1KB1R w KQkq - 0 0 +go +setboard 4b3/p3kp2/6p1/3pP2p/2pP1P2/4K1P1/P3N2P/8 w - - 0 0 +go +setboard r3r1k1/ppqb1ppp/8/4p1NQ/8/2P5/PP3PPP/R3R1K1 b - - 0 0 +go +setboard 2r2rk1/1bqnbpp1/1p1ppn1p/pP6/N1P1P3/P2B1N1P/1B2QPP1/R2R2K1 b - - 0 0 +go +setboard r1bqk2r/pp2bppp/2p5/3pP3/P2Q1P2/2N1B3/1PP3PP/R4RK1 b kq - 0 0 +go +quit diff --git a/tests/convert_epd.pl b/tests/convert_epd.pl new file mode 100755 index 0000000..cdd774c --- /dev/null +++ b/tests/convert_epd.pl @@ -0,0 +1,21 @@ +#!/usr/bin/perl + +# Yes, I never wrote real code to parse EPD files. This script converts +# "normal" style EPDs into what typhoon wants to eat. + +while(<>) { + @lines = split(/;/); + for $line(@lines) { + $id = $1 if ($line =~ /^\s*(id.*)$/); + if ($line =~ /^([pnbrqk\-\d\/]+\s[^b]+)bm\s([^;]+)/i) { + $fen = $1; + $solution = "solution $2"; + } elsif ($line =~ /^([pnbrqk\-\d\/]+\s[^b]+)am\s([^;]+)/i) { + $fen = $1; + $solution = "avoid $2"; + } + } + if ($#lines > 0) { + print "setboard $fen\n$id\n$solution\ngo\n"; + } +} diff --git a/tests/dann.epd b/tests/dann.epd new file mode 100644 index 0000000..6ec87a4 --- /dev/null +++ b/tests/dann.epd @@ -0,0 +1,472 @@ +1rbq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NPP/PP2PPB1/R1BQ1RK1 w - - pm Be3 {22} Bf4 {1} Bg5 {13} a4 {1} d5 {1} e4 {100}; +r1b1kb1r/1p1n1ppp/pq1ppn2/6B1/4PP2/1NN5/PPP3PP/R2QKB1R w KQkq - pm Bd3 {1} Be2 {12} Qd2 {2} Qd3 {3} Qe2 {3} Qf3 {100}; +r1bq1rk1/pp2ppbp/2n3p1/2pP4/4P3/2P2N2/P3BPPP/1RBQK2R b K - pm Bxc3+ {18} Ne5 {100}; +r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R b KQ - pm Bd7 {1} Rb8 {6} Re8 {1} a5 {1} a6 {100}; +r1bq1rk1/ppp2pbp/n2p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - - pm Be3 {100} Bg5 {9} Rb1 {1} Re1 {92} d5 {1}; +r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PNB1/PP1N1PPP/R2QKB1R b KQkq - pm Bxg3 {13} O-O {100} Qe7 {22} b6 {3} c4 {11} cxd4 {3}; +r1bqkb1r/pp1ppppp/2n5/2pnP3/2B5/2P2N2/PP1P1PPP/RNBQK2R b KQkq - pm Nb6 {100} e6 {6}; +r1bqkb1r/pp3pp1/2np1n1p/4p3/4P3/2N2N2/PPP1BPPP/R1BQ1RK1 b kq - pm Be6 {4} Be7 {100}; +r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq - pm Bg5 {3} Nc3 {5} a3 {1} b3 {19} c3 {9} c4 {100} e3 {12}; +r1bqkb1r/pppn1ppp/4pn2/8/Q1pP4/5NP1/PP2PP1P/RNB1KB1R w KQkq - pm Bg2 {100} Nc3 {1} Qxc4 {6}; +r2q1rk1/pb1n1ppp/1ppbpn2/3p4/2PP4/1PN1PN2/P1Q1BPPP/R1B2RK1 w - - pm Bb2 {100} Bd2 {3} Rd1 {6} a4 {13} e4 {5} h3 {4}; +r2qk2r/p2nbppp/bpp1pn2/3p4/2PPP3/1PB2NP1/P2N1PBP/R2QK2R b KQkq - pm Ng4 {2} Nxe4 {7} O-O {100} Qc7 {3} Rb8 {1} Rc8 {10} b5 {10} c5 {1} dxe4 {5}; +r2qkb1r/1b1n1ppp/p3pn2/1pp5/3P4/1BN1PN2/PP2QPPP/R1BR2K1 b kq - pm Bd6 {11} Qb6 {46} Qb8 {100} Qc7 {23} b4 {1}; +r2qkb1r/2p2ppp/p1n1b3/1pnpP3/8/1B3N2/PPPN1PPP/R1BQ1RK1 w kq - pm c3 {100}; +r2qkbnr/pppb1ppp/2np4/1B2p3/3PP3/5N2/PPP2PPP/RNBQK2R w KQkq - pm Bxc6 {4} Nc3 {100} O-O {6} c3 {2} d5 {3} dxe5 {1}; +r2qrbk1/1bp2ppp/p1np1n2/1p2p3/P2PP3/1BP2N1P/1P1N1PP1/R1BQR1K1 b - - pm Na5 {21} Nb8 {1} Qd7 {10} bxa4 {1} exd4 {18} h6 {100}; +rn1q1rk1/1pp1bppp/p3pn2/3b2B1/P1QP4/5NP1/1P2PPBP/RN3RK1 w - - pm Qc2 {38} Qd3 {100}; +rn1q1rk1/pbp1bpp1/1p2pn1p/8/2BP3B/2N1PN2/PP3PPP/R2QK2R w KQ - pm O-O {100} Qe2 {11} Rc1 {11}; +rn1qkbnr/pp3ppp/2p1p3/3pPb2/3P4/4B3/PPP2PPP/RN1QKBNR w KQkq - pm Nd2 {100} c3 {2}; +rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R w KQkq - pm Bb5+ {3} Bc4 {1} Bd3 {20} Be2 {100} Bf4 {3} Bg5 {26} Nd2 {28} h3 {67}; +rnbqk2r/pppp1ppp/4pn2/8/1bPP4/P1N5/1P2PPPP/R1BQKBNR b KQkq - pm Bxc3+ {100}; +rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1b5/1P2PPPP/R1BQKBNR w KQkq - pm bxc3 {100}; +rnbqkb1r/1p3ppp/p3pn2/2pP4/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq - pm exd5 {100}; +rnbqkb1r/1p3ppp/p3pn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq - pm Bd3 {4} a3 {27} cxd5 {100} dxc5 {13}; +rnbqkb1r/pp1ppp1p/5np1/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq - pm Nc3 {100} Nf3 {23} f3 {1} g3 {9}; +rnbqkbnr/pppp1ppp/8/4p3/8/1P6/PBPPPPPP/RN1QKBNR b KQkq - pm Nc6 {100} d6 {50}; +r1b2rk1/pp1n1pbp/1qpp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQR1K1 b - - pm Re8 {4} a5 {1} exd4 {101}; +r1bq1rk1/pp4pp/2n1pn2/3p4/3P1b2/3B1N2/PP2NPPP/R2Q1RK1 w - - pm Nxf4 {101}; +r1bq1rk1/pp4pp/2nbpn2/3p4/3P1B2/3B1N2/PP2NPPP/R2Q1RK1 b - - pm Bxf4 {101} Kh8 {14} Nb4 {3} Ng4 {6} Nh5 {2} Nxd4 {1} Qc7 {2} Rb8 {1} g6 {3}; +r1bqk1nr/pp2ppbp/2p3p1/2p5/4P3/3P1N1P/PPP2PP1/RNBQK2R b KQkq - pm Nf6 {101} Nh6 {2} b6 {23} e5 {23}; +r1bqk2r/1p2bppp/p1n1pn2/2p5/P1BP4/2N1PN2/1P3PPP/R1BQ1RK1 w kq - pm Ne5 {16} Qc2 {1} Qd3 {1} Qe2 {101} b3 {1} dxc5 {77}; +r1bqk2r/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq - pm Ne4 {1} O-O {101} c6 {10} h6 {11}; +r1bqkb1r/1p3ppp/p1nppn2/2p5/4P3/2N2NP1/PPPP1PBP/R1BQ1RK1 w kq - pm Re1 {1} d3 {6} d4 {101}; +r1bqkb1r/3n2pp/p3pn2/1p6/2p1P3/2NB1N2/PP3PPP/R1BQK2R w KQkq - pm Bb1 {3} Bc2 {101} Be2 {10}; +r1bqkb1r/pp1n1ppp/2pp1n2/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq - pm Be7 {101} Qc7 {5} a6 {3} g6 {28}; +r1bqkb1r/pp1p1ppp/2n1pn2/2p5/2P5/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq - pm Be2 {7} a3 {18} d4 {101}; +r1bqkbnr/pp1npppp/2p5/8/3PN3/5N2/PPP2PPP/R1BQKB1R b KQkq - pm Ndf6 {6} Ngf6 {101}; +r2qkb1r/1b1n1ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNBR2K1 w kq - pm Nc3 {101} a4 {3} e4 {3}; +r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPPN1PPP/R1BQ1RK1 b kq - pm Bc5 {7} Be7 {36} Nc5 {101}; +r2qkb1r/pppb1ppp/2np1n2/1B6/3NP3/2N5/PPP2PPP/R1BQ1RK1 b kq - pm Be7 {101} Nxd4 {9}; +r3kb1r/ppq2ppp/2p2n2/4nb2/P1N5/2N3P1/1P2PP1P/R1BQKB1R w KQkq - pm Bf4 {101}; +r3kb1r/ppqn1ppp/2p2n2/4Pb2/P1N5/2N3P1/1P2PP1P/R1BQKB1R b KQkq - pm Nxe5 {101}; +r3kb1r/ppqn1ppp/2p2n2/4pb2/P1NP4/2N3P1/1P2PP1P/R1BQKB1R w KQkq - pm Bg2 {8} Bg5 {2} dxe5 {101} e4 {1}; +rn1qk2r/pp1bnppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R w KQkq - pm Bd3 {2} Be2 {7} Rb1 {4} a4 {101} dxc5 {13} h4 {2}; +rn1qk2r/pp1bnppp/4p3/2ppP3/P2P4/2P2N2/2P2PPP/R1BQKB1R b KQkq - pm Nbc6 {3} Qa5 {101} c4 {1}; +rnb1k2r/pp2ppbp/6p1/q1p5/3PP3/2P1BN2/P4PPP/R2QKB1R w KQkq - pm Bd2 {17} Nd2 {1} Qb3 {1} Qd2 {101}; +rnbq1rk1/pp2ppbp/5np1/3p4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQ - pm Bg5 {3} Ne5 {101} O-O {40} Qb3 {1}; +rnbqk2r/ppp1p1bp/3p1np1/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b kq - pm O-O {101} c6 {6}; +rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq - pm Bg5 {101} Nf3 {3} a3 {1}; +rnbqkb1r/pp1p1ppp/4pn2/8/2Pp4/2N2N2/PP2PPPP/R1BQKB1R w KQkq - pm Nxd4 {101}; +rnbqkb1r/pp2pppp/3p1n2/8/3NP3/5P2/PPP3PP/RNBQKB1R b KQkq - pm Nc6 {101} Qb6 {4} a6 {10} e5 {58} e6 {34} g6 {6}; +rnbqkb1r/pp2pppp/5n2/3p4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq - pm Bf4 {98} Bg5 {3} Nf3 {101} Qb3 {4}; +rnbqkbnr/pp3ppp/4p3/2p5/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq - pm Bxc4 {101}; +rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq - pm Nf3 {72} d3 {12} d4 {62} e3 {18} e4 {17} g3 {101}; +r1b1k2r/1pq1bppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R3QRK1 b kq - pm Bd7 {6} Nxd4 {2} O-O {102}; +r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq - pm Bd3 {32} Be2 {5} Kb1 {2} Qg3 {5} Re1 {1} f5 {7} g4 {102} h4 {1}; +r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPPP1/2N2Q2/PPP4P/2KR1B1R b kq - pm b5 {102}; +r1bq1rk1/pp2ppbp/2n3p1/2p5/2BPP3/2P5/P3NPPP/R1BQ1RK1 w - - pm Be3 {102} dxc5 {5}; +r1bqkb1r/1p3ppp/p1nppn2/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq - pm Bd7 {15} Be7 {102} Qc7 {17}; +r1bqkbnr/pp3ppp/2np4/2p1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq - pm Nd5 {1} O-O {1} b3 {1} d3 {102} h3 {2}; +r2q1rk1/1bpnbp1p/p3pp2/1p6/3PN3/5NP1/PPP1QPBP/R4RK1 w - - pm Nc3 {2} Ne1 {2} Ned2 {3} Qe3 {6} Rad1 {59} Rfd1 {102} Rfe1 {23} a4 {32} c3 {1}; +r2q1rk1/1p1nbppp/p2pbn2/4p3/P3P3/1NN1B3/1PPQBPPP/R4RK1 b - - pm Nb6 {6} Nc5 {1} Qc7 {4} Rc8 {102} b6 {1}; +r2qkb1r/1p1b1pp1/p1nppn1p/8/3NP3/2N1B3/PPPQ1PPP/2KR1B1R w kq - pm f3 {102} f4 {86}; +r2qkb1r/pp1n1pp1/2p1pn1p/7P/3P1B2/3Q1NN1/PPP2PP1/2KR3R b kq - pm Be7 {102} Nd5 {21} Qa5 {9}; +r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQ1RK1 b kq - pm Bg7 {102}; +r2qr1k1/1bp1bppp/p1np1n2/1p2p1N1/3PP3/1BP4P/PP3PP1/RNBQR1K1 b - - pm Rf8 {102}; +rn1q1rk1/pbp1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP2BPPP/R2Q1RK1 b - - pm Nbd7 {102} Nc6 {6} Ne4 {8} c5 {7} dxc4 {33}; +rn1qkbnr/pp2pppp/2p5/3pPb2/3P4/4B3/PPP2PPP/RN1QKBNR b KQkq - pm Qb6 {7} e6 {102}; +rnbq1rk1/pppp1ppp/5n2/4p3/1bP1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQ - pm Bxc3 {102} Nc6 {3} c6 {3} d6 {2}; +rnbqk2r/pp1pppbp/5np1/2p5/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq - pm Bg2 {102} Nc3 {63} d5 {36} dxc5 {2}; +rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1b5/1PPB1PPP/R2QKBNR w KQkq - pm Bxc3 {102} bxc3 {1}; +rnbqk2r/pp2ppbp/2p2np1/3P4/3P4/5NP1/PP2PPBP/RNBQK2R b KQkq - pm Nxd5 {2} cxd5 {102}; +rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq - pm O-O {102} a6 {1}; +rnbqk2r/ppp2ppp/4pn2/3p4/2PP4/P1P2P2/4P1PP/R1BQKBNR b KQkq - pm O-O {6} c5 {102} c6 {11} dxc4 {1}; +rnbqkbnr/1p3ppp/p7/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq - pm Be2 {102} Qe2+ {2} b3 {1} c3 {1} c4 {1} dxc5 {65}; +rnbqkbnr/pp1ppp1p/6p1/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq - pm Bg7 {102} Nc6 {12} Nf6 {11}; +1rb1r1k1/1pq1bppp/p1nppn2/8/P2NPP2/2N1BB2/1PP3PP/R2Q1R1K w - - pm Be2 {1} Bf2 {3} Kg1 {1} Nb3 {61} Nde2 {4} Nxc6 {6} Qd2 {103} Qd3 {29} Qe1 {23} Rb1 {2} g4 {33} h3 {2}; +1rbq1rk1/1p2ppbp/p2p1np1/n1pP4/2P5/1PN3P1/P1QNPPBP/R1B2RK1 b - - pm Bf5 {1} b5 {103} e5 {1}; +r1b1r1k1/p2nqppp/1ppbpn2/3p4/2PP4/1PN1PN2/P1Q1BPPP/R1BR2K1 w - - pm Bb2 {9} a4 {16} cxd5 {1} e4 {103} h3 {3}; +r1b1r1k1/pp1nqppp/2pbpn2/3p4/2PP4/2N1PN2/PPQ1BPPP/R1BR2K1 w - - pm Bd2 {2} a3 {5} a4 {7} b3 {103} e4 {2} h3 {93}; +r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQK2R w K - pm Bd3 {3} Ne2 {3} Ne4 {40} O-O {103} Qb3 {1} Qc2 {16}; +r1b2rk1/pp1nqppp/2pbpn2/8/2BP4/2N1PN1P/PPQ2PP1/R1B2RK1 b - - pm a6 {3} c5 {8} e5 {103}; +r1bn1rk1/ppp1qppp/3p1n2/1B2p1B1/3PP3/2P2N2/P1P2PPP/R2QR1K1 b - - pm Bg4 {7} Ne6 {103}; +r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - - pm Na5 {103} Nb4 {1}; +r1bq1rk1/pp3ppp/2n1p3/3n4/1b1P4/2NB1N2/PP1B1PPP/R2QK2R w KQ - pm O-O {103} Qc2 {1}; +r1bq1rk1/ppp1n1bp/3p1np1/3Ppp2/2P1P3/2NN1P2/PP1BB1PP/R2Q1RK1 b - - pm Kh8 {12} c5 {3} f4 {103}; +r1bqk2r/1p2bppp/p1nppn2/8/2P1P3/N1N5/PP2BPPP/R1BQK2R b KQkq - pm Nd7 {5} O-O {103} Qa5 {2} Qb6 {3} Qc7 {1} b6 {18}; +r1bqk2r/4bpp1/p2ppn1p/1p6/3BP3/2N2P2/PPPQ2PP/2KR1B1R w kq - pm Bd3 {1} Kb1 {103} Qe3 {2} Qf2 {2} g4 {1} h4 {5}; +r1bqk2r/pp1nbppp/2p2n2/3p2B1/3P4/2N1PN2/PP3PPP/R2QKB1R w KQkq - pm Bd3 {74} Qc2 {103}; +r1bqk2r/pp2bppp/2npp3/3nP3/2BP4/5N2/PP2QPPP/RNB2RK1 b kq - pm Nb6 {2} O-O {103} dxe5 {1}; +r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P1P2/2P5/PP1N2PP/R1BQKBNR w KQkq - pm Ndf3 {103} Ngf3 {2}; +r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq - pm Bg5 {32} dxe5 {1} e3 {7} e4 {103} g3 {26}; +r2qkb1r/pppb1ppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 b kq - pm Be7 {103} exd4 {50}; +r3kbnr/pp1n1pp1/2p1p2p/q6P/3P4/3Q1NN1/PPPB1PP1/R3K2R b KQkq - pm Bb4 {17} Qb6 {3} Qc7 {103}; +r4rk1/pbqn1ppp/2pb1n2/1p2p3/3PP3/2N2NP1/PPQ1BP1P/R1BR2K1 b - - pm Rad8 {1} Rae8 {21} Rfe8 {103} b4 {5} h6 {2}; +rn1q1rk1/pb3pp1/1pp2b1p/3p4/1P1P4/2N1PN2/P3BPPP/R2Q1RK1 b - - pm Qd6 {15} Qe7 {1} Re8 {51} a5 {103}; +rnb1k2r/2q1bppp/p2ppn2/1p6/3NP3/1BN2Q2/PPP2PPP/R1B2RK1 w kq - pm Be3 {1} Qg3 {103} Re1 {8} a3 {2}; +rnb1k2r/pp3ppp/4p3/q1Pn4/8/P1P2P2/4P1PP/R1BQKBNR w KQkq - pm Qb3 {1} e4 {103}; +rnbq1rk1/pp2ppbp/2pp1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQ1RK1 w - - pm Be3 {1} Bf4 {8} Bg5 {2} Re1 {34} a4 {103} h3 {36}; +rnbqk2r/pp2nppp/4p3/2ppP3/1b1P4/2N5/PPPB1PPP/R2QKBNR w KQkq - pm Nb5 {11} Nf3 {4} a3 {103} dxc5 {15} f4 {7}; +rnbqk2r/pp2nppp/4p3/2ppP3/1b1P4/P1N5/1PPB1PPP/R2QKBNR b KQkq - pm Bxc3 {103}; +rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq - pm Bc4 {77} Nf3 {103} a3 {3} b3 {2} d4 {6} f4 {38} g3 {62} h3 {1}; +rnbqkb1r/pppppppp/5n2/8/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq - pm Nc6 {23} c5 {101} c6 {56} d5 {24} d6 {24} e5 {103} e6 {49} g6 {61}; +rnbqkbnr/pp2pppp/2p5/3p4/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq - pm Nc3 {103} e5 {26} exd5 {25}; +rnbqkbnr/pp3ppp/2p1p3/8/2PPN3/8/PP3PPP/R1BQKBNR b KQkq - pm Bb4+ {103} Nf6 {4} e5 {2}; +r1b1kb1r/pp1n1ppp/2p1p3/q2n2B1/3P4/2N1PN2/PP3PPP/R2QKB1R w KQkq - pm Qb3 {3} Qd2 {104} e4 {1}; +r1bq1rk1/1ppnnpbp/3p2p1/p2Pp3/2P1P3/P1N5/1P1NBPPP/R1BQ1RK1 w - - pm Bd3 {1} Kh1 {2} Ndb1 {1} Nf3 {20} Qc2 {1} Rb1 {104} Re1 {3} a4 {12} b3 {1} f3 {1} h4 {16}; +r1bq1rk1/pp2ppbp/2np1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - - pm Re1 {2} d5 {104} dxc5 {74} e3 {4}; +r1bqk2r/pp2bppp/2npp3/3nP3/2BP4/5N2/PP3PPP/RNBQ1RK1 w kq - pm Bd2 {7} Nc3 {13} Qe2 {104} Re1 {3} a3 {3} exd6 {8}; +r1bqk2r/pp2ppbp/2np1np1/8/4P3/1NN5/PPP1BPPP/R1BQ1RK1 b kq - pm Bd7 {1} O-O {104} a6 {1}; +r1bqkb1r/pp3pp1/2np1n1p/4p3/4P3/2N2N2/PPP1BPPP/R1BQK2R w KQkq - pm Bc4 {4} O-O {104}; +r1bqkbnr/pp3ppp/2np4/1N2p3/2P1P3/8/PP3PPP/RNBQKB1R b KQkq - pm Be6 {7} Be7 {104} Nf6 {1} h6 {1}; +r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/6P1/PP1PPPBP/RNBQK1NR w KQkq - pm Nc3 {104} b3 {5} d3 {2} e3 {7}; +r1bqr1k1/ppp2pp1/2np1n1p/8/2P1p3/2P1N1P1/PP2PPBP/R1BQ1RK1 w - - pm Nd5 {13} Qc2 {104} b3 {6} f3 {3} f4 {1}; +r3kb1r/1bqn1ppp/p3Pn2/1p6/2p1P3/2N2N2/PPB2PPP/R1BQ1RK1 b kq - pm fxe6 {104}; +r3kb1r/1bqn1ppp/p3pn2/1p1P4/2p1P3/2N2N2/PPB2PPP/R1BQ1RK1 w kq - pm Be3 {1} Bg5 {1} Nd4 {14} Ng5 {1} Qe2 {3} dxe6 {104} g3 {1}; +rn1qkb1r/pp3ppp/2p1pn2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R w KQkq - pm Bg5 {1} f3 {104} g3 {3}; +rn1qkbnr/ppp1pppp/8/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R b KQkq - pm Nd7 {104} Nf6 {9} c6 {98} e6 {7}; +rnbq1rk1/pp3ppp/4pn2/3p4/1bPP4/2NB1N2/PP3PPP/R1BQ1RK1 b - - pm dxc4 {104}; +rnbq1rk1/pp3ppp/4pn2/8/1bpP4/2NB1N2/PP3PPP/R1BQ1RK1 w - - pm Bxc4 {104}; +rnbqk2r/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq - pm Bf4 {2} Na3 {5} Nbd2 {18} Nc3 {2} Ne5 {2} O-O {55} Qa4 {11} Qb3 {21} b3 {19} cxd5 {104}; +rnbqk2r/pp2ppbp/5np1/3p4/3P4/2N2NP1/PP2PPBP/R1BQK2R b KQkq - pm Nc6 {8} Ne4 {6} O-O {104} Qb6 {1}; +rnbqk2r/pp3ppp/4p3/2Pn4/8/P1P2P2/4P1PP/R1BQKBNR b KQkq - pm Qa5 {104} f5 {11}; +rnbqkb1r/pp1p1ppp/2p2n2/4p3/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq - pm Bb3 {2} Bg5 {9} Nc3 {6} Nf3 {104}; +rnbqkb1r/pp2pppp/8/3n4/8/2N5/PP1P1PPP/R1BQKBNR w KQkq - pm Bc4 {5} Nf3 {104} d4 {14}; +rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq - pm Bf5 {28} Nbd7 {104} c5 {22} c6 {34} e6 {11} g6 {3} h6 {4}; +rnbqkb1r/pppppp1p/5np1/8/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq - pm Bg7 {104} c5 {12} d6 {3}; +rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - pm Nc3 {1} Nf3 {6} c3 {5} d5 {104} dxc5 {10} e3 {8} e4 {9}; +rnbqkbnr/ppppp1pp/8/5p2/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq - pm Nf6 {104} c6 {1} d6 {25} e6 {34} g6 {9}; +1rbq1rk1/1p2ppbp/p2p1np1/n1pP4/2P5/2N3P1/PPQNPPBP/R1B2RK1 w - - pm Nce4 {10} Rb1 {9} a3 {19} a4 {20} b3 {105} e4 {1}; +r1b1k2r/1pqp1ppp/p3pn2/2b5/4P3/2NQ4/PPP1BPPP/R1B2R1K b kq - pm O-O {7} b5 {105} b6 {1} h5 {10}; +r1bqk2r/pp2bppp/2nppn2/8/3NP3/2N1B3/PPP1BPPP/R2QK2R w KQkq - pm O-O {105} Qd2 {8} f4 {24} g4 {2}; +r1bqkb1r/pp1npppp/2p2n2/8/2BPN3/8/PPP2PPP/R1BQK1NR w KQkq - pm Ng3 {4} Ng5 {105} Nxf6+ {19}; +r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N2P2/PPP3PP/R1BQKB1R b KQkq - pm Bd7 {7} Nxd4 {23} Qb6 {6} a6 {10} e5 {105} e6 {34} g6 {6}; +r1bqr1k1/pp1nbppp/2pp1n2/4p3/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 w - - pm Rd1 {18} b3 {4} dxe5 {105}; +r2q1rk1/1p1nbppp/p2pbn2/4p3/4P3/1NN1B3/PPPQBPPP/R4RK1 w - - pm Bf3 {2} Rad1 {5} Rfd1 {3} Rfe1 {1} a4 {105} f3 {1} f4 {38}; +r2q1rk1/ppp1bppp/2n1p3/1B1n1b2/3P4/P4N1P/1PP2PP1/RNBQK2R w KQ - pm O-O {105}; +r2qk2r/ppp1bppp/2n1p3/1B1n1b2/3P4/P4N1P/1PP2PP1/RNBQK2R b KQkq - pm O-O {105}; +r2qk2r/ppp1bppp/2n1p3/3n1b2/3P4/P4N1P/1PP1BPP1/RNBQK2R w KQkq - pm Bb5 {105}; +r2qkb1r/ppp2ppp/2n1p3/3n1b2/3P4/5N1P/PPP1BPP1/RNBQK2R w KQkq - pm a3 {105}; +r2qkb1r/ppp2ppp/2n1p3/3n1b2/3P4/P4N1P/1PP1BPP1/RNBQK2R b KQkq - pm Be7 {105}; +rn1qkb1r/pb1ppp1p/1p3np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 b kq - pm Bg7 {105} Nc6 {7} d6 {1}; +rn1qkb1r/ppp1pppp/8/3n1b2/3P4/5N1P/PPP2PP1/RNBQKB1R b KQkq - pm e6 {105}; +rn1qkb1r/ppp1pppp/8/3n1b2/3P4/7P/PPP2PP1/RNBQKBNR w KQkq - pm Nf3 {105}; +rn1qkb1r/ppp2ppp/4p3/3n1b2/3P4/5N1P/PPP1BPP1/RNBQK2R b KQkq - pm Nc6 {105}; +rn1qkb1r/ppp2ppp/4p3/3n1b2/3P4/5N1P/PPP2PP1/RNBQKB1R w KQkq - pm Be2 {105}; +rnb1k2r/pppnqppp/4p3/3pP3/3P1P2/2N5/PPP3PP/R2QKBNR b KQkq - pm Nb6 {2} O-O {105} a6 {45}; +rnb2rk1/pp2ppbp/6p1/8/3PP3/5N2/P2BBPPP/1R2K2R b K - pm Rd8 {36} b6 {105} e6 {10}; +rnbq1rk1/pp2ppbp/5np1/3pN3/3P4/2N3P1/PP2PPBP/R1BQK2R b KQ - pm Bf5 {4} Nc6 {8} Ng4 {1} b6 {2} e6 {105}; +rnbq1rk1/ppppp1bp/5np1/5p2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - - pm Nbd2 {8} b3 {20} b4 {7} c3 {6} c4 {105}; +rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq - pm O-O {105} b3 {4} d4 {45}; +rnbqk2r/ppp2pbp/4p1p1/3P2N1/3P4/2N5/PP2PPPP/R2QKB1R w KQkq - pm Nf3 {105} Qd2 {86} h4 {2}; +rnbqk2r/ppp2pbp/4p1p1/3P4/3P4/2N2N2/PP2PPPP/R2QKB1R b KQkq - pm exd5 {105}; +rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P1P2/2P5/PP1N2PP/R1BQKBNR b KQkq - pm Be7 {1} Nc6 {105} cxd4 {3} f5 {1}; +rnbqkb1r/ppp1pppp/8/3n4/3P4/7P/PPP2PP1/RNBQKBNR b KQkq - pm Bf5 {105}; +rnbqkb1r/ppp1pppp/8/3n4/3P4/8/PPP2PPP/RNBQKBNR w KQkq - pm Be2 {4} Nc3 {1} Nf3 {62} c3 {2} c4 {44} g3 {3} h3 {105}; +rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/5NP1/PP2PP1P/RNB1KB1R b KQkq - pm Bd7 {25} Nbd7 {105} Nc6 {3} c6 {13}; +rnbqkbnr/1pp2ppp/p3p3/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R b KQkq - pm Nf6 {5} c5 {105}; +rnbqkbnr/ppp1pppp/8/3p4/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq - pm Bf5 {53} Bg4 {63} Nc6 {33} Nf6 {105} c5 {84} c6 {53} g6 {55}; +r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - - pm a3 {2} d3 {9} d4 {106} e3 {4}; +r1bq1rk1/pppp1pp1/1bn2n1p/1B2p3/3PP2B/2P2N2/PP3PPP/RN1Q1RK1 b - - pm d6 {106} exd4 {1}; +r1bq1rk1/pppp1ppp/5n2/2b5/B2nP3/2NN4/PPPP1PPP/R1BQK2R b KQ - pm Bb6 {106} d6 {1}; +r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 b kq - pm O-O {106} d5 {5} d6 {31}; +r1bqk2r/pp2bppp/2n1p3/3n4/3P4/2NB1N2/PP3PPP/R1BQ1RK1 b kq - pm Bd7 {1} Nf6 {4} O-O {106}; +r1bqk2r/pp3ppp/2n1p3/3n4/1b1P4/2N2N2/PP1B1PPP/R2QKB1R w KQkq - pm Bb5 {17} Bd3 {106} Nxd5 {1} a3 {1}; +r1bqkb1r/pp3ppp/2n1pn2/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq - pm O-O {2} b3 {3} cxd5 {106} d3 {2} d4 {2}; +r1bqkb1r/pppp1ppp/2n1pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq - pm Bf4 {11} Bg5 {9} Nc3 {106} a3 {42} d5 {10} e3 {37} g3 {27}; +r1bqkbnr/pp2pppp/2np4/8/3QP3/5N2/PPP2PPP/RNB1KB1R w KQkq - pm Bb5 {106} Qd2 {1}; +r2qkb1r/1b1n1pp1/p3p2p/1p1N4/3N2P1/P3BP2/1PPQ3P/2KR1B1R b kq - pm Bxd5 {106}; +r2qkb1r/1b1n1pp1/p3p2p/1p1n4/3N2P1/P1N1BP2/1PPQ3P/2KR1B1R w kq - pm Nxd5 {106}; +r2qkb1r/1b1n1pp1/p3pn1p/1p1P4/3N2P1/P1N1BP2/1PPQ3P/2KR1B1R b kq - pm Bxd5 {9} Nxd5 {106}; +r2qkb1r/pp1npppp/2p2n2/3p4/6b1/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq - pm e5 {106} e6 {30}; +rn1q1rk1/p1ppbppp/bp2pn2/8/2PPP3/1PN2NP1/P2B1P1P/R2QKB1R b KQ - pm Bb7 {5} d5 {106}; +rn1q1rk1/pbp1bpp1/1p2pn1p/8/2BP3B/2N1PN2/PP3PPP/R2Q1RK1 b - - pm Nbd7 {106} Ne4 {6} Qc8 {1} a6 {4} c5 {61}; +rn1q1rk1/pbpp1ppp/1p2pn2/8/1PP5/P1Q2N2/1B1PPPPP/R3KB1R b KQ - pm a5 {1} c5 {1} d6 {106}; +rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNBR2K1 b kq - pm Nbd7 {106} c4 {1}; +rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP1NPPBP/R1BQK2R b KQkq - pm Bb4 {3} Be7 {46} c5 {106} d5 {4}; +rnbq1rk1/ppp3bp/3p1pp1/4p3/2PPP1nB/2N2N2/PP2BPPP/R2QK2R b KQ - pm Na6 {3} Nc6 {106} Nd7 {2} Qd7 {2} Re8 {1} c6 {1} exd4 {11} g5 {49}; +rnbq1rk1/ppppp1bp/5np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQK2R b KQ - pm d6 {106}; +rnbqk2r/1p2bppp/p2ppn2/8/3NP3/2N1B3/PPP1BPPP/R2QK2R w KQkq - pm O-O {56} Qd2 {1} a4 {13} f4 {106} g4 {1}; +rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N1P/PPP2PP1/R1BQKB1R b KQkq - pm Nc6 {1} O-O {106} b6 {2} c5 {1} c6 {21}; +rnbqkb1r/pp1ppp1p/5np1/2p5/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq - pm Bg7 {106} Qa5+ {7} cxd4 {25}; +rnbqkb1r/pp2pp1p/2pp1np1/8/3PP3/2N1B3/PPPQ1PPP/R3KBNR b KQkq - pm Bg7 {13} Nbd7 {10} b5 {106}; +rnbqkb1r/pp3ppp/4pn2/2pp4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq - pm Bb5+ {5} e5 {30} exd5 {106}; +rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq - pm Bg7 {13} Ne4 {106} dxc4 {5}; +rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq - pm Nc3 {1} Nf3 {106} c3 {2} f4 {1} g3 {56}; +1rr3k1/2qp1ppp/p1p1pn2/8/1b2P3/4B3/PPP1BPPP/R2Q1RK1 w - - pm Bxa6 {107} a3 {1} e5 {7}; +2rq1rk1/pb1n1ppp/1p1ppn2/2p3B1/2PP4/P1QBPP2/1P2N1PP/R3K2R w KQ - pm O-O {107} Qb3 {35} Qd2 {21} Rc1 {1} Rd1 {10} a4 {4} b3 {22} b4 {9}; +r1b1k2r/1pq1bppp/p1nppn2/8/2BNP3/2N1B3/PPP1QPPP/2KR3R w kq - pm Bb3 {107} Nxc6 {2} a3 {1}; +r1b1k2r/pp1n1ppp/4pB2/qB6/3NP3/2P5/P4PPP/R2QK2R b KQkq - pm Qxc3+ {107} gxf6 {2}; +r1b1kbnr/pp3ppp/1qn1p3/3pP3/2pP4/P1P2N2/1P3PPP/RNBQKB1R w KQkq - pm Be2 {8} Nbd2 {107} Qc2 {1} g3 {15} h4 {3}; +r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - - pm Bb7 {107} Bd7 {42} Be6 {18} Nc6 {15} Rd8 {11}; +r1b2rk1/pp1n1pbp/1qpp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 w - - pm Rb1 {1} Re1 {107} b3 {2} c5 {68} d5 {21} dxe5 {3}; +r1bq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ - pm Nc1 {3} Qd2 {107} Rc1 {2} a3 {5} h4 {3}; +r1bq1rk1/1ppnn1bp/3p2p1/p2Ppp2/1PP1P3/P1N5/3NBPPP/1RBQ1RK1 b - - pm Kh8 {107} Nf6 {1} axb4 {10} b6 {1}; +r1bq1rk1/pp1nbppp/2pp1n2/4p3/2PP4/2N2NP1/PPQ1PPBP/R1B1K2R w KQ - pm O-O {107}; +r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ - pm Nge2 {107} Qd2 {20} Rb1 {3}; +r1bq1rk1/pppp1pp1/1bn2n1p/1B2p1B1/3PP3/2P2N2/PP3PPP/RN1Q1RK1 w - - pm Bh4 {107} Bxf6 {5}; +r1bq1rk1/pppp1ppp/5n2/2b1N3/B2nP3/2N5/PPPP1PPP/R1BQK2R w KQ - pm Nd3 {107}; +r1bqk2r/pp1nbppp/2pp1n2/4p3/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQkq - pm O-O {32} Qc2 {107} e4 {31}; +r1bqk2r/pp1nbppp/2pp1n2/4p3/2PP4/2N2NP1/PPQ1PPBP/R1B1K2R b KQkq - pm O-O {107}; +r1bqk2r/pppp1ppp/5n2/2b1N3/B2nP3/2N5/PPPP1PPP/R1BQK2R b KQkq - pm O-O {107}; +r1bqk2r/pppp1ppp/5n2/2b1p3/B2nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq - pm Nxe5 {107} O-O {1} d3 {2}; +r1bqkb1r/pp1p1ppp/2n1pn2/2p5/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq - pm cxd4 {6} d5 {107}; +r2q1rk1/1bpnbpp1/pp2pn1p/8/2BP3B/2N1PN2/PP3PPP/2RQ1RK1 w - - pm Bd3 {3} Be2 {9} Bg3 {1} Qc2 {22} Qe2 {4} Re1 {1} a4 {107} d5 {6}; +r2qk2r/pp1n1ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b kq - pm Bg4 {29} Bg6 {99} Ne4 {9} O-O {107}; +r2qk2r/pp2bppp/5n2/2np4/8/1N3N2/PPP2PPP/R1BQ1RK1 b kq - pm Nce4 {107} Ne6 {65} Nxb3 {4} O-O {13} Qb6 {1} b6 {5}; +r2qkb1r/1p1b1pp1/p1nppn1p/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq - pm Bh4 {107} Bxf6 {15}; +rn1q1rk1/pbp1bpp1/1p2pB1p/3p4/2PP4/2N1PN2/PP3PPP/2RQKB1R b K - pm Bxf6 {107}; +rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq - pm Nc3 {33} Rd1 {107} a4 {52}; +rn1qkb1r/ppp2ppp/3pp3/3nP3/3P2b1/5N2/PPP1BPPP/RNBQ1RK1 b kq - pm Be7 {107} Nb6 {1} Nc6 {2} a6 {1}; +rnbq1rk1/p4ppp/1p2pn2/6B1/1bBP4/2N2N2/PP3PPP/R2Q1RK1 b - - pm Bb7 {107} Bxc3 {1}; +rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQ1RK1 b - - pm Nc6 {107} Nd7 {2} Qc7 {5} cxd4 {2}; +rnbq1rk1/pp3ppp/4pn2/8/1bBP4/2N2N2/PP3PPP/R1BQK2R w KQ - pm O-O {107} a3 {2}; +rnbqk1nr/ppp1bppp/4p3/3P4/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq - pm exd5 {107}; +rnbqk2r/pp4pp/2pbpn2/3p1p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w kq - pm Bf4 {35} Bg5 {3} Nbd2 {10} Nc3 {5} Ne5 {4} Qc2 {17} b3 {107}; +rnbqkb1r/pp1ppppp/2p2n2/8/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq - pm Nc3 {66} Qa4 {11} b3 {35} d4 {107} e3 {13} g3 {53}; +rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq - pm d5 {1} dxe5 {107}; +rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq - pm Nc3 {28} Nf3 {18} e3 {1} g3 {107}; +rnbqkbnr/1pp2ppp/p3p3/8/2BP4/4PN2/PP3PPP/RNBQK2R b KQkq - pm Nf6 {53} b5 {12} c5 {107}; +rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq - pm Bd7 {23} Nc6 {107} Nf6 {1} a6 {58}; +rnbqkbnr/ppp1pppp/3p4/8/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq - pm Nf6 {107} e5 {3}; +rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq - pm Nf6 {39} c5 {96} c6 {3} d5 {107} d6 {2} e5 {14} e6 {1} g6 {9}; +r1b1k2r/1pq1bppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 w kq - pm Bf3 {1} Kh1 {89} Nb3 {3} Nxc6 {22} Qd2 {5} Qd3 {4} Qe1 {108} a3 {4} a4 {68} f5 {6} g4 {5}; +r1b1k2r/pp1p1ppp/1q2pn2/4n3/1bP1P3/1NN3P1/PP2QP1P/R1B1KB1R b KQkq - pm Bxc3+ {1} O-O {11} Qc6 {1} a5 {7} d6 {108}; +r1b1kb1r/pp1n1ppp/2p1pn2/q2P2B1/3P4/2N1PN2/PP3PPP/R2QKB1R b KQkq - pm Nxd5 {108} exd5 {2}; +r1b2rk1/ppq2ppp/2n1p1n1/2ppP2Q/3P4/P1PB1N2/2P2PPP/R1B2RK1 b - - pm Nce7 {8} c4 {108}; +r1b2rk1/ppq2ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 w - - pm Ba2 {46} Bb2 {67} Bb5 {35} Bd3 {108} Be2 {5} Qc2 {37} Qd3 {1} Qe2 {1} Rb1 {36} Re1 {3} a4 {61} h3 {18}; +r1b2rk1/ppq2ppp/2n2n2/2p1p3/3P4/P1PBPN2/5PPP/R1BQ1RK1 w - - pm Ng5 {1} Qc2 {108}; +r1bq1rk1/pp2bpp1/2n2n1p/3p2B1/3N4/2N3P1/PP2PPBP/R2Q1RK1 w - - pm Be3 {108} Bf4 {11}; +r1bq1rk1/ppp1ppbp/1nn3p1/8/3P4/2N1PNP1/PP3PBP/R1BQ1RK1 b - - pm Bg4 {38} Re8 {108} a5 {1} e5 {37} e6 {1}; +r1bqk2r/pp2bppp/2n1p3/3n4/3P4/2NB1N2/PP3PPP/R1BQK2R w KQkq - pm Be4 {1} O-O {108} a3 {2}; +r1bqkb1r/1p1pnppp/p1n1p3/1Bp5/4P3/2P2N2/PP1P1PPP/RNBQ1RK1 w kq - pm Ba4 {108} Be2 {9}; +r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/2N2N2/PPP1BPPP/R1BQK2R b KQkq - pm Be7 {5} b6 {3} h6 {108}; +r2qk2r/1p1bbppp/p1nppn2/6B1/3NP3/2N2P2/PPPQ2PP/2KR1B1R w kq - pm Be3 {11} Kb1 {4} Nb3 {6} g4 {6} h4 {108}; +r2qk2r/3nbpp1/p2pbn1p/1p2p3/4P1PP/1NN1BP2/PPPQ4/2KR1B1R b kq - pm Nb6 {108} Qc7 {5} b4 {20}; +r4rk1/1bqnbppp/pp1ppn2/8/2PNP3/2N1B1P1/PP3PBP/2RQR1K1 w - - pm Nd5 {2} Qd3 {4} Qe2 {23} Rc2 {1} b3 {108} f3 {48} f4 {83} h3 {11}; +rn1q1rk1/pbp2pp1/1p2pb1p/3P4/3P4/2N1PN2/PP3PPP/2RQKB1R b K - pm exd5 {108}; +rn1q1rk1/pbp2pp1/1p2pb1p/3p4/2PP4/2N1PN2/PP3PPP/2RQKB1R w K - pm cxd5 {108}; +rn1q1rk1/pbpp1ppp/1p2pn2/8/1PP5/P1Q2N2/3PPPPP/R1B1KB1R w KQ - pm Bb2 {108}; +rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/5NP1/PPQNPP1P/R1B1KB1R b KQkq - pm Bb7 {108} O-O {9} c5 {5}; +rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PPQNPP1P/R1B1KB1R w KQkq - pm Bg2 {108}; +rn1qkbnr/pp3ppp/4p3/2ppPb2/3P4/4BN2/PPP1BPPP/RN1QK2R b KQkq - pm Nc6 {1} Nd7 {69} Ne7 {17} Qb6 {4} cxd4 {108}; +rn1qkbnr/pp3ppp/4p3/3pPb2/3N4/4B3/PPP1BPPP/RN1QK2R b KQkq - pm Ne7 {108}; +rn1qkbnr/pp3ppp/4p3/3pPb2/3p4/4BN2/PPP1BPPP/RN1QK2R w KQkq - pm Nxd4 {108}; +rnb1k2r/pp3ppp/4pn2/qN4B1/2B1P3/2P5/P4PPP/R2QK2R b KQkq - pm Nxe4 {108}; +rnb2rk1/1pq1bppp/p2ppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 w - - pm Bf3 {38} Kh1 {15} Nb3 {5} Qd3 {4} Qe1 {108} a3 {1} a4 {49} f5 {19} g4 {68}; +rnbq1rk1/p1pp1ppp/1p2pn2/8/1PP5/P1Q2N2/3PPPPP/R1B1KB1R b KQ - pm Bb7 {108} a5 {2}; +rnbq1rk1/p4ppp/1p2pn2/8/1bBP4/2N2N2/PP3PPP/R1BQ1RK1 w - - pm Bg5 {108} Ne5 {1} Qa4 {1} Qb3 {5} Qe2 {5} Re1 {13}; +rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/P1N1P3/1P2NPPP/R1BQKB1R b KQ - pm Bd6 {30} Be7 {108}; +rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq - pm Bxc3+ {7} Nc6 {43} Ne4 {21} O-O {23} b5 {1} b6 {10} cxd4 {108} d5 {1} d6 {2}; +rnbqk2r/pp1p1ppp/4pn2/8/1bPp4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq - pm Nxd4 {108}; +rnbqk2r/pp1pppbp/2p2np1/8/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq - pm O-O {90} a6 {12} d5 {108}; +rnbqk2r/pp4pp/2pbpn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b kq - pm Nbd7 {1} O-O {6} Qe7 {108}; +rnbqkbnr/pp2pppp/8/3p4/4P3/8/PP1P1PPP/RNBQKBNR w KQkq - pm Qa4+ {6} e5 {3} exd5 {108}; +r1b1k2r/pp1n1ppp/4pn2/qB4B1/3NP3/2P5/P4PPP/R2QK2R w KQkq - pm Bxf6 {109} Qc2 {1} Qd3 {5} Qf3 {18}; +r1b2rk1/ppq2ppp/2n1pn2/2p5/3P4/P1PBPN2/5PPP/R1BQ1RK1 b - - pm e5 {109}; +r1bq1rk1/4bppp/ppnppn2/8/2P1P3/N1N5/PP2BPPP/R1BQ1RK1 w - - pm Be3 {109} Nc2 {7} Qd3 {1} b3 {1} f4 {3} h4 {1}; +r1bqk2r/1p2bppp/p1nppn2/8/2BNP3/2N1B3/PPP1QPPP/R3K2R w KQkq - pm Bb3 {26} Nxc6 {8} O-O-O {109} O-O {34} Rd1 {9} a3 {2}; +r1bqkb1r/pp3ppp/2n1pn2/2pP4/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq - pm Nxd5 {74} exd5 {109}; +r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq - pm Bg2 {46} Nf3 {109} a3 {8} d3 {5}; +r1bqkbnr/pp1p1ppp/2n1p3/2p5/4P3/5N2/PPPPQPPP/RNB1KB1R w KQkq - pm b3 {1} c3 {4} d3 {2} g3 {109}; +r2qkbnr/pp1bpppp/2Bp4/8/3QP3/5N2/PPP2PPP/RNB1K2R b KQkq - pm Bxc6 {109} bxc6 {3}; +r3kb1r/p1ppqppp/b1p5/3nP3/2P5/8/PP2QPPP/RNB1KB1R w KQkq - pm Nd2 {14} Qe4 {12} a3 {1} b3 {109} g3 {13}; +rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq - pm Bb4 {109} Be7 {4} Ne4 {6} c5 {10} d5 {67} g6 {2}; +rn1qkbnr/pppb1ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq - pm Bd3 {1} Be2 {3} Nf3 {109} c4 {5}; +rnbqk1nr/pp1pppbp/6p1/2p5/2P1P3/5N2/PP1P1PPP/RNBQKB1R w KQkq - pm Nc3 {10} d4 {109}; +rnbqk2r/pp3ppp/4pn2/8/1bBP4/2N2N2/PP3PPP/R1BQK2R b KQkq - pm Nc6 {1} O-O {109} Qc7 {3} a6 {3}; +rnbqkb1r/1p2pppp/p1p2n2/3p4/2PP4/2N1P3/PP3PPP/R1BQKBNR w KQkq - pm Bd2 {5} Bd3 {17} Nf3 {109} Qc2 {68} a4 {4} b3 {5} c5 {1} cxd5 {1}; +rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/4PN2/PPP2PPP/RN1QKB1R w KQkq - pm Nbd2 {26} Nc3 {1} c3 {109} c4 {1} dxc5 {1}; +rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq - pm Bc5 {32} Be7 {8} Nc6 {109} Nxe4 {38} c6 {10} d6 {19}; +rnbqkbnr/1pp2ppp/p3p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq - pm Bd3 {2} Ngf3 {109} e5 {2}; +rnbqkbnr/pp3ppp/2p1p3/3p4/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq - pm Bb4 {22} Nf6 {2} dxe4 {109}; +rnbqkbnr/pp3ppp/2p1p3/8/2PPp3/2N5/PP3PPP/R1BQKBNR w KQkq - pm Nxe4 {109}; +r1b1k2r/1pqp1ppp/p3pn2/2b1n3/3NP3/2NBB2P/PPP2PP1/R2Q1R1K b kq - pm b5 {1} d6 {110}; +r1b1k2r/ppppnppp/5q2/2b1n3/2BNP3/2P1B3/PP3PPP/RN1QK2R w KQkq - pm Bb3 {1} Be2 {110}; +r1b2rk1/ppp1qppp/2np1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2QR1K1 b - - pm Nd8 {110} h6 {1}; +r1bn1rk1/ppp1qppp/3p1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2QR1K1 w - - pm d4 {110}; +r1bq1rk1/pppn1pbp/3p1np1/8/2PNP3/2N3P1/PP3PBP/R1BQ1RK1 b - - pm Nb6 {3} Nc5 {2} Ne5 {5} Ng4 {15} Re8 {110} a6 {2} c6 {6}; +r1bqk2r/pp4pp/2nbpn2/3p4/3P4/3B1N2/PP2NPPP/R1BQK2R w KQkq - pm Bf4 {5} O-O {110} Qb3 {3}; +r1bqkb1r/pp3ppp/2np1n2/4p3/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq - pm Nb3 {17} Nf3 {110} Nxc6 {5}; +r1bqkb1r/pppp1ppp/5n2/4p3/B2nP3/2N2N2/PPPP1PPP/R1BQK2R b KQkq - pm Bc5 {110} Nxf3+ {13} c6 {96}; +r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq - pm Nf6 {1} Nge7 {13} Nxd4 {1} Qc7 {110} d6 {29}; +r2q1rk1/1b2bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - - pm Nbd2 {110} a4 {1} b3 {15} b4 {1} d5 {55} dxc5 {2} dxe5 {5}; +r2qk2r/pp1n1ppp/2p1pn2/5b2/PbBP4/1QN1PN2/1P3PPP/R1B2RK1 b kq - pm Bxc3 {5} Qb6 {101} Qe7 {1} a5 {110}; +r2qkb1r/1p1n1ppp/p2pbn2/4p3/4P3/1NN1B3/PPPQ1PPP/R3KB1R w KQkq - pm Bd3 {2} Be2 {19} O-O-O {11} Rd1 {2} f3 {110} f4 {8}; +rn1qk2r/1p2bppp/p2pbn2/4p3/4P3/1NN1BP2/PPP1B1PP/R2QK2R b KQkq - pm Nbd7 {110} O-O {62} d5 {8}; +rnb1k2r/1pq1bppp/p2ppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b kq - pm Nbd7 {17} Nc6 {55} O-O {110}; +rnbq1rk1/p1pp1ppp/1p2pn2/8/2P5/P1Q2N2/1P1PPPPP/R1B1KB1R w KQ - pm b3 {2} b4 {110} d4 {5} e3 {24} g3 {11}; +rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N2P2/1P2P1PP/R1BQKBNR b KQkq - pm Bd6 {4} Be7 {22} Bxc3+ {110}; +rnbqk2r/ppp2ppp/4pn2/3p4/2PP4/P1b2P2/1P2P1PP/R1BQKBNR w KQkq - pm bxc3 {110}; +rnbqkbnr/ppp1pppp/3p4/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq - pm Nc3 {27} d4 {38} g3 {110}; +r1b1k2r/1pqp1ppp/p3pn2/2b1n3/3NP3/2NBB2P/PPP2PP1/R2Q1RK1 w kq - pm Kh1 {111} Na4 {21} Qd2 {6} Qe2 {17} a3 {1} f4 {3}; +r1b1k2r/ppppnppp/2n2q2/2b5/2BNP3/2P1B3/PP3PPP/RN1QK2R b KQkq - pm Ne5 {111} O-O {96} b6 {10} d6 {1}; +r1b2rk1/ppp1qppp/2np1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2Q1RK1 w - - pm Ba4 {3} Bxc6 {10} Nd2 {5} Qe2 {2} Rb1 {9} Re1 {111} d4 {3} h3 {1}; +r1bk1b1r/ppp1nppp/2p5/4P3/8/2N2N1P/PPP2PP1/R1B2RK1 b - - pm Bf5 {3} Ke8 {1} Ng6 {34} h6 {111}; +r1bq1rk1/1p1n1ppp/p2bpn2/2p5/2BP4/2N1PN2/PPQB1PPP/R4RK1 w - - pm Bd3 {111} Be2 {1} dxc5 {16}; +r1bq1rk1/1pp2ppp/p1np1n2/2b1p3/4P3/1BPP1N2/PP3PPP/RNBQ1RK1 w - - pm Be3 {1} Bg5 {5} Nbd2 {111} Re1 {2} a4 {1} h3 {9}; +r1bqk2r/2pp1ppp/p1n2n2/1pb1p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq - pm Nxe5 {8} Re1 {1} a4 {111} c3 {42} d3 {12}; +r1bqk2r/ppp2ppp/2n1p3/8/QnpP4/5NP1/PP2PPBP/RN3RK1 b kq - pm Bd7 {11} O-O {3} Rb8 {111} a6 {4}; +r1bqkb1r/pp3ppp/2n1pn2/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQK2R b KQkq - pm Bd6 {1} Be7 {111} g6 {6}; +r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq - pm Bg7 {111} Nf6 {4} a6 {1} d6 {4}; +r2qkb1r/pp1b1ppp/2n1pn2/2p1N3/2pP4/N5P1/PP2PPBP/R1BQ1RK1 b kq - pm Nd5 {3} cxd4 {111}; +r2qkb1r/pp1b1ppp/2n1pn2/4N3/2pp4/N5P1/PP2PPBP/R1BQ1RK1 w kq - pm Naxc4 {111}; +rn1q1rk1/p1ppbppp/bp2pn2/8/2PP4/1PN2NP1/P2BPP1P/R2QKB1R w KQ - pm Bg2 {20} Qc2 {25} Rc1 {68} e4 {111}; +rn1qkb1r/4pppp/p1p2n2/1p1p4/2PP2b1/1PN1PN2/P3BPPP/R1BQK2R b KQkq - pm Nbd7 {43} e6 {111}; +rn1qkb1r/ppp2ppp/3pp3/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq - pm Nc3 {1} O-O {111} c4 {5} h3 {6}; +rnbq2k1/pp2n1pp/4pr2/2pp2B1/3P2Q1/P1PB4/2P2PPP/R3K1NR b KQ - pm Nd7 {1} Rf7 {111} e5 {3}; +rnbqk2r/ppp1bppp/5n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq - pm Nf3 {15} Qc2 {5} e3 {111}; +rnbqkb1r/1pp2ppp/p3pn2/8/2BP4/4PN2/PP2QPPP/RNB1K2R b KQkq - pm Be7 {1} b5 {5} c5 {111}; +rnbqkb1r/pp1ppppp/5n2/2p5/2P5/6P1/PP1PPP1P/RNBQKBNR w KQkq - pm Bg2 {104} Nc3 {47} Nf3 {111}; +rnbqkb1r/ppp1pp1p/3p1np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq - pm Bg7 {111} Nbd7 {3} Nc6 {1} c5 {2} c6 {2} e5 {3}; +rnbqkb1r/ppp2ppp/4pn2/3p4/4P3/3P4/PPPN1PPP/R1BQKBNR w KQkq - pm Ngf3 {111} g3 {9}; +rnbqkbnr/pp1ppp1p/6p1/2p5/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq - pm Bg7 {111} Bh6 {1} Nc6 {29} Nf6 {16} Qa5 {12} d6 {10}; +r1b1k2r/pp1n1ppp/5n2/q1pp2B1/1b1P4/2NBPN2/PPQ2PPP/R3K2R b KQkq - pm O-O {7} b6 {3} c4 {112} h6 {2}; +r1b1k2r/pp1n1ppp/5n2/q2p2B1/1bpP4/2NBPN2/PPQ2PPP/R3K2R w KQkq - pm Bf5 {112}; +r1bq1rk1/pppp1ppp/1bn2n2/1B2p1B1/3PP3/2P2N2/PP3PPP/RN1Q1RK1 b - - pm d6 {4} exd4 {2} h6 {112}; +r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq - pm Bb4 {15} Bc5 {112} Be7 {13} Nxe4 {28} h6 {15}; +r1bqkbnr/pp3ppp/2np4/1N2p3/4P3/8/PPP2PPP/RNBQKB1R w KQkq - pm Bc4 {10} Be3 {31} Bg5 {3} N1c3 {65} a4 {13} c4 {112} g3 {3}; +r2qkbnr/pp1bpppp/2np4/1B6/3QP3/5N2/PPP2PPP/RNB1K2R w KQkq - pm Bxc6 {112} Qd3 {5}; +r3kb1r/ppqnpppp/2p2n2/5b2/P1NP4/2N3P1/1P2PP1P/R1BQKB1R b KQkq - pm e5 {112}; +r3kb1r/ppqnpppp/2p2n2/5b2/P1NP4/2N5/1P2PPPP/R1BQKB1R w KQkq - pm Bg5 {6} Qd2 {1} e4 {1} g3 {112}; +rn1qkb1r/pbp2ppp/1p2pn2/3p4/2PP4/3BPN2/PP3PPP/RNBQ1RK1 b kq - pm Bd6 {112} Be7 {4} Nbd7 {30} c5 {1} dxc4 {21}; +rn2kbnr/pp1qpppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq - pm Nc6 {112} Nf6 {47} e6 {24} g6 {2}; +rnb2rk1/p1p1qpp1/1p5p/3p4/3P4/4PN2/PP3PPP/R2QKB1R w KQ - pm Bd3 {19} Be2 {21} Qb3 {3} Rc1 {112} a3 {1} b3 {3}; +rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N1P/PP3PP1/R1BQKB1R w KQ - pm Bd3 {112} Be3 {1} Bg5 {1}; +rnbqk2r/pp3ppp/4p3/8/1b1PP3/5N2/P4PPP/R1BQKB1R w KQkq - pm Bd2 {112}; +rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR w KQkq - pm Nf3 {28} Qa4+ {1} Rc1 {20} cxd5 {2} e3 {112}; +rnbqkb1r/1p2pppp/p1p2n2/3p4/P1PP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq - pm Bf5 {2} Bg4 {1} Nbd7 {1} e6 {112}; +rnbqkb1r/pp3ppp/4p3/8/3PP3/5N2/P4PPP/R1BQKB1R b KQkq - pm Bb4+ {112} Nc6 {33} Qa5+ {1} b6 {1}; +rnbqkb1r/ppp1pppp/5n2/3p4/3P4/2N2N2/PPP1PPPP/R1BQKB1R b KQkq - pm Bf5 {27} Nbd7 {33} Nc6 {63} c5 {2} c6 {33} e6 {62} g6 {112}; +rnbqkbnr/p2ppppp/1p6/2p5/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq - pm Bg2 {112} c4 {25} e4 {15}; +rnbqkbnr/p2ppppp/1p6/2p5/8/5NP1/PPPPPPBP/RNBQK2R b KQkq - pm Bb7 {112}; +rnbqkbnr/ppp1pp1p/6p1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq - pm Bg2 {112} c4 {51} d4 {29}; +rnbqkbnr/ppp2ppp/4p3/3p4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq - pm Bd6 {29} Nd7 {10} Nf6 {112} c5 {58} c6 {37}; +rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPPQPPP/RNB1KBNR b KQkq - pm Be7 {5} Nc6 {4} Nf6 {32} c5 {112} d5 {6} e5 {5}; +rnbqkbnr/pppp2pp/4p3/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq - pm Bd2 {9} Nc3 {50} Nf3 {47} a3 {5} e3 {15} e4 {11} g3 {112} g4 {5}; +r1b1k2r/pp1n1ppp/5n2/q2p1BB1/1bpP4/2N1PN2/PPQ2PPP/R3K2R b KQkq - pm Bxc3+ {2} O-O {113} g6 {5}; +r1b2rk1/pp1n1ppp/5n2/q2p1BB1/1bpP4/2N1PN2/PPQ2PPP/R3K2R w KQ - pm O-O {113}; +r1bqk2r/ppp2ppp/2np1n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQK2R w KQkq - pm Be3 {6} Bg5 {113} Na4 {6} Nd5 {21} Ne2 {2} O-O {20} h3 {4}; +r1bqk2r/pppp1ppp/5n2/4p3/1bP5/1QN2BP1/PP1PPP1P/R1B1K2R b KQkq - pm Bc5 {113} Bxc3 {1} Qe7 {3} a5 {6} c5 {1}; +r1bqkb1r/pp1p1ppp/2n1pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq - pm Be7 {34} Qb6 {26} a6 {7} d5 {113} d6 {5} g6 {3}; +r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/6P1/PP1PPPBP/RNBQK1NR w KQkq - pm Nc3 {113} Nf3 {35} a3 {12} d3 {11} e3 {10}; +r2q1rk1/p2nb1pp/bpp1p3/3p1p2/2PP4/1PB3P1/P2NPPBP/R2Q1RK1 w - - pm Bb2 {49} Nf3 {77} Qc1 {10} Qc2 {113} Rc1 {44} Re1 {3} a3 {12} a4 {61} b4 {3} e3 {49} h3 {1}; +r2qkb1r/pppb1ppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQK2R w KQkq - pm Be3 {1} Bxc6 {9} O-O {113} dxe5 {1}; +rn1q1rk1/pbp2pp1/1p3b1p/3p4/3P4/1QN1PN2/PP2BPPP/R3K2R b KQ - pm Be7 {1} Qd6 {113} Qd7 {13} Re8 {43} a5 {1} a6 {1} c5 {1} c6 {76}; +rn1qk2r/pbp2pp1/1p1ppn1p/8/2PP3B/2P1PN2/P4PPP/R2QKB1R w KQkq - pm Bd3 {50} Nd2 {113} Qc2 {4} c5 {1}; +rnbq1rk1/pp1p1ppp/4pn2/8/1bPN4/2N3P1/PP2PP1P/R1BQKB1R w KQ - pm Bg2 {113} Qb3 {1}; +rnbq1rk1/pp2bppp/2p1pn2/3p4/2PP4/5NP1/PPQBPPBP/RN3RK1 b - - pm Nbd7 {46} b6 {113}; +rnbqk1nr/ppppppbp/6p1/8/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq - pm Nf3 {2} d4 {113}; +rnbqkb1r/1p3ppp/p2ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R w KQkq - pm Bd3 {25} Be2 {113} Be3 {24} Nf3 {1} Qf3 {57}; +rnbqkb1r/pp1p1ppp/4p3/2pnP3/8/2P2N2/PP1P1PPP/RNBQKB1R w KQkq - pm Bc4 {100} Na3 {2} c4 {1} d4 {113} g3 {12}; +rnbqkb1r/pp2pppp/5n2/3P4/8/8/PP1P1PPP/RNBQKBNR w KQkq - pm Bb5+ {34} Nc3 {113} Nf3 {12} Qa4+ {23} d4 {3}; +rnbqkbnr/pppppp1p/6p1/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq - pm Bg7 {113} Nf6 {49} c5 {20} e5 {2}; +r1b1kb1r/ppp2ppp/2p5/4Pn2/8/2N2N2/PPP2PPP/R1BR2K1 b - - pm Bd7 {1} Be6 {70} Be7 {12} Ne7 {10} Rg8 {1} a5 {4} h6 {114}; +r1b2rk1/pp1n1ppp/5n2/q2p1BB1/1bpP4/2N1PN2/PPQ2PPP/R4RK1 b - - pm Bxc3 {1} Re8 {114} g6 {13} h6 {3}; +r1b2rk1/pp1nqppp/2pbpn2/8/2BP4/2N1PN2/PPQ2PPP/R1B2RK1 w - - pm Bd2 {83} Bd3 {1} Ne2 {1} Rd1 {21} a3 {59} a4 {4} b3 {1} e4 {1} h3 {114}; +r1bq1rk1/pp1pppbp/2n2np1/8/3NP3/1BN1B3/PPP2PPP/R2QK2R b KQ - pm Ng4 {3} Qa5 {9} Qc7 {2} a5 {69} b6 {2} d6 {114} e6 {7}; +r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - - pm Nxd4 {114} a6 {1} d5 {14} e5 {3} h6 {86}; +r1bq1rk1/pp2bppp/3ppn2/6B1/3nPP2/2N5/PPPQ2PP/2KR1B1R w - - pm Qxd4 {114}; +r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2NN4/PP1BBPPP/R2Q1RK1 b - - pm Kh8 {18} Nf6 {114} Rf7 {2} c5 {1} fxe4 {10}; +r1bqk2r/4bpp1/p2ppn1p/1p6/3BPP2/2N5/PPPQ2PP/2KR1B1R w kq - pm Bd3 {114} Be2 {45} Bxf6 {8} Kb1 {36} Qe3 {114} a3 {4} e5 {6} g3 {16}; +r1bqk2r/5pbp/p1np1p2/1p1Np3/4P3/N7/PPP2PPP/R2QKB1R w KQkq - pm Bd3 {114} Ne7 {1} Qf3 {3} c3 {54} c4 {58} g3 {7}; +r1bqkb1r/3n1ppp/p3Pn2/1p6/2p1P3/2NB1N2/PP3PPP/R1BQK2R b KQkq - pm cxd3 {34} fxe6 {114}; +r1bqkbnr/pppp1ppp/2n5/4p3/2P5/6P1/PP1PPPBP/RNBQK1NR b KQkq - pm Bc5 {7} Be7 {3} Nf6 {46} Nge7 {9} d6 {44} f5 {38} g6 {114} h5 {5}; +r2qkb1r/pp1b1ppp/2n1pn2/2p1N3/2pP4/6P1/PP2PPBP/RNBQ1RK1 w kq - pm Be3 {1} Na3 {114} Nxc4 {5} Nxc6 {15} e3 {7}; +rn1qkb1r/pp2pppp/5n2/3p1b2/3P4/1Q2PN2/PP3PPP/RNB1KB1R b KQkq - pm Qc7 {114} Qc8 {1}; +rn1qkbnr/pppb1ppp/4p3/8/3PN3/5N2/PPP2PPP/R1BQKB1R b KQkq - pm Bc6 {114} Nf6 {5}; +rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ - pm Bd2 {11} Bd3 {114} Be2 {1} Qc2 {3} a3 {7}; +rnbq1rk1/ppppppbp/5np1/8/2P5/5NP1/PP1PPPBP/RNBQK2R w KQ - pm Nc3 {13} O-O {114} d4 {53}; +rnbqk2r/4bppp/p2ppn2/1p6/3NP3/1BN2Q2/PPP2PPP/R1B2RK1 b kq - pm Bb7 {7} O-O {1} Qb6 {73} Qc7 {114} Ra7 {1}; +rnbqk2r/pp1p1ppp/4pn2/8/1bPN4/2N3P1/PP2PP1P/R1BQKB1R b KQkq - pm Nc6 {4} Ne4 {56} O-O {114} Qc7 {2}; +rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N1P/PP3PP1/R1BQKB1R b KQkq - pm O-O {114} a6 {8}; +rnbqkbnr/pp1ppppp/2p5/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq - pm Nf3 {4} c4 {36} e4 {114}; +rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPNPPP/RNBQKB1R b KQkq - pm Nc6 {114} Nf6 {39} a6 {1} d6 {21} e6 {21} g6 {7}; +rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq - pm Bg2 {114} c4 {27} d3 {18} d4 {64}; +rnbqkbnr/pp3ppp/4p3/2pP4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq - pm exd5 {114}; +rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq - pm Nc3 {6} cxd5 {114} e3 {23} g3 {10}; +1rN2rk1/2qp1ppp/p1p1pn2/8/1b2P3/4B3/PPP1BPPP/R2Q1RK1 b - - pm Qxc8 {1} Rfxc8 {115}; +r1b1k2r/ppppqppp/2n2n2/4p3/2P5/2Q1PN2/PP1P1PPP/R1B1KB1R w KQkq - pm Be2 {9} a3 {115} d3 {4} d4 {1}; +r1bq1rk1/5ppp/p1np1b2/1p1Np3/4P3/N1P5/PP3PPP/R2QKB1R w KQ - pm Bd3 {12} Be2 {1} Nc2 {115} Nxf6+ {2}; +r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - - pm Qa5 {115} Qc7 {2} a6 {11} h6 {22}; +r1bqk2r/pp1p1ppp/2n1pn2/8/4P3/P1N5/1PP2PPP/R1BQKB1R b KQkq - pm O-O {3} d5 {115}; +r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq - pm Be7 {5} c6 {115} g6 {6}; +r2qkb1r/1b1n1pp1/p3pn1p/1p1p4/3NP1P1/P1N1BP2/1PPQ3P/2KR1B1R w kq - pm exd5 {115} g5 {2}; +r2qkb1r/pp1nppp1/2p2n1p/7P/3P1B2/3Q1NN1/PPP2PP1/R3K2R b KQkq - pm Nd5 {4} Qa5+ {115} e6 {38}; +r3kbnr/ppqnppp1/2p4p/7P/3P4/3Q1NN1/PPP2PP1/R1B1K2R w KQkq - pm Bd2 {73} Be3 {14} Ne2 {5} Ne4 {1} O-O {2} Qe2 {9} Rh4 {115} c4 {1}; +rn1q1rk1/pbp1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/2RQKB1R w K - pm Bd3 {37} Be2 {115} Bxf6 {107} Qc2 {1} a3 {1} cxd5 {105}; +rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N1BN2/PP3PPP/R3KB1R b KQ - pm Nc6 {1} Nfd7 {115}; +rn1qkb1r/pp2pppp/5n2/3p1b2/3P4/4PN2/PP3PPP/RNBQKB1R w KQkq - pm Nc3 {33} Ne5 {2} Qa4+ {3} Qb3 {115}; +rnbq1rk1/pp3ppp/4p3/2bN4/5B2/4PN2/PP3PPP/R2QKB1R b KQ - pm Qxd5 {13} exd5 {115}; +rnbq2k1/pp2n1pp/4pr2/2pp4/3P2Q1/P1PB4/2P2PPP/R1B1K1NR w KQ - pm Bg5 {115} Qh5 {22}; +rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq - pm Bxc3+ {2} Na6 {4} Qe7 {10} a5 {14} c5 {115}; +rnbqk2r/pp3ppp/4p3/2pn4/3P4/P1P2P2/4P1PP/R1BQKBNR w KQkq - pm Qd3 {15} dxc5 {115}; +rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq - pm Bg2 {115} Nc3 {3} Nf3 {28}; +rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq - pm Nf3 {94} Qf3 {9} d3 {3} d4 {115} e5 {2} exd5 {18} f4 {7} g3 {17}; +rnbqkbnr/pppppp1p/6p1/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq - pm Bg7 {115} Nc6 {2} c5 {13} c6 {1} d6 {8} e5 {33}; +1rb2rk1/2qp1ppp/pNp1pn2/8/1b2P3/4B3/PPP1BPPP/R2Q1RK1 w - - pm Nxc8 {116} c3 {3}; +r1b1k2r/pp1n1ppp/5n2/q1pp2B1/1b1P4/2NBPN2/PP3PPP/R2QK2R w KQkq - pm O-O {24} Qc2 {116}; +r1b2rk1/ppq2ppp/2n1p1n1/2ppP2Q/3P4/P1PB1N2/2P2PPP/R1B1K2R w KQ - pm Bd2 {2} Be3 {45} Ng5 {7} O-O {116} dxc5 {5} h4 {1}; +r1bq1rk1/ppp1n1bp/3p1np1/3Ppp2/2P1P3/2NN4/PP1BBPPP/R2Q1RK1 w - - pm f3 {116}; +r1bqk2r/1ppp1ppp/p1n2n2/2b1p3/2B1P3/2PP1N2/PP3PPP/RNBQK2R w KQkq - pm Bb3 {109} Nbd2 {48} O-O {116} h3 {8}; +r1bqk2r/pp2bppp/2n1pn2/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQK2R w KQkq - pm O-O {116}; +r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq - pm Nc3 {7} Nf3 {116}; +r1bqkbnr/ppp2ppp/2np4/1B2p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq - pm Bd7 {116} Bg4 {6} exd4 {31}; +r2qk2r/pb1nbppp/2p1pN2/8/1p1P4/3BPN2/PP3PPP/R1BQ1RK1 b kq - pm Bxf6 {5} Nxf6 {116}; +rn1q1rk1/pbp2pp1/1p3b1p/3p4/3P4/2N1PN2/PP2BPPP/R2Q1RK1 b - - pm Be7 {19} Nc6 {73} Nd7 {20} Qd6 {116} Qe7 {51} Re8 {80} a6 {12} c5 {87} c6 {48} g6 {2}; +rn1q1rk1/pbp2ppp/1p2pn2/3P4/1b1P4/2NBPN2/PP3PPP/R1BQ1RK1 b - - pm exd5 {116}; +rn1q1rk1/pbp2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - - pm Bd2 {6} a3 {67} cxd5 {116}; +rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ - pm Bd3 {1} Be2 {2} Be3 {116} Bf4 {1} Ne5 {5}; +rnb1kbnr/1pqp1ppp/p3p3/8/3NP3/2NB4/PPP2PPP/R1BQK2R b KQkq - pm Bc5 {5} Bd6 {3} Nc6 {71} Nf6 {116} b5 {3} d6 {2} g6 {2}; +rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ - pm Be3 {21} O-O {116} Rb1 {2} h4 {1}; +rnbqk2r/pp3ppp/4pn2/3p4/1bPP4/2NB1N2/PP3PPP/R1BQK2R b KQkq - pm O-O {14} dxc4 {116}; +rnbqk2r/pp3ppp/4pn2/8/1bpP4/2NB1N2/PP3PPP/R1BQK2R w KQkq - pm Bxc4 {116}; +rnbqkb1r/pp1p1ppp/4p3/2pnP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq - pm Nc6 {1} cxd4 {116}; +rnbqkb1r/ppp1pp1p/5np1/3p4/3P1B2/2N2N2/PPP1PPPP/R2QKB1R b KQkq - pm Bg7 {116} Nh5 {6} c6 {28} e6 {7}; +rnbqkb1r/ppp1pppp/3p4/3nP3/2PP4/8/PP3PPP/RNBQKBNR b KQkq - pm Nb6 {116}; +rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPPQPPP/RNB1KB1R b KQkq - pm Nc6 {116} Nf6 {1}; +rnbqkbnr/pp3ppp/3pp3/8/3pP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq - pm Bb5+ {2} Nxd4 {116} Qxd4 {26}; +r1b1k2r/ppp1qppp/2nppn2/8/2PP4/5NP1/PP1NPPBP/R2QK2R w KQkq - pm Nf1 {4} O-O {117} Qb3 {1} e4 {4}; +r1b1k2r/ppppqppp/2n1p3/8/2PPn3/2B2NP1/PP2PP1P/R2QKB1R w KQkq - pm Bd2 {1} Bg2 {1} Qc2 {16} Rc1 {117}; +r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq - pm Be2 {3} Bxf6 {3} Nd2 {117} Qc2 {1} cxd5 {110}; +r1b2rk1/pp2bppp/2n1pn2/q2p4/2P2B2/P1N1PN2/1PQ2PPP/2KR1B1R w - - pm Bd3 {1} Bg5 {2} Kb1 {117} Nd2 {3} Rd2 {1} Rg1 {2} cxd5 {11} e4 {9} g4 {22} h3 {37} h4 {62}; +r1bq1rk1/pp2bppp/2n2n2/2Pp4/8/2N2NP1/PP2PPBP/R1BQ1RK1 b - - pm Bxc5 {117} d4 {1}; +r1bq1rk1/pppnn1bp/3p2p1/3Pp3/2P1Pp2/2N2P2/PP2BBPP/R2QNRK1 b - - pm b6 {3} g5 {117}; +r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq - pm Nf3 {117} Nh3 {3} Rb1 {2} a3 {95} b3 {2} d3 {11} e3 {29} e4 {24}; +r1bqkb1r/pp1pnppp/2n1p3/1Bp5/4P3/2P2N2/PP1P1PPP/RNBQ1RK1 b kq - pm a6 {117} d5 {13} g6 {2}; +r1bqkb1r/pp2pppp/2n2n2/2pP4/8/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq - pm Nxd5 {117}; +r1bqkb1r/pp2pppp/2n2n2/2pp4/2P5/2N2NP1/PP1PPP1P/R1BQKB1R w KQkq - pm cxd5 {117} d4 {84}; +r1bqkb1r/pp2pppp/2n5/2pn4/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq - pm Nb6 {4} Nc7 {117} Nf6 {3} Nxc3 {2} e6 {66} g6 {42}; +r1bqkbnr/pp2pppp/2np4/1B6/3QP3/5N2/PPP2PPP/RNB1K2R b KQkq - pm Bd7 {117} Bg4 {3} Nf6 {2} Qc7 {3} Qd7 {8} a6 {1} e5 {1}; +r2q1rk1/pp2ppbp/3pbnp1/8/3BP3/2N2P2/PPPQ2PP/2KR1B1R w - - pm Kb1 {117} a3 {1} g4 {2} h4 {13}; +r2qkb1r/1b1n1pp1/p2ppn1p/1p6/3NP1P1/P1N1BP2/1PPQ3P/2KR1B1R b kq - pm Be7 {17} Ne5 {8} Qc7 {9} Rc8 {82} d5 {117}; +rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/5NP1/PP1NPP1P/R1BQKB1R w KQkq - pm Qa4 {10} Qb3 {8} Qc2 {117} a3 {4}; +rnb1kb1r/1pq2ppp/p2ppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 b kq - pm Bd7 {1} Be7 {117} Nbd7 {1} b5 {1}; +rnb1kbnr/ppp1pppp/8/q7/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq - pm Bf5 {6} Nf6 {117} c6 {42} e5 {2}; +rnbqk2r/p1p1bp1p/1p2pp2/8/3PN3/5N2/PPP2PPP/R2QKB1R w KQkq - pm Bb5+ {8} Bc4 {117} Bd3 {20} Qd3 {1} c4 {1}; +rnbqk2r/pp2bppp/2p2n2/3p2B1/3P4/2N2N2/PP2PPPP/R2QKB1R w KQkq - pm Qc2 {117} e3 {41} g3 {2}; +rnbqkb1r/ppp2p1p/5n2/3PN3/2B2ppP/8/PPPP2P1/RNBQK2R b KQkq - pm Bb4 {3} Bd6 {48} Be7 {1} Bg7 {117} Nbd7 {5} Ne4 {5} Nh5 {7} Nxd5 {35} Qe7 {1}; +rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq - pm Bb4+ {4} Be7 {20} b6 {11} c5 {117} d5 {21} d6 {1} g6 {1} h6 {68}; +rnbqkbnr/pp2pppp/2p5/3P4/4P3/8/PP1P1PPP/RNBQKBNR b KQkq - pm cxd5 {117}; +r1b1k2r/1pq1bppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1R1K w kq - pm Be3 {118} Bf3 {2} Nxc6 {9} a4 {20} f5 {4}; +r1b1kbnr/ppqppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq - pm Be2 {2} Be3 {4} Nb5 {20} Nc3 {118} c4 {5}; +r1b2rk1/2q1bppp/p2p1n2/nppPp3/4P3/2P2N1P/PPB2PP1/RNBQR1K1 b - - pm Bd7 {118} Nb7 {6} Nc4 {14} Nd7 {14} Rb8 {4} Re8 {1} c4 {1} h6 {2}; +r1bq1rk1/pp2ppbp/2n3p1/2p5/3PP3/2P2N2/P3BPPP/1RBQK2R w K - pm Be3 {12} d5 {118}; +r1bq1rk1/pp3ppp/2n2n2/2bp4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - - pm Bf4 {11} Bg5 {118} Na4 {15} a3 {4} b3 {1}; +r1bq1rk1/ppp2pbp/n2p2p1/4p1B1/2PPP1n1/2N2N2/PP2BPPP/R2Q1RK1 b - - pm Qd7 {2} Qe8 {118} f6 {16}; +r1bq1rk1/pppp1ppp/1bn2n2/1B2p3/3PP3/2P2N2/PP3PPP/RNBQ1RK1 w - - pm Bg5 {118} Bxc6 {1} Qd3 {2} Re1 {17} a4 {3} dxe5 {5}; +r1bqk2r/pp1p1ppp/2n1pn2/1N6/1b2P3/2N5/PPP2PPP/R1BQKB1R w KQkq - pm Bf4 {26} Nd6+ {3} a3 {118}; +r1bqk2r/pp1p1ppp/2n1pn2/1N6/1b2P3/P1N5/1PP2PPP/R1BQKB1R b KQkq - pm Bxc3+ {118}; +r1bqk2r/pp1p1ppp/2n1pn2/1N6/4P3/P1b5/1PP2PPP/R1BQKB1R w KQkq - pm Nxc3 {118}; +r1bqk2r/pp1pppbp/2n2np1/1Bp5/4P3/2P2N2/PP1P1PPP/RNBQ1RK1 w kq - pm Qa4 {5} Qe2 {9} Re1 {118} d4 {2} e5 {10}; +r1bqkb1r/pp4pp/2n1pn2/3p4/3P4/3B1N2/PP2NPPP/R1BQK2R b KQkq - pm Bb4+ {6} Bd6 {118} Be7 {4} Qb6 {4} Qc7 {4}; +r1bqkb1r/pppn1ppp/4pN2/8/3P4/5N2/PPP2PPP/R1BQKB1R b KQkq - pm Nxf6 {118}; +r1bqkb1r/pppn1ppp/4pn2/8/3PN3/5N2/PPP2PPP/R1BQKB1R w KQkq - pm Bd3 {30} Bg5 {72} Ng3 {3} Nxf6+ {118}; +r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq - pm Nc3 {30} Nf3 {118} d3 {17}; +r2qk2r/pppbbppp/2np1n2/1B6/3NP3/2N5/PPP2PPP/R1BQR1K1 b kq - pm Nxd4 {4} O-O {118}; +r2qkb1r/1ppb1ppp/p1n1pn2/8/2pP4/2N1PNP1/PP3PBP/R1BQ1RK1 b kq - pm Bb4 {1} Bd6 {118} Nd5 {18} Rb8 {5} b5 {1}; +rn1q1rk1/pbp1bpp1/1p2pn1p/8/2BP3B/2N1PN2/PP3PPP/2RQK2R b K - pm Nbd7 {118} Nc6 {2} Nd5 {7} Ne8 {2} a6 {7} c5 {40}; +rnb1qrk1/ppp1p1bp/3p1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - - pm Be3 {1} Nd5 {18} Qb3 {2} Re1 {11} b3 {31} d5 {118}; +rnbq1rk1/pp1p1ppp/4pn2/2b5/2P5/P1N2N2/1PQ1PPPP/R1B1KB1R b KQ - pm Nc6 {41} Qc7 {3} b6 {118} d5 {6}; +rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq - pm Bc4 {43} Bd3 {11} Be2 {64} Be3 {2} Nc3 {118} c3 {52} c4 {23} h3 {13}; +rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq - pm Nc6 {2} O-O {118} c6 {2}; +rnbqk2r/ppppppbp/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R w KQkq - pm Nbd2 {20} Nc3 {6} c3 {16} c4 {1} e3 {118} h3 {3}; +rnbqkb1r/pp1ppppp/5n2/2p5/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq - pm c3 {27} c4 {60} d5 {118} dxc5 {3} e3 {30} g3 {1}; +rnbqkb1r/pp3ppp/5n2/2pp4/3P4/4PN2/PP3PPP/RNBQKB1R w KQkq - pm Bb5+ {118} Be2 {16} Nc3 {12}; +rnbqkbnr/ppp2ppp/4p3/3p4/4P3/3P4/PPPN1PPP/R1BQKBNR b KQkq - pm Nc6 {2} Nf6 {118} c5 {45} dxe4 {1}; +2rq1rk1/p2nbppp/bpp1p3/3p4/2PP4/1PB3P1/P2NPPBP/R2Q1RK1 w - - pm Bb2 {10} Bf3 {1} Qc1 {4} Qc2 {72} Rb1 {1} Rc1 {35} Re1 {119} a4 {26} e3 {18} e4 {82}; +r1b2rk1/2qp1ppp/p1p1pn2/8/Nb2P3/4B3/PPP1BPPP/R2Q1RK1 w - - pm Bb6 {6} Bd3 {2} Nb6 {119} c4 {12} f4 {24}; +r1b2rk1/2qp1ppp/pNp1pn2/8/1b2P3/4B3/PPP1BPPP/R2Q1RK1 b - - pm Rb8 {119}; +r1bq1rk1/1ppnn1bp/3p2p1/p2Ppp2/2P1P3/P1N5/1P1NBPPP/1RBQ1RK1 w - - pm Re1 {1} b + diff --git a/tests/ecm-gcp.ep_ b/tests/ecm-gcp.ep_ new file mode 100644 index 0000000..65c1730 --- /dev/null +++ b/tests/ecm-gcp.ep_ @@ -0,0 +1,732 @@ +setboard +id "ECM.946" + +go +setboard +id "ECM.949" + +go +setboard 2k4r/1pp2ppp/p1p1bn2/4N3/1q1rP3/2N1Q3/PPP2PPP/R4RK1 w - - +id "ECM.952" +solution Nd5 +go +setboard rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - +id "ECM.961" +solution Bxd5 +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +id "ECM.973" +solution Rxc8 +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +id "ECM.977" +solution Rxc8 +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +id "ECM.978" +solution Nxc6 +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +id "ECM.986" +solution Nxc6 +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +id "ECM.987" +solution Qxf7+ +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +id "ECM.993" +solution Qxf7+ +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +id "ECM.999" +solution Nxf7 +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +id "ECM.1004" +solution Nxf7 +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +id "ECM.1007" +solution g6 +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +id "ECM.1009" +solution Kg2 +go +setboard r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - +id "ECM.1011" +solution Nh7 +go +setboard 4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - +id "ECM.1016" +solution Nxc5 +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +id "ECM.1018" +solution Rd4 +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +id "ECM.1020" +solution exf6 +go +setboard 2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - +id "ECM.1025" +solution Nh6+ +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +id "ECM.1028" +solution Re7 +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +id "ECM.1038" +solution Re7 +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +id "ECM.1041" +solution Re7 +go +setboard r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - +id "ECM.1045" +solution Qxf5+ +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +id "ECM.1053" +solution Nxh7 +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +id "ECM.1057" +solution Rxf6 +go +setboard rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - +id "ECM.1065" +solution Nf6+ +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +id "ECM.1066" +solution Nxh5 +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +id "ECM.1068" +solution Rxe7 +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +id "ECM.1076" +solution Rxe7 +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +id "ECM.1080" +solution Rxe7 +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +id "ECM.1082" +solution Bd5+ +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +id "ECM.1084" +solution Ba3 +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +id "ECM.1085" +solution g6 +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +id "ECM.1093" +solution g6 +go +setboard 8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - +id "ECM.1096" +solution g4+ +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +id "ECM.1098" +solution Ba4 +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +id "ECM.1114" +solution Nxf7 +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +id "ECM.1122" +solution Nxf7 +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +id "ECM.1127" +solution Nxf7 +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +id "ECM.1131" +solution Nb6 +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +id "ECM.1132" +solution Nb6 +go +setboard 1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - +id "ECM.1133" +solution Bxc5 +go +setboard 2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - +id "ECM.1134" +solution Rxd5 +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +id "ECM.1147" +solution Rb3 +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +id "ECM.1150" +solution Bf4 +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +id "ECM.1151" +solution Re7 +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +id "ECM.1152" +solution Re7 +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +id "ECM.1160" +solution Re7 +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +id "ECM.1161" +solution Bg7 +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +id "ECM.1176" +solution Qc1 +go +setboard 3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - +id "ECM.1177" +solution Rxc5 +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +id "ECM.1178" +solution Rxd6 +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +id "ECM.1179" +solution Rxd6 +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +id "ECM.1185" +solution Bh7+ +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +id "ECM.1188" +solution Bxf7+ +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +id "ECM.1189" +solution Bb7 +go +setboard 5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - +id "ECM.1193" +solution Rxd7 +go +setboard 2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - +id "ECM.1199" +solution Bxh6 +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +id "ECM.1200" +solution Rxh8+ +go +setboard r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - +id "ECM.1202" +solution Bh7+ +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1204" +solution Nxf7 +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1208" +solution Nxf7 +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1214" +solution Nxf7 +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1217" +solution Nxf7 +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +id "ECM.1218" +solution Nxg7 +go +setboard b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - +id "ECM.1223" +solution Bxg6+ +go +setboard r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - +id "ECM.1224" +solution Qh6+ +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +id "ECM.1227" +solution Nxg7 +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +id "ECM.1229" +solution Nxg7 +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +id "ECM.1232" +solution Qxg6+ +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +id "ECM.1234" +solution Qxg6+ +go +setboard r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - +id "ECM.1249" +solution Re7 +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +id "ECM.1254" +solution R1b4 +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +id "ECM.1257" +solution R1b4 +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +id "ECM.1259" +solution Nd5 +go +setboard 5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - +id "ECM.1262" +solution Rxe7 +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +id "ECM.1265" +solution Rxd7 +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +id "ECM.1267" +solution Qh6 +go +setboard 3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - +id "ECM.1269" +solution Rxe6 +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +id "ECM.1270" +solution Rxc8+ +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +id "ECM.1271" +solution Rxe4 +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +id "ECM.1273" +solution Rxe4 +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +id "ECM.1274" +solution Rxe4 +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +id "ECM.1277" +solution Rxc5 +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +id "ECM.1278" +solution Rxc5 +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +id "ECM.1281" +solution Nxe6 +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +id "ECM.1285" +solution Nxe6 +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +id "ECM.1293" +solution Rxd7 +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +id "ECM.1294" +solution Rxd7 +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +id "ECM.1295" +solution Rxd4 +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +id "ECM.1304" +solution Rxd8 +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +id "ECM.1306" +solution Rxg6+ +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +id "ECM.1308" +solution Bd8 +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +id "ECM.1314" +solution Bd8 +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +id "ECM.1317" +solution Bxe5+ +go +setboard r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - +id "ECM.1318" +solution Bc3 +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +id "ECM.1321" +solution Rxc4 +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +id "ECM.1325" +solution Rxc4 +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +id "ECM.1327" +solution Nf6+ +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +id "ECM.1329" +solution Nf6+ +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +id "ECM.1332" +solution Rxa6 +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +id "ECM.1335" +solution Rxa6 +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +id "ECM.1336" +solution Rxd3 +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +id "ECM.1340" +solution e5 +go +setboard r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - +id "ECM.1341" +solution Rxh5 +go +setboard R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - +id "ECM.1344" +solution Nxe5 +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +id "ECM.1346" +solution Rxc4 +go +setboard 4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - +id "ECM.1347" +solution Rxf6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "ECM.1348" +solution e6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "ECM.1350" +solution e6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "ECM.1352" +solution e6 +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +id "ECM.1354" +solution Ng5 +go +setboard 1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - +id "ECM.1355" +solution bxc6 +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +id "ECM.1357" +solution Rxf6 +go +setboard 1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - +id "ECM.1371" +solution Bxh6 +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +id "ECM.1376" +solution Bh4 +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +id "ECM.1377" +solution Bf8 +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +id "ECM.1380" +solution Ng6+ +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +id "ECM.1381" +solution Qb2 +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +id "ECM.1383" +solution Qxg5+ +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +id "ECM.1387" +solution Qxg5+ +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +id "ECM.1394" +solution Qxg5+ +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +id "ECM.1398" +solution Bxh5 +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +id "ECM.1403" +solution Rxd5 +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +id "ECM.1405" +solution Rf6 +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +id "ECM.1408" +solution Rf6 +go +setboard 2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - +id "ECM.1409" +solution Nxf5+ +go +setboard 1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - +id "ECM.1410" +solution Ne6 +go +setboard r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - +id "ECM.1421" +solution Nxh6 +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +id "ECM.1423" +solution Bg5 +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +id "ECM.1426" +solution Bg5 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1433" +solution Nd6 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1434" +solution Nd6 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1438" +solution Nd6 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1439" +solution Nd6 +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +id "ECM.1448" +solution Rxe6 +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +id "ECM.1450" +solution Nxf5 +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +id "ECM.1452" +solution Nxf5 +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +id "ECM.1454" +solution Bxf6 +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +id "ECM.1457" +solution Bxf6 +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +id "ECM.1478" +solution Nf5+ +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +id "ECM.1495" +solution Nf5+ +go +setboard 1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - +id "ECM.1503" +solution Nxf7 +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +id "ECM.1504" +solution Rxc5 +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +id "ECM.1516" +solution Bh3 +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +id "ECM.1525" +solution Nxc6 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1527" +solution h3 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1529" +solution h3 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1533" +solution h3 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1536" +solution h3 +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +id "ECM.1546" +solution Rxc6 +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +id "ECM.1547" +solution f6 +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +id "ECM.1551" +solution e5 +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +id "ECM.1553" +solution b5 +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +id "ECM.1554" +solution Rxa6 +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +id "ECM.1561" +solution Rxa6 +go +setboard 2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - +id "ECM.1563" +solution Nxe6 +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +id "ECM.1564" +solution Ba6 +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +id "ECM.1573" +solution Nxa7 +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +id "ECM.1578" +solution Nxa7 +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +id "ECM.1579" +solution cxb6 +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +id "ECM.1582" +solution f5 +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +id "ECM.1584" +solution f5 +go +setboard r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - +id "ECM.1590" +solution Bxh7+ +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +id "ECM.1592" +solution Bxh7+ +go +setboard 1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - +id "ECM.1594" +solution Bxh7+ +go +setboard r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - +id "ECM.1597" +solution Bxh7+ +go +setboard 2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - +id "ECM.1600" +solution Rxh7+ +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +id "ECM.1601" +solution Rxh7 +go +setboard 4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - +id "ECM.1602" +solution Bxh7+ +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +id "ECM.1604" +solution Nxh7 +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +id "ECM.1605" +solution Nxh7 +go +setboard b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - +id "ECM.1606" +solution Bxh7+ +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +id "ECM.1607" +solution Qxh7+ +go +setboard 5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - +id "ECM.1610" +solution Bxh7+ +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +id "ECM.1612" +solution Nxh7 +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +id "ECM.1614" +solution Rxh7 +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +id "ECM.1617" +solution Nxh7 +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +id "ECM.1618" +solution Bxh7+ +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +id "ECM.1620" +solution Bxh7+ +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +id "ECM.1621" +solution Bxh7+ +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "ECM.1622" +solution Nxh7 +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +id "ECM.1623" +solution Rxh7 +go diff --git a/tests/ecm-hard.ep_ b/tests/ecm-hard.ep_ new file mode 100644 index 0000000..d47a3ce --- /dev/null +++ b/tests/ecm-hard.ep_ @@ -0,0 +1,1512 @@ +setboard 1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - +solution Nxg4 +id "ECM.011" +go +setboard 2rr2k1/1b3p1p/p4qpb/2R1n3/3p4/BP2P3/P3QPPP/3R1BKN b - - +solution Rxc5 +id "ECM.016" +go +setboard r3rbk1/1pq2ppp/2ppbnn1/p3p3/P1PPN3/BP1BPN1P/2Q2PP1/R2R2K1 w - - +solution Nxd6 +id "ECM.018" +go +setboard b7/2q2kp1/p3pbr1/1pPpP2Q/1P1N3P/6P1/P7/5RK1 w - - +solution Rxf6+ +id "ECM.019" +go +setboard r1b2rk1/2q2ppp/2pbp3/p7/4Nn2/3B4/PPPBQ1PP/R4R1K w - - +solution Rxf4 +id "ECM.028" +go +setboard 3r2k1/1q1P1ppp/r2R2n1/p4Q2/1ppB2R1/6P1/PP3PP1/6K1 w - - +solution Rgxg6 +id "ECM.029" +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +solution Rxc8 +id "ECM.035" +go +setboard r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - +solution Rxa1 +id "ECM.039" +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +solution Nxc6 +id "ECM.040" +go +setboard 2rr4/5pk1/p1q3p1/3bpP1p/1p4nR/1N4Q1/PPP3PP/3NR2K b - - +solution Bxg2+ +id "ECM.043" +go +setboard r4rk1/pp4pp/2nqb3/3p4/8/2NB4/PP1Q1PPP/4RRK1 w - - +solution Bxh7+ +id "ECM.044" +go +setboard 3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - +solution d3 +id "ECM.048" +go +setboard 1k1r1b1r/p1p1q3/2p1p3/4Ppp1/4nP2/P2BQ3/1PP3PB/2KR3R b - - +solution Rxh2 +id "ECM.051" +go +setboard r1bq1rk1/pp3pbp/2pp1np1/2n3B1/2PNP3/2N2P2/PP1QB1PP/R4RK1 b - - +solution Nfxe4 +id "ECM.053" +go +setboard r4rk1/pp1b2pp/3bpq2/3p1p2/2PPn3/PP1B4/1BQN1PPP/R4RK1 b - - +solution Bxh2+ +id "ECM.060" +go +setboard 4nk2/r1r1bppp/pN2p3/2np4/8/BPN3PP/P3PPK1/2RR4 w - - +solution Ncxd5 +id "ECM.063" +go +setboard 3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - +solution Rxd4 +id "ECM.066" +go +setboard r1b2rk1/1p2bppp/p3pn2/4B3/1qBR4/2N5/P3QPPP/R5K1 w - - +solution Bd3 +id "ECM.068" +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +solution Qh6 +id "ECM.071" +go +setboard r1b2kr1/1p1p1pNp/p1n1p1p1/5P2/3QP3/2N5/PqP1B1PP/R4RK1 w - - +solution fxg6 +id "ECM.076" +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +solution Rd4 +id "ECM.080" +go +setboard Q7/p1r1ppk1/1qP4p/2Rb2p1/8/3N2P1/4PP1P/6K1 b - - +solution Qb1+ +id "ECM.081" +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +solution exf6 +id "ECM.082" +go +setboard 4r1k1/1b4pp/p7/1prP3q/2P1B3/5P2/P3Q2P/3RR2K w - - +solution Bg6 +id "ECM.084" +go +setboard rn1q1r2/4bpk1/p3p3/1pN1N1np/2pP4/4PpBb/PPQ4P/1B1RK1R1 w - - +solution Nc6 +id "ECM.091" +go +setboard 6k1/1pqb1p2/5bpB/r2n4/4N1P1/1P3P2/1P1Q4/1K5R w - - +solution Qxd5 +id "ECM.099" +go +setboard 2kr1r2/1pp3pp/1n2p1b1/pN2B3/P1q5/1Q1p3P/5PP1/R4R1K w - - +solution Rac1 +id "ECM.109" +go +setboard r1b1Q3/6pk/p6p/1pq1n3/4N3/8/PPP3PP/R6K b - - +solution Qc6 +id "ECM.112" +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +solution Nxh7 +id "ECM.115" +go +setboard 4qbk1/1R5n/p2pr1p1/2pQpNPp/P1P1P3/2P2P2/3B4/5K2 w - - +solution Ne7+ +id "ECM.117" +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +solution Rxf6 +id "ECM.119" +go +setboard 2b1rr1k/1p5p/1Ppp2q1/p3bN2/2P1n3/5R2/PBQ3BP/3R2K1 w - - +solution Nxd6 +id "ECM.123" +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +solution Nxh5 +id "ECM.128" +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +solution Rxe7 +id "ECM.130" +go +setboard 2rq1rk1/pp2bppp/1npp1n2/3PpN1b/2P5/2N3PP/PP2PPB1/R1BQ1RK1 w - - +solution c5 +id "ECM.131" +go +setboard 2n1rbk1/5pp1/7p/qP1pp3/4b1Q1/1B5P/1P1N1PP1/2B1R1K1 w - - +solution Rxe4 +id "ECM.133" +go +setboard 4k3/2R2p2/5p1p/8/rb6/1N6/5PPP/5K2 w - - +solution Rc4 +id "ECM.134" +go +setboard 2k3r1/pp2rp2/1np5/2Np1p2/P2P3p/1R2P1Pq/2Q2P1P/1R4K1 w - - +solution Nxb7 +id "ECM.135" +go +setboard 8/1Qp3pk/7p/5p2/5Pqn/1P1r4/P5PP/2B2RK1 b - - +solution c6 +id "ECM.137" +go +setboard b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - +solution d3+ +id "ECM.142" +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +solution Bd5+ +id "ECM.144" +go +setboard 6k1/4ppbp/p5p1/1B1Q4/2P2Pn1/8/qr4PP/2B2RK1 b - - +solution Bd4+ +id "ECM.145" +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +solution Ba3 +id "ECM.146" +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +solution g6 +id "ECM.147" +go +setboard 5r2/1b3pk1/pqrpp1p1/4n1Nn/1p2PP1P/8/PPPQB3/1NKR2R1 b - - +solution Rfc8 +id "ECM.148" +go +setboard 8/1bq3kp/p5p1/1pb1p3/4P2P/2PQ2P1/1P5B/5N1K b - - +solution Qd8 +id "ECM.153" +go +setboard 4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - +solution Ra8 +id "ECM.155" +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +solution Ba4 +id "ECM.160" +go +setboard r1bq3k/ppp2Qp1/2n1p2p/6N1/2BPN3/2P1n3/PP4PP/R5K1 w - - +solution Nf6 +id "ECM.161" +go +setboard 3R4/1p2kp2/p1b1nN2/6p1/8/6BP/2r1qPPK/Q7 w - - +solution Rd7+ +id "ECM.162" +go +setboard r1b3k1/ppp2r2/6p1/3n3p/6qP/3BQ3/PBP5/2KR3R w - - +solution Bd4 +id "ECM.180" +go +setboard 1R3b2/3r3k/2p1bp1p/r1q1pNpQ/2PpP2P/6B1/P4PP1/1R4K1 w - - +solution Nxh6 +id "ECM.186" +go +setboard r1b4r/pp2ppk1/2np1np1/3N3p/2B1P3/q3BP2/P1PQ2PP/1R3RK1 w - - +solution Nxe7 +id "ECM.187" +go +setboard 5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - +solution Ne4 +id "ECM.189" +go +setboard 5rk1/5pbp/b5p1/p1nNN3/1p2n3/1P4PP/P4PB1/2BR2K1 w - - +solution Nd7 +id "ECM.190" +go +setboard 2k1r1r1/ppb2p2/6b1/2qP4/2P2P2/4pP1p/P3Q2P/2RBRN1K b - - +solution Bd3 +id "ECM.191" +go +setboard 5r1k/pp1n1p1p/1b1qpP2/8/1PrN4/P1N1Q1P1/7P/3R1R1K w - - +solution Qh6 +id "ECM.192" +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +solution Nb6 +id "ECM.193" +go +setboard r1k3r1/pppnb1p1/4N3/3QP2p/3P3q/4B3/PPP2P2/R3KB2 w Q - +solution Ba6 +id "ECM.198" +go +setboard r1bq1rk1/pppn2bp/3p2p1/3N1p2/8/BP1BRQ1P/P1PP1PP1/4R1K1 w - - +solution Nxc7 +id "ECM.206" +go +setboard 2q1r1k1/1b3pbp/3p2p1/1Ppn3n/5P2/5B2/1P1B2PP/R2NNQ1K b - - +solution Ndxf4 +id "ECM.208" +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +solution Rb3 +id "ECM.209" +go +setboard r2qr1n1/p4pk1/1p1p2p1/4p3/4PQ2/1PN2P2/1PP3P1/2KR3R w - - +solution Rh7+ +id "ECM.210" +go +setboard r4rk1/ppp3b1/3p1qp1/3Pp3/2P1Bn2/4BP2/PP1Q4/2K3RR w - - +solution Rxg6 +id "ECM.211" +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +solution Re7 +id "ECM.213" +go +setboard r4n1r/ppq1nk2/1bpRpN2/4PpQ1/8/2B4P/PPP2PP1/2KR4 w - - +solution Rd7 +id "ECM.215" +go +setboard 3r2k1/p5pp/bpP1p3/3n1p2/2NQpP1q/P3P3/1B1R1R2/4KBr1 b - - +solution Rxf1+ +id "ECM.216" +go +setboard rnb1kr2/p4pQ1/8/1ppPpP2/2p1P3/N6P/Pq4B1/3R1RK1 w q - +solution Nxb5 +id "ECM.226" +go +setboard 5r1k/2p3pp/3pQ3/3P1rN1/pp5q/5PR1/P4PKP/B7 w - - +solution Bxg7+ +id "ECM.227" +go +setboard 8/pR3Bk1/3p2p1/5b1p/2P4P/6P1/P4bQK/4q3 b - - +solution Bg1+ +id "ECM.228" +go +setboard rq3r1k/p2n1p2/1pbb1np1/2p2BB1/8/2N2N2/PP3QPP/3R1RK1 w - - +solution Rxd6 +id "ECM.231" +go +setboard 3rr1k1/1b5p/p6p/1p3N2/6Pb/P1Q1p3/1PP4P/R5K1 b - - +solution Bf2+ +id "ECM.237" +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +solution Qc1 +id "ECM.238" +go +setboard 6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - +solution Rh4+ +id "ECM.241" +go +setboard 4rrk1/3b1ppp/pb6/1pqP4/P1p1PP2/1P2NK2/3QB2P/R2R4 b - - +solution Rxe4 +id "ECM.244" +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +solution Bh7+ +id "ECM.247" +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +solution Bxf7+ +id "ECM.250" +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +solution Bb7 +id "ECM.251" +go +setboard 2b3k1/p4ppp/7q/2Q5/8/P3r1P1/1r4BP/R3R1K1 b - - +solution Rxg2+ +id "ECM.259" +go +setboard r1b1rbk1/7p/2p1pBp1/p2pP1P1/5P2/1PqB4/P1P1Q3/1K4RR w - - +solution Rxh7 +id "ECM.260" +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +solution Rxh8+ +id "ECM.262" +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +solution Nxf7 +id "ECM.266" +go +setboard r1b1r1k1/1p1n1p2/p1nBp1p1/q2pP1Np/P7/R2B3Q/2P2PPP/5RK1 w - - +solution Nxf7 +id "ECM.267" +go +setboard 4n1q1/1k1b4/2p4R/2Pp4/1p1N1rpQ/3B4/PPP2P2/2K5 w - - +solution Nxc6 +id "ECM.271" +go +setboard r3r1k1/pp3pp1/2bb1q2/3p4/4n1Pp/2P1BB1P/PP2NPK1/R1Q4R b - - +solution Qxf3+ +id "ECM.274" +go +setboard rn4k1/pp2p1b1/4b3/q2p2Q1/2B2P2/8/P1P1K1P1/R6R w - - +solution Rh8+ +id "ECM.277" +go +setboard 2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - +solution Rxc3 +id "ECM.279" +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +solution Nxg7 +id "ECM.280" +go +setboard 4k3/p4ppp/nb1P4/4p3/1P6/P4BP1/3q1r1P/2R2QKR w - - +solution Qb5+ +id "ECM.287" +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +solution Nxg7 +id "ECM.289" +go +setboard 1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - +solution Rxb2 +id "ECM.291" +go +setboard 5rk1/ppp1q2p/1n1p1np1/3P2N1/1P1R2P1/2Q4P/P3r1B1/5RK1 b - - +solution Rxg2+ +id "ECM.292" +go +setboard 6k1/pp2p2p/3p2p1/4b1r1/2Pn1r1q/2B1N3/PP4B1/R3QRK1 b - - +solution Qh2+ +id "ECM.293" +go +setboard r2k3r/2pb1ppp/p1p1q3/2Q5/5B2/2N5/PPP2PPP/3R2K1 w - - +solution Bxc7+ +id "ECM.295" +go +setboard 2r1qrk1/pp1b1ppp/4pn2/n1b5/8/2NQ1NP1/PP1BPPBP/R2R2K1 w - - +solution b4 +id "ECM.297" +go +setboard 2b1qr1k/7p/p1pR2p1/1pP1p1Q1/4P3/1B6/PP4PP/6K1 w - - +solution Re6 +id "ECM.298" +go +setboard 8/2b2k1p/2N2pp1/P2p4/3KnP2/6BP/P5P1/8 w - - +solution Kxd5 +id "ECM.300" +go +setboard 3r1rk1/2p1qp1p/pnP3p1/4n3/PP1NpR2/1BQ4P/6P1/5RK1 w - - +solution Ne6 +id "ECM.307" +go +setboard r5rk/1p1bqpnp/3p1b1B/pBnPp2P/4P3/2N2Q2/PP3P2/R3KNR1 b Q - +solution Nf5 +id "ECM.310" +go +setboard r3r1k1/p1q2pp1/2p4p/7n/BPPP2N1/3Q1N2/P3n1P1/R1B4K b - - +solution Nhg3+ +id "ECM.312" +go +setboard r1b2rk1/p3bppp/2q5/8/2p1NR2/PnB1P3/1PB1Q1PP/3R2K1 w - - +solution Rd6 +id "ECM.315" +go +setboard 1rb2rk1/p1p2ppp/2q5/3R4/2P1N3/bP4B1/P1Q2P1P/1K5R w - - +solution Bd6 +id "ECM.318" +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +solution Rd5 +id "ECM.321" +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +solution Rxd7 +id "ECM.327" +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +solution Qh6 +id "ECM.329" +go +setboard 2r2r1k/1pq1b1p1/p1b1Qn1p/8/3B4/2NB4/PPP3PP/3R1R1K w - - +solution Rxf6 +id "ECM.330" +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +solution Rxc8+ +id "ECM.332" +go +setboard 8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - +solution Rxd4 +id "ECM.335" +go +setboard r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - +solution Rxe5 +id "ECM.336" +go +setboard r3r1k1/pbqn1ppp/1p3n2/1Pb5/2p5/5N1P/PBQ1BPP1/1N1R1RK1 b - - +solution Rxe2 +id "ECM.337" +go +setboard 2r2rbk/6bp/5qp1/1N1p1n2/4p3/1p5P/1P3PP1/RBBQ1RK1 b - - +solution Ng3 +id "ECM.338" +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +solution Rxc5 +id "ECM.339" +go +setboard 1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - +solution Rxe7 +id "ECM.340" +go +setboard r1b2r1R/1p2bpk1/4p1p1/4P1N1/p2p4/5Q2/qPP2PP1/1NKR4 w - - +solution Qf6+ +id "ECM.342" +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +solution Nxe6 +id "ECM.343" +go +setboard 2r1k2r/1pq1bppp/p3bn2/4N3/2pPN3/2P5/P3QPPP/R1B1R1K1 w k - +solution Nxf6+ +id "ECM.345" +go +setboard 1r3k1r/4Rn1p/pb1p1P2/1p1q2P1/5p2/7Q/PPP1B1RP/2K5 w - - +solution Rxf7+ +id "ECM.346" +go +setboard r3r1k1/pp3ppp/1qp5/2bbNQ2/5B2/2P5/PP3PPP/3RR1K1 w - - +solution Rxd5 +id "ECM.349" +go +setboard r2qn1k1/1p1b3p/2pp1b2/6pQ/p1P1P3/P1N3PB/1P6/3R1R1K w - - +solution Rxf6 +id "ECM.351" +go +setboard r4k1r/pp2pp2/3p1b2/q2PnQpp/3N4/1BP3P1/PP3PP1/3RR1K1 w - - +solution Rxe5 +id "ECM.353" +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +solution Rxd7 +id "ECM.355" +go +setboard 2r2rk1/p3p1bp/3qP1p1/1Q1p4/P4P2/3R4/1P4PP/2B2RK1 b - - +solution Rxc1 +id "ECM.356" +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +solution Rxd4 +id "ECM.357" +go +setboard 1r6/3b1pk1/pr1p1q1p/2pPb1p1/2B1P1P1/2N2PP1/1PQ3K1/RR6 b - - +solution Rxb2 +id "ECM.358" +go +setboard 2r3k1/p1r1ppb1/2bp1np1/q5N1/1p1BP2Q/3P4/PP2N1PP/2R2R1K w - - +solution Bxf6 +id "ECM.360" +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +solution Rxd8 +id "ECM.366" +go +setboard r4rk1/5p2/p1b1pQpq/8/1B2P3/2NR4/PPP3PP/1K6 w - - +solution Rd5 +id "ECM.367" +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +solution Rxg6+ +id "ECM.368" +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +solution Bd8 +id "ECM.370" +go +setboard 1k2rb1r/pbp1q1pp/2pp4/2PnpP2/Q7/1P3NP1/PB5P/2KR1B1R w - - +solution Rxd5 +id "ECM.371" +go +setboard 7k/p1p1r2p/1p1pnr1q/5pp1/2PPPp2/2PB1P1P/P2Q1PRK/7R b - - +solution g4 +id "ECM.372" +go +setboard 5qk1/p4p2/1p3Pp1/2p4Q/3rr3/7R/PP6/6RK b - - +solution Rh4 +id "ECM.373" +go +setboard 2b4B/1pp2k2/1p6/3P3n/5p1P/1P4p1/P2r2P1/R5KR b - - +solution f3 +id "ECM.375" +go +setboard r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b q - +solution Bh2 +id "ECM.376" +go +setboard r2q1r2/p1pbppbk/1p3npp/n2P2B1/7Q/2NB1N2/PPP3PP/4RRK1 w - - +solution d6 +id "ECM.377" +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +solution Bxe5+ +id "ECM.379" +go +setboard r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - +solution d4 +id "ECM.387" +go +setboard 2k1r3/Qp3pb1/2p4p/6q1/8/1P4PN/PBPn1P2/K2R4 b - - +solution Qe5 +id "ECM.390" +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +solution Rxa6 +id "ECM.394" +go +setboard r5kr/p3PR1p/1p1p2pq/4n3/8/3B4/P4QPP/4R1K1 w - - +solution Rxe5 +id "ECM.395" +go +setboard 2bq1b2/1p3k2/1r1p1p1p/pNpP1PpP/P1P3P1/6B1/1P5Q/2K1R3 w - - +solution Re6 +id "ECM.396" +go +setboard 2kr3r/pp3p1p/2b1p3/q3Q3/5P2/2P1B3/P1P3PP/1R3RK1 b - - +solution Rhg8 +id "ECM.397" +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +solution Rxd3 +id "ECM.398" +go +setboard 2r2nk1/6pp/p1rPqp2/1pP1p3/1P6/2B3R1/1P2Q1PP/5RK1 w - - +solution Rxf6 +id "ECM.399" +go +setboard r2rnbk1/pp3ppp/1q4n1/3p1N2/5P2/1PQB4/PBP3PP/4RR1K w - - +solution Nh6+ +id "ECM.401" +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +solution e5 +id "ECM.402" +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +solution Rxc4 +id "ECM.408" +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +solution e6 +id "ECM.410" +go +setboard r4rk1/1b4bp/p1npq1P1/R3p3/8/1N2BP2/1PPQ2P1/4KB1R w K - +solution Qxd6 +id "ECM.411" +go +setboard 6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - +solution Bd2 +id "ECM.412" +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +solution Ng5 +id "ECM.416" +go +setboard r3kbnr/1ppb3p/p1q1pp2/3p4/3P4/2N2N2/PPP2PPP/R1BQ1RK1 w kq - +solution Ne5 +id "ECM.418" +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +solution Rxf6 +id "ECM.419" +go +setboard 3rr1k1/1p1qb2p/pP4p1/2p2p2/4RQ2/3P4/1PPB2PP/4R1K1 w - - +solution Bc3 +id "ECM.420" +go +setboard 6k1/rnqb3p/5ppQ/2pPp3/p1N1P3/2PB3P/5PP1/1R4K1 w - - +solution f4 +id "ECM.422" +go +setboard 7r/pp4k1/3pn1p1/q1pB1b2/2P5/5NR1/1P3PP1/2Q3K1 w - - +solution b4 +id "ECM.423" +go +setboard 6k1/p4p1p/3pqp2/2p1r3/2Pnr1N1/P6P/1P1Q1PP1/3R1RK1 b - - +solution Ne2+ +id "ECM.427" +go +setboard r2b4/pb2q1k1/np1p2r1/1N1Pp2Q/PPN1Pp2/8/2R2BPp/2R4K w - - +solution Ncxd6 +id "ECM.434" +go +setboard r7/2qnb1kp/p2p1nP1/1p1Pp1p1/6N1/3BB2Q/PPP4P/5RK1 w - - +solution Qxh7+ +id "ECM.435" +go +setboard n1rqk3/1p2p3/1n1pP1p1/pP1P1p1r/3B3P/1BN3p1/3Q4/R3K2R w KQ - +solution Qg5 +id "ECM.436" +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +solution Bh4 +id "ECM.438" +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +solution Bf8 +id "ECM.439" +go +setboard 4rr1k/pbp3bp/3p4/1p5q/3n4/1B1Q2B1/PP1N1N1P/4RRK1 b - - +solution Rf3 +id "ECM.440" +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +solution Ng6+ +id "ECM.442" +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +solution Qb2 +id "ECM.443" +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +solution Qxg5+ +id "ECM.445" +go +setboard 2k5/1p1b4/2n1p1r1/7q/4RP2/3BQN2/2P2K1P/8 w - - +solution f5 +id "ECM.447" +go +setboard 2k3r1/1ppr3p/p1pB2q1/6n1/N3Pp2/8/PPP1Q1PP/3R1RK1 b - - +solution f3 +id "ECM.448" +go +setboard 6r1/6rk/3p3p/p2Rp3/R1PqPp1b/2N2Q2/6PP/7K b - - +solution Rxg2 +id "ECM.450" +go +setboard 2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - +solution h4 +id "ECM.456" +go +setboard 6nk/p4rrp/1p1p1p2/1q1Pp2R/4B1P1/1PP2Q1R/P6P/7K w - - +solution g5 +id "ECM.458" +go +setboard r1b1k2r/6pp/p1p1p3/3np1B1/1b2N3/8/q1PQB1PP/3RK2R w Kkq - +solution Qxb4 +id "ECM.459" +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +solution Bxh5 +id "ECM.460" +go +setboard 4r1kb/p2r4/1np1p1p1/3nP1Bp/1p3P1R/1B2qP2/PPPN3Q/2K4R w - - +solution Rxh5 +id "ECM.463" +go +setboard 2rq2k1/pp1bpp1p/3p1np1/8/3NPPnQ/1BP5/P1P3P1/1K1R3R w - - +solution e5 +id "ECM.464" +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +solution Rxd5 +id "ECM.465" +go +setboard 2r1kr2/p1qbbp1Q/3pp3/5p2/1p1N1PB1/6P1/PPP4P/K2RR3 w - - +solution Bxf5 +id "ECM.466" +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +solution Rf6 +id "ECM.467" +go +setboard 2rr2k1/5pn1/1b2q1pp/pP1pP3/2pP1PP1/2R1B2P/2Q3B1/3R3K w - - +solution f5 +id "ECM.468" +go +setboard 2Q2bkr/5p2/1rb5/1pN1n1qB/1P1pPN2/6P1/5P2/R1R3K1 w - - +solution Nce6 +id "ECM.469" +go +setboard 2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - +solution Nc3+ +id "ECM.470" +go +setboard r7/pp4pk/2n3qp/5p2/3p4/P4QB1/1PP1RPPP/6K1 b - - +solution d3 +id "ECM.473" +go +setboard 2r2r1k/1p3p1p/p2p1Pp1/3Pp3/1q2Bn1Q/8/1PP3PP/4RR1K w - - +solution Rxf4 +id "ECM.474" +go +setboard r4rk1/5ppp/p7/4PR2/P1qnp2Q/4B3/1P4PP/5RK1 w - - +solution Rh5 +id "ECM.475" +go +setboard 4r3/pb3pk1/6p1/8/6P1/1PNrB2K/P4P1P/2R5 b - - +solution Rexe3+ +id "ECM.476" +go +setboard 1r2k2r/1bq2pp1/pn2p2p/1p2P1b1/3N4/2N3Q1/PPP3PP/1K1R1BR1 w k - +solution Bxb5+ +id "ECM.482" +go +setboard 2r2r2/p4p1k/1p2pBpn/2p5/6N1/8/P4P2/R3R1K1 w - - +solution Kg2 +id "ECM.484" +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +solution Bg5 +id "ECM.485" +go +setboard 2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - +solution Bh3 +id "ECM.488" +go +setboard 2b3k1/5qp1/p2r1n1p/3p4/3B4/1RP3QP/P2Nr1P1/3R2K1 b - - +solution Ne4 +id "ECM.489" +go +setboard 1r2r1k1/p4ppb/q1pbnn1p/4p3/N1P1P3/pPB2NP1/2Q1RPBP/R5K1 b - - +solution Nxe4 +id "ECM.491" +go +setboard r4r2/1pnqb2k/3p1p1p/p1pPpPpP/2P1N1P1/4BP2/PP1Q4/R2R2K1 w - - +solution Bxc5 +id "ECM.492" +go +setboard 6kr/1p1r1p1p/p2pnPpQ/3Np2R/2q1P3/5P2/PPP5/2KR4 w - - +solution Rxe5 +id "ECM.494" +go +setboard rq1r2k1/3nbp1p/p2p2p1/1p1Pp1P1/3B1P2/3B3Q/PPP4P/2KR2R1 w - - +solution f5 +id "ECM.497" +go +setboard r4rk1/1bq1bppp/8/p2pPR2/3B4/1NnP3Q/1P4PP/4R1K1 w - - +solution Rh5 +id "ECM.498" +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +solution Nxh5 +id "ECM.499" +go +setboard r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - +solution f3 +id "ECM.500" +go +setboard 4rqk1/p5b1/3p3p/3Pn1p1/1pP1NrP1/4NP2/P3Q1P1/1K1RR3 b - - +solution Nxf3 +id "ECM.501" +go +setboard r3rk2/pb2bpp1/1n5p/q1pP1B2/1p3B2/5N2/PPQ2PPP/R2R2K1 w - - +solution Bc8 +id "ECM.503" +go +setboard r1bqr2k/ppp2p1p/5b2/3Pn1p1/1PP1Bp2/8/PB2N1PP/R2Q1RK1 w - - +solution Nxf4 +id "ECM.504" +go +setboard 1q4k1/p3rppp/3b1n2/8/5P2/4P3/PP1B3P/RNQ3K1 b - - +solution Bxf4 +id "ECM.505" +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +solution Rxe6 +id "ECM.510" +go +setboard 2bk3r/3r2pp/p2nQ3/q2R2P1/1p6/8/PPP2P1P/1K3B1R b - - +solution Qxd5 +id "ECM.525" +go +setboard 1kb3rr/1p2n2q/1Np2p2/1p6/1P1N1P1p/8/2P1RQPP/R6K w - - +solution Nxb5 +id "ECM.529" +go +setboard 6k1/5qp1/pN5p/3pRp2/3QnP2/2r4P/r5P1/6RK b - - +solution Qh5 +id "ECM.539" +go +setboard r1b2rk1/ppp2ppp/2n3q1/b2N2N1/2BP4/4p2P/PPP3P1/R2Q1RK1 w - - +solution Nxf7 +id "ECM.553" +go +setboard r6r/pR1nqkpp/2p1p3/3p4/6Q1/2b4P/P1PP1PP1/2B1R1K1 w - - +solution Rxe6 +id "ECM.555" +go +setboard 5rk1/p1p1br2/1p1p2qp/4p3/2PPn1pP/3Q2P1/PPN1P1K1/2RR2B1 b - - +solution Bxh4 +id "ECM.557" +go +setboard r1b2rk1/4bnpp/2p5/pp2q3/4N3/PQ2B1P1/1PP3BP/4RRK1 w - - +solution Ng5 +id "ECM.559" +go +setboard 2rr2k1/1p3p2/p2n2p1/P2PnNq1/3QP1p1/1RN5/6PP/5RK1 b - - +solution Nf3+ +id "ECM.560" +go +setboard r3k1r1/pb1qpp1p/1pnp1n1B/2p2R2/3PP3/2P3PN/P1P3BP/R2Q3K b q - +solution Nxe4 +id "ECM.561" +go +setboard 2r2rk1/pp2bppp/3q1n2/3nNRB1/3P4/1B5Q/PP4PP/3R2K1 w - - +solution Nxf7 +id "ECM.562" +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +solution Rxc5 +id "ECM.566" +go +setboard 2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - +solution Nxc1 +id "ECM.569" +go +setboard 5rk1/bp4p1/p2rp2p/8/8/2PN4/PP1R1PPP/3R2K1 b - - +solution e5 +id "ECM.577" +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +solution Bh3 +id "ECM.578" +go +setboard r3r1k1/p2n4/3p1pp1/qnp3B1/1p2P1P1/1P3P2/PP2N2Q/1K1R1B2 w - - +solution Nf4 +id "ECM.580" +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +solution Nxc6 +id "ECM.587" +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +solution h3 +id "ECM.589" +go +setboard 4r1k1/r1q2p1p/p5pB/1pbBpN1n/1n2P3/5Q2/PP3PPP/R1R3K1 w - - +solution Rxc5 +id "ECM.592" +go +setboard r1r3k1/ppnbb1pp/2ppp1q1/1P3p2/P1PPn3/2N2NP1/2Q1PPBP/1RB2RK1 w - - +solution Nxe4 +id "ECM.593" +go +setboard 1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - +solution Nxh2 +id "ECM.595" +go +setboard rnb2rk1/pp4pp/2pb1n2/3N1p1q/2P5/3N2P1/P1Q1PPBP/R1B2RK1 w - - +solution Bf4 +id "ECM.597" +go +setboard 8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - +solution f4 +id "ECM.598" +go +setboard 7k/8/1p1ppp1p/1Pp5/2P2P2/8/3P2PP/6K1 w - - +solution f5 +id "ECM.600" +go +setboard 8/p5k1/2p2p2/4p1p1/1p2P3/1P4PP/1PP5/5K2 b - - +solution g4 +id "ECM.601" +go +setboard 8/8/4b1p1/2Bp3p/5P1P/1pK1Pk2/8/8 b - - +solution g5 +id "ECM.605" +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +solution Bxg6 +id "ECM.607" +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +solution Rxc6 +id "ECM.608" +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +solution f6 +id "ECM.609" +go +setboard 2kr3r/ppp1qpp1/2p5/2b2b2/2P1pPP1/1P2P1p1/PBQPB3/RN2K1R1 b Q - +solution Rh1 +id "ECM.610" +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +solution e5 +id "ECM.613" +go +setboard 5r2/pp1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +id "ECM.614" +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +solution b5 +id "ECM.615" +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +solution Rxa6 +id "ECM.616" +go +setboard 3r2k1/p6p/b2r2p1/2qPQp2/2P2P2/8/6BP/R4R1K w - - +solution Rxa6 +id "ECM.617" +go +setboard 6B1/2p2pp1/2p5/p3K3/1k6/nP4P1/5P1P/8 b - - +solution Nc4+ +id "ECM.621" +go +setboard 6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - +solution Rc4 +id "ECM.623" +go +setboard 4r2k/3n1Qpp/1pRP1p2/p4P2/1p1P2P1/6rP/P3q1B1/6RK w - - +solution Qe6 +id "ECM.624" +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +solution Ba6 +id "ECM.626" +go +setboard 3rr1k1/pppRn1pp/4Pp2/1P5q/1QB5/4P3/P4P1P/4K1R1 w - - +solution Qxe7 +id "ECM.627" +go +setboard 8/6Bp/6p1/2k1p3/4PPP1/1pb4P/8/2K5 b - - +solution b2+ +id "ECM.629" +go +setboard 3qr1k1/p4ppp/1p1P4/2r1nN2/4P2n/P7/1B4P1/3QRRK1 w - - +solution d7 +id "ECM.632" +go +setboard 4r3/p4pk1/6p1/P1pB2Pp/2P3b1/2p1N1P1/Qb1r1P2/6K1 b - - +solution Rxe3 +id "ECM.634" +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +solution Nxa7 +id "ECM.635" +go +setboard r4rk1/ppq3pp/2p1Pn2/4p1Q1/8/2N5/PP4PP/2KR1R2 w - - +solution Rxf6 +id "ECM.636" +go +setboard r3qr1k/1b4pp/p2RQ3/Bp2p3/4p3/6P1/PPP2P1P/3R2K1 b - - +solution Qh5 +id "ECM.637" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "ECM.640" +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +solution f5 +id "ECM.644" +go +setboard 8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - +solution Bxb3 +id "ECM.646" +go +setboard 4r2k/p2qr1pp/1pp2p2/2p1nP1N/4R3/1P1P2RP/1PP2QP1/7K w - - +solution Rxg7 +id "ECM.648" +go +setboard 8/1R2P3/6k1/3B4/2P2P2/1p2r3/1Kb4p/8 w - - +solution Be6 +id "ECM.650" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Bb5 +id "ECM.653" +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +solution Bxh7+ +id "ECM.654" +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +solution Rxh7 +id "ECM.663" +go +setboard r1b2rk1/2q1bppp/p1n1p3/1p1np1P1/5P2/1NNBBQ2/PPP4P/R4RK1 w - - +solution Bxh7+ +id "ECM.665" +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +solution Nxh7 +id "ECM.666" +go +setboard 2rqr1k1/1p1bbppp/p3p3/n7/3P2Q1/2PB1N2/P4PPP/R1B1R1K1 w - - +solution Bxh7+ +id "ECM.673" +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +solution Nxh7 +id "ECM.674" +go +setboard rn1q1rk1/pb1p1ppp/4p3/2pnP3/1bp5/2N2N2/PP3PPP/RBBQK2R w KQ - +solution Bxh7+ +id "ECM.675" +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +solution Rxh7 +id "ECM.676" +go +setboard r1b2rk1/1pq2ppp/p1p1p3/2n1P3/2N2P2/3B4/PPP3PP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.677" +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +solution Nxh7 +id "ECM.679" +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +solution Bxh7+ +id "ECM.680" +go +setboard 1r2nrkb/2n2p1p/p2p1Pp1/P1pPp1P1/1pP1P1q1/1P1BB1N1/3Q4/2KR3R w - - +solution Rxh7 +id "ECM.681" +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +solution Bxh7+ +id "ECM.682" +go +setboard r2q3r/2pkb1p1/p2p1n2/4p1p1/Pp2P1P1/1QP5/1P1P2PP/RNB2RK1 b - - +solution Rxh2 +id "ECM.683" +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +solution Nxh7 +id "ECM.684" +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +solution Rxh7 +id "ECM.685" +go +setboard r2qn1k1/pb4Pp/1pn5/2p5/2P2p2/P1PB4/5PPP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.686" +go +setboard r4rk1/pp1n1ppp/3qp3/3nN1P1/b2P4/P2B1Q2/3B1P1P/1R2R1K1 w - - +solution Bxh7+ +id "ECM.687" +go +setboard r2r2k1/ppqbbppp/4pn2/6N1/n1P4P/3B1N2/PP2QPP1/1KBR3R w - - +solution Nxh7 +id "ECM.688" +go +setboard r6r/4ppk1/p2p1bp1/B2p4/3P2p1/QP2P3/P1R1qPPP/2R3K1 b - - +solution Rxh2 +id "ECM.690" +go +setboard 4nrk1/r4p1p/p2p2pQ/2pPpNPP/qpn1P3/5P1R/PPP1N3/2K3R1 w - - +solution Qxh7+ +id "ECM.691" +go +setboard r3k2r/1b1n1p2/pq1p1bp1/1p4p1/P3P3/1NN5/1PP3PP/R2QRB1K b kq - +solution Rxh2+ +id "ECM.692" +go +setboard r2qrnk1/4bppp/b1p5/1p1p2P1/p2P1N1P/2NBP3/PPQ2P2/2K3RR w - - +solution Bxh7+ +id "ECM.693" +go +setboard 3r1rk1/4qp1p/p1bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxh2+ +id "ECM.696" +go +setboard r2q1rk1/3n1ppp/8/1pbP2P1/p1N4P/PnBBPQ2/5P2/R3K2R w KQ - +solution Bxh7+ +id "ECM.697" +go +setboard 2k3r1/ppq2p1p/n1Pb1p2/8/6r1/4BN1b/PPQ2PPP/R3RBK1 b - - +solution Bxh2+ +id "ECM.698" +go +setboard 3qr1k1/1br2ppp/p2b4/8/PpNp4/3P4/1PP2PPP/R1BQ1RK1 b - - +solution Bxh2+ +id "ECM.699" +go +setboard r1b4r/3p1kp1/pp3q1p/4RP2/8/B7/P5PP/4QRK1 w - - +solution Qe4 +id "ECM.701" +go +setboard 1r2rnk1/2R2bpp/p2q4/1p1N2R1/5P2/1Q1B3P/PP4P1/7K w - - +solution Rxg7+ +id "ECM.702" +go +setboard 2r2r1k/3b1pb1/p3pp1p/q2p1P1B/8/2N2RR1/P1PQ2PP/7K w - - +solution Rxg7 +id "ECM.706" +go +setboard r2qr1k1/1p3ppp/2pb4/2Np4/1P1P2bn/3BP3/2QN1PPP/1RR3K1 b - - +solution Nxg2 +id "ECM.712" +go +setboard r3r1k1/pp3pp1/3p4/2q4p/2P5/1PB2Q1P/n4PP1/3R1RK1 w - - +solution Bxg7 +id "ECM.713" +go +setboard r5k1/pn1q1rpp/2pp4/5R1N/bP6/4BQ2/P4PPP/2R3K1 w - - +solution Nxg7 +id "ECM.714" +go +setboard 3r1rk1/5pp1/pq1n1n1p/2pPR3/2B2P2/1PBQ2RP/P5P1/6K1 w - - +solution Rxg7+ +id "ECM.715" +go +setboard rn3rk1/ppq2ppp/2pb1nb1/5N2/2BP4/8/PPP1N1P1/R1B1QR1K w - - +solution Nxg7 +id "ECM.716" +go +setboard r1qb1r1k/2p3pp/p1n1bp2/1p1Np2Q/P3P3/1BP3R1/1P3PPP/R1B3K1 w - - +solution Rxg7 +id "ECM.717" +go +setboard r4rk1/5ppp/p2pbb2/3B3Q/qp2p3/4B3/PPP2P1P/2KR2R1 w - - +solution Rxg7+ +id "ECM.718" +go +setboard 4q1k1/1b3r1p/p4pp1/1p6/2P2n2/1P3N2/1B3PPP/R2Q3K b - - +solution Nxg2 +id "ECM.719" +go +setboard 4rrk1/2pn2pb/p1p1qp2/1pb1pN2/P3P1PN/1P1P4/1BP2PK1/R2Q3R w - - +solution Nxg7 +id "ECM.721" +go +setboard r3r1k1/p3bppp/q1b2n2/5Q2/1p1B4/1BNR4/PPP3PP/2K2R2 w - - +solution Rg3 +id "ECM.722" +go +setboard 4kbr1/pp1bpp1p/3p1p2/3N4/1PBQP3/q7/P1r2PPP/R4RK1 b - - +solution Rxg2+ +id "ECM.725" +go +setboard rq1r1bk1/1b3pp1/3pn2p/1n2BN1P/1P2P3/3R1NP1/3Q1PB1/2R3K1 w - - +solution Bxg7 +id "ECM.728" +go +setboard 3q1r2/1p1b1pk1/pn5p/3pN1pQ/3P3P/2r3B1/P4PP1/3RR1K1 w - - +solution Nxf7 +id "ECM.730" +go +setboard 2r3k1/pbq1np1p/1p1b1Bp1/8/6QP/2P2N2/B4PP1/4R1K1 w - - +solution Bxf7+ +id "ECM.733" +go +setboard r3r1k1/1bqn1ppp/1pp2p2/8/3P4/1B4N1/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.734" +go +setboard r3r1k1/pp3ppp/8/1Nbp3q/3NnBn1/2P5/PPQ2PPP/3R1RK1 b - - +solution Ngxf2 +id "ECM.735" +go +setboard r2r2k1/1b2qpp1/1p2n3/p1b1p2p/4P1n1/PP1B2PP/1B1NQP2/R3NRK1 b - - +solution Nxf2 +id "ECM.736" +go +setboard r5k1/1pp3pp/1b1p1r2/pN1P1n2/P1P3nq/6N1/1P1B1PQP/4RRK1 b - - +solution Nxf2 +id "ECM.738" +go +setboard r2qr1k1/pb2bp1p/1pn1p1pB/8/2BP4/P1P2N2/4QPPP/3R1RK1 w - - +solution d5 +id "ECM.742" +go +setboard r2qr1k1/1b1nbp1p/p3pp2/1p2N3/3P4/3B1N2/PP2QPPP/R2R2K1 w - - +solution Nxf7 +id "ECM.745" +go +setboard r3kr2/1b2qp2/pp2p2N/4p2Q/8/2n5/P3B1PP/3R1R1K w q - +solution Nxf7 +id "ECM.752" +go +setboard rqb1k2r/1p1nbp1p/p4pp1/8/1PBN1P2/P1N1P3/7P/2RQ1RK1 w kq - +solution Bxf7+ +id "ECM.754" +go +setboard r2r2k1/4ppbp/5np1/p1q5/QnB1P3/5N2/1P3PPP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.755" +go +setboard 1r4k1/p4pp1/bqnrpn1p/2ppN3/2P2P1B/P3P3/1P2B1PP/1Q1R1RK1 w - - +solution Bxf6 +id "ECM.758" +go +setboard 2rqr1k1/pp2nppp/3p2b1/6B1/2BNn1Q1/P7/1PP2PPP/2KRR3 w - - +solution Bxf7+ +id "ECM.761" +go +setboard r3r1k1/pbq1ppbp/1pp2np1/4N3/3P4/2P5/PPB1QPPP/R1B1R1K1 w - - +solution Nxf7 +id "ECM.762" +go +setboard r1b2rk1/p6p/2p3Pb/3pp1q1/8/2PB4/PP3PP1/RN1Q1K1R b - - +solution Rxf2+ +id "ECM.763" +go +setboard r2rn3/1p3pk1/p1pNn1pp/q3P3/P7/1PN4P/2QR1PP1/3R2K1 w - - +solution Nxf7 +id "ECM.764" +go +setboard r1bqr1k1/1p1nnpb1/p5pp/2P1p1B1/B3N3/5N2/P4PPP/2RQR1K1 w - - +solution Nd6 +id "ECM.765" +go +setboard r1b1r1k1/pp2qpbp/2p3p1/2P5/3NnB2/7P/PPQ1PPB1/2RR2K1 b - - +solution Nxf2 +id "ECM.766" +go +setboard rn2r1k1/pp3p1p/3P2p1/2p1bbB1/2B5/2N5/Pq4PP/R2Q1RK1 w - - +solution Bxf7+ +id "ECM.767" +go +setboard 1bq2k2/1b1n1pp1/pp5p/2pBpN2/P3P2B/3Q1P2/1PP3PP/4K3 w - - +solution Bxf7 +id "ECM.769" +go +setboard rnb2rk1/pp3pbp/2p3pB/2q5/4P3/1BN5/PPP3PP/R2Q1R1K w - - +solution Rxf7 +id "ECM.770" +go +setboard 3qr1k1/1br1bp1p/p3p1pB/1p1nN3/3PB3/7Q/PP3PPP/3RR1K1 w - - +solution Nxf7 +id "ECM.771" +go +setboard rr1q2k1/1p2bpp1/2p1p2p/P1Pn4/2NP4/3Q1RP1/5PKP/2B1R3 w - - +solution Bxh6 +id "ECM.773" +go +setboard r2r2k1/pb1nbpp1/1qp1pn1p/1p2N3/3P1B2/P1N1P3/BPQ2PPP/2R2RK1 w - - +solution Bxh6 +id "ECM.774" +go +setboard r1b1r3/pp2Npbk/3pp2p/q5p1/2QNPP2/6P1/PPP3P1/2KR3R w - - +solution Ndf5 +id "ECM.776" +go +setboard 1rbqnr2/5p1k/p1np3p/1p1Np3/4P2P/1Q2B3/PPP1BP2/2KR3R w - - +solution Bxh6 +id "ECM.779" +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.780" +go +setboard 3r1r1k/p5p1/n1p2p1p/1qp2b2/N1R4R/1PB1P1P1/P2P3P/3Q2K1 w - - +solution Rxh6+ +id "ECM.781" +go +setboard 6rk/3b1n1p/1p1q3b/1PpNp3/2P1Pp2/2Q2NrP/5RP1/2R2B1K b - - +solution Bxh3 +id "ECM.783" +go +setboard 2r1r1k1/pb1n1pp1/1p1qpn1p/4N1B1/2PP4/3B4/P2Q1PPP/3RR1K1 w - - +solution Bxh6 +id "ECM.789" +go +setboard 2br2k1/4qppp/p5r1/2pBp3/2P1Pn2/4Q2P/RP3PPK/1N4R1 b - - +solution Bxh3 +id "ECM.791" +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +solution Bxh6 +id "ECM.792" +go +setboard 6k1/p4ppp/1pn1b1rr/8/PBpPp2q/2P1P1NP/5PP1/RR3QK1 b - - +solution Bxh3 +id "ECM.795" +go +setboard r1b2rk1/1p3pp1/p5Pp/2bpPp1Q/3N4/1Pq1B1R1/2P4P/3R2K1 w - - +solution Bxh6 +id "ECM.796" +go +setboard 2b1rk2/r6p/1pP1p1p1/p2pNnR1/5Q2/P1B4q/1PP2P1P/1K4R1 w - - +solution Nxg6+ +id "ECM.799" +go +setboard r6r/ppnqpk2/3pbpp1/5N2/1PP1P3/5RR1/P2QB1PP/6K1 w - - +solution Nh6+ +id "ECM.801" +go +setboard 2b2r1k/2p3pp/2Nb4/pP5q/2PP4/P4pP1/5P1P/R1BQ2K1 b - - +solution Bxg3 +id "ECM.803" +go +setboard r1bq2k1/pp3r1p/2n1p1p1/3pP3/6Q1/2PB2P1/P4PK1/R1B4R w - - +solution Bxg6 +id "ECM.804" +go +setboard 3q1rk1/2r4p/n1p1n1pQ/p2pP3/Np1P2R1/5PN1/PP3KP1/2R5 w - - +solution Rxg6+ +id "ECM.805" +go +setboard 2rqr1k1/pb2bp1p/1pn1pnpB/4N3/3P4/P1N3R1/1P3PPP/RB1Q2K1 w - - +solution Rxg6+ +id "ECM.810" +go +setboard 2r5/pp2qr1k/1nb3pp/2ppBp2/2P4P/3B2R1/P3QPP1/1R4K1 w - - +solution Rxg6 +id "ECM.811" +go +setboard 3rr3/3q1p1k/p2P2pp/1bp1b3/5N2/6QP/P1B3P1/3RR1K1 w - - +solution Bxg6+ +id "ECM.812" +go +setboard 1n1b1rk1/r4p1p/p1p2qpQ/P3Np2/2BP4/2P1R3/5PPP/R5K1 w - - +solution Rb1 +id "ECM.814" +go +setboard 6rk/pb3p1p/3bpPq1/3P4/1p1B3r/1B4P1/PPRQ1R1P/6K1 b - - +solution Bxg3 +id "ECM.815" +go +setboard 3rr1k1/pb2bp1p/3qp1pB/1p2N3/3P2Q1/2P1R3/P4PPP/4R1K1 w - - +solution Nxg6 +id "ECM.816" +go +setboard 1Q4R1/r2qbp2/3p1kp1/3Bp2p/8/3PP1P1/5PKP/8 w - - +solution Rxg6+ +id "ECM.818" +go +setboard k2r3r/ppq2p1p/n1pb1Pp1/4p3/2Q5/1R2B1P1/PPP2PBP/R5K1 w - - +solution Rxb7 +id "ECM.821" +go +setboard 1rb2rk1/p1p1qppp/2p2n2/3P4/1b3P2/2NB4/PPPBQ1PP/2KR3R b - - +solution Ba3 +id "ECM.822" +go +setboard 4rrk1/p5pp/1p4q1/3p2n1/2pP2P1/P1P1PP2/3B2K1/1R2QR2 b - - +solution Nxf3 +id "ECM.824" +go +setboard 1q1r3k/3P1pp1/ppBR1n1p/4Q2P/P4P2/8/5PK1/8 w - - +solution Rxf6 +id "ECM.825" +go +setboard 1rbq2k1/b1p3pp/p1Pp4/3Ppr2/8/5N2/PPQ2PPP/R1B2RK1 b - - +solution Rxf3 +id "ECM.826" +go +setboard 1r1q1r1k/2p3pp/1p1bQ3/p7/1PP5/Pn3B2/1B3PPP/R4RK1 b - - +solution Rxf3 +id "ECM.827" +go +setboard r1bq1rk1/1p2bppp/p3p3/n3P3/4N3/1P1P1N2/PB4PP/R3QR1K w - - +solution Nf6+ +id "ECM.829" +go +setboard 1n2r3/p1pq1kp1/1b1pNpp1/3P4/5RP1/3Q3P/1B3P2/6K1 w - - +solution Bxf6 +id "ECM.830" +go +setboard r1bq1rk1/ppp3p1/7p/3P2n1/2PQ1p2/1N5P/PPP2PPK/R1B2R2 b - - +solution Nf3+ +id "ECM.831" +go +setboard 3r1b2/p4bkp/1p1P1p2/r3p1p1/2q1N3/2N2P2/1P1R2PP/2QR3K w - - +solution Nxf6 +id "ECM.832" +go +setboard rqbn1rk1/1p3ppp/p3p3/8/4NP2/8/PPP1BQPP/1K1R3R w - - +solution Nf6+ +id "ECM.833" +go +setboard r1b1kb1r/1p4pp/p2ppn2/8/2qNP3/2N1B3/PPP3PP/R2Q1RK1 w kq - +solution Rxf6 +id "ECM.834" +go +setboard 2nr2k1/1pq1bppp/p1p5/2p1P1PQ/2P1NP2/1PNR4/P6P/6K1 w - - +solution Nf6+ +id "ECM.836" +go +setboard 6nk/pn2qr1r/1pbp1p1p/2p1pPpN/P1P1P1PP/2PP3R/7Q/2BBK2R w K - +solution Nxf6 +id "ECM.837" +go +setboard r1b1kb1r/1p1n1ppp/p2ppn2/6BB/2qNP3/2N5/PPP2PPP/R2Q1RK1 w kq - +solution Nxe6 +id "ECM.841" +go +setboard r1b1k1nr/3n1p1p/1qpBp1p1/pp2b3/4PN2/PBN2Q2/1PP2PPP/2KR3R w kq - +solution Nxe6 +id "ECM.842" +go +setboard 2r2rk1/1b3ppp/pq2p3/1pbn2N1/3B3P/1B4P1/P1P1QP2/2KRR3 w - - +solution Qh5 +id "ECM.843" +go +setboard r3k2r/pp1n1pb1/1qn1p1p1/2p3Pp/4R2P/2NP2QB/PPPB1P2/2K1R3 w kq - +solution Rxe6+ +id "ECM.844" +go +setboard r3k2r/1q3ppp/p3p3/2b1P3/p2N1Q2/P7/1PP3PP/3R1R1K w kq - +solution Nxe6 +id "ECM.845" +go +setboard 3qr1k1/rp3pbp/2p3p1/3p1b2/N1nP4/P2NP3/1PQ2PPP/1BRR2K1 b - - +solution Rxe3 +id "ECM.846" +go +setboard 1r3rk1/5pbp/p2Pp1p1/q1n3P1/2p2P1P/2N1Q2R/PP6/1BKR4 b - - +solution Rxb2 +id "ECM.852" +go +setboard rr4k1/5p1p/n2p1npQ/q1pP4/6P1/2N2P1N/PP1R3P/2K4R b - - +solution Rxb2 +id "ECM.853" +go +setboard 1k2bb1r/1p3p1p/p2qpP1p/3pN3/3P1Q2/2RB2P1/PP3P1P/6K1 w - - +solution Qc1 +id "ECM.854" +go +setboard 5rk1/5rp1/p2qb3/R2Np2Q/3bP2B/7P/P5PK/1R6 b - - +solution Rf1 +id "ECM.856" +go +setboard 3r1rk1/p3q1pp/2Rb4/3P4/8/1P2Qp2/PB3PPP/3R2K1 b - - +solution Bxh2+ +id "ECM.858" +go +setboard 1r4k1/1q3pb1/r1b3p1/pp1Qp3/P3P3/1B2BP2/1PP3P1/1K1R3R w - - +solution Qd8+ +id "ECM.860" +go +setboard 3r4/kb6/pp6/4R1pr/PPpq4/2N3Q1/2P3PP/3R3K b - - +solution Rf8 +id "ECM.862" +go +setboard 8/2q1np1k/6p1/1PPn3p/8/P2Q3P/6P1/2R4K b - - +solution Nf5 +id "ECM.864" +go +setboard 7R/1p1r4/2b2p2/2Pp1qk1/3P1bp1/3N4/2Q2PB1/6K1 w - - +solution Rg8+ +id "ECM.866" +go +setboard r6r/1pn1b1k1/2p1pq2/2Pp3p/p2P1Pp1/P2BP1P1/1P2QB2/3R2KR w - - +solution Rxh5 +id "ECM.867" +go +setboard 1r4k1/pp4pp/2n1b3/1Rq1p3/2P2r2/P1B2P2/2Q1B1PP/3R1K2 b - - +solution Rxf3+ +id "ECM.868" +go +setboard 2rq1rk1/5ppp/2b1pb2/np6/6N1/2NBB3/PP3PPP/R2Q2K1 w - - +solution Bb6 +id "ECM.872" +go +setboard 5r2/p2p2kp/3PnNp1/1qr1Pp2/2p5/P1R5/6PP/2Q1R1K1 w - - +solution Qh6+ +id "ECM.873" +go +setboard 2kr1br1/ppp2p1p/2n1p1q1/2Nn4/3P4/1Q2PB2/PP1B1P1P/2R1K2R b K - +solution Qg1+ +id "ECM.875" +go +setboard 2kr3r/1Rp1bpp1/p6q/Q3P3/2P5/3p1NP1/P3P2P/1R4K1 b - - +solution Qe3+ +id "ECM.877" +go +setboard 6k1/1R4pp/2p5/8/P1rNp3/6Pb/4PK2/8 w - - +solution a5 +id "ECM.878" +go +setboard r2r2k1/pp3ppp/2q5/2p5/2P1P1n1/P4P1b/1BQ1BP1P/R3R2K b - - +solution Rd2 +id "ECM.879" +go \ No newline at end of file diff --git a/tests/ecm.ep_ b/tests/ecm.ep_ new file mode 100644 index 0000000..e61f615 --- /dev/null +++ b/tests/ecm.ep_ @@ -0,0 +1,3518 @@ +setboard 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - +solution f7+ +id "ECM.001" +go +setboard 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - +solution Bxf3+ +id "ECM.002" +go +setboard 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - +solution Qb5 +id "ECM.003" +go +setboard 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - +solution Rcxc5 +id "ECM.004" +go +setboard 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - +solution Bxf2+ +id "ECM.005" +go +setboard 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - +solution Bxf6+ +id "ECM.006" +go +setboard 3rr1k1/pb3pp1/1p1q1b1p/1P2NQ2/3P4/P1NB4/3K1P1P/2R3R1 w - - +solution Rxg7+ +id "ECM.007" +go +setboard r1b1r1k1/p1p3pp/2p2n2/2bp4/5P2/3BBQPq/PPPK3P/R4N1R b - - +solution Bg4 +id "ECM.008" +go +setboard 3r4/1b2k3/1pq1pp2/p3n1pr/2P5/5PPN/PP1N1QP1/R2R2K1 b - - +solution Rxh3 +id "ECM.009" +go +setboard 2r4k/pB4bp/6p1/6q1/1P1n4/2N5/P4PPP/2R1Q1K1 b - - +solution Qxc1 +id "ECM.010" +go +setboard 1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - +solution Nxg4 +id "ECM.011" +go +setboard 5rk1/7p/p1N5/3pNp2/2bPnqpQ/P7/1P3PPP/4R1K1 w - - +solution Ne7+ +id "ECM.012" +go +setboard rnb2rk1/pp2np1p/2p2q1b/8/2BPPN2/2P2Q2/PP4PP/R1B2RK1 w - - +solution Nd5 +id "ECM.013" +go +setboard 2k4r/1pp2ppp/p1p1bn2/4N3/1q1rP3/2N1Q3/PPP2PPP/R4RK1 w - - +solution Nd5 +id "ECM.014" +go +setboard r3kb1r/pp2pppp/3q4/3Pn3/6b1/2N1BN2/PP3PPP/R2QKB1R w KQkq - +solution Nxe5 +id "ECM.015" +go +setboard 2rr2k1/1b3p1p/p4qpb/2R1n3/3p4/BP2P3/P3QPPP/3R1BKN b - - +solution Rxc5 +id "ECM.016" +go +setboard r1b1k3/5p1p/p1p5/3np3/1b2N3/4B3/PPP1BPrP/2KR3R w q - +solution Rxd5 +id "ECM.017" +go +setboard r3rbk1/1pq2ppp/2ppbnn1/p3p3/P1PPN3/BP1BPN1P/2Q2PP1/R2R2K1 w - - +solution Nxd6 +id "ECM.018" +go +setboard b7/2q2kp1/p3pbr1/1pPpP2Q/1P1N3P/6P1/P7/5RK1 w - - +solution Rxf6+ +id "ECM.019" +go +setboard 1rr1nbk1/5ppp/3p4/1q1PpN2/np2P3/5Q1P/P1BB1PP1/2R1R1K1 w - - +solution Bxa4 +id "ECM.020" +go +setboard r7/5kp1/2p1p2p/1p1n3P/2rP4/2P3R1/PK2RPP1/2B5 b - - +solution Rxc3 +id "ECM.021" +go +setboard r1r3k1/p3qpp1/b1P4p/3p4/3Nn3/4P3/P1Q2PPP/1BR1K2R b K - +solution Qb4+ +id "ECM.022" +go +setboard rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - +solution Bxd5 +id "ECM.023" +go +setboard 6rk/1p1br2p/pqp5/3pNP2/3Pp3/P5PR/5PKR/Q7 w - - +solution Rxh7+ +id "ECM.024" +go +setboard 2b3k1/5p1p/7b/p2B3p/3P4/P2Q1N1P/1q3PP1/6K1 w - - +solution Bxf7+ +id "ECM.025" +go +setboard r1b5/4k3/p7/3p1n2/3Bp3/2P2r1P/PPBK1P2/4R2R w - - +solution Bc5+ +id "ECM.026" +go +setboard r4rk1/1b3Npp/p7/1p3Q2/3P4/1B2q3/P5PP/3n1R1K b - - +solution Bxg2+ +id "ECM.027" +go +setboard r1b2rk1/2q2ppp/2pbp3/p7/4Nn2/3B4/PPPBQ1PP/R4R1K w - - +solution Rxf4 +id "ECM.028" +go +setboard 3r2k1/1q1P1ppp/r2R2n1/p4Q2/1ppB2R1/6P1/PP3PP1/6K1 w - - +solution Rgxg6 +id "ECM.029" +go +setboard r2q1rk1/p3b1pp/2p5/1pn5/1n1Bp1b1/1P6/PQ1PPP2/2RNKBNR b K - +solution Bxe2 +id "ECM.030" +go +setboard 3r2k1/p2r1p1p/1p2p1p1/q4n2/3P4/PQ1R3P/1P2NPP1/3R2K1 b - - +solution Nxd4 +id "ECM.031" +go +setboard 2bnr1k1/2q2ppp/p7/2p1b3/2N1B3/R7/1P2QPPP/2B3K1 w - - +solution Nxe5 +id "ECM.032" +go +setboard r1b2r1k/3nN2p/p2Q1p2/8/4PP2/1R6/q1PK2PP/4R3 w - - +solution Qd5 +id "ECM.033" +go +setboard 1nk1r1r1/pp2n1pp/4p3/q2pPp1N/b1pP1P2/B1P2R2/2P1B1PP/R2Q2K1 w - - +solution Nf6 +id "ECM.034" +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +solution Rxc8 +id "ECM.035" +go +setboard br1r2k1/1q4p1/p2ppb1p/2p2p2/2P1n3/Pn2P2P/QPR2PPB/2NRNBK1 b - - +solution Nxc1 +id "ECM.036" +go +setboard 2k4r/ppp1n1p1/2n2qb1/2N5/Q1P3p1/P2r3P/1P3PB1/R1B2RK1 w - - +solution Qb5 +id "ECM.037" +go +setboard 8/6bk/1B1R4/6p1/2bNP3/4KP2/1r6/8 b - - +solution Be5 +id "ECM.038" +go +setboard r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - +solution Rxa1 +id "ECM.039" +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +solution Nxc6 +id "ECM.040" +go +setboard 5rk1/1b3ppp/p3p3/1p1q2N1/4n3/6P1/PP2PPBP/2Q2RK1 b - - +solution Nxg3 +id "ECM.041" +go +setboard 2kr3r/pppq2p1/1bn1R3/6N1/1P6/1QN1B1p1/P4PP1/R5K1 b - - +solution gxf2+ +id "ECM.042" +go +setboard 2rr4/5pk1/p1q3p1/3bpP1p/1p4nR/1N4Q1/PPP3PP/3NR2K b - - +solution Bxg2+ +id "ECM.043" +go +setboard r4rk1/pp4pp/2nqb3/3p4/8/2NB4/PP1Q1PPP/4RRK1 w - - +solution Bxh7+ +id "ECM.044" +go +setboard 3rk1r1/3b1p1p/p2BpQ2/8/2q5/2P5/PP3PPP/3R2K1 b - - +solution Rxg2+ +id "ECM.045" +go +setboard 3r1rk1/4pp1p/p1Q1b1p1/3N4/3b4/5B2/Pq3PPP/R4RK1 b - - +solution Bxd5 +id "ECM.046" +go +setboard 5bk1/1bqn1r1p/p3Q1p1/4p3/1PN1Pp2/P1N4P/5PP1/R1BR2K1 w - - +solution Qxf7+ +id "ECM.047" +go +setboard 3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - +solution d3 +id "ECM.048" +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +solution Qxf7+ +id "ECM.049" +go +setboard 2kr1b1R/1b3pp1/p2pp3/1pq3P1/2nQPP2/P1N5/1PP1BB2/1K6 w - - +solution Rxf8 +id "ECM.050" +go +setboard 1k1r1b1r/p1p1q3/2p1p3/4Ppp1/4nP2/P2BQ3/1PP3PB/2KR3R b - - +solution Rxh2 +id "ECM.051" +go +setboard r3nb1Q/p1q2kr1/2p3p1/2ppnpP1/1P3N2/4P3/PB1P4/1R2KB1R w K - +solution Qxf8+ +id "ECM.052" +go +setboard r1bq1rk1/pp3pbp/2pp1np1/2n3B1/2PNP3/2N2P2/PP1QB1PP/R4RK1 b - - +solution Nfxe4 +id "ECM.053" +go +setboard 1rb1qn2/1p2nrbk/p2p2p1/P2Pp1Pp/NP2P2P/2RNB3/2QKB3/1R6 w - - +solution Ba7 +id "ECM.054" +go +setboard 5r2/1b2k2p/3bp3/5PP1/Bn1Q3P/1N6/1Pr5/1K3R2 b - - +solution Rxb2+ +id "ECM.055" +go +setboard r1b1r1k1/pp4bp/5np1/2qPB3/8/6NP/PPP1Q1B1/R4R1K w - - +solution Rxf6 +id "ECM.056" +go +setboard r1b2r1k/1pq3bp/8/3Qp2n/1P1n1pp1/2NP2P1/3BPPBP/1R2NRK1 b - - +solution Qxc3 +id "ECM.057" +go +setboard 4qk2/pp3pp1/1nbr3p/2p5/5N2/2P1Q3/PPB2PPP/2K1R3 w - - +solution Ng6+ +id "ECM.058" +go +setboard 3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - +solution Rd5 +id "ECM.059" +go +setboard r4rk1/pp1b2pp/3bpq2/3p1p2/2PPn3/PP1B4/1BQN1PPP/R4RK1 b - - +solution Bxh2+ +id "ECM.060" +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +solution Nxf7 +id "ECM.061" +go +setboard 2rq1r2/pp3pnk/2n1b1pp/3pQ3/3P1N2/P1N5/1P3PPP/1BR2RK1 w - - +solution Bxg6+ +id "ECM.062" +go +setboard 4nk2/r1r1bppp/pN2p3/2np4/8/BPN3PP/P3PPK1/2RR4 w - - +solution Ncxd5 +id "ECM.063" +go +setboard r4r1k/2pqn1b1/p1bp2pp/1p2pn2/4N3/2PP1PPQ/PPB4P/R1B1RNK1 b - - +solution Nd4 +id "ECM.064" +go +setboard r1bQ1nk1/bp3ppp/p7/3B4/1P6/P3P1P1/2P4P/q1B2RK1 b - - +solution Bxe3+ +id "ECM.065" +go +setboard 3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - +solution Rxd4 +id "ECM.066" +go +setboard 2nq2k1/2r3pp/p1p1rp2/PpQ1N3/1P1PR3/8/5PPP/2R3K1 w - - +solution Nf7 +id "ECM.067" +go +setboard r1b2rk1/1p2bppp/p3pn2/4B3/1qBR4/2N5/P3QPPP/R5K1 w - - +solution Bd3 +id "ECM.068" +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +solution g6 +id "ECM.069" +go +setboard 5r1k/p6p/1p1p1qp1/2pQpr2/8/2PP2P1/PP2RPKP/5R2 b - - +solution e4 +id "ECM.070" +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +solution Qh6 +id "ECM.071" +go +setboard 2r2rk1/5pbp/p5p1/3P2q1/1QbN4/5P2/P4BPP/2RR2K1 b - - +solution Bf1 +id "ECM.072" +go +setboard r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - +solution Nh7 +id "ECM.073" +go +setboard 3nk3/3q1p2/1B3pr1/4p3/bP2P2p/r2B4/2Q2RPP/3R2K1 w - - +solution Bb5 +id "ECM.074" +go +setboard 3rnr1k/pp3ppp/4b3/2p1qNP1/P2pPR2/1P1P2Q1/2P3BP/5RK1 w - - +solution Nh6 +id "ECM.075" +go +setboard r1b2kr1/1p1p1pNp/p1n1p1p1/5P2/3QP3/2N5/PqP1B1PP/R4RK1 w - - +solution fxg6 +id "ECM.076" +go +setboard 5rk1/3r1p1p/3b2pQ/8/4q3/4B2P/3R1PP1/4R1K1 w - - +solution Rxd6 +id "ECM.077" +go +setboard 4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - +solution Nxc5 +id "ECM.078" +go +setboard 2rnrbnk/3q1ppp/p1p5/3p1P2/1p1PPN2/4BQ1R/PP1N2PP/3R2K1 w - - +solution Ng6+ +id "ECM.079" +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +solution Rd4 +id "ECM.080" +go +setboard Q7/p1r1ppk1/1qP4p/2Rb2p1/8/3N2P1/4PP1P/6K1 b - - +solution Qb1+ +id "ECM.081" +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +solution exf6 +id "ECM.082" +go +setboard r2qr1k1/pp3pbp/3p1np1/2pP1bB1/2P1N3/3Q1PN1/PP4PP/R4RK1 b - - +solution Nxe4 +id "ECM.083" +go +setboard 4r1k1/1b4pp/p7/1prP3q/2P1B3/5P2/P3Q2P/3RR2K w - - +solution Bg6 +id "ECM.084" +go +setboard r1br2k1/ppb1qpp1/2P4p/2n1p3/4B3/P1N2N2/1P3PPP/2RQ1RK1 w - - +solution Nd5 +id "ECM.085" +go +setboard 2r3k1/1nqbrp2/p5pp/1p1Pp1N1/8/1P5P/P1B2PP1/2RQR1K1 w - - +solution Nxf7 +id "ECM.086" +go +setboard 2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - +solution Nh6+ +id "ECM.087" +go +setboard r1b1rk2/3n1pbQ/2qp2p1/p2N2P1/2Bp3N/4P3/PP3PP1/2KR3R w - - +solution Nxg6+ +id "ECM.088" +go +setboard r1r2qkb/4pp1p/pBbp3P/3Nn1P1/4Q3/1B6/PPP5/1K1R2R1 w - - +solution g6 +id "ECM.089" +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +solution Re7 +id "ECM.090" +go +setboard rn1q1r2/4bpk1/p3p3/1pN1N1np/2pP4/4PpBb/PPQ4P/1B1RK1R1 w - - +solution Nc6 +id "ECM.091" +go +setboard 5rk1/6pp/8/2Q4q/N2pP3/4b1Pb/4PP1K/1R3R2 b - - +solution Bxf1+ +id "ECM.092" +go +setboard 2r4k/pp2Q1pp/5r2/P2P4/3Pb1P1/4Ppq1/1P1R3N/3R3K b - - +solution Qe1+ +id "ECM.093" +go +setboard 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - +solution Qxh7+ +id "ECM.094" +go +setboard r1b4k/p2n1Bpp/1p1Q1n2/5p2/3P4/P3BqP1/1P3P1P/R4RK1 b - - +solution Bb7 +id "ECM.095" +go +setboard rn1r2k1/p4ppp/2p3b1/3PQ3/1B2Np1q/1B3P2/P1P3PP/4R1K1 w - - +solution Nf6+ +solution Qe8+ +id "ECM.096" +go +setboard 4r2k/5R1p/pp1Bq1pN/2p1P3/1n1b3Q/3P4/1P4KP/8 w - - +solution Rxh7+ +id "ECM.097" +go +setboard r2nk1r1/pb3q1p/4p3/3p2pQ/8/BP6/P4PPP/2R1R1K1 w q - +solution Rc7 +id "ECM.098" +go +setboard 6k1/1pqb1p2/5bpB/r2n4/4N1P1/1P3P2/1P1Q4/1K5R w - - +solution Qxd5 +id "ECM.099" +go +setboard rr4k1/2p1ppb1/3pbnpp/q1pP4/4P3/1PNNBP1P/P1KR2P1/2Q4R b - - +solution Qxc3+ +id "ECM.100" +go +setboard 1r3rk1/3Q2pp/p3p3/6B1/3np3/6R1/PqP1B2P/3K2R1 w - - +solution Qxg7+ +id "ECM.101" +go +setboard 2r5/p4Q2/k1bBp3/4P3/p1nq4/5B2/2Pr2P1/1R1RK3 w - - +solution Qb7+ +id "ECM.102" +go +setboard 5rk1/p1pb2pp/2p5/3p3q/2P3n1/1Q4BN/PP1Np1KP/R3R3 b - - +solution Qxh3+ +id "ECM.103" +go +setboard 2r1nk2/4qpbQ/4b3/1p2RpP1/4P3/p7/PBP5/1K5R w - - +solution Qxg7+ +id "ECM.104" +go +setboard 2kr4/1bpr3p/4R3/1pQ5/8/6B1/3q2PP/2R4K w - - +solution Qxc7+ +id "ECM.105" +go +setboard r4rk1/1pbb2pp/p1p1p2q/2Pp4/1P1Pn3/P3B2P/2Q1BPP1/R4RNK b - - +solution Qxe3 +id "ECM.106" +go +setboard r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - +solution Qxf5+ +id "ECM.107" +go +setboard 6r1/p4rkp/3RQ1n1/1pp1p1B1/2p1P3/2P3R1/P4qPK/8 w - - +solution Qxe5+ +id "ECM.108" +go +setboard 2kr1r2/1pp3pp/1n2p1b1/pN2B3/P1q5/1Q1p3P/5PP1/R4R1K w - - +solution Rac1 +id "ECM.109" +go +setboard 2kr1bnr/1ppq4/p3bp2/6pp/4p3/2N2NBP/PP3PP1/2RQ1RK1 w - - +solution Na4 +id "ECM.110" +go +setboard r2q2rk/p3bp1p/4b1p1/3pP2R/1p1B4/3BQ3/PPP3PP/5R1K w - - +solution Rxf7 +id "ECM.111" +go +setboard r1b1Q3/6pk/p6p/1pq1n3/4N3/8/PPP3PP/R6K b - - +solution Qc6 +id "ECM.112" +go +setboard q6r/pp3pkp/5np1/4Q3/4P3/6N1/P4PPP/5RK1 w - - +solution Nh5+ +id "ECM.113" +go +setboard r1b1rk2/pp3ppQ/1np5/4q3/2B4N/4P3/PP3PP1/2R2K1R w - - +solution Qg8+ +id "ECM.114" +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +solution Nxh7 +id "ECM.115" +go +setboard r3r1k1/p2N1pp1/1pn1p3/q1n5/2PQ4/P3B3/4PPKP/R5R1 w - - +solution Nf6+ +id "ECM.116" +go +setboard 4qbk1/1R5n/p2pr1p1/2pQpNPp/P1P1P3/2P2P2/3B4/5K2 w - - +solution Ne7+ +id "ECM.117" +go +setboard 3qr1k1/1p1bppbp/p2p2p1/2rPn3/P2N4/4BP2/1PPQ2PP/R2R1BK1 w - - +solution Ne6 +id "ECM.118" +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +solution Rxf6 +id "ECM.119" +go +setboard 8/R5p1/6k1/pr2p1b1/4K3/7P/5P2/6R1 w - - +solution h4 +id "ECM.120" +go +setboard 5rk1/1b1r1p2/p1q1pQp1/1p2P2p/8/1BP1NR2/PP1n2PP/5R1K w - - +solution Bxe6 +id "ECM.121" +go +setboard 6k1/p1p2r2/1p1p1P1Q/3P4/2P5/5qr1/PP4RP/6RK w - - +solution Qh3 +id "ECM.122" +go +setboard 2b1rr1k/1p5p/1Ppp2q1/p3bN2/2P1n3/5R2/PBQ3BP/3R2K1 w - - +solution Nxd6 +id "ECM.123" +go +setboard 3b2rk/7p/p7/2pbqNrn/Pp1p1R2/1P1Q2P1/1BPN1R1P/6K1 w - - +solution Rxd4 +id "ECM.124" +go +setboard 1rbr2k1/1pq1bp1p/p1pNn1p1/2n1p3/2B1P2P/1NQ1BP2/PP4P1/1K1R3R w - - +solution Nxf7 +id "ECM.125" +go +setboard r4rk1/1pp1b1pp/p1q5/3pPp2/3Pn3/P3N3/1P3PPP/R1BQR1K1 w - - +solution Qb3 +id "ECM.126" +go +setboard rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - +solution Nf6+ +id "ECM.127" +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +solution Nxh5 +id "ECM.128" +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +solution Re6 +id "ECM.129" +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +solution Rxe7 +id "ECM.130" +go +setboard 2rq1rk1/pp2bppp/1npp1n2/3PpN1b/2P5/2N3PP/PP2PPB1/R1BQ1RK1 w - - +solution c5 +id "ECM.131" +go +setboard rnbq1rk1/pp2b1pp/5n2/2pPp3/2P1N3/3B1N2/PP4PP/R1BQK2R w KQ - +solution d6 +id "ECM.132" +go +setboard 2n1rbk1/5pp1/7p/qP1pp3/4b1Q1/1B5P/1P1N1PP1/2B1R1K1 w - - +solution Rxe4 +id "ECM.133" +go +setboard 4k3/2R2p2/5p1p/8/rb6/1N6/5PPP/5K2 w - - +solution Rc4 +id "ECM.134" +go +setboard 2k3r1/pp2rp2/1np5/2Np1p2/P2P3p/1R2P1Pq/2Q2P1P/1R4K1 w - - +solution Nxb7 +id "ECM.135" +go +setboard 2r1k3/p3nrR1/1p1p4/2p1p1p1/2P1B3/2PP1P2/P5K1/7R w - - +solution Rh8+ +id "ECM.136" +go +setboard 8/1Qp3pk/7p/5p2/5Pqn/1P1r4/P5PP/2B2RK1 b - - +solution c6 +id "ECM.137" +go +setboard 2rr1bk1/5p1p/pPN2np1/3Bp3/2Q1n3/1P2B1Pq/P3PP2/R2R2K1 b - - +solution Rxd5 +id "ECM.138" +go +setboard 3r2k1/1p4pp/p1q1p3/3p1B2/bP1B2P1/P4Q2/5PKP/2b2R2 w - - +solution Rxc1 +id "ECM.139" +go +setboard rnb1r1k1/pp5p/2pp2p1/4b3/2P1P2q/1NN1BPp1/PP1QB1P1/3RR1K1 b - - +solution Bf4 +id "ECM.140" +go +setboard 5n1r/1p2kp2/rB1Nb3/4p1Pp/4p2P/1PP5/8/1K1R1R2 w - - +solution Rxf7+ +id "ECM.141" +go +setboard b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - +solution d3+ +id "ECM.142" +go +setboard 4r1k1/3R1ppp/p2p4/5PP1/2q2P2/2n2B2/P1P3QP/1r3R1K w - - +solution Rxb1 +id "ECM.143" +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +solution Bd5+ +id "ECM.144" +go +setboard 6k1/4ppbp/p5p1/1B1Q4/2P2Pn1/8/qr4PP/2B2RK1 b - - +solution Bd4+ +id "ECM.145" +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +solution Ba3 +id "ECM.146" +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +solution g6 +id "ECM.147" +go +setboard 5r2/1b3pk1/pqrpp1p1/4n1Nn/1p2PP1P/8/PPPQB3/1NKR2R1 b - - +solution Rfc8 +id "ECM.148" +go +setboard 1r2k2r/p5bp/4p1p1/q2pn3/1p2N1P1/6QP/PPP5/1KBR3R w k - +solution Bh6 +id "ECM.149" +go +setboard rn1q1rk1/pp3p1p/2p5/3p4/5Q1P/2NP3R/PPP3P1/4RK2 w - - +solution Rg3+ +id "ECM.150" +go +setboard 7r/kppQP1pp/p7/2qp1R2/4n3/1P2b2P/P1P3PK/R7 b - - +solution Re8 +id "ECM.151" +go +setboard r1b1kb1Q/qp2pp2/p3n1p1/2nN2Pp/2B4P/7N/PPP5/2KRR3 w q - +solution Nc7+ +id "ECM.152" +go +setboard 8/1bq3kp/p5p1/1pb1p3/4P2P/2PQ2P1/1P5B/5N1K b - - +solution Qd8 +id "ECM.153" +go +setboard 2r1q1r1/6bk/p2pN1pp/1p1N4/4P3/3R3Q/PnP4P/1K4R1 w - - +solution Nf6+ +id "ECM.154" +go +setboard 4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - +solution Ra8 +id "ECM.155" +go +setboard 6k1/p1q2pp1/2n2b2/3B2Pp/2P2P2/5N1P/Pr1Q2K1/4R3 w - - +solution Re8+ +id "ECM.156" +go +setboard r1r3k1/p4n2/3p4/5NpR/8/2q2P2/P1PQ4/2K4R w - - +solution Rh8+ +id "ECM.157" +go +setboard 8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - +solution g4+ +id "ECM.158" +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +solution Nd6 +id "ECM.159" +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +solution Ba4 +id "ECM.160" +go +setboard r1bq3k/ppp2Qp1/2n1p2p/6N1/2BPN3/2P1n3/PP4PP/R5K1 w - - +solution Nf6 +id "ECM.161" +go +setboard 3R4/1p2kp2/p1b1nN2/6p1/8/6BP/2r1qPPK/Q7 w - - +solution Rd7+ +id "ECM.162" +go +setboard 6k1/p5p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - +solution Rh8+ +id "ECM.163" +go +setboard 8/5P2/4K1kP/4R3/8/8/8/5r2 w - - +solution Rg5+ +id "ECM.164" +go +setboard 3r1rk1/p1p1qp1p/2p1b1p1/8/P2PRP2/2P1NQ2/6PP/R5K1 w - - +solution f5 +id "ECM.165" +go +setboard 6k1/pr3ppp/1p3qn1/5NQ1/2p5/8/P4PPP/4R1K1 w - - +solution Re8+ +id "ECM.166" +go +setboard Q7/1pq2kpp/4bp2/3r4/2B5/P3P3/1r3PPP/2R1K2R b K - +solution Rd1+ +id "ECM.167" +go +setboard 4r1k1/p4ppp/4q2r/1Q6/4p3/4P1P1/P4P1P/2RR2K1 w - - +solution Rd6 +id "ECM.168" +go +setboard 8/5p1k/4p1p1/3p2K1/3P1Q1P/P4P2/7q/8 b - - +solution f6+ +id "ECM.169" +go +setboard r4r2/6k1/3p4/2pPp2p/4Pqp1/3P1P2/1R2Q1KP/5R2 b - - +solution Ra1 +id "ECM.170" +go +setboard 4r1k1/1np1r1pp/1ppp1q2/6N1/1P3P2/4RQP1/7P/4R1K1 w - - +solution Qh5 +id "ECM.171" +go +setboard r4rk1/pp3p1p/3pq1p1/2nNp3/3R1P2/7Q/PP4PP/5RK1 w - - +solution f5 +id "ECM.172" +go +setboard 3qn2k/1p3Bp1/rbn4p/2p5/p1P2p2/P2b2PP/1BQNRP2/1R4K1 w - - +solution Qxd3 +id "ECM.173" +go +setboard 3r1rk1/1pp4p/1q3bp1/p3p3/P2n1P2/2BB3P/1PP2QP1/R4RK1 b - - +solution Bh4 +id "ECM.174" +go +setboard 4rrk1/2p2ppp/p2b4/1p1P4/3P2nq/2P4P/PPQ1RPP1/RNB3K1 b - - +solution Qxf2+ +id "ECM.175" +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +solution Nxf7 +id "ECM.176" +go +setboard r3kb1r/2q2p2/3p4/ppp1n1B1/P6P/1B3pQ1/1PP3b1/2KRR3 w kq - +solution Bd5 +id "ECM.177" +go +setboard r1b2rk1/1p4pp/p1n3q1/4ppN1/7Q/2P1B3/P1P2PPP/R2R2K1 w - - +solution Rd6 +id "ECM.178" +go +setboard 1rb2r2/1pR1N2p/p2R2pk/5p2/4pP2/1P1nP3/P4P1P/5BK1 w - - +solution Rf6 +id "ECM.179" +go +setboard r1b3k1/ppp2r2/6p1/3n3p/6qP/3BQ3/PBP5/2KR3R w - - +solution Bd4 +id "ECM.180" +go +setboard 3r2k1/p2q1r1p/1p1N2p1/1PpP4/3b1Bn1/1Q4Pb/1P2RP1P/R5KB b - - +solution Qxd6 +id "ECM.181" +go +setboard 4r1k1/1pbb3p/2pp2q1/p1n5/2P2R2/1PN1n1P1/PB2Q1B1/5RK1 w - - +solution Qxe3 +id "ECM.182" +go +setboard 3r2k1/p2r1p1p/1pR1p1qP/3P1pP1/3R4/1P2Q3/P4K2/8 w - - +solution dxe6 +id "ECM.183" +go +setboard 3r3k/p1Q3bp/2p3p1/8/2P1BRn1/1P4Pb/P1N1q2P/6BK b - - +solution Nf2+ +id "ECM.184" +go +setboard r4k2/p1pr1ppp/2q5/3PR2P/3Q4/8/6P1/5RK1 w - - +solution Re7 +id "ECM.185" +go +setboard 1R3b2/3r3k/2p1bp1p/r1q1pNpQ/2PpP2P/6B1/P4PP1/1R4K1 w - - +solution Nxh6 +id "ECM.186" +go +setboard r1b4r/pp2ppk1/2np1np1/3N3p/2B1P3/q3BP2/P1PQ2PP/1R3RK1 w - - +solution Nxe7 +id "ECM.187" +go +setboard r3k2r/pb1n1pbp/4p1p1/q1n1P3/Bp1N1N2/4B3/PP3PPP/R2Q1RK1 w kq - +solution Ndxe6 +id "ECM.188" +go +setboard 5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - +solution Ne4 +id "ECM.189" +go +setboard 5rk1/5pbp/b5p1/p1nNN3/1p2n3/1P4PP/P4PB1/2BR2K1 w - - +solution Nd7 +id "ECM.190" +go +setboard 2k1r1r1/ppb2p2/6b1/2qP4/2P2P2/4pP1p/P3Q2P/2RBRN1K b - - +solution Bd3 +id "ECM.191" +go +setboard 5r1k/pp1n1p1p/1b1qpP2/8/1PrN4/P1N1Q1P1/7P/3R1R1K w - - +solution Qh6 +id "ECM.192" +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +solution Nb6 +id "ECM.193" +go +setboard 1r3rk1/p4pbp/q1p2pp1/3p1b2/1n1P1P1B/PB3N2/1PPQR1PP/2KR4 b - - +solution Bxc2 +id "ECM.194" +go +setboard 1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - +solution Bxc5 +id "ECM.195" +go +setboard 2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - +solution Rxd5 +id "ECM.196" +go +setboard rn3rk1/pp2ppbp/6p1/2R3N1/2B3b1/q3B3/P1P1Q1PP/5RK1 w - - +solution Rxf7 +id "ECM.197" +go +setboard r1k3r1/pppnb1p1/4N3/3QP2p/3P3q/4B3/PPP2P2/R3KB2 w Q - +solution Ba6 +id "ECM.198" +go +setboard r1nqr2k/1p1b1Q1p/p5p1/P1pPb3/5B2/2N5/BP4PP/R4RK1 w - - +solution Qf8+ +id "ECM.199" +go +setboard 8/k3r1b1/Pp2rpp1/1qpQ4/4nB2/2P2NP1/7P/R4RK1 w - - +solution Bb8+ +id "ECM.200" +go +setboard 1k1r4/ppq2p2/8/2pPb1r1/2P1Q1B1/6P1/PP3PK1/R4R2 b - - +solution f5 +id "ECM.201" +go +setboard r1b2nk1/2qn1p1p/1ppR2p1/8/1PP1NP2/4r1PP/1Q2N1B1/3R2K1 w - - +solution b5 +id "ECM.202" +go +setboard 8/5pk1/3q2p1/8/7P/5Q1K/6B1/6b1 b - - +solution Qh2+ +id "ECM.203" +go +setboard 6r1/ppp4k/3p2rp/3Pb3/PPP1Np1q/5P1b/3QRRBP/6K1 b - - +solution Bd4 +id "ECM.204" +go +setboard 4br1k/pR4bp/2r1B1pN/4npB1/3p4/P7/5PPP/4R1K1 w - - +solution Rxg7 +id "ECM.205" +go +setboard r1bq1rk1/pppn2bp/3p2p1/3N1p2/8/BP1BRQ1P/P1PP1PP1/4R1K1 w - - +solution Nxc7 +id "ECM.206" +go +setboard r6r/1p2kp2/3p1b2/pPpPpQ1P/1nP1P2P/6R1/1P2K3/1B6 w - - +solution Rg6 +id "ECM.207" +go +setboard 2q1r1k1/1b3pbp/3p2p1/1Ppn3n/5P2/5B2/1P1B2PP/R2NNQ1K b - - +solution Ndxf4 +id "ECM.208" +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +solution Rb3 +id "ECM.209" +go +setboard r2qr1n1/p4pk1/1p1p2p1/4p3/4PQ2/1PN2P2/1PP3P1/2KR3R w - - +solution Rh7+ +id "ECM.210" +go +setboard r4rk1/ppp3b1/3p1qp1/3Pp3/2P1Bn2/4BP2/PP1Q4/2K3RR w - - +solution Rxg6 +id "ECM.211" +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +solution Bf4 +id "ECM.212" +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +solution Re7 +id "ECM.213" +go +setboard 1q3rk1/r5b1/pNp1bn1p/2Pp1n2/1P2p3/1N2P2P/PBQKB3/3R3R b - - +solution Nxe3 +id "ECM.214" +go +setboard r4n1r/ppq1nk2/1bpRpN2/4PpQ1/8/2B4P/PPP2PP1/2KR4 w - - +solution Rd7 +id "ECM.215" +go +setboard 3r2k1/p5pp/bpP1p3/3n1p2/2NQpP1q/P3P3/1B1R1R2/4KBr1 b - - +solution Rxf1+ +id "ECM.216" +go +setboard 1rq1r2k/5Rbp/p2p1p1B/2p1p3/2P1P2Q/1P6/P5PP/3b3K w - - +solution Bxg7+ +id "ECM.217" +go +setboard 5Q2/5p1p/3p2p1/4p1k1/4P1P1/3R1P1K/r6P/4q3 w - - +solution f4+ +id "ECM.218" +go +setboard 2b2r1k/ppq3pp/3b3r/n3NpN1/Q2PpP1B/2P1R3/PP5P/4R1K1 w - - +solution Ngf7+ +id "ECM.219" +go +setboard 2r1r1k1/1R4bp/p5p1/2pqn3/8/2B5/1PQ1B1PP/5RK1 w - - +solution Bc4 +id "ECM.220" +go +setboard 7k/pp1q2pp/3Nr1n1/3B2Q1/2pP4/B3P1Pb/P6P/6K1 w - - +solution Qd8+ +id "ECM.221" +go +setboard r5k1/5p1p/bq1p2p1/r2Pp3/1p2N1P1/1P3P2/1KPQ3P/3R3R b - - +solution Ra2+ +id "ECM.222" +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +solution Bg7 +id "ECM.223" +go +setboard 5nk1/2b1q1p1/2p5/3pP1pQ/1r1P2P1/3B1R2/5PP1/6K1 w - - +solution Rxf8+ +id "ECM.224" +go +setboard 1k1r3r/1pp2p2/p2b4/4n1p1/N3q1P1/1B2B3/PP3RP1/4RQK1 b - - +solution Rh1+ +id "ECM.225" +go +setboard rnb1kr2/p4pQ1/8/1ppPpP2/2p1P3/N6P/Pq4B1/3R1RK1 w q - +solution Nxb5 +id "ECM.226" +go +setboard 5r1k/2p3pp/3pQ3/3P1rN1/pp5q/5PR1/P4PKP/B7 w - - +solution Bxg7+ +id "ECM.227" +go +setboard 8/pR3Bk1/3p2p1/5b1p/2P4P/6P1/P4bQK/4q3 b - - +solution Bg1+ +id "ECM.228" +go +setboard r1b1Rnk1/6pp/p4q2/1pp2P2/3r4/2NB4/PP1Q2PP/4R1K1 w - - +solution Nd5 +id "ECM.229" +go +setboard 1Q6/pb3pk1/1p3qp1/1N3p1p/2Pr3P/3BR1PK/r7/6R1 b - - +solution Rh2+ +id "ECM.230" +go +setboard rq3r1k/p2n1p2/1pbb1np1/2p2BB1/8/2N2N2/PP3QPP/3R1RK1 w - - +solution Rxd6 +id "ECM.231" +go +setboard 2kr3r/Qpp1n1p1/2b2pp1/4b3/8/6N1/PPP2P2/R1B2RK1 b - - +solution Rh1+ +id "ECM.232" +go +setboard 8/2p2Q1p/1rp5/p3q1kp/P7/2P2RP1/5PK1/8 w - - +solution Rf5+ +id "ECM.233" +go +setboard 1r2b3/1p2q1bk/p1p1p1p1/P1PpP2r/1P1KpPQP/4P2N/6R1/4B2R b - - +solution Rxe5 +id "ECM.234" +go +setboard 6k1/3b1p1p/6p1/2BPR3/8/4Q2P/1q3rPK/8 w - - +solution Re8+ +id "ECM.235" +go +setboard 2R5/4ppkp/6p1/p2P4/4P2P/p3B1P1/qbR2PK1/8 w - - +solution Rg8+ +id "ECM.236" +go +setboard 3rr1k1/1b5p/p6p/1p3N2/6Pb/P1Q1p3/1PP4P/R5K1 b - - +solution Bf2+ +id "ECM.237" +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +solution Qc1 +id "ECM.238" +go +setboard 3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - +solution Bf3 +solution Rxc5 +id "ECM.239" +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +solution Rxd6 +id "ECM.240" +go +setboard 6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - +solution Rh4+ +id "ECM.241" +go +setboard 3r4/1pQ4R/p1b2kp1/P6p/2q5/7P/2P3P1/6K1 b - - +solution Rd1+ +id "ECM.242" +go +setboard 6rr/1b3k1p/pbqppPn1/1p5Q/4PN2/P6R/1PP3BP/2B2R1K w - - +solution Qxh7+ +id "ECM.243" +go +setboard 4rrk1/3b1ppp/pb6/1pqP4/P1p1PP2/1P2NK2/3QB2P/R2R4 b - - +solution Rxe4 +id "ECM.244" +go +setboard 2r1r1k1/1p4bp/p2p1qp1/1n1P4/2P1B2P/1N1Q4/PP2R3/1K5R b - - +solution Rxc4 +id "ECM.245" +go +setboard 6rr/ppqb1pkp/2pb1pn1/3p3Q/3P1P1N/3B1RN1/PPP3PP/5RK1 w - - +solution Qh6+ +id "ECM.246" +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +solution Bh7+ +id "ECM.247" +go +setboard r2q1rk1/1b1nbpp1/p1p1p2p/1pPpN3/3P1N2/P2BP3/1PQ2PPP/R4RK1 w - - +solution Bh7+ +id "ECM.248" +go +setboard 2r2rk1/pb4pp/1p2p3/4Npq1/3P1n2/5P2/PP1R2PP/RB2Q1K1 b - - +solution Rc1 +id "ECM.249" +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +solution Bxf7+ +id "ECM.250" +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +solution Bb7 +id "ECM.251" +go +setboard r5k1/pp2ppb1/4qn2/r3B1p1/3P4/3QNP1R/PP2K1P1/7R w - - +solution Bxf6 +id "ECM.252" +go +setboard 1R2br1k/5r1p/p2p1P2/6RQ/3p1P2/4p2B/q6P/5N1K w - - +solution Rxe8 +id "ECM.253" +go +setboard kr1r4/7p/2bqp1p1/p7/1Pp1PP1P/K1B1nNPB/PP5R/RN2Q3 b - - +solution Qxb4+ +id "ECM.254" +go +setboard 5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - +solution Rxd7+ +id "ECM.255" +go +setboard kn5r/p2r2p1/1pqBp1np/1Q1pPp2/R2P4/1N6/2P2PPP/R5K1 w - - +solution Rxa7+ +id "ECM.256" +go +setboard 4Rnk1/2p2pp1/3r3p/p2P4/P5Q1/1B5P/5PK1/q7 w - - +solution Rxf8+ +id "ECM.257" +go +setboard 4r3/2k1p2q/pp1nR1p1/2pP1pP1/2P2P2/1P6/P1K3B1/4Q3 w - - +solution Rxd6 +id "ECM.258" +go +setboard 2b3k1/p4ppp/7q/2Q5/8/P3r1P1/1r4BP/R3R1K1 b - - +solution Rxg2+ +id "ECM.259" +go +setboard r1b1rbk1/7p/2p1pBp1/p2pP1P1/5P2/1PqB4/P1P1Q3/1K4RR w - - +solution Rxh7 +id "ECM.260" +go +setboard 2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - +solution Bxh6 +id "ECM.261" +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +solution Rxh8+ +id "ECM.262" +go +setboard 3r2k1/p4rPp/1b1q3Q/n1p1pP2/1p6/3B1NR1/P4P1P/6RK w - - +solution Qxh7+ +id "ECM.263" +go +setboard r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - +solution Bh7+ +id "ECM.264" +go +setboard r2rn1k1/1bqn1ppp/p7/2bpP1P1/1p1N1Q2/1P3B2/PBP1NR1P/3R2K1 w - - +solution Qxf7+ +id "ECM.265" +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +solution Nxf7 +id "ECM.266" +go +setboard r1b1r1k1/1p1n1p2/p1nBp1p1/q2pP1Np/P7/R2B3Q/2P2PPP/5RK1 w - - +solution Nxf7 +id "ECM.267" +go +setboard r1b1k2r/ppp3pp/1qp5/2b1Pp2/3Qn3/5N2/PPPBNPPP/2KR3R w kq - +solution Qd8+ +id "ECM.268" +go +setboard 1k6/1p4p1/P1p5/5Q2/2q2r2/P7/8/4R2K w - - +solution Re8+ +id "ECM.269" +go +setboard 6k1/1p3p2/4r1p1/1PPrbq1p/2QN4/P2R1P1P/R4KP1/8 b - - +solution Bg3+ +id "ECM.270" +go +setboard 4n1q1/1k1b4/2p4R/2Pp4/1p1N1rpQ/3B4/PPP2P2/2K5 w - - +solution Nxc6 +id "ECM.271" +go +setboard r2qk2r/1pp2ppp/p3pnn1/6N1/1B1P2P1/1Q2P2P/PP3PK1/R6R b kq - +solution Nh4+ +id "ECM.272" +go +setboard 2kr2r1/R2p3p/2n2p2/1R3P2/2P1p3/4BQ2/1Pq4P/4K3 w - - +solution Ra8+ +id "ECM.273" +go +setboard r3r1k1/pp3pp1/2bb1q2/3p4/4n1Pp/2P1BB1P/PP2NPK1/R1Q4R b - - +solution Qxf3+ +id "ECM.274" +go +setboard r1br4/ppq2pk1/3bpN2/8/2P5/3n2B1/PP2QPPP/R4K1R w - - +solution Qg4+ +id "ECM.275" +go +setboard 6kb/B1p2p2/5r2/1r1p2pR/6q1/3P2P1/P1P2PP1/2KR3Q b - - +solution Rb1+ +id "ECM.276" +go +setboard rn4k1/pp2p1b1/4b3/q2p2Q1/2B2P2/8/P1P1K1P1/R6R w - - +solution Rh8+ +id "ECM.277" +go +setboard 3k2r1/pp1b3Q/1b2pP1p/3pN2q/5B2/7B/PP2nP1K/2R5 b - - +solution Rg2+ +id "ECM.278" +go +setboard 2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - +solution Rxc3 +id "ECM.279" +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +solution Nxg7 +id "ECM.280" +go +setboard 4k2r/1bqnbppp/p3p3/1p2P1N1/2r2BB1/8/PPP3PP/R2Q1R1K w k - +solution Nxf7 +id "ECM.281" +go +setboard 5r1k/1pqb3p/2n5/p1pB4/2Pp1r1P/1P5P/R2N2K1/3Q1R2 b - - +solution Bxh3+ +id "ECM.282" +go +setboard r4r2/pp2qk2/4pnp1/3pQ3/2p2P2/3B4/PPP2P2/2KR3R w - - +solution Bxg6+ +id "ECM.283" +go +setboard 3bq3/p1n2rk1/1pp1p1p1/3pPnPp/1P1P1N1P/2PN3K/P2BQR2/8 w - - +solution Nxg6 +id "ECM.284" +go +setboard b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - +solution Bxg6+ +id "ECM.285" +go +setboard r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - +solution Qh6+ +id "ECM.286" +go +setboard 4k3/p4ppp/nb1P4/4p3/1P6/P4BP1/3q1r1P/2R2QKR w - - +solution Qb5+ +id "ECM.287" +go +setboard r2q1rk1/pp2pp2/3pb3/3Qb2R/4P1p1/1BN1Bn2/PPP2P2/2K4R w - - +solution Rh8+ +id "ECM.288" +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +solution Nxg7 +id "ECM.289" +go +setboard 1rbk2nr/p1pp2b1/7p/2qP1pp1/2Bn4/2NKBP2/PP2N1PP/R2Q3R b - - +solution Qxc4+ +id "ECM.290" +go +setboard 1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - +solution Rxb2 +id "ECM.291" +go +setboard 5rk1/ppp1q2p/1n1p1np1/3P2N1/1P1R2P1/2Q4P/P3r1B1/5RK1 b - - +solution Rxg2+ +id "ECM.292" +go +setboard 6k1/pp2p2p/3p2p1/4b1r1/2Pn1r1q/2B1N3/PP4B1/R3QRK1 b - - +solution Qh2+ +id "ECM.293" +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +solution Qxg6+ +id "ECM.294" +go +setboard r2k3r/2pb1ppp/p1p1q3/2Q5/5B2/2N5/PPP2PPP/3R2K1 w - - +solution Bxc7+ +id "ECM.295" +go +setboard 2r2r2/2N2pkp/2Q5/1N2p1b1/1p6/3P1qPb/PPR2P1P/4R1K1 b - - +solution e4 +id "ECM.296" +go +setboard 2r1qrk1/pp1b1ppp/4pn2/n1b5/8/2NQ1NP1/PP1BPPBP/R2R2K1 w - - +solution b4 +id "ECM.297" +go +setboard 2b1qr1k/7p/p1pR2p1/1pP1p1Q1/4P3/1B6/PP4PP/6K1 w - - +solution Re6 +id "ECM.298" +go +setboard 1r2k2r/2p2p1b/q1Pppb1N/p2p2P1/Q2P4/P3B3/1P5P/2KRR3 b k - +solution Rb4 +id "ECM.299" +go +setboard 8/2b2k1p/2N2pp1/P2p4/3KnP2/6BP/P5P1/8 w - - +solution Kxd5 +id "ECM.300" +go +setboard 4b1r1/1p3ppk/3r3p/p1p1qP1B/3pPN2/3P3R/nPPQ3P/6RK w - - +solution Ne6 +id "ECM.301" +go +setboard 4b2k/7p/3q3P/1p1pRpr1/1P1B4/2P2Q2/7K/8 w - - +solution Qg3 +id "ECM.302" +go +setboard 2kr2r1/pbp4p/1p4p1/1NqpNp2/4nQ2/8/PPPR1PPP/2K1R3 w - - +solution Nc6 +id "ECM.303" +go +setboard 1rr3k1/1p1bqpbp/1R1p2p1/pN1P4/P3P1n1/1Q6/3NB1PP/2B1R1K1 b - - +solution Rc3 +id "ECM.304" +go +setboard r1br4/1p3k2/p2q1p2/3N1Pp1/3Q4/8/PP4P1/4RR1K w - - +solution Re6 +id "ECM.305" +go +setboard r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - +solution Bd5 +id "ECM.306" +go +setboard 3r1rk1/2p1qp1p/pnP3p1/4n3/PP1NpR2/1BQ4P/6P1/5RK1 w - - +solution Ne6 +id "ECM.307" +go +setboard r1bq1k2/5pb1/p2p1n2/2pPrP2/2p4B/3B2R1/PP1Q2PP/R5K1 w - - +solution Qg5 +id "ECM.308" +go +setboard 2bq1rk1/p4pbp/p2p2p1/3P4/2p1QP2/2Pr3P/PP1N2P1/R1B2RK1 b - - +solution Bd4+ +id "ECM.309" +go +setboard r5rk/1p1bqpnp/3p1b1B/pBnPp2P/4P3/2N2Q2/PP3P2/R3KNR1 b Q - +solution Nf5 +id "ECM.310" +go +setboard r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - +solution Re7 +id "ECM.311" +go +setboard r3r1k1/p1q2pp1/2p4p/7n/BPPP2N1/3Q1N2/P3n1P1/R1B4K b - - +solution Nhg3+ +id "ECM.312" +go +setboard r2qrbk1/1p4pb/2n2p1p/pNpn4/2N5/PP1PPQPB/1B5P/2R2RK1 w - - +solution Nbd6 +id "ECM.313" +go +setboard 5r1k/1p1b1p1p/p2ppb2/5P1B/1q6/1Pr3R1/2PQ2PP/5R1K w - - +solution Qh6 +id "ECM.314" +go +setboard r1b2rk1/p3bppp/2q5/8/2p1NR2/PnB1P3/1PB1Q1PP/3R2K1 w - - +solution Rd6 +id "ECM.315" +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +solution R1b4 +id "ECM.316" +go +setboard 4r3/pp1b3k/2p2qpp/2Pp4/1P6/PBbP1N1P/2R3P1/3Q3K b - - +solution Re1+ +id "ECM.317" +go +setboard 1rb2rk1/p1p2ppp/2q5/3R4/2P1N3/bP4B1/P1Q2P1P/1K5R w - - +solution Bd6 +id "ECM.318" +go +setboard 8/5k1p/5PpB/3PR3/2r4P/1p3K2/2b5/8 b - - +solution Re4 +id "ECM.319" +go +setboard 4r2k/3b3p/p2p4/2pP1p2/q1B2Q1P/2PK1P2/Pr1R4/7R b - - +solution Re4 +id "ECM.320" +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +solution Rd5 +id "ECM.321" +go +setboard 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - +solution Rxh7+ +id "ECM.322" +go +setboard r1b1r1kb/p1qn1pnp/2p1p1p1/4P1N1/2p1NPP1/4B3/PPPQ3P/3RK2R w K - +solution Qxd7 +id "ECM.323" +go +setboard 5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - +solution Rxe7 +id "ECM.324" +go +setboard 5rk1/5p1p/8/3pNp2/RPrqn3/1Q5P/1P3PP1/4R1K1 w - - +solution Rxe4 +id "ECM.325" +go +setboard 2rr2k1/4qppp/bn6/p1bB4/4N3/6P1/PB2PP1P/2RQ1RK1 w - - +solution Rxc5 +id "ECM.326" +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +solution Rxd7 +id "ECM.327" +go +setboard 5rk1/r2nqpp1/p3p3/1p2P3/4N1pP/8/PPP3Q1/1K1R3R w - - +solution Rxd7 +id "ECM.328" +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +solution Qh6 +id "ECM.329" +go +setboard 2r2r1k/1pq1b1p1/p1b1Qn1p/8/3B4/2NB4/PPP3PP/3R1R1K w - - +solution Rxf6 +id "ECM.330" +go +setboard 3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - +solution Rxe6 +id "ECM.331" +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +solution Rxc8+ +id "ECM.332" +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +solution Rxe4 +id "ECM.333" +go +setboard r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - +solution Rxe5 +id "ECM.334" +go +setboard 8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - +solution Rxd4 +id "ECM.335" +go +setboard r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - +solution Rxe5 +id "ECM.336" +go +setboard r3r1k1/pbqn1ppp/1p3n2/1Pb5/2p5/5N1P/PBQ1BPP1/1N1R1RK1 b - - +solution Rxe2 +id "ECM.337" +go +setboard 2r2rbk/6bp/5qp1/1N1p1n2/4p3/1p5P/1P3PP1/RBBQ1RK1 b - - +solution Ng3 +id "ECM.338" +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +solution Rxc5 +id "ECM.339" +go +setboard 1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - +solution Rxe7 +id "ECM.340" +go +setboard r1k2n1r/2pb4/1p1p1qpp/p2P1p2/3N1P1P/2Q3P1/PPP1R3/2K1RB2 w - - +solution Re8+ +id "ECM.341" +go +setboard r1b2r1R/1p2bpk1/4p1p1/4P1N1/p2p4/5Q2/qPP2PP1/1NKR4 w - - +solution Qf6+ +id "ECM.342" +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +solution Nxe6 +id "ECM.343" +go +setboard 4q1r1/5kpp/2p1nb2/2PpQp2/r4P2/1N3P2/1BP1R2P/6RK w - - +solution Rxg7+ +id "ECM.344" +go +setboard 2r1k2r/1pq1bppp/p3bn2/4N3/2pPN3/2P5/P3QPPP/R1B1R1K1 w k - +solution Nxf6+ +id "ECM.345" +go +setboard 1r3k1r/4Rn1p/pb1p1P2/1p1q2P1/5p2/7Q/PPP1B1RP/2K5 w - - +solution Rxf7+ +id "ECM.346" +go +setboard 4rrk1/ppn3pp/2pb1n1q/3p4/1P1P4/P3BNP1/2P1BPKP/R2Q1R2 b - - +solution Rxe3 +id "ECM.347" +go +setboard 2b1r2k/2Q4p/4q3/1pp5/3b4/4NP2/1P3BP1/3R2K1 w - - +solution Rxd4 +id "ECM.348" +go +setboard r3r1k1/pp3ppp/1qp5/2bbNQ2/5B2/2P5/PP3PPP/3RR1K1 w - - +solution Rxd5 +id "ECM.349" +go +setboard 7r/3qbk1r/3p1n2/p1pPp1p1/Pp1nPpP1/1P1Q1P1B/1NP3K1/R3B2R b - - +solution Nxg4 +id "ECM.350" +go +setboard r2qn1k1/1p1b3p/2pp1b2/6pQ/p1P1P3/P1N3PB/1P6/3R1R1K w - - +solution Rxf6 +id "ECM.351" +go +setboard 2rq3r/5p2/p3pkbQ/3p4/3N4/2P4R/P4PP1/4R1K1 w - - +solution Rf3+ +id "ECM.352" +go +setboard r4k1r/pp2pp2/3p1b2/q2PnQpp/3N4/1BP3P1/PP3PP1/3RR1K1 w - - +solution Rxe5 +id "ECM.353" +go +setboard 5rk1/2p3pp/p1p4r/2P1p3/3pPnq1/1P3R1P/PN1Q3K/R5N1 b - - +solution Qxf3 +id "ECM.354" +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +solution Rxd7 +id "ECM.355" +go +setboard 2r2rk1/p3p1bp/3qP1p1/1Q1p4/P4P2/3R4/1P4PP/2B2RK1 b - - +solution Rxc1 +id "ECM.356" +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +solution Rxd4 +id "ECM.357" +go +setboard 1r6/3b1pk1/pr1p1q1p/2pPb1p1/2B1P1P1/2N2PP1/1PQ3K1/RR6 b - - +solution Rxb2 +id "ECM.358" +go +setboard 2r2rk1/5ppp/1p2p3/p7/1n1R4/P1NnPN2/1P3PPP/1R4K1 b - - +solution Nxb2 +id "ECM.359" +go +setboard 2r3k1/p1r1ppb1/2bp1np1/q5N1/1p1BP2Q/3P4/PP2N1PP/2R2R1K w - - +solution Bxf6 +id "ECM.360" +go +setboard r3r1k1/p4ppp/2pp1b2/8/q2n1P2/2BQ3P/PPP3P1/1K1R2NR b - - +solution Re3 +id "ECM.361" +go +setboard rn1kr3/pppb4/3p1q2/3P1pNn/2P2P1p/1P2Q2P/P2NR1B1/4R1K1 w - - +solution Qxe8+ +id "ECM.362" +go +setboard r2q1rk1/ppp1b1pp/1nn1p3/4P3/2PP4/2N1B2P/PP1Q4/2KR1B1R b - - +solution Rxf1 +id "ECM.363" +go +setboard r3k3/1pqb1p2/p3p3/4n2r/3N1Q2/2P5/PP4B1/4RRK1 w q - +solution Rxe5 +id "ECM.364" +go +setboard 1rb2bk1/q4r2/pB1p1nn1/3Pp3/N3PpP1/8/1PQ1BNP1/R1R3K1 b - - +solution Rxb6 +id "ECM.365" +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +solution Rxd8 +id "ECM.366" +go +setboard r4rk1/5p2/p1b1pQpq/8/1B2P3/2NR4/PPP3PP/1K6 w - - +solution Rd5 +id "ECM.367" +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +solution Rxg6+ +id "ECM.368" +go +setboard 2rr2k1/5ppp/p1b1pn2/q1p5/P1B1PQ2/R1PN1P2/6PP/1R4K1 b - - +solution Rxd3 +id "ECM.369" +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +solution Bd8 +id "ECM.370" +go +setboard 1k2rb1r/pbp1q1pp/2pp4/2PnpP2/Q7/1P3NP1/PB5P/2KR1B1R w - - +solution Rxd5 +id "ECM.371" +go +setboard 7k/p1p1r2p/1p1pnr1q/5pp1/2PPPp2/2PB1P1P/P2Q1PRK/7R b - - +solution g4 +id "ECM.372" +go +setboard 5qk1/p4p2/1p3Pp1/2p4Q/3rr3/7R/PP6/6RK b - - +solution Rh4 +id "ECM.373" +go +setboard 5r1k/5Bb1/3p2Pp/p1pP4/1p2Q3/4P1P1/q7/3K3R w - - +solution Rxh6+ +id "ECM.374" +go +setboard 2b4B/1pp2k2/1p6/3P3n/5p1P/1P4p1/P2r2P1/R5KR b - - +solution f3 +id "ECM.375" +go +setboard r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b q - +solution Bh2 +id "ECM.376" +go +setboard r2q1r2/p1pbppbk/1p3npp/n2P2B1/7Q/2NB1N2/PPP3PP/4RRK1 w - - +solution d6 +id "ECM.377" +go +setboard 5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - +solution Nf7+ +id "ECM.378" +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +solution Bxe5+ +id "ECM.379" +go +setboard r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - +solution Bc3 +id "ECM.380" +go +setboard 2r1k2r/3b1pb1/p2ppp2/2q2P2/2p1P2p/P1N2N2/1PP1Q1PP/3R1R1K w k - +solution e5 +id "ECM.381" +go +setboard 3r1rk1/1pq1bppp/p7/n2RN3/P7/1P6/1B2QPPP/R5K1 w - - +solution Nd7 +id "ECM.382" +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +solution Rxc4 +id "ECM.383" +go +setboard r3bknr/1p4pp/p3Q3/q4pb1/P1Bn4/8/1PP2PPP/R1B1R1K1 w - - +solution Qd6+ +id "ECM.384" +go +setboard r1b1nrk1/p2n3p/2pp4/8/2P2q1N/1PB4P/P4PB1/R2QR1K1 w - - +solution Bd5+ +id "ECM.385" +go +setboard 7k/5rp1/p1bQB2p/1p4nN/4P3/1Pq5/P5PP/3R3K b - - +solution Bxe4 +id "ECM.386" +go +setboard r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - +solution d4 +id "ECM.387" +go +setboard r2r2k1/1bq2pb1/6pp/2P1p3/1nBpN2N/6PP/2Q2P2/3RR1K1 w - - +solution Nf6+ +id "ECM.388" +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +solution Nf6+ +id "ECM.389" +go +setboard 2k1r3/Qp3pb1/2p4p/6q1/8/1P4PN/PBPn1P2/K2R4 b - - +solution Qe5 +id "ECM.390" +go +setboard r3r1k1/1pp2p1b/7p/2Q5/2PP2p1/2P1NpPq/P2R1P1P/6RK b - - +solution Rxe3 +id "ECM.391" +go +setboard 5bk1/5p1p/Q5p1/1B4n1/8/2q1p3/6PP/3R2K1 b - - +solution e2 +id "ECM.392" +go +setboard r5k1/1p3pp1/1p3q1p/1P1bQ3/P2P3n/8/3B1PPP/R3R1K1 b - - +solution Nf3+ +id "ECM.393" +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +solution Rxa6 +id "ECM.394" +go +setboard r5kr/p3PR1p/1p1p2pq/4n3/8/3B4/P4QPP/4R1K1 w - - +solution Rxe5 +id "ECM.395" +go +setboard 2bq1b2/1p3k2/1r1p1p1p/pNpP1PpP/P1P3P1/6B1/1P5Q/2K1R3 w - - +solution Re6 +id "ECM.396" +go +setboard 2kr3r/pp3p1p/2b1p3/q3Q3/5P2/2P1B3/P1P3PP/1R3RK1 b - - +solution Rhg8 +id "ECM.397" +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +solution Rxd3 +id "ECM.398" +go +setboard 2r2nk1/6pp/p1rPqp2/1pP1p3/1P6/2B3R1/1P2Q1PP/5RK1 w - - +solution Rxf6 +id "ECM.399" +go +setboard 3r2k1/pb3p1p/1q4p1/2b1P3/1Pp5/2P1p1P1/P3Q1BP/R1B4K b - - +solution Qc6 +id "ECM.400" +go +setboard r2rnbk1/pp3ppp/1q4n1/3p1N2/5P2/1PQB4/PBP3PP/4RR1K w - - +solution Nh6+ +id "ECM.401" +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +solution e5 +id "ECM.402" +go +setboard r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - +solution Rxh5 +id "ECM.403" +go +setboard 5rr1/pp1kq1bp/2bppn2/2p3B1/4N3/2NP2P1/PPP4P/R3QRK1 b - - +solution Nxe4 +id "ECM.404" +go +setboard 1r1q1k2/R4pp1/5p1r/1p1p1n1p/3Pb2N/1BP5/2P1Q1PP/4R1K1 w - - +solution Qxe4 +id "ECM.405" +go +setboard R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - +solution Nxe5 +id "ECM.406" +go +setboard r1b3kr/bp3ppp/p1nNp3/4P3/P1Q2P2/BBP5/5qPP/R2R3K w - - +solution Nxc8 +id "ECM.407" +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +solution Rxc4 +id "ECM.408" +go +setboard 4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - +solution Rxf6 +id "ECM.409" +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +solution e6 +id "ECM.410" +go +setboard r4rk1/1b4bp/p1npq1P1/R3p3/8/1N2BP2/1PPQ2P1/4KB1R w K - +solution Qxd6 +id "ECM.411" +go +setboard 6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - +solution Bd2 +id "ECM.412" +go +setboard 6k1/2p3p1/2b4p/p4P2/2pR2PK/2P1r2P/1B6/8 b - - +solution Bg2 +id "ECM.413" +go +setboard r1b2rk1/pp2ppbp/2np1np1/q7/4P3/2N1BN2/PPPQBPPP/2KR3R b - - +solution Nxe4 +id "ECM.414" +go +setboard 3r1rk1/p1q4p/1p3bp1/3bnp2/3B4/1NPB3P/P1PQ2P1/1R2R2K b - - +solution Nf3 +id "ECM.415" +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +solution Ng5 +id "ECM.416" +go +setboard 1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - +solution bxc6 +id "ECM.417" +go +setboard r3kbnr/1ppb3p/p1q1pp2/3p4/3P4/2N2N2/PPP2PPP/R1BQ1RK1 w kq - +solution Ne5 +id "ECM.418" +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +solution Rxf6 +id "ECM.419" +go +setboard 3rr1k1/1p1qb2p/pP4p1/2p2p2/4RQ2/3P4/1PPB2PP/4R1K1 w - - +solution Bc3 +id "ECM.420" +go +setboard 2b2r2/rpp2pkp/3pq3/2pR2P1/2n1P1N1/2P2B2/1P3Q1P/1K5R b - - +solution Qxd5 +id "ECM.421" +go +setboard 6k1/rnqb3p/5ppQ/2pPp3/p1N1P3/2PB3P/5PP1/1R4K1 w - - +solution f4 +id "ECM.422" +go +setboard 7r/pp4k1/3pn1p1/q1pB1b2/2P5/5NR1/1P3PP1/2Q3K1 w - - +solution b4 +id "ECM.423" +go +setboard 5r2/4prkp/3q2p1/2pP1n2/N1Q2R2/1P4PP/P5K1/4R3 b - - +solution g5 +id "ECM.424" +go +setboard B1b1rbk1/5ppp/pq6/1p2n3/2p2P2/6PP/PPQ4K/R1BR4 b - - +solution Ng4+ +id "ECM.425" +go +setboard 8/2R4p/2R3bk/8/5N1P/1p3PP1/2pqP1K1/8 w - - +solution g4 +id "ECM.426" +go +setboard 6k1/p4p1p/3pqp2/2p1r3/2Pnr1N1/P6P/1P1Q1PP1/3R1RK1 b - - +solution Ne2+ +id "ECM.427" +go +setboard 1kqr3r/p1p4p/RpQP4/2P1p3/4B3/4Bp2/P4P1P/6K1 b - - +solution Rdg8+ +id "ECM.428" +go +setboard 6k1/3Q1pp1/4p2p/p2pP3/1p1P2P1/nP1R1N2/q1r2PKP/8 w - - +solution Qe8+ +id "ECM.429" +go +setboard 6k1/5pp1/p5r1/3Np2q/4P2p/1r3P1Q/n4P1P/3R2RK w - - +solution Rxg6 +id "ECM.430" +go +setboard nr2rb2/3q1kpp/3p4/pnpPpNBP/2N1P3/3Q4/PP3P2/2K3RR w - - +solution Nh6+ +id "ECM.431" +go +setboard r3k1r1/1pp2ppp/pb1p1qn1/4p2b/2B1P3/N1PP1NPP/PP2QPK1/R4R2 b q - +solution Nh4+ +id "ECM.432" +go +setboard 1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - +solution Bxh6 +id "ECM.433" +go +setboard r2b4/pb2q1k1/np1p2r1/1N1Pp2Q/PPN1Pp2/8/2R2BPp/2R4K w - - +solution Ncxd6 +id "ECM.434" +go +setboard r7/2qnb1kp/p2p1nP1/1p1Pp1p1/6N1/3BB2Q/PPP4P/5RK1 w - - +solution Qxh7+ +id "ECM.435" +go +setboard n1rqk3/1p2p3/1n1pP1p1/pP1P1p1r/3B3P/1BN3p1/3Q4/R3K2R w KQ - +solution Qg5 +id "ECM.436" +go +setboard rn2kr2/pp1b1pQp/3Pp3/qB1n4/3N4/P7/1PP2PPP/2KR3R w q - +solution Nxe6 +id "ECM.437" +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +solution Bh4 +id "ECM.438" +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +solution Bf8 +id "ECM.439" +go +setboard 4rr1k/pbp3bp/3p4/1p5q/3n4/1B1Q2B1/PP1N1N1P/4RRK1 b - - +solution Rf3 +id "ECM.440" +go +setboard r3k2r/pp2ppbp/1qp5/2n2b2/2P5/4BN2/PP1QBP1P/2KR3R b kq - +solution Nb3+ +id "ECM.441" +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +solution Ng6+ +id "ECM.442" +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +solution Qb2 +id "ECM.443" +go +setboard 2r3k1/n3qppp/1B1r1n2/N7/N4P2/1Q4PP/P5B1/R1b4K b - - +solution Qe1+ +id "ECM.444" +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +solution Qxg5+ +id "ECM.445" +go +setboard rnb2k2/ppbp2p1/2p2pB1/8/1PN5/2P5/P4PPP/R1B3K1 w - - +solution Bf4 +id "ECM.446" +go +setboard 2k5/1p1b4/2n1p1r1/7q/4RP2/3BQN2/2P2K1P/8 w - - +solution f5 +id "ECM.447" +go +setboard 2k3r1/1ppr3p/p1pB2q1/6n1/N3Pp2/8/PPP1Q1PP/3R1RK1 b - - +solution f3 +id "ECM.448" +go +setboard r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - +solution Rxh2+ +id "ECM.449" +go +setboard 6r1/6rk/3p3p/p2Rp3/R1PqPp1b/2N2Q2/6PP/7K b - - +solution Rxg2 +id "ECM.450" +go +setboard 4r1k1/1p2rq1p/2bQpp2/p1Pp4/3P4/P3RN2/5PPP/4R1K1 w - - +solution Ne5 +id "ECM.451" +go +setboard b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1KP/8 w - - +solution g6 +id "ECM.452" +go +setboard 1k4q1/1p2Rprp/p1p5/2Pp4/1P1Q3P/6P1/P5K1/8 w - - +solution Qe5+ +id "ECM.453" +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +solution Ng6+ +id "ECM.454" +go +setboard r4r1k/p2bN2p/1p1p1p2/2q4P/3Q4/1P6/1PP3P1/1K2R2R w - - +solution Ng6+ +id "ECM.455" +go +setboard 2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - +solution h4 +id "ECM.456" +go +setboard r1b2k1r/1p2qp2/pN1p1n2/2pP2pp/P2bP1P1/2N5/1P2BPP1/R2Q1RK1 b - - +solution hxg4 +id "ECM.457" +go +setboard 6nk/p4rrp/1p1p1p2/1q1Pp2R/4B1P1/1PP2Q1R/P6P/7K w - - +solution g5 +id "ECM.458" +go +setboard r1b1k2r/6pp/p1p1p3/3np1B1/1b2N3/8/q1PQB1PP/3RK2R w Kkq - +solution Qxb4 +id "ECM.459" +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +solution Bxh5 +id "ECM.460" +go +setboard 2r3k1/4qpp1/2p1r3/pbQpN1Pp/3P1P1P/4P3/PP6/1KR3R1 w - - +solution Qxb5 +id "ECM.461" +go +setboard 4r2k/p2Q3p/2p1r1p1/4NpR1/3P4/2P1PP1b/P4q1P/6RK w - - +solution Nxg6+ +id "ECM.462" +go +setboard 4r1kb/p2r4/1np1p1p1/3nP1Bp/1p3P1R/1B2qP2/PPPN3Q/2K4R w - - +solution Rxh5 +id "ECM.463" +go +setboard 2rq2k1/pp1bpp1p/3p1np1/8/3NPPnQ/1BP5/P1P3P1/1K1R3R w - - +solution e5 +id "ECM.464" +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +solution Rxd5 +id "ECM.465" +go +setboard 2r1kr2/p1qbbp1Q/3pp3/5p2/1p1N1PB1/6P1/PPP4P/K2RR3 w - - +solution Bxf5 +id "ECM.466" +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +solution Rf6 +id "ECM.467" +go +setboard 2rr2k1/5pn1/1b2q1pp/pP1pP3/2pP1PP1/2R1B2P/2Q3B1/3R3K w - - +solution f5 +id "ECM.468" +go +setboard 2Q2bkr/5p2/1rb5/1pN1n1qB/1P1pPN2/6P1/5P2/R1R3K1 w - - +solution Nce6 +id "ECM.469" +go +setboard 2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - +solution Nc3+ +id "ECM.470" +go +setboard 2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - +solution Nxf5+ +id "ECM.471" +go +setboard 1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - +solution Ne6 +id "ECM.472" +go +setboard r7/pp4pk/2n3qp/5p2/3p4/P4QB1/1PP1RPPP/6K1 b - - +solution d3 +id "ECM.473" +go +setboard 2r2r1k/1p3p1p/p2p1Pp1/3Pp3/1q2Bn1Q/8/1PP3PP/4RR1K w - - +solution Rxf4 +id "ECM.474" +go +setboard r4rk1/5ppp/p7/4PR2/P1qnp2Q/4B3/1P4PP/5RK1 w - - +solution Rh5 +id "ECM.475" +go +setboard 4r3/pb3pk1/6p1/8/6P1/1PNrB2K/P4P1P/2R5 b - - +solution Rexe3+ +id "ECM.476" +go +setboard 1r3kr1/p3q1b1/3p2Q1/2p2p2/2P2N2/4Pn2/PB6/K2R3R w - - +solution Ne6+ +id "ECM.477" +go +setboard 5r1k/6bp/3p1q2/3Q1nP1/8/6P1/PP3BKP/R2N4 b - - +solution Ne3+ +id "ECM.478" +go +setboard 1r1q1k1r/Q4ppp/2B2n2/8/Pbbp4/1P4P1/2PP1P1P/R1B1K2R b KQ - +solution Qe8+ +id "ECM.479" +go +setboard 5rk1/p1p1R1p1/1p5p/8/2pP1P2/3n2P1/PP2Q2P/5KNq b - - +solution Nxf4 +id "ECM.480" +go +setboard r5k1/1N3ppp/4b3/1Nq5/Pn3pn1/5B2/1PPQ3P/R6K b - - +solution Qxb5 +id "ECM.481" +go +setboard 1r2k2r/1bq2pp1/pn2p2p/1p2P1b1/3N4/2N3Q1/PPP3PP/1K1R1BR1 w k - +solution Bxb5+ +id "ECM.482" +go +setboard r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - +solution Nxh6 +id "ECM.483" +go +setboard 2r2r2/p4p1k/1p2pBpn/2p5/6N1/8/P4P2/R3R1K1 w - - +solution Kg2 +id "ECM.484" +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +solution Bg5 +id "ECM.485" +go +setboard 3rn1k1/pp3ppp/6b1/2p1Q3/2P1P3/P4P2/1B1qBP1P/1R5K w - - +solution Rd1 +id "ECM.486" +go +setboard 4r1k1/5ppp/p1q3b1/1ppNr3/2P1P3/1P4QP/P4PP1/4RRK1 w - - +solution f4 +id "ECM.487" +go +setboard 2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - +solution Bh3 +id "ECM.488" +go +setboard 2b3k1/5qp1/p2r1n1p/3p4/3B4/1RP3QP/P2Nr1P1/3R2K1 b - - +solution Ne4 +id "ECM.489" +go +setboard 6k1/5rp1/4Nb1p/2p5/4Q3/1r5P/q5P1/3R1R1K w - - +solution Rxf6 +id "ECM.490" +go +setboard 1r2r1k1/p4ppb/q1pbnn1p/4p3/N1P1P3/pPB2NP1/2Q1RPBP/R5K1 b - - +solution Nxe4 +id "ECM.491" +go +setboard r4r2/1pnqb2k/3p1p1p/p1pPpPpP/2P1N1P1/4BP2/PP1Q4/R2R2K1 w - - +solution Bxc5 +id "ECM.492" +go +setboard rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - +solution Nf6+ +id "ECM.493" +go +setboard 6kr/1p1r1p1p/p2pnPpQ/3Np2R/2q1P3/5P2/PPP5/2KR4 w - - +solution Rxe5 +id "ECM.494" +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +solution Nd6 +id "ECM.495" +go +setboard r2q1rk1/pp1n2pp/2pb4/1P1p3n/P1PPpP2/4P2b/1BNNBP1P/R2QR1K1 b - - +solution Nxf4 +id "ECM.496" +go +setboard rq1r2k1/3nbp1p/p2p2p1/1p1Pp1P1/3B1P2/3B3Q/PPP4P/2KR2R1 w - - +solution f5 +id "ECM.497" +go +setboard r4rk1/1bq1bppp/8/p2pPR2/3B4/1NnP3Q/1P4PP/4R1K1 w - - +solution Rh5 +id "ECM.498" +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +solution Nxh5 +id "ECM.499" +go +setboard r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - +solution f3 +id "ECM.500" +go +setboard 4rqk1/p5b1/3p3p/3Pn1p1/1pP1NrP1/4NP2/P3Q1P1/1K1RR3 b - - +solution Nxf3 +id "ECM.501" +go +setboard r2qkr2/1p3pQp/2p1b3/1B1pN3/1p6/8/1P1K1PPP/2B1R3 w q - +solution Nxc6 +id "ECM.502" +go +setboard r3rk2/pb2bpp1/1n5p/q1pP1B2/1p3B2/5N2/PPQ2PPP/R2R2K1 w - - +solution Bc8 +id "ECM.503" +go +setboard r1bqr2k/ppp2p1p/5b2/3Pn1p1/1PP1Bp2/8/PB2N1PP/R2Q1RK1 w - - +solution Nxf4 +id "ECM.504" +go +setboard 1q4k1/p3rppp/3b1n2/8/5P2/4P3/PP1B3P/RNQ3K1 b - - +solution Bxf4 +id "ECM.505" +go +setboard r3k2r/1p1b1p2/p3p3/2b3p1/4N1n1/1B5P/PPP3P1/R1B2R1K b kq - +solution Bc6 +id "ECM.506" +go +setboard r3kb1r/npqbpp1p/p3n1p1/P3P3/6N1/3B1NB1/1PP3PP/R3QRK1 w kq - +solution Ng5 +id "ECM.507" +go +setboard 7k/p6p/4bppb/1N6/P2p1p2/1PrP2P1/2r1P2P/1R1Q2K1 b - - +solution f3 +id "ECM.508" +go +setboard 2kr4/pp1r1pp1/4n1p1/4R3/2Pp1qP1/3P2QP/5PB1/1R4K1 w - - +solution Rc5+ +id "ECM.509" +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +solution Rxe6 +id "ECM.510" +go +setboard r2qkn1r/pb2bp2/1pp1p3/5p1p/2BPN3/5NQ1/PPP2PPP/1K1RR3 w kq - +solution d5 +id "ECM.511" +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +solution Nxf5 +id "ECM.512" +go +setboard 3r3k/p4npp/1p2qpb1/4P3/5P2/P3N3/1B2QP1P/6RK w - - +solution exf6 +id "ECM.513" +go +setboard 6rk/1b2bp1p/ppq1p3/2p1Pp2/P1Br1P2/1PNR2P1/2P1QK1P/6R1 b - - +solution Rxf4+ +id "ECM.514" +go +setboard r3r1k1/p1q2pp1/b1pb3p/n7/B3n3/2P1BN2/PP1N1PPP/R2QK2R b KQ - +solution Nxc3 +id "ECM.515" +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +solution Bxf6 +id "ECM.516" +go +setboard r5n1/pppb1B2/2k1pb2/3p2B1/5P2/2N5/PPP3P1/2KR4 w - - +solution Nxd5 +id "ECM.517" +go +setboard 2b2q2/r2n2kp/1n1p1pp1/p1pP4/1pP1NPN1/1P1B4/P5PP/Q3R1K1 w - - +solution Nexf6 +id "ECM.518" +go +setboard 1k1r2r1/p1p3q1/2p2p2/3pn3/1P1b2bB/1QN5/P4PPP/1R2RBK1 b - - +solution Nf3+ +id "ECM.519" +go +setboard r3k2r/1bq1bp1p/p2p1np1/1p2p3/3NP3/P1N2QB1/1PP2PPP/3RR1K1 w kq - +solution Ndxb5 +id "ECM.520" +go +setboard r2q4/5p1P/2p1bR2/ppk1p1P1/3pB2Q/8/PPP5/6K1 w - - +solution g6 +id "ECM.521" +go +setboard r3kb1r/pp1b1pp1/4p3/2q3Qp/5B2/2PB4/P4PPP/R3R1K1 w kq - +solution Rxe6+ +id "ECM.522" +go +setboard 1rbr2k1/p4pp1/5b1p/2p1p3/3qPP2/1PNB2PP/PKP2Q2/5R1R b - - +solution c4 +id "ECM.523" +go +setboard r3r1k1/p6p/bp4p1/2bPN3/6n1/6P1/PB2RPB1/3R2K1 w - - +solution d6 +id "ECM.524" +go +setboard 2bk3r/3r2pp/p2nQ3/q2R2P1/1p6/8/PPP2P1P/1K3B1R b - - +solution Qxd5 +id "ECM.525" +go +setboard 3r1k2/1q1r1pp1/3p2bp/p2N4/8/2P1RQ1P/P4PP1/4R1K1 w - - +solution Nf6 +id "ECM.526" +go +setboard 3q3r/p2r1pkp/bp1N1np1/n2p4/5Q2/B1P5/P4PPP/R3R1K1 w - - +solution Nf5+ +id "ECM.527" +go +setboard r4Nk1/1p2pp1p/p1np2p1/3N4/P3PPn1/8/1bPKBqPP/R2Q1R2 b - - +solution Qd4+ +id "ECM.528" +go +setboard 1kb3rr/1p2n2q/1Np2p2/1p6/1P1N1P1p/8/2P1RQPP/R6K w - - +solution Nxb5 +id "ECM.529" +go +setboard r3r1k1/p3Rp1p/1qp1bQ2/8/1p1P4/3R4/PP3PPP/6K1 w - - +solution Rg3+ +id "ECM.530" +go +setboard rn4k1/pp2rpb1/2pNb1pp/4p3/P3Pq2/2P2N1P/1PB1QPP1/R3R1K1 w - - +solution Nf5 +id "ECM.531" +go +setboard 3r1rk1/pp3ppp/8/2p5/4PB1n/P1P2qPP/Q3RP1K/6R1 b - - +solution Qg2+ +id "ECM.532" +go +setboard r4rn1/ppp1q3/2bp2kp/6P1/3QpP2/2N5/PPP1B3/2KR3R w - - +solution f5+ +id "ECM.533" +go +setboard 3qr2r/1p1bppk1/3p2p1/p1nP1PQp/3N3R/1P4PP/P1P3BK/4R3 w - - +solution Ne6+ +id "ECM.534" +go +setboard 2rq1rk1/1b1nbpp1/1p5p/p2pNB2/3p1N2/4P3/PPQ2PPP/2RR2K1 w - - +solution Bh7+ +id "ECM.535" +go +setboard 8/5pkp/2pp2p1/4P3/1P2P3/2QBq2P/2PnNnPK/8 b - - +solution Nf1+ +id "ECM.536" +go +setboard r3r2k/pb2q1p1/1p2Nn1p/2b5/2B5/2P2P2/PPQ3PP/4RR1K w - - +solution Nf4 +id "ECM.537" +go +setboard r1b2nk1/ppq2ppp/8/1BP1p1NQ/5p2/8/PP3PPP/3R2K1 w - - +solution Rd7 +id "ECM.538" +go +setboard 6k1/5qp1/pN5p/3pRp2/3QnP2/2r4P/r5P1/6RK b - - +solution Qh5 +id "ECM.539" +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +solution Nf5+ +id "ECM.540" +go +setboard 6rk/p2b4/3p1Nqp/2pPpn2/P1P4p/5P1P/Q2B1NP1/6RK b - - +solution Ng3+ +id "ECM.541" +go +setboard r4r1k/pppb2pp/8/3q4/2N5/P1P2nQ1/BP2R2P/R6K b - - +solution Ne1+ +id "ECM.542" +go +setboard r5rk/1pp1n1pp/p1n1b1q1/3p1p2/7R/2QB1N2/PB3PPP/4R1K1 w - - +solution Rxe6 +id "ECM.543" +go +setboard 8/4Ppk1/6p1/1p6/1Pb1Q3/6pq/8/6K1 w - - +solution Qe5+ +id "ECM.544" +go +setboard 3R4/4Qpk1/4p1p1/7p/7K/5rP1/5P2/2q5 w - - +solution Qf8+ +id "ECM.545" +go +setboard 8/5pk1/p6p/2R5/3q2p1/6P1/2Q3PK/4r3 w - - +solution Rg5+ +id "ECM.546" +go +setboard 1Q4R1/8/P1b2p2/2p2k2/2P5/5p2/1r5P/4R1K1 b - - +solution f2+ +id "ECM.547" +go +setboard 5r1k/1q2R3/8/6Q1/8/8/6P1/7K b - - +solution Rf1+ +id "ECM.548" +go +setboard 8/4p3/8/3P3p/P2pK3/6P1/7b/3k4 w - - +solution d6 +id "ECM.549" +go +setboard 3Q4/k3K3/q7/2N1P3/1P6/5r2/8/8 b - - +solution Rf7+ +id "ECM.550" +go +setboard 3k4/p1p5/8/2p1p3/4P3/PpPP2K1/1P6/8 b - - +solution c4 +id "ECM.551" +go +setboard 6r1/5p1k/4p3/3pQp2/1p1P1P1q/1P3RR1/7r/5K2 w - - +solution Rxg8 +id "ECM.552" +go +setboard r1b2rk1/ppp2ppp/2n3q1/b2N2N1/2BP4/4p2P/PPP3P1/R2Q1RK1 w - - +solution Nxf7 +id "ECM.553" +go +setboard 1r4k1/3qb2p/pr1pppn1/2p2N2/2P2PQ1/1P4P1/P2R2BP/R5K1 w - - +solution Bd5 +id "ECM.554" +go +setboard r6r/pR1nqkpp/2p1p3/3p4/6Q1/2b4P/P1PP1PP1/2B1R1K1 w - - +solution Rxe6 +id "ECM.555" +go +setboard 1k1r3r/ppq2pnp/1npbb1p1/3p4/3P1NP1/2NBP2P/PPQ2P1B/1KR4R w - - +solution Nb5 +id "ECM.556" +go +setboard 5rk1/p1p1br2/1p1p2qp/4p3/2PPn1pP/3Q2P1/PPN1P1K1/2RR2B1 b - - +solution Bxh4 +id "ECM.557" +go +setboard r5r1/4q2k/p2p3p/5p2/4p3/P2QR3/1PP2PPP/4R1K1 w - - +solution Rxe4 +id "ECM.558" +go +setboard r1b2rk1/4bnpp/2p5/pp2q3/4N3/PQ2B1P1/1PP3BP/4RRK1 w - - +solution Ng5 +id "ECM.559" +go +setboard 2rr2k1/1p3p2/p2n2p1/P2PnNq1/3QP1p1/1RN5/6PP/5RK1 b - - +solution Nf3+ +id "ECM.560" +go +setboard r3k1r1/pb1qpp1p/1pnp1n1B/2p2R2/3PP3/2P3PN/P1P3BP/R2Q3K b q - +solution Nxe4 +id "ECM.561" +go +setboard 2r2rk1/pp2bppp/3q1n2/3nNRB1/3P4/1B5Q/PP4PP/3R2K1 w - - +solution Nxf7 +id "ECM.562" +go +setboard r1bq1rk1/1pp2ppn/1pnp3p/3N4/2B1PN2/3P4/PPP3PP/R2Q1RK1 w - - +solution Ng6 +id "ECM.563" +go +setboard r1b2rk1/pp3p1p/2pq2pn/2nNN3/2B1QP2/8/P1PP2PP/R1B1K2R w KQ - +solution Nxf7 +id "ECM.564" +go +setboard 1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - +solution Nxf7 +id "ECM.565" +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +solution Rxc5 +id "ECM.566" +go +setboard r1b3k1/2pq2pp/p4p2/1p1Nr3/2n2R2/1B6/PPQ2PPP/R5K1 w - - +solution Rxc4 +id "ECM.567" +go +setboard 2rq1rk1/3bbppp/p3pn2/1p1pN3/2nP1B2/P1NBP2Q/1P3PPP/2R2RK1 w - - +solution Nxd5 +id "ECM.568" +go +setboard 2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - +solution Nxc1 +id "ECM.569" +go +setboard 1r4nk/3b2bp/3p4/3P3p/2pNPq2/P1N2p1P/1P3Q2/1R4KR b - - +solution Rxb2 +id "ECM.570" +go +setboard 2r5/p3kpp1/P2p4/1P2pP1p/1P2PqnP/6R1/r2N2P1/3RQ1K1 b - - +solution Rxd2 +id "ECM.571" +go +setboard 2br2k1/1p2qppp/r1n1p3/pQ1nN3/P2P4/2B3P1/1P3PBP/2RR2K1 w - - +solution Qxa6 +id "ECM.572" +go +setboard 5rk1/3q2bp/3pb2r/1p1n1p2/3p1P2/P2B1QN1/1P1B2PP/2R1R1K1 w - - +solution Nxf5 +id "ECM.573" +go +setboard 4r1k1/1ppQr1p1/1p1p1pP1/3P3p/7P/1P3q2/P1P5/1KRR4 w - - +solution Re1 +id "ECM.574" +go +setboard 2Rr2k1/7p/4pqp1/p4p2/1p1P1Q1P/8/PP3PP1/6K1 w - - +solution Qe5 +id "ECM.575" +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +solution Rc1 +id "ECM.576" +go +setboard 5rk1/bp4p1/p2rp2p/8/8/2PN4/PP1R1PPP/3R2K1 b - - +solution e5 +id "ECM.577" +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +solution Bh3 +id "ECM.578" +go +setboard n1bq3k/pp4bp/6p1/5pP1/3p1P2/1B1P4/PB3Q1P/4R1K1 w - - +solution Bxd4 +id "ECM.579" +go +setboard r3r1k1/p2n4/3p1pp1/qnp3B1/1p2P1P1/1P3P2/PP2N2Q/1K1R1B2 w - - +solution Nf4 +id "ECM.580" +go +setboard 6k1/pb3ppp/1p2p3/4P3/5P2/P1r5/1q4PP/1B2Q1RK b - - +solution Rc1 +id "ECM.581" +go +setboard 2rq1kbR/4R1p1/3p3r/pp1P1Pp1/6P1/3B4/PPP1Q3/6K1 w - - +solution f6 +id "ECM.582" +go +setboard 2r5/5kb1/4ppp1/pp1qB3/2rP4/1RP2R1Q/P4PP1/6K1 b - - +solution Rh8 +id "ECM.583" +go +setboard 4k3/4Bp2/1p2nP1P/2p5/2K1b1B1/8/P7/8 w - - +solution Bf3 +id "ECM.584" +go +setboard 3rr1k1/ppp1qp1p/3b2p1/4np1P/1P1N1Pn1/P1P4R/1B1NB3/R2Q1K2 b - - +solution Nf3 +id "ECM.585" +go +setboard 1k1r3r/ppqb4/5Ppp/3p4/P2np3/3BR1Q1/2PB1PPP/R5K1 w - - +solution Rxe4 +id "ECM.586" +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +solution Nxc6 +id "ECM.587" +go +setboard 8/2R2pbk/6pp/1p2pq2/1P2Qn2/3P3P/3B1PP1/r3N1K1 b - - +solution Nxd3 +id "ECM.588" +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +solution h3 +id "ECM.589" +go +setboard r2b1rnk/1p4qp/p1p1b1p1/2PpNp2/PP1PnP1Q/3BB2R/4N1PP/R6K w - - +solution Qxh7+ +id "ECM.590" +go +setboard r1b2rk1/1p3pbp/2p3p1/p1q5/1P6/1Q4P1/1P2PPBP/R1B1R1K1 b - - +solution Be6 +id "ECM.591" +go +setboard 4r1k1/r1q2p1p/p5pB/1pbBpN1n/1n2P3/5Q2/PP3PPP/R1R3K1 w - - +solution Rxc5 +id "ECM.592" +go +setboard r1r3k1/ppnbb1pp/2ppp1q1/1P3p2/P1PPn3/2N2NP1/2Q1PPBP/1RB2RK1 w - - +solution Nxe4 +id "ECM.593" +go +setboard r1b1k2r/2q1bppp/p3p3/1p1nP1B1/3Q4/2N5/PPP1B1PP/2KR3R w kq - +solution Bxe7 +id "ECM.594" +go +setboard 1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - +solution Nxh2 +id "ECM.595" +go +setboard 2rqk1nr/pp3ppp/2n1p3/2b5/3N4/2NQB1P1/PP2PPKP/R4R2 w k - +solution Nxe6 +id "ECM.596" +go +setboard rnb2rk1/pp4pp/2pb1n2/3N1p1q/2P5/3N2P1/P1Q1PPBP/R1B2RK1 w - - +solution Bf4 +id "ECM.597" +go +setboard 8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - +solution f4 +id "ECM.598" +go +setboard 8/5pp1/7p/5P1P/2p3P1/2k5/5P2/2K5 w - - +solution f6 +id "ECM.599" +go +setboard 7k/8/1p1ppp1p/1Pp5/2P2P2/8/3P2PP/6K1 w - - +solution f5 +id "ECM.600" +go +setboard 8/p5k1/2p2p2/4p1p1/1p2P3/1P4PP/1PP5/5K2 b - - +solution g4 +id "ECM.601" +go +setboard 8/5K2/kp6/p1p5/P2p4/1P3P2/2P5/8 b - - +solution b5 +id "ECM.602" +go +setboard 8/2k3p1/2p4p/5P2/2K3PP/8/8/8 w - - +solution g5 +id "ECM.603" +go +setboard 8/1kp1b3/1p4K1/4P2p/P1P3p1/5pP1/P4P2/4B3 b - - +solution h4 +id "ECM.604" +go +setboard 8/8/4b1p1/2Bp3p/5P1P/1pK1Pk2/8/8 b - - +solution g5 +id "ECM.605" +go +setboard 8/8/3K1k2/5p1p/4p1p1/4P1P1/5PP1/8 b - - +solution f4 +id "ECM.606" +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +solution Bxg6 +id "ECM.607" +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +solution Rxc6 +id "ECM.608" +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +solution f6 +id "ECM.609" +go +setboard 2kr3r/ppp1qpp1/2p5/2b2b2/2P1pPP1/1P2P1p1/PBQPB3/RN2K1R1 b Q - +solution Rh1 +id "ECM.610" +go +setboard 1r3qk1/pb3p1p/1pn2PpQ/2pN4/3r4/5B2/PPP4P/4RRK1 w - - +solution Ne7+ +id "ECM.611" +go +setboard 4r1k1/5p1p/3q2p1/1p1P4/1P6/2p4P/2Q1nPB1/4RK2 b - - +solution Ng3+ +id "ECM.612" +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +solution e5 +id "ECM.613" +go +setboard 5r2/pp1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +id "ECM.614" +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +solution b5 +id "ECM.615" +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +solution Rxa6 +id "ECM.616" +go +setboard 3r2k1/p6p/b2r2p1/2qPQp2/2P2P2/8/6BP/R4R1K w - - +solution Rxa6 +id "ECM.617" +go +setboard 8/p3q1k1/6p1/1p3nP1/2pp1QBr/P2P4/1PP2K2/R7 b - - +solution Qe3+ +id "ECM.618" +go +setboard 7k/4b2p/5p1P/5PP1/1pNp1P2/1P1B4/2P2K2/r7 w - - +solution g6 +id "ECM.619" +go +setboard 5r1k/1p1b2rP/p2p4/3P3B/P2P4/5pP1/1P2pP2/R3R1K1 b - - +solution Rxg3+ +id "ECM.620" +go +setboard 6B1/2p2pp1/2p5/p3K3/1k6/nP4P1/5P1P/8 b - - +solution Nc4+ +id "ECM.621" +go +setboard 3q1k2/5p2/p5pN/1b2Q2P/8/8/5PPK/8 w - - +solution Qh8+ +id "ECM.622" +go +setboard 6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - +solution Rc4 +id "ECM.623" +go +setboard 4r2k/3n1Qpp/1pRP1p2/p4P2/1p1P2P1/6rP/P3q1B1/6RK w - - +solution Qe6 +id "ECM.624" +go +setboard 2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - +solution Nxe6 +id "ECM.625" +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +solution Ba6 +id "ECM.626" +go +setboard 3rr1k1/pppRn1pp/4Pp2/1P5q/1QB5/4P3/P4P1P/4K1R1 w - - +solution Qxe7 +id "ECM.627" +go +setboard rn1q2k1/pp3pb1/3p2pp/2pP2N1/3r1P2/7Q/PP4PP/R1B2RK1 w - - +solution Nxf7 +id "ECM.628" +go +setboard 8/6Bp/6p1/2k1p3/4PPP1/1pb4P/8/2K5 b - - +solution b2+ +id "ECM.629" +go +setboard 5bk1/r4ppp/1r1P1n2/2p2N2/b7/2B3P1/5PBP/R3R1K1 w - - +solution Bxf6 +id "ECM.630" +go +setboard 8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - +solution a6 +id "ECM.631" +go +setboard 3qr1k1/p4ppp/1p1P4/2r1nN2/4P2n/P7/1B4P1/3QRRK1 w - - +solution d7 +id "ECM.632" +go +setboard 6k1/5pbp/6p1/2p1r3/1pPr4/3n2NP/1PB2PP1/1R1R2K1 b - - +solution Nxb2 +id "ECM.633" +go +setboard 4r3/p4pk1/6p1/P1pB2Pp/2P3b1/2p1N1P1/Qb1r1P2/6K1 b - - +solution Rxe3 +id "ECM.634" +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +solution Nxa7 +id "ECM.635" +go +setboard r4rk1/ppq3pp/2p1Pn2/4p1Q1/8/2N5/PP4PP/2KR1R2 w - - +solution Rxf6 +id "ECM.636" +go +setboard r3qr1k/1b4pp/p2RQ3/Bp2p3/4p3/6P1/PPP2P1P/3R2K1 b - - +solution Qh5 +id "ECM.637" +go +setboard 8/6kP/6p1/1p1pP3/pP6/P1n2K2/2N5/8 w - - +solution e6 +id "ECM.638" +go +setboard 8/Pb6/8/8/7K/5k1p/6pB/8 b - - +solution g1=Q +id "ECM.639" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "ECM.640" +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +solution cxb6 +id "ECM.641" +go +setboard 6k1/p4pbp/Bp2p1p1/n2P4/q3P3/B1rQP3/P5PP/5RK1 w - - +solution dxe6 +id "ECM.642" +go +setboard 5r2/R4p2/5P1k/4PK2/1p6/8/8/8 w - - +solution Rxf7 +id "ECM.643" +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +solution f5 +id "ECM.644" +go +setboard 1r6/3r1Pk1/p2p1np1/5q2/1p3P2/1B5R/PPP4Q/1K1R4 w - - +solution Rh8 +id "ECM.645" +go +setboard 8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - +solution Bxb3 +id "ECM.646" +go +setboard 2r5/1r5k/1P3p2/PR2pP1p/4P2p/2p1BP2/1p2n3/4R2K b - - +solution Nd4 +id "ECM.647" +go +setboard 4r2k/p2qr1pp/1pp2p2/2p1nP1N/4R3/1P1P2RP/1PP2QP1/7K w - - +solution Rxg7 +id "ECM.648" +go +setboard 6k1/p4p2/5Ppp/3RP3/Pr4P1/2p2K2/7P/8 w - - +solution Rd8+ +id "ECM.649" +go +setboard 8/1R2P3/6k1/3B4/2P2P2/1p2r3/1Kb4p/8 w - - +solution Be6 +id "ECM.650" +go +setboard 2kr2r1/pp2bQ1p/2b1P3/2qN4/8/1B2p2P/PPP3P1/3R1R1K b - - +solution e2 +id "ECM.651" +go +setboard r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - +solution Bxh7+ +id "ECM.652" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Bb5 +id "ECM.653" +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +solution Bxh7+ +id "ECM.654" +go +setboard 6rk/3nrpbp/p1bq1npB/1p2p1N1/4P1PQ/P2B3R/1PP1N2P/5R1K w - - +solution Nxh7 +id "ECM.655" +go +setboard 1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - +solution Bxh7+ +id "ECM.656" +go +setboard 2k5/ppp3pp/8/NQ2n2q/2Pp1n2/R4bP1/1P3P1P/4R1K1 b - - +solution Qxh2+ +id "ECM.657" +go +setboard 5rrk/1p3qpp/p3pn2/2PpBp2/3P1P1Q/P1P1R2R/2b1B1PP/6K1 w - - +solution Qxh7+ +id "ECM.658" +go +setboard r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - +solution Bxh7+ +id "ECM.659" +go +setboard r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/1P3PPP/2R3K1 w - - +solution Bxh7+ +id "ECM.660" +go +setboard r5rk/1p1q1p1p/5pn1/p2p1N1Q/3P2P1/PP2R3/5P1P/5RK1 w - - +solution Qxh7+ +id "ECM.661" +go +setboard 2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - +solution Rxh7+ +id "ECM.662" +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +solution Rxh7 +id "ECM.663" +go +setboard 4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - +solution Bxh7+ +id "ECM.664" +go +setboard r1b2rk1/2q1bppp/p1n1p3/1p1np1P1/5P2/1NNBBQ2/PPP4P/R4RK1 w - - +solution Bxh7+ +id "ECM.665" +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +solution Nxh7 +id "ECM.666" +go +setboard r4rk1/pp2q1p1/4b2p/2ppb3/6n1/2P3N1/PPQBBPPP/R4RK1 b - - +solution Nxh2 +id "ECM.667" +go +setboard b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - +solution Bxh7+ +id "ECM.668" +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +solution Qxh7+ +id "ECM.669" +go +setboard r1b1rnk1/pp1nb1pp/2p1pp2/q3N3/2PP1P2/3BP1N1/PBQ3PP/R4RK1 w - - +solution Bxh7+ +id "ECM.670" +go +setboard 4r1k1/2q2r1p/p3bQ2/1p4Bp/2np4/8/PPB2PP1/3RR1K1 w - - +solution Bxh7+ +id "ECM.671" +go +setboard 5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - +solution Bxh7+ +id "ECM.672" +go +setboard 2rqr1k1/1p1bbppp/p3p3/n7/3P2Q1/2PB1N2/P4PPP/R1B1R1K1 w - - +solution Bxh7+ +id "ECM.673" +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +solution Nxh7 +id "ECM.674" +go +setboard rn1q1rk1/pb1p1ppp/4p3/2pnP3/1bp5/2N2N2/PP3PPP/RBBQK2R w KQ - +solution Bxh7+ +id "ECM.675" +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +solution Rxh7 +id "ECM.676" +go +setboard r1b2rk1/1pq2ppp/p1p1p3/2n1P3/2N2P2/3B4/PPP3PP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.677" +go +setboard rnq3rk/4bp1p/p1p3pQ/1p1pP3/1P1N1B2/2P3R1/1P3PPP/R5K1 w - - +solution e6 +id "ECM.678" +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +solution Nxh7 +id "ECM.679" +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +solution Bxh7+ +id "ECM.680" +go +setboard 1r2nrkb/2n2p1p/p2p1Pp1/P1pPp1P1/1pP1P1q1/1P1BB1N1/3Q4/2KR3R w - - +solution Rxh7 +id "ECM.681" +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +solution Bxh7+ +id "ECM.682" +go +setboard r2q3r/2pkb1p1/p2p1n2/4p1p1/Pp2P1P1/1QP5/1P1P2PP/RNB2RK1 b - - +solution Rxh2 +id "ECM.683" +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +solution Nxh7 +id "ECM.684" +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +solution Rxh7 +id "ECM.685" +go +setboard r2qn1k1/pb4Pp/1pn5/2p5/2P2p2/P1PB4/5PPP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.686" +go +setboard r4rk1/pp1n1ppp/3qp3/3nN1P1/b2P4/P2B1Q2/3B1P1P/1R2R1K1 w - - +solution Bxh7+ +id "ECM.687" +go +setboard r2r2k1/ppqbbppp/4pn2/6N1/n1P4P/3B1N2/PP2QPP1/1KBR3R w - - +solution Nxh7 +id "ECM.688" +go +setboard r5k1/6bp/2q1p1p1/p2pP3/3P4/1rP2QP1/3B1PK1/2R4R w - - +solution Rxh7 +id "ECM.689" +go +setboard r6r/4ppk1/p2p1bp1/B2p4/3P2p1/QP2P3/P1R1qPPP/2R3K1 b - - +solution Rxh2 +id "ECM.690" +go +setboard 4nrk1/r4p1p/p2p2pQ/2pPpNPP/qpn1P3/5P1R/PPP1N3/2K3R1 w - - +solution Qxh7+ +id "ECM.691" +go +setboard r3k2r/1b1n1p2/pq1p1bp1/1p4p1/P3P3/1NN5/1PP3PP/R2QRB1K b kq - +solution Rxh2+ +id "ECM.692" +go +setboard r2qrnk1/4bppp/b1p5/1p1p2P1/p2P1N1P/2NBP3/PPQ2P2/2K3RR w - - +solution Bxh7+ +id "ECM.693" +go +setboard rn1q1rk1/pppbb1pp/4p3/3pP1p1/3P3P/2NB4/PPP2PP1/R2QK2R w KQ - +solution Bxh7+ +id "ECM.694" +go +setboard 1r2nr1k/6pp/pp1p1p2/2pPnN2/q1P1PB2/5PR1/4K1P1/2Q4R w - - +solution Bxe5 +id "ECM.695" +go +setboard 3r1rk1/4qp1p/p1bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxh2+ +id "ECM.696" +go +setboard r2q1rk1/3n1ppp/8/1pbP2P1/p1N4P/PnBBPQ2/5P2/R3K2R w KQ - +solution Bxh7+ +id "ECM.697" +go +setboard 2k3r1/ppq2p1p/n1Pb1p2/8/6r1/4BN1b/PPQ2PPP/R3RBK1 b - - +solution Bxh2+ +id "ECM.698" +go +setboard 3qr1k1/1br2ppp/p2b4/8/PpNp4/3P4/1PP2PPP/R1BQ1RK1 b - - +solution Bxh2+ +id "ECM.699" +go +setboard 3r2k1/p1R2p2/4pQp1/1q5p/5P1P/1PR5/2Pr2P1/6K1 b - - +solution Rxg2+ +id "ECM.700" +go +setboard r1b4r/3p1kp1/pp3q1p/4RP2/8/B7/P5PP/4QRK1 w - - +solution Qe4 +id "ECM.701" +go +setboard 1r2rnk1/2R2bpp/p2q4/1p1N2R1/5P2/1Q1B3P/PP4P1/7K w - - +solution Rxg7+ +id "ECM.702" +go +setboard 3r2k1/pb5p/1p2qpp1/8/2p5/1P1nP3/P1N2PPP/1Q1R1R1K b - - +solution Bxg2+ +id "ECM.703" +go +setboard 4rrk1/2qb2pp/p5P1/1p2p3/1b2P3/2N5/PPPQ4/1K1R2R1 w - - +solution gxh7+ +id "ECM.704" +go +setboard 3q1k2/pp3ppn/2p1n2p/4pN1N/P3P2P/5Q2/1PP2PP1/6K1 w - - +solution Nhxg7 +id "ECM.705" +go +setboard 2r2r1k/3b1pb1/p3pp1p/q2p1P1B/8/2N2RR1/P1PQ2PP/7K w - - +solution Rxg7 +id "ECM.706" +go +setboard 5bk1/1p4p1/4N1R1/3p4/p1r2P1q/Pr1QP2P/1P6/1K4R1 w - - +solution Rxg7+ +id "ECM.707" +go +setboard 2r1r1k1/5ppp/p3pn2/1pb1N3/2P5/1PQ3R1/PB2qPPP/3R2K1 w - - +solution Rxg7+ +id "ECM.708" +go +setboard 7k/1bp1P1p1/3p2rp/1pb2p1q/5P2/1BP2N1P/1P4P1/R1B2R1K b - - +solution Rxg2 +id "ECM.709" +go +setboard r1q1bk1r/1p3pp1/4pn1p/p3Q3/P1P2N2/1B4R1/1P3PPP/4R1K1 w - - +solution Rxg7 +id "ECM.710" +go +setboard r4rk1/p2n2p1/1q1Qpn1p/1P6/P6B/2p5/2B1KP1P/R5R1 w - - +solution Rxg7+ +id "ECM.711" +go +setboard r2qr1k1/1p3ppp/2pb4/2Np4/1P1P2bn/3BP3/2QN1PPP/1RR3K1 b - - +solution Nxg2 +id "ECM.712" +go +setboard r3r1k1/pp3pp1/3p4/2q4p/2P5/1PB2Q1P/n4PP1/3R1RK1 w - - +solution Bxg7 +id "ECM.713" +go +setboard r5k1/pn1q1rpp/2pp4/5R1N/bP6/4BQ2/P4PPP/2R3K1 w - - +solution Nxg7 +id "ECM.714" +go +setboard 3r1rk1/5pp1/pq1n1n1p/2pPR3/2B2P2/1PBQ2RP/P5P1/6K1 w - - +solution Rxg7+ +id "ECM.715" +go +setboard rn3rk1/ppq2ppp/2pb1nb1/5N2/2BP4/8/PPP1N1P1/R1B1QR1K w - - +solution Nxg7 +id "ECM.716" +go +setboard r1qb1r1k/2p3pp/p1n1bp2/1p1Np2Q/P3P3/1BP3R1/1P3PPP/R1B3K1 w - - +solution Rxg7 +id "ECM.717" +go +setboard r4rk1/5ppp/p2pbb2/3B3Q/qp2p3/4B3/PPP2P1P/2KR2R1 w - - +solution Rxg7+ +id "ECM.718" +go +setboard 4q1k1/1b3r1p/p4pp1/1p6/2P2n2/1P3N2/1B3PPP/R2Q3K b - - +solution Nxg2 +id "ECM.719" +go +setboard r2r3k/5bp1/2p2N2/5P1p/3q3Q/3B2R1/n5PP/3R3K w - - +solution Rxg7 +id "ECM.720" +go +setboard 4rrk1/2pn2pb/p1p1qp2/1pb1pN2/P3P1PN/1P1P4/1BP2PK1/R2Q3R w - - +solution Nxg7 +id "ECM.721" +go +setboard r3r1k1/p3bppp/q1b2n2/5Q2/1p1B4/1BNR4/PPP3PP/2K2R2 w - - +solution Rg3 +id "ECM.722" +go +setboard r4rk1/1p1q1ppp/p1b4B/8/2R3R1/P2P4/1b1N1QPP/6K1 w - - +solution Bxg7 +id "ECM.723" +go +setboard rq3rk1/3b1ppp/p2bp3/3pB2Q/8/1B5P/PP3PP1/2RR2K1 w - - +solution Bxg7 +id "ECM.724" +go +setboard 4kbr1/pp1bpp1p/3p1p2/3N4/1PBQP3/q7/P1r2PPP/R4RK1 b - - +solution Rxg2+ +id "ECM.725" +go +setboard 2r3k1/1p2R1p1/p3n2p/2pq4/7P/1P1P2P1/PB1Q3K/8 w - - +solution Bxg7 +id "ECM.726" +go +setboard 2rr2k1/4bppp/p1n1p3/3q4/1p1P2N1/2P3R1/P3QPPP/2B2RK1 w - - +solution Nh6+ +id "ECM.727" +go +setboard rq1r1bk1/1b3pp1/3pn2p/1n2BN1P/1P2P3/3R1NP1/3Q1PB1/2R3K1 w - - +solution Bxg7 +id "ECM.728" +go +setboard r1b5/ppqn2bk/3R2pp/2p2p2/2P1rN2/4BN2/PPQ2PPP/4R1K1 w - - +solution Rxg6 +id "ECM.729" +go +setboard 3q1r2/1p1b1pk1/pn5p/3pN1pQ/3P3P/2r3B1/P4PP1/3RR1K1 w - - +solution Nxf7 +id "ECM.730" +go +setboard r1bqkbnr/pp2ppp1/2p4p/3n2N1/2BP4/5N2/PPP2PPP/R1BQK2R w KQkq - +solution Nxf7 +id "ECM.731" +go +setboard r2qr1k1/1ppb1p1p/p1np2p1/7Q/3PP2b/1B2N2P/PP3PP1/R1B2RK1 w - - +solution Bxf7+ +id "ECM.732" +go +setboard 2r3k1/pbq1np1p/1p1b1Bp1/8/6QP/2P2N2/B4PP1/4R1K1 w - - +solution Bxf7+ +id "ECM.733" +go +setboard r3r1k1/1bqn1ppp/1pp2p2/8/3P4/1B4N1/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.734" +go +setboard r3r1k1/pp3ppp/8/1Nbp3q/3NnBn1/2P5/PPQ2PPP/3R1RK1 b - - +solution Ngxf2 +id "ECM.735" +go +setboard r2r2k1/1b2qpp1/1p2n3/p1b1p2p/4P1n1/PP1B2PP/1B1NQP2/R3NRK1 b - - +solution Nxf2 +id "ECM.736" +go +setboard r2qr1k1/1b2bp1p/p3p1p1/1p2N1Bn/3P4/P6Q/1P3PPP/RB2R1K1 w - - +solution Nxf7 +id "ECM.737" +go +setboard r5k1/1pp3pp/1b1p1r2/pN1P1n2/P1P3nq/6N1/1P1B1PQP/4RRK1 b - - +solution Nxf2 +id "ECM.738" +go +setboard 2rqnk1r/pp2bpp1/2p1pn1p/2P1N2P/3P1BP1/3BQ3/PP6/2K2R1R w - - +solution Nxf7 +id "ECM.739" +go +setboard 2rq1rk1/1b2bppp/p1n5/1p1BN3/5B2/P7/1P3PPP/R2Q1RK1 w - - +solution Nd7 +id "ECM.740" +go +setboard 3r1qrk/p1p5/bbp3pp/4p3/4Pp1N/2Pn3P/PPQN1PPB/R4RK1 b - - +solution Nxf2 +id "ECM.741" +go +setboard r2qr1k1/pb2bp1p/1pn1p1pB/8/2BP4/P1P2N2/4QPPP/3R1RK1 w - - +solution d5 +id "ECM.742" +go +setboard r3r1k1/1bq1nppp/p1np4/1ppBpN2/4P3/2PP1N2/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.743" +go +setboard r5k1/p4ppp/3qpb2/1P2N3/1nBP4/1P5P/4QPP1/4R1K1 w - - +solution Nxf7 +id "ECM.744" +go +setboard r2qr1k1/1b1nbp1p/p3pp2/1p2N3/3P4/3B1N2/PP2QPPP/R2R2K1 w - - +solution Nxf7 +id "ECM.745" +go +setboard r3k2r/p1qb1p2/1p2p2p/3pPpN1/P1nP3Q/8/2P2PPP/R1B1R1K1 w kq - +solution Nxf7 +id "ECM.746" +go +setboard 3qNk2/5p1p/1r3p2/2p5/Q1pb4/3b2P1/P4PBP/4R1K1 b - - +solution Bxf2+ +id "ECM.747" +go +setboard 2r1r1k1/1pq1bp1p/p3pnp1/P2n2N1/7R/2P4P/1PB1QPP1/2B1R1K1 w - - +solution Nxf7 +id "ECM.748" +go +setboard r1bq2k1/pp1n1ppp/3b1n2/PQ1B3r/3N1P2/2N5/1PP3PP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.749" +go +setboard 2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - +solution Bxf7+ +id "ECM.750" +go +setboard r4rk1/ppRn1p2/6pb/2P1pq1p/3N4/P1QPn1Pb/1B1NPP1P/4R1KB b - - +solution Qxf2+ +id "ECM.751" +go +setboard r3kr2/1b2qp2/pp2p2N/4p2Q/8/2n5/P3B1PP/3R1R1K w q - +solution Nxf7 +id "ECM.752" +go +setboard b2r1rk1/pq2bpp1/1p2p2p/4N2n/2P2R2/1PB2N2/1P2QPPP/4R1K1 w - - +solution Rxf7 +id "ECM.753" +go +setboard rqb1k2r/1p1nbp1p/p4pp1/8/1PBN1P2/P1N1P3/7P/2RQ1RK1 w kq - +solution Bxf7+ +id "ECM.754" +go +setboard r2r2k1/4ppbp/5np1/p1q5/QnB1P3/5N2/1P3PPP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.755" +go +setboard 1r2q1k1/p3pp2/3p1bp1/2pP2N1/8/P5PB/2Q2PK1/1rBR4 w - - +solution Nxf7 +id "ECM.756" +go +setboard 2rqrbk1/pb1n1p1p/1p2pnp1/4N3/2BP1N2/1P2Q3/PB3PPP/3R1RK1 w - - +solution Nxf7 +id "ECM.757" +go +setboard 1r4k1/p4pp1/bqnrpn1p/2ppN3/2P2P1B/P3P3/1P2B1PP/1Q1R1RK1 w - - +solution Bxf6 +id "ECM.758" +go +setboard r1bqrbk1/5p1p/2pp2nB/pp5Q/4P3/PBNPR2P/1P4P1/R5K1 w - - +solution Bxf7+ +id "ECM.759" +go +setboard r1bqkb1r/1p3ppp/pn1P1n2/4p3/2B5/2N2N2/PP3PPP/R1BQ1RK1 w kq - +solution Bxf7+ +id "ECM.760" +go +setboard 2rqr1k1/pp2nppp/3p2b1/6B1/2BNn1Q1/P7/1PP2PPP/2KRR3 w - - +solution Bxf7+ +id "ECM.761" +go +setboard r3r1k1/pbq1ppbp/1pp2np1/4N3/3P4/2P5/PPB1QPPP/R1B1R1K1 w - - +solution Nxf7 +id "ECM.762" +go +setboard r1b2rk1/p6p/2p3Pb/3pp1q1/8/2PB4/PP3PP1/RN1Q1K1R b - - +solution Rxf2+ +id "ECM.763" +go +setboard r2rn3/1p3pk1/p1pNn1pp/q3P3/P7/1PN4P/2QR1PP1/3R2K1 w - - +solution Nxf7 +id "ECM.764" +go +setboard r1bqr1k1/1p1nnpb1/p5pp/2P1p1B1/B3N3/5N2/P4PPP/2RQR1K1 w - - +solution Nd6 +id "ECM.765" +go +setboard r1b1r1k1/pp2qpbp/2p3p1/2P5/3NnB2/7P/PPQ1PPB1/2RR2K1 b - - +solution Nxf2 +id "ECM.766" +go +setboard rn2r1k1/pp3p1p/3P2p1/2p1bbB1/2B5/2N5/Pq4PP/R2Q1RK1 w - - +solution Bxf7+ +id "ECM.767" +go +setboard 5rk1/r2qnppp/p1nN4/2Q5/3PB3/4P3/6PP/R4RK1 w - - +solution Nxf7 +id "ECM.768" +go +setboard 1bq2k2/1b1n1pp1/pp5p/2pBpN2/P3P2B/3Q1P2/1PP3PP/4K3 w - - +solution Bxf7 +id "ECM.769" +go +setboard rnb2rk1/pp3pbp/2p3pB/2q5/4P3/1BN5/PPP3PP/R2Q1R1K w - - +solution Rxf7 +id "ECM.770" +go +setboard 3qr1k1/1br1bp1p/p3p1pB/1p1nN3/3PB3/7Q/PP3PPP/3RR1K1 w - - +solution Nxf7 +id "ECM.771" +go +setboard 1qr1b1k1/4bpp1/pn2p2p/1p1nN3/3P4/P2BBN1Q/1P3PPP/4R1K1 w - - +solution Bxh6 +id "ECM.772" +go +setboard rr1q2k1/1p2bpp1/2p1p2p/P1Pn4/2NP4/3Q1RP1/5PKP/2B1R3 w - - +solution Bxh6 +id "ECM.773" +go +setboard r2r2k1/pb1nbpp1/1qp1pn1p/1p2N3/3P1B2/P1N1P3/BPQ2PPP/2R2RK1 w - - +solution Bxh6 +id "ECM.774" +go +setboard 2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - +solution Rxh6+ +id "ECM.775" +go +setboard r1b1r3/pp2Npbk/3pp2p/q5p1/2QNPP2/6P1/PPP3P1/2KR3R w - - +solution Ndf5 +id "ECM.776" +go +setboard r1q3r1/1ppQ2pk/3bNp1p/p3pP2/P3P3/7R/1PP3PP/3R2K1 w - - +solution Rxh6+ +id "ECM.777" +go +setboard 4r1k1/p1pq1pp1/2p5/3p1b2/Q7/2P1B2P/P1P1rPP1/2R2RK1 b - - +solution Bxh3 +id "ECM.778" +go +setboard 1rbqnr2/5p1k/p1np3p/1p1Np3/4P2P/1Q2B3/PPP1BP2/2KR3R w - - +solution Bxh6 +id "ECM.779" +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.780" +go +setboard 3r1r1k/p5p1/n1p2p1p/1qp2b2/N1R4R/1PB1P1P1/P2P3P/3Q2K1 w - - +solution Rxh6+ +id "ECM.781" +go +setboard r4rk1/2q1b1p1/p4p1p/n3pP2/1p2Q1N1/4B3/PPP3PP/4RR1K w - - +solution Nxh6+ +id "ECM.782" +go +setboard 6rk/3b1n1p/1p1q3b/1PpNp3/2P1Pp2/2Q2NrP/5RP1/2R2B1K b - - +solution Bxh3 +id "ECM.783" +go +setboard r2q1rk1/ppp2pp1/1b2b2p/3n3Q/2Bp4/3P1N2/PPP2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.784" +go +setboard r3rbk1/1bp1qpp1/p6p/np2p2Q/4P2N/1BP4P/PP3PP1/R1B1R1K1 w - - +solution Bg5 +id "ECM.785" +go +setboard 4q3/p2r1ppk/R6p/3n4/3B1Q2/4P2P/5PP1/6K1 w - - +solution Rxh6+ +id "ECM.786" +go +setboard 7r/1p2qk2/pQ1p2p1/3Ppp2/P4b2/2P2PrP/1P2R1B1/4R2K b - - +solution Rhxh3+ +id "ECM.787" +go +setboard 5rk1/Qp5p/3pp1p1/4n3/2P1P2q/5r1P/P3NPP1/3R1RK1 b - - +solution Rxh3 +id "ECM.788" +go +setboard 2r1r1k1/pb1n1pp1/1p1qpn1p/4N1B1/2PP4/3B4/P2Q1PPP/3RR1K1 w - - +solution Bxh6 +id "ECM.789" +go +setboard 3q1rk1/p2bbpp1/1rn4p/1pp2P2/3pBBP1/3P3P/PPPQ3N/R4RK1 w - - +solution Bxh6 +id "ECM.790" +go +setboard 2br2k1/4qppp/p5r1/2pBp3/2P1Pn2/4Q2P/RP3PPK/1N4R1 b - - +solution Bxh3 +id "ECM.791" +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +solution Bxh6 +id "ECM.792" +go +setboard r5r1/pbn4k/1p1p1Ppp/2pPn3/4BQq1/1PN3P1/PB3PK1/3R1R2 w - - +solution Qxh6+ +id "ECM.793" +go +setboard r1b2rk1/pp2bpp1/4p2p/2q4Q/5nNB/2PB4/PP3PPP/2KR3R w - - +solution Nxh6+ +id "ECM.794" +go +setboard 6k1/p4ppp/1pn1b1rr/8/PBpPp2q/2P1P1NP/5PP1/RR3QK1 b - - +solution Bxh3 +id "ECM.795" +go +setboard r1b2rk1/1p3pp1/p5Pp/2bpPp1Q/3N4/1Pq1B1R1/2P4P/3R2K1 w - - +solution Bxh6 +id "ECM.796" +go +setboard r2r2k1/pp1n1bp1/2p2p1p/b4N2/q2BR3/2QB2PP/1PP5/2KR4 w - - +solution Nxh6+ +id "ECM.797" +go +setboard 3r2bk/1q4p1/p2P1N1p/2p1rP2/pb5R/7P/1P4P1/2Q2RK1 w - - +solution Rxh6+ +id "ECM.798" +go +setboard 2b1rk2/r6p/1pP1p1p1/p2pNnR1/5Q2/P1B4q/1PP2P1P/1K4R1 w - - +solution Nxg6+ +id "ECM.799" +go +setboard 6R1/6Q1/3q2p1/5p1p/P3p1k1/1P1r2P1/5PK1/8 b - - +solution Rxg3+ +id "ECM.800" +go +setboard r6r/ppnqpk2/3pbpp1/5N2/1PP1P3/5RR1/P2QB1PP/6K1 w - - +solution Nh6+ +id "ECM.801" +go +setboard 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - +solution Rfxg6+ +id "ECM.802" +go +setboard 2b2r1k/2p3pp/2Nb4/pP5q/2PP4/P4pP1/5P1P/R1BQ2K1 b - - +solution Bxg3 +id "ECM.803" +go +setboard r1bq2k1/pp3r1p/2n1p1p1/3pP3/6Q1/2PB2P1/P4PK1/R1B4R w - - +solution Bxg6 +id "ECM.804" +go +setboard 3q1rk1/2r4p/n1p1n1pQ/p2pP3/Np1P2R1/5PN1/PP3KP1/2R5 w - - +solution Rxg6+ +id "ECM.805" +go +setboard 2Nq1rk1/6pp/b1p2b2/p6Q/np1p4/6P1/PB3PBP/R3R1K1 w - - +solution Be4 +id "ECM.806" +go +setboard r2r4/p4pk1/2p3p1/1p1nPR2/5p1Q/2N5/PPPq4/1K4R1 w - - +solution e6 +id "ECM.807" +go +setboard 2kr3r/pbq3p1/1p2pp2/2b4n/2P1B3/1P1N2Pp/PB2QP1P/R4RK1 b - - +solution Nxg3 +id "ECM.808" +go +setboard r5k1/1p2Rpb1/3p1np1/2nP2B1/1qP5/1pN1Q2P/P5P1/1B4K1 w - - +solution Bxg6 +id "ECM.809" +go +setboard 2rqr1k1/pb2bp1p/1pn1pnpB/4N3/3P4/P1N3R1/1P3PPP/RB1Q2K1 w - - +solution Rxg6+ +id "ECM.810" +go +setboard 2r5/pp2qr1k/1nb3pp/2ppBp2/2P4P/3B2R1/P3QPP1/1R4K1 w - - +solution Rxg6 +id "ECM.811" +go +setboard 3rr3/3q1p1k/p2P2pp/1bp1b3/5N2/6QP/P1B3P1/3RR1K1 w - - +solution Bxg6+ +id "ECM.812" +go +setboard r2q1rk1/pp2ppb1/3pn1pQ/3R4/2P3B1/4BR2/PP4PP/6K1 w - - +solution Qxg6 +id "ECM.813" +go +setboard 1n1b1rk1/r4p1p/p1p2qpQ/P3Np2/2BP4/2P1R3/5PPP/R5K1 w - - +solution Rb1 +id "ECM.814" +go +setboard 6rk/pb3p1p/3bpPq1/3P4/1p1B3r/1B4P1/PPRQ1R1P/6K1 b - - +solution Bxg3 +id "ECM.815" +go +setboard 3rr1k1/pb2bp1p/3qp1pB/1p2N3/3P2Q1/2P1R3/P4PPP/4R1K1 w - - +solution Nxg6 +id "ECM.816" +go +setboard r2q1rk1/pb1nbp1p/1p2p1p1/4N1BQ/2PP4/P7/5PPP/RB2R1K1 w - - +solution Nxg6 +id "ECM.817" +go +setboard 1Q4R1/r2qbp2/3p1kp1/3Bp2p/8/3PP1P1/5PKP/8 w - - +solution Rxg6+ +id "ECM.818" +go +setboard r3r1k1/b1p2pn1/p2q1Bp1/1p1bN1Qp/3P4/2P4P/PPB2PP1/R3R1K1 w - - +solution Nxg6 +id "ECM.819" +go +setboard 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - +solution Nxe6 +id "ECM.820" +go +setboard k2r3r/ppq2p1p/n1pb1Pp1/4p3/2Q5/1R2B1P1/PPP2PBP/R5K1 w - - +solution Rxb7 +id "ECM.821" +go +setboard 1rb2rk1/p1p1qppp/2p2n2/3P4/1b3P2/2NB4/PPPBQ1PP/2KR3R b - - +solution Ba3 +id "ECM.822" +go +setboard k7/pp1N4/4P3/5P2/8/5p2/1R6/B4Knq w - - +solution Nb6+ +id "ECM.823" +go +setboard 4rrk1/p5pp/1p4q1/3p2n1/2pP2P1/P1P1PP2/3B2K1/1R2QR2 b - - +solution Nxf3 +id "ECM.824" +go +setboard 1q1r3k/3P1pp1/ppBR1n1p/4Q2P/P4P2/8/5PK1/8 w - - +solution Rxf6 +id "ECM.825" +go +setboard 1rbq2k1/b1p3pp/p1Pp4/3Ppr2/8/5N2/PPQ2PPP/R1B2RK1 b - - +solution Rxf3 +id "ECM.826" +go +setboard 1r1q1r1k/2p3pp/1p1bQ3/p7/1PP5/Pn3B2/1B3PPP/R4RK1 b - - +solution Rxf3 +id "ECM.827" +go +setboard r4rk1/2p1qpp1/p1p5/2Ppn2b/2PQ1N1p/4P3/PB3PPP/R4RK1 b - - +solution Nf3+ +id "ECM.828" +go +setboard r1bq1rk1/1p2bppp/p3p3/n3P3/4N3/1P1P1N2/PB4PP/R3QR1K w - - +solution Nf6+ +id "ECM.829" +go +setboard 1n2r3/p1pq1kp1/1b1pNpp1/3P4/5RP1/3Q3P/1B3P2/6K1 w - - +solution Bxf6 +id "ECM.830" +go +setboard r1bq1rk1/ppp3p1/7p/3P2n1/2PQ1p2/1N5P/PPP2PPK/R1B2R2 b - - +solution Nf3+ +id "ECM.831" +go +setboard 3r1b2/p4bkp/1p1P1p2/r3p1p1/2q1N3/2N2P2/1P1R2PP/2QR3K w - - +solution Nxf6 +id "ECM.832" +go +setboard rqbn1rk1/1p3ppp/p3p3/8/4NP2/8/PPP1BQPP/1K1R3R w - - +solution Nf6+ +id "ECM.833" +go +setboard r1b1kb1r/1p4pp/p2ppn2/8/2qNP3/2N1B3/PPP3PP/R2Q1RK1 w kq - +solution Rxf6 +id "ECM.834" +go +setboard 1rn5/p3Bk1p/1pq1bpp1/P3p3/1Q2P2P/2P3P1/5PB1/1R4K1 w - - +solution Bxf6 +id "ECM.835" +go +setboard 2nr2k1/1pq1bppp/p1p5/2p1P1PQ/2P1NP2/1PNR4/P6P/6K1 w - - +solution Nf6+ +id "ECM.836" +go +setboard 6nk/pn2qr1r/1pbp1p1p/2p1pPpN/P1P1P1PP/2PP3R/7Q/2BBK2R w K - +solution Nxf6 +id "ECM.837" +go +setboard 7r/4p1k1/p3Pppp/1p6/3N1R2/3PQ2P/qr4b1/5RK1 w - - +solution Rxf6 +id "ECM.838" +go +setboard r3k2r/1bq1bp2/p3p1pp/1p2P3/3NpP2/4B1Q1/PPP3PP/1K1R3R w kq - +solution Nxe6 +id "ECM.839" +go +setboard rnbqkb1r/pp1n1p2/4p1p1/1N1pP2p/1P4Q1/3B1N2/P1PB1PPP/R3K2R w KQkq - +solution Qxe6+ +id "ECM.840" +go +setboard r1b1kb1r/1p1n1ppp/p2ppn2/6BB/2qNP3/2N5/PPP2PPP/R2Q1RK1 w kq - +solution Nxe6 +id "ECM.841" +go +setboard r1b1k1nr/3n1p1p/1qpBp1p1/pp2b3/4PN2/PBN2Q2/1PP2PPP/2KR3R w kq - +solution Nxe6 +id "ECM.842" +go +setboard 2r2rk1/1b3ppp/pq2p3/1pbn2N1/3B3P/1B4P1/P1P1QP2/2KRR3 w - - +solution Qh5 +id "ECM.843" +go +setboard r3k2r/pp1n1pb1/1qn1p1p1/2p3Pp/4R2P/2NP2QB/PPPB1P2/2K1R3 w kq - +solution Rxe6+ +id "ECM.844" +go +setboard r3k2r/1q3ppp/p3p3/2b1P3/p2N1Q2/P7/1PP3PP/3R1R1K w kq - +solution Nxe6 +id "ECM.845" +go +setboard 3qr1k1/rp3pbp/2p3p1/3p1b2/N1nP4/P2NP3/1PQ2PPP/1BRR2K1 b - - +solution Rxe3 +id "ECM.846" +go +setboard rnbqkb1r/1p1n1pp1/p3p2p/3pP3/3p1NQP/2N5/P1PB1PP1/R3KB1R w KQkq - +solution Nxe6 +id "ECM.847" +go +setboard 3r1b1R/3bkpp1/1p1np3/1BqpPPP1/PQ1N4/8/1PP5/1K6 w - - +solution f6+ +id "ECM.848" +go +setboard 4r1k1/pp2n2p/1r1n1bp1/q2p1pB1/3P3N/P1NQ1P1P/1PP3R1/1K5R b - - +solution Rxb2+ +id "ECM.849" +go +setboard 3r2k1/2p1bppp/4b3/p2pP3/qr1N1B1P/8/1PPQ2P1/1K1RR3 b - - +solution Rxb2+ +id "ECM.850" +go +setboard 1k1r3r/ppR2ppp/1q2b3/1N6/4Q3/8/PP3PPP/4R1K1 w - - +solution Rxb7+ +id "ECM.851" +go +setboard 1r3rk1/5pbp/p2Pp1p1/q1n3P1/2p2P1P/2N1Q2R/PP6/1BKR4 b - - +solution Rxb2 +id "ECM.852" +go +setboard rr4k1/5p1p/n2p1npQ/q1pP4/6P1/2N2P1N/PP1R3P/2K4R b - - +solution Rxb2 +id "ECM.853" +go +setboard 1k2bb1r/1p3p1p/p2qpP1p/3pN3/3P1Q2/2RB2P1/PP3P1P/6K1 w - - +solution Qc1 +id "ECM.854" +go +setboard 1r4k1/1r3p2/p1p1b1pQ/q3P3/P7/bPN1R1P1/2P4P/1K1R1B2 b - - +solution Bxb3 +id "ECM.855" +go +setboard 5rk1/5rp1/p2qb3/R2Np2Q/3bP2B/7P/P5PK/1R6 b - - +solution Rf1 +id "ECM.856" +go +setboard 6k1/5p2/R3p1p1/1pq1PpB1/4nP2/5Q1P/P2r2PK/8 w - - +solution Ra8+ +id "ECM.857" +go +setboard 3r1rk1/p3q1pp/2Rb4/3P4/8/1P2Qp2/PB3PPP/3R2K1 b - - +solution Bxh2+ +id "ECM.858" +go +setboard 1r6/5pk1/p1b2qpp/P1P1n3/1N6/Q5NP/5PP1/3R2K1 b - - +solution Bxg2 +id "ECM.859" +go +setboard 1r4k1/1q3pb1/r1b3p1/pp1Qp3/P3P3/1B2BP2/1PP3P1/1K1R3R w - - +solution Qd8+ +id "ECM.860" +go +setboard 2R5/p3q1kp/6p1/3p4/b2P2p1/Pr4N1/5Q2/3K3R w - - +solution Nf5+ +id "ECM.861" +go +setboard 3r4/kb6/pp6/4R1pr/PPpq4/2N3Q1/2P3PP/3R3K b - - +solution Rf8 +id "ECM.862" +go +setboard 4r1k1/5p1p/4q1p1/8/Q5n1/3B2P1/P4P1P/2R3K1 b - - +solution Nxf2 +id "ECM.863" +go +setboard 8/2q1np1k/6p1/1PPn3p/8/P2Q3P/6P1/2R4K b - - +solution Nf5 +id "ECM.864" +go +setboard r1bq1rk1/ppp1n1bn/3p2p1/3Pp1Pp/1PP1Pp1P/2NN1P2/P3B3/R1BQ1RK1 b - - +solution Nxg5 +id "ECM.865" +go +setboard 7R/1p1r4/2b2p2/2Pp1qk1/3P1bp1/3N4/2Q2PB1/6K1 w - - +solution Rg8+ +id "ECM.866" +go +setboard r6r/1pn1b1k1/2p1pq2/2Pp3p/p2P1Pp1/P2BP1P1/1P2QB2/3R2KR w - - +solution Rxh5 +id "ECM.867" +go +setboard 1r4k1/pp4pp/2n1b3/1Rq1p3/2P2r2/P1B2P2/2Q1B1PP/3R1K2 b - - +solution Rxf3+ +id "ECM.868" +go +setboard 7k/1p4p1/2p4r/5p2/p1QP1q2/2P2PR1/r4P1P/4R2K b - - +solution Rxh2+ +id "ECM.869" +go +setboard 1r3r2/6kp/3p1pp1/qnp1pP2/1p2P2N/3P4/PPPQ1P1P/1K1R2R1 w - - +solution fxg6 +id "ECM.870" +go +setboard 5rk1/1rP3pp/p4n2/3Pp3/1P2Pq2/2Q4P/P5P1/R3R1K1 b - - +solution Rxc7 +id "ECM.871" +go +setboard 2rq1rk1/5ppp/2b1pb2/np6/6N1/2NBB3/PP3PPP/R2Q2K1 w - - +solution Bb6 +id "ECM.872" +go +setboard 5r2/p2p2kp/3PnNp1/1qr1Pp2/2p5/P1R5/6PP/2Q1R1K1 w - - +solution Qh6+ +id "ECM.873" +go +setboard 2Qbq1k1/6p1/1p4Np/4p2P/3rP3/8/3p2PK/3R4 w - - +solution Rf1 +id "ECM.874" +go +setboard 2kr1br1/ppp2p1p/2n1p1q1/2Nn4/3P4/1Q2PB2/PP1B1P1P/2R1K2R b K - +solution Qg1+ +id "ECM.875" +go +setboard 2K5/6p1/kp2P3/1p6/1P6/2P1P2p/8/1r6 w - - +solution e7 +id "ECM.876" +go +setboard 2kr3r/1Rp1bpp1/p6q/Q3P3/2P5/3p1NP1/P3P2P/1R4K1 b - - +solution Qe3+ +id "ECM.877" +go +setboard 6k1/1R4pp/2p5/8/P1rNp3/6Pb/4PK2/8 w - - +solution a5 +id "ECM.878" +go +setboard r2r2k1/pp3ppp/2q5/2p5/2P1P1n1/P4P1b/1BQ1BP1P/R3R2K b - - +solution Rd2 +id "ECM.879" +go \ No newline at end of file diff --git a/tests/everything.ep_ b/tests/everything.ep_ new file mode 100644 index 0000000..c84f88f --- /dev/null +++ b/tests/everything.ep_ @@ -0,0 +1,11276 @@ +setboard r3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq - +id "POS-01" +solution d6 +go +setboard r3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq - +id "POS-02" +solution d6 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-03" +solution Qc5 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-04" +solution Qc5 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-05" +solution Qc5 +go +setboard r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - +id "POS-06" +solution Qc5 +go +setboard r1b2r1k/pp2q1pp/2p2p2/2p1n2N/4P3/1PNP2QP/1PP2RP1/5RK1 w - - +id "POS-07" +solution Nd1 +go +setboard r2qrnk1/pp3ppb/3b1n1p/1Pp1p3/2P1P2N/P5P1/1B1NQPBP/R4RK1 w - - +id "POS-08" +solution Bh3 +go +setboard 5nk1/Q4bpp/5p2/8/P1n1PN2/q4P2/6PP/1R4K1 w - - +id "POS-09" +solution Qd4 +go +setboard 5nk1/Q4bpp/5p2/8/P1n1PN2/q4P2/6PP/1R4K1 w - - +id "POS-10" +solution Qd4 +go +setboard bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - +id "POS-11" +solution h4 +go +setboard bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - +id "POS-12" +solution h4 +go +setboard bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - +id "POS-13" +solution h4 +go +setboard r2qkb1r/1b3ppp/p3pn2/1p6/1n1P4/1BN2N2/PP2QPPP/R1BR2K1 w kq - +id "POS-14" +solution d5 +go +setboard 8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - +id "FIN-01" +solution f6 +go +setboard 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - +id "FIN-02" +solution f5 +go +setboard 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - +id "FIN-03" +solution f5 +go +setboard 8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - +id "FIN-04" +solution f5 +go +setboard 6k1/6p1/7p/P1N5/1r3p2/7P/1b3PP1/3bR1K1 w - - +id "FIN-05" +solution a6 +go +setboard 6k1/6p1/7p/P1N5/1r3p2/7P/1b3PP1/3bR1K1 w - - +id "FIN-06" +solution a6 +go +setboard 6k1/4pp1p/3p2p1/P1pPb3/R7/1r2P1PP/3B1P2/6K1 w - - +id "FIN-07" +solution Bb4 +go +setboard 2k5/p7/Pp1p1b2/1P1P1p2/2P2P1p/3K3P/5B2/8 w - - +id "FIN-08" +solution c5 +go +setboard 8/5Bp1/4P3/6pP/1b1k1P2/5K2/8/8 w - - +id "FIN-09" +solution Kg4 +go +setboard 1r4k1/1q2bp2/3p2p1/2pP4/p1N4R/2P2QP1/1P3PK1/8 w - - +id "CMB-01" +solution Nd6 +go +setboard rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - +id "CMB-02" +solution Qh7 +go +setboard rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - +id "CMB-03" +solution Qh7 +go +setboard 2k2b1r/1pq3p1/2p1pp2/p1n1PnNp/2P2B2/2N4P/PP2QPP1/3R2K1 w - - +id "CMB-04" +solution ef6 +go +setboard 2r2r2/3qbpkp/p3n1p1/2ppP3/6Q1/1P1B3R/PBP3PP/5R1K w - - +id "CMB-05" +solution Rh7 +go +setboard 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - +id "CMB-06" +solution ef6 +go +setboard 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - +id "CMB-07" +solution ef6 +go +setboard 2b1r1k1/r4ppp/p7/2pNP3/4Q3/q6P/2P2PP1/3RR1K1 w - - +id "CMB-08" +solution Nf6 +go +setboard 2b1r1k1/r4ppp/p7/2pNP3/4Q3/q6P/2P2PP1/3RR1K1 w - - +id "CMB-09" +solution Nf6 +go +setboard rq2rbk1/6p1/p2p2Pp/1p1Rn3/4PB2/6Q1/PPP1B3/2K3R1 w - - +id "CMB-10" +solution Bh6 +go +setboard rnbq2k1/p1r2p1p/1p1p1Pp1/1BpPn1N1/P7/2P5/6PP/R1B1QRK1 w - - +id "CMB-11" +solution Nh7 +go +setboard r2qrb1k/1p1b2p1/p2ppn1p/8/3NP3/1BN5/PPP3QP/1K3RR1 w - - +id "CMB-12" +solution e5 +go +setboard +id "arasan4.1" + +go +setboard 8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - +id "arasan4.2" +avoid Rxb6 +go +setboard 8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - +id "arasan4.3" +avoid Rxb6 +go +setboard 8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - +id "arasan4.4" +avoid Rxb6 +go +setboard 2r3k1/1b1nqppp/p3p3/8/1pQPn3/4PNP1/PP3PBP/RN4K1 w - - +id "arasan4.5" +solution Qf1 +go +setboard r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - +id "arasan4.6" +solution f6 +go +setboard r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - +id "arasan4.7" +solution f6 +go +setboard r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - +id "arasan4.8" +solution f6 +go +setboard 4k3/5ppQ/1n3b2/3bp3/1B6/1P1R2NP/5PPK/1qr5 w - - +id "arasan4.9" +solution Ba5 +go +setboard r3r1k1/pb1n1p2/1p1p1n1p/q1pPpN2/2P4p/2PBPP2/P1Q3PP/1R3RK1 w - - +id "arasan4.10" +solution Qf2 +go +setboard r3r1k1/pb1n1p2/1p1p1n1p/q1pPpN2/2P4p/2PBPP2/P1Q3PP/1R3RK1 w - - +id "arasan4.11" +solution Qf2 +go +setboard q2r2k1/1bpn1ppp/1p1bp3/8/r2PP3/P4NP1/1BQ2PBP/3RR1K1 w - - +id "arasan4.12" +solution e5 +go +setboard q2r2k1/1bpn1ppp/1p1bp3/8/r2PP3/P4NP1/1BQ2PBP/3RR1K1 w - - +id "arasan4.13" +solution e5 +go +setboard rnbq1rk1/p3nppp/1p2p3/2ppP3/3P4/P1PB1N2/2P2PPP/R1BQK2R w KQ - +id "arasan4.14" +solution Bxh7+ +go +setboard 4nr1k/r4p1p/2bq4/pp1pNP2/3P3Q/2P5/4PPB1/RR4K1 w - - +id "arasan4.15" +solution c4 +go +setboard 4nr1k/r4p1p/2bq4/pp1pNP2/3P3Q/2P5/4PPB1/RR4K1 w - - +id "arasan4.16" +solution c4 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.17" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.18" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.19" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.20" +solution Bh6 +go +setboard 1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - +id "arasan4.21" +solution Bh6 +go +setboard 2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - +id "arasan4.22" +solution Rxd7 +go +setboard 2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - +id "arasan4.23" +solution Rxd7 +go +setboard 2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - +id "arasan4.24" +solution Rxd7 +go +setboard 5q2/3Q1N1p/r4kp1/4p3/3nb3/1B5P/5PP1/1R4K1 w - - +id "arasan4.25" +solution f4 +go +setboard 5rk1/1p1P1ppp/pBn1p1r1/3p4/6P1/RPP4K/7P/4R3 w - - +id "arasan4.26" +solution Ra5 +go +setboard 5rk1/1p1P1ppp/pBn1p1r1/3p4/6P1/RPP4K/7P/4R3 w - - +id "arasan4.27" +solution Ra5 +go +setboard 3r2k1/2qn1ppp/8/1pbrp3/pP1N4/P2P2P1/RB2RP1P/4QK2 w - - +id "arasan4.28" +solution Nxb5 +go +setboard 3r2k1/2qn1ppp/8/1pbrp3/pP1N4/P2P2P1/RB2RP1P/4QK2 w - - +id "arasan4.29" +solution Nxb5 +go +setboard 2Q5/8/8/8/3kbP1N/2pq3P/6PK/8 w - - +id "arasan4.30" +solution f5 +go +setboard 2Q5/8/8/8/3kbP1N/2pq3P/6PK/8 w - - +id "arasan4.31" +solution f5 +go +setboard r1b2rk1/pp3pp1/4p2p/2ppP1b1/3Pq3/2P1PNP1/PP2Q2P/R3KB1R w KQ - +id "arasan4.32" +solution Nxg5 +go +setboard Qn3rk1/p5p1/1pnqp3/6p1/6P1/2P5/P4P1P/R1B2RK1 w - - +id "arasan4.33" +solution Qb7 +go +setboard Qn3rk1/p5p1/1pnqp3/6p1/6P1/2P5/P4P1P/R1B2RK1 w - - +id "arasan4.34" +solution Qb7 +go +setboard r1b2r2/pp3p1p/1q1p3k/2p1n2N/3N4/4P1P1/P1PP2BP/R4QK1 w - - +id "arasan4.35" +solution Qf6+ +go +setboard r1bq2k1/1p1n1r1p/3Qppp1/pP5N/2P1B3/8/P4P1P/2KR2R1 w - - +id "arasan4.36" +solution Bxg6 +go +setboard r1bq2k1/1p1n1r1p/3Qppp1/pP5N/2P1B3/8/P4P1P/2KR2R1 w - - +id "arasan4.37" +solution Bxg6 +go +setboard r4rk1/2qbbpp1/7p/2pPp3/ppN1P3/4Q1P1/PPPN4/2K3RR w - - +id "arasan4.38" +solution Rxh6 +go +setboard r2q1r1k/1p2bppp/pnb1p3/4P3/6R1/2N5/PPB1QPPP/R1B3K1 w - - +id "arasan4.39" +solution Rxg7 +go +setboard 1r3k2/4q3/2Pp3b/3Bp3/2Q2p2/1p1P2P1/1P2KP2/3N4 w - - +id "arasan4.40" +solution Be6 +go +setboard r4rk1/pp1nqppp/2b1p3/6N1/4N3/6Q1/PPP2PPP/1K1RR3 w - - +id "arasan4.41" +solution Rxd7 +go +setboard r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - +id "arasan4.42" +solution Qg3 +go +setboard r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - +id "arasan4.43" +solution Qg3 +go +setboard r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - +id "arasan4.44" +solution Qg3 +go +setboard r1bk2nr/ppp2ppp/2np1b2/1N6/N4P1q/P3B3/1PP1B1PP/R2QR1K1 w - - +id "arasan4.45" +solution Nxd6 +go +setboard r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - +id "arasan4.46" +solution Rxe6 +go +setboard r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - +id "arasan4.47" +solution Rxe6 +go +setboard r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - +id "arasan4.48" +solution Rxe6 +go +setboard 2r1k1nr/p1Pq4/1p3p2/4pn1p/1B1p4/1N3Q2/PP2P1RP/2R4K w - - +id "arasan4.49" +solution Nd2 +go +setboard r2qr1k1/pp1b2pp/2nBpp1n/6NQ/2B1N3/P3b3/1PP3PP/R4R1K w - - +id "arasan4.50" +solution Nxf6+ +go +setboard 1n3rn1/3b4/rq1P1pkp/1p4p1/p1p1N1N1/2Q2B1P/1P3PP1/R3R1K1 w - - +id "arasan4.51" +solution Nexf6 Ngxf6 +go +setboard r1bq1rk1/ppp1bpp1/2np3p/3N3n/2P1PB2/3BQN2/PP3PPP/R3K2R w KQ - +id "arasan4.52" +solution Bxh6 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.53" +solution Qd4 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.54" +solution Qd4 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.55" +solution Qd4 +go +setboard 2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - +id "arasan4.56" +solution Qd4 +go +setboard r2r2k1/pbpq1ppp/1pn1pn2/8/P2PP3/B1R2NP1/P1Q2PBP/3R2K1 w - - +id "arasan4.57" +solution d5 +go +setboard r2r2k1/pbpq1ppp/1pn1pn2/8/P2PP3/B1R2NP1/P1Q2PBP/3R2K1 w - - +id "arasan4.58" +solution d5 +go +setboard 1b6/4kPp1/Pp6/2p2K1B/2P5/3p4/8/8 w - - +id "arasan4.59" +solution Ke4 +go +setboard 4r1k1/pppb3p/1n4p1/3P4/1bP2p2/qN3PPP/P1Q3B1/2R3KR w - - +id "arasan4.60" +solution g4 +go +setboard 2r3k1/2r1b1p1/p1q3Pp/3pP3/1p6/1P2B2Q/2PR4/1K4R1 w - - +id "arasan4.61" +solution Bxh6 +go +setboard 4R3/1k4p1/8/pp4P1/8/3K4/1b5P/8 w - - +id "arasan4.62" +solution Re2 +go +setboard r3k2r/pb3ppp/1p2pn2/1Nb1q3/4P3/P2B4/1PQ2PPP/R1B2RK1 w kq - +id "arasan4.63" +solution b4 +go +setboard 2r1r1k1/1pn3qp/2pbn1p1/p2pN3/3P1P2/3BP1BP/PPQ3K1/2R2R2 w - - +id "arasan4.64" +solution f5 +go +setboard 5Nk1/1p2n3/p2q1rp1/3p1pQP/5P2/2P2B2/b1PK2P1/4R3 w - - +id "arasan4.65" +solution Nd7 +go +setboard 5Nk1/1p2n3/p2q1rp1/3p1pQP/5P2/2P2B2/b1PK2P1/4R3 w - - +id "arasan4.66" +solution Nd7 +go +setboard 8/1B1r1b1k/3N2pp/p3Qp2/3P1P2/7P/1P1b1K2/2r5 w - - +id "arasan4.67" +solution Nxf5 +go +setboard 8/1B1r1b1k/3N2pp/p3Qp2/3P1P2/7P/1P1b1K2/2r5 w - - +id "arasan4.68" +solution Nxf5 +go +setboard 2kb4/r7/4p1r1/1RNn2p1/8/6P1/pB3PK1/7R w - - +id "arasan4.69" +solution Be5 +go +setboard 2kb4/r7/4p1r1/1RNn2p1/8/6P1/pB3PK1/7R w - - +id "arasan4.70" +solution Be5 +go +setboard 4rrk1/1bpn1qp1/1p1b3p/pP1Ppn2/4N3/P2Q1N1P/1BB2PP1/2R1R1K1 w - - +id "arasan4.71" +solution g4 +go +setboard 4rrk1/1bpn1qp1/1p1b3p/pP1Ppn2/4N3/P2Q1N1P/1BB2PP1/2R1R1K1 w - - +id "arasan4.72" +solution g4 +go +setboard 1r5k/pp5p/3Nn1p1/3R4/3b4/BP3rPP/P4P2/1R4K1 w - - +id "arasan4.73" +solution Rxd4 +go +setboard rn1r2k1/p4p2/1pp1pqp1/6Rp/3PB2P/8/PPPQ1P2/2KR4 w - - +id "arasan4.74" +solution Bxg6 +go +setboard r4rk1/1pp3q1/2np3p/p2Npb1B/2PbN1p1/3P2P1/PP4PP/R2Q1R1K w - - +id "arasan4.75" +solution Ndf6+ Nef6+ +go +setboard r5k1/p6r/1n2p2p/2BbPpp1/8/P2B4/5PPP/2RR2K1 w - - +id "arasan4.76" +solution Bxf5 +go +setboard 5rk1/q4ppp/pp1bp1n1/6N1/4QP2/P3P3/1P1B2PP/2R3K1 w - - +id "arasan4.77" +solution Nxe6 +go +setboard r3kb1r/2R2bpp/p2p1p2/1p2pPP1/3qP3/5Q2/1PPB3P/2K2B1R w kq - +id "arasan4.78" +solution Bc4 +go +setboard r3kb1r/2R2bpp/p2p1p2/1p2pPP1/3qP3/5Q2/1PPB3P/2K2B1R w kq - +id "arasan4.79" +solution Bc4 +go +setboard 6k1/3p2p1/1p1Npq2/3n3r/1P6/5PQ1/P4KP1/RNBR3r w - - +id "arasan4.80" +solution Ne4 +go +setboard 6k1/3p2p1/1p1Npq2/3n3r/1P6/5PQ1/P4KP1/RNBR3r w - - +id "arasan4.81" +solution Ne4 +go +setboard 2k4r/1q1bBQ2/2p1p3/1p2P2p/6r1/8/5PP1/R1R3K1 w - - +id "arasan4.82" +solution Bf8 +go +setboard 2r2k1r/p1q3pp/1p3p2/3Bp3/2Pb2b1/P1Q5/1B1R1PPP/4R1K1 w - - +id "arasan4.83" +solution Rxd4 +go +setboard 2r2k1r/p1q3pp/1p3p2/3Bp3/2Pb2b1/P1Q5/1B1R1PPP/4R1K1 w - - +id "arasan4.84" +solution Rxd4 +go +setboard 3q1k2/8/1p1b1r1p/p2R2p1/P1BQ2P1/1P3P2/8/3K4 w - - +id "arasan4.85" +solution f4 +go +setboard 2r2rk1/5qp1/1pN2p1p/pPnRp3/P1P5/5PP1/2Q1R1KP/8 w - - +id "arasan4.86" +solution Rxc5 +go +setboard 3r1r2/pb3pkp/1pn1qNp1/2p1P3/5P2/P2BQ3/1P4PP/3R1R1K w - - +id "arasan4.87" +solution f5 +go +setboard r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - +id "arasan4.88" +solution N3h4 +go +setboard r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - +id "arasan4.89" +solution N3h4 +go +setboard r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - +id "4.90" +solution N3h4 +go +setboard r3rk2/ppq2pbQ/2p1b1p1/4p1B1/2P3P1/3P1B2/P3PPK1/1R5R w - - +id "4.91" +solution Qxg7+ Qh8+ +go +setboard r1b2rk1/1pqp1p1p/p3nBpQ/4p3/4P3/1N4P1/PbP2PBP/R4RK1 w - - +id "4.92" +solution Nd2 +go +setboard 4r1k1/2P3pp/1n2q3/2pn1p2/8/6B1/1P1QBP1P/4R1K1 w - - +id "arasan4.93" +solution Rd1 +go +setboard r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - +id "arasan4.94" +solution Nxg5 +go +setboard r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - +id "arasan4.95" +solution Nxg5 +go +setboard r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - +id "arasan4.96" +solution Nxg5 +go +setboard 5rk1/3R1p2/ppp3r1/b1p1P2p/2P2B1q/2P2Q2/P5PP/3R3K w - - +id "arasan4.97" +solution h3 +go +setboard 2r1r1k1/5p1p/p3qBp1/1ppbP3/2n5/2PB3P/P3QPP1/3RR1K1 w - - +id "arasan4.98" +solution Bxc4 +go +setboard r1br3k/pp2qn1p/4p2P/4Ppp1/2B5/P4NQ1/1P3PP1/3R1RK1 w - - +id "arasan4.99" +solution Nxg5 +go +setboard 2r2rk1/3bq1p1/4p1Pp/3pP3/1p1N1PQ1/pP5R/P1P4R/4K3 w - - +id "arasan4.100" +solution Rxh6 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.101" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.102" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.103" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.104" +solution Qf2 +go +setboard 2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - +id "arasan4.105" +solution Qf2 +go +setboard 4r1k1/p5qp/Pp1Rbb2/4pp1r/2P1p1p1/1PB1P3/1Q2BPPP/3R2K1 w - - +id "arasan4.106" +solution c5 +go +setboard 8/4k1p1/8/5P1p/b1N4P/5PP1/1p1K4/1B1n4 w - - +id "arasan4.107" +solution g4 +go +setboard 3q1r1k/1P1n2p1/4R2p/2QBp2P/3pPb2/R1p2P2/5P2/5K2 w - - +id "arasan4.108" +solution Qxf8+ +go +setboard 3q1r1k/1P1n2p1/4R2p/2QBp2P/3pPb2/R1p2P2/5P2/5K2 w - - +id "arasan4.109" +solution Qxf8+ +go +setboard 2rbk1r1/7R/p1n3p1/1p3q2/2n2N2/4pQ2/PP2B1PP/3R2K1 w - - +id "arasan4.110" +solution g4 +go +setboard 8/8/3k4/1p1npP1p/pP2B2P/P7/5K2/8 w - - +id "arasan4.111" +solution Bxd5 +go +setboard 5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - +id "arasan4.112" +solution f5 +go +setboard 5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - +id "arasan4.113" +solution f5 +go +setboard 5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - +id "arasan4.114" +solution f5 +go +setboard 2kr3r/Rbpnq3/1p1pp3/2P3p1/3P4/2P1P1p1/Q2N1PP1/4KB2 w - - +id "arasan4.115" +solution Rxb7 +go +setboard 2R2b1r/3nkp2/B2pp1p1/1N4Pn/P3P3/4BP2/1r5q/3QK1R1 w - - +id "arasan4.116" +solution Nd4 Na7 +go +setboard r3r1k1/1p1b2pp/p2qpp2/3n4/Pn1P4/1BN2Q2/1P1B1PPP/R2R2K1 w - - +id "arasan5.1" +solution Ne4 +go +setboard r3r1k1/1p1b2pp/p2qpp2/3n4/Pn1P4/1BN2Q2/1P1B1PPP/R2R2K1 w - - +id "arasan5.2" +solution Ne4 +go +setboard 8/6p1/1b4k1/1p1KP3/1p3PP1/pB6/8/8 w - - +id "arasan5.3" +solution e6 +go +setboard r4rk1/1bq2p2/p3p1p1/n3P2p/3NpP2/2P1B2R/2P3PP/R3Q1K1 w - - +id "arasan5.4" +solution g4 +go +setboard 2rq1rk1/pb1n1p2/1p2pn1p/6p1/2BP3B/1QR2N2/PP3PPP/4R1K1 w - - +id "arasan5.5" +solution Nxg5 +go +setboard 2r1qrk1/1b1nbppp/4p3/pB1nP1B1/Pp2N3/5N1P/1P1Q1PP1/R2R2K1 w - - +id "arasan5.6" +solution Nf6+ +go +setboard 1q4k1/r4p1p/6p1/1p1Q3n/p3N3/P7/1P3PPP/4R1K1 w - - +id "arasan5.7" +solution g4 +go +setboard 3rr1k1/1pq2p1p/p1n3p1/3Bb3/P7/2P1BQ2/1P3PKP/3RR3 w - - +id "arasan5.8" +solution Bb6 +go +setboard 3rr1k1/1pq2p1p/p1n3p1/3Bb3/P7/2P1BQ2/1P3PKP/3RR3 w - - +id "arasan5.9" +solution Bb6 +go +setboard r2qr1k1/pb4b1/1pnP2pp/5p2/5PB1/B4NQ1/P5PP/2R1R1K1 w - - +id "arasan5.10" +solution Bxf5 +go +setboard r1b2rk1/p1q4p/1p4p1/2NP1p2/1PPB4/6P1/P6P/Q3R1K1 w - - +id "arasan5.11" +solution Qc1 +go +setboard 8/3k4/1p4b1/3p1p1p/K2P1PpP/3B2P1/1P6/8 w - - +id "arasan5.12" +solution Kb5 +go +setboard r1bn1rk1/2q2ppN/7p/p2p4/R7/2PB4/3B1PPb/3QRK2 w - - +id "arasan5.13" +solution Nf6+ +go +setboard 4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - +id "arasan5.14" +solution g5 +go +setboard 4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - +id "arasan5.15" +solution g5 +go +setboard 4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - +id "arasan5.16" +solution g5 +go +setboard r1bq1rk1/4ppbp/p2p1n1B/2p5/1p2p2Q/3P1N2/PPP1N1PP/R4RK1 w - - +id "arasan5.17" +solution Ng5 +go +setboard 4rrk1/p2n2pp/npbp4/2p1p3/2P2P1q/PNB1P3/1P2B1PP/1R1Q1RK1 w - - +id "arasan5.18" +avoid Qxd6 +go +setboard 4rrk1/p2n2pp/npbp4/2p1p3/2P2P1q/PNB1P3/1P2B1PP/1R1Q1RK1 w - - +id "arasan5.19" +avoid Qxd6 +go +setboard 8/B3r1p1/8/P4k1p/1P6/5P2/5K2/8 w - - +id "arasan5.21" +solution Bc5 +go +setboard b2rn1k1/3r1ppp/3N2n1/1pB1P3/p5P1/P3KP2/B6P/1RR5 w - - +id "arasan5.24" +solution e6 +go +setboard 8/4rq2/2Q1N1pk/p3R2p/3p1P2/2n4P/6P1/7K w - - +id "arasan5.25" +solution g4 +go +setboard 4kb1r/3n1p1p/p1q1p1p1/1p1nP3/1prPN3/4BB2/P2Q1PPP/3R1RK1 w - - +id "arasan5.26" +solution Bh6 +go +setboard 3q2k1/rbp2r1p/1p1p1pp1/p1nN4/2P1PP2/1P2QBPP/1P5K/3RR3 w - - +id "arasan5.27" +solution e5 +go +setboard 3q2k1/rbp2r1p/1p1p1pp1/p1nN4/2P1PP2/1P2QBPP/1P5K/3RR3 w - - +id "arasan5.28" +solution e5 +go +id "ECM.946" +go +setboard +id "ECM.949" +go +setboard 2k4r/1pp2ppp/p1p1bn2/4N3/1q1rP3/2N1Q3/PPP2PPP/R4RK1 w - - +id "ECM.952" +solution Nd5 +go +setboard rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - +id "ECM.961" +solution Bxd5 +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +id "ECM.973" +solution Rxc8 +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +id "ECM.977" +solution Rxc8 +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +id "ECM.978" +solution Nxc6 +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +id "ECM.986" +solution Nxc6 +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +id "ECM.987" +solution Qxf7+ +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +id "ECM.993" +solution Qxf7+ +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +id "ECM.999" +solution Nxf7 +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +id "ECM.1004" +solution Nxf7 +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +id "ECM.1007" +solution g6 +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +id "ECM.1009" +solution Kg2 +go +setboard r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - +id "ECM.1011" +solution Nh7 +go +setboard 4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - +id "ECM.1016" +solution Nxc5 +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +id "ECM.1018" +solution Rd4 +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +id "ECM.1020" +solution exf6 +go +setboard 2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - +id "ECM.1025" +solution Nh6+ +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +id "ECM.1028" +solution Re7 +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +id "ECM.1038" +solution Re7 +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +id "ECM.1041" +solution Re7 +go +setboard r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - +id "ECM.1045" +solution Qxf5+ +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +id "ECM.1053" +solution Nxh7 +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +id "ECM.1057" +solution Rxf6 +go +setboard rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - +id "ECM.1065" +solution Nf6+ +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +id "ECM.1066" +solution Nxh5 +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +id "ECM.1068" +solution Rxe7 +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +id "ECM.1076" +solution Rxe7 +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +id "ECM.1080" +solution Rxe7 +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +id "ECM.1082" +solution Bd5+ +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +id "ECM.1084" +solution Ba3 +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +id "ECM.1085" +solution g6 +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +id "ECM.1093" +solution g6 +go +setboard 8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - +id "ECM.1096" +solution g4+ +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +id "ECM.1098" +solution Ba4 +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +id "ECM.1114" +solution Nxf7 +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +id "ECM.1122" +solution Nxf7 +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +id "ECM.1127" +solution Nxf7 +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +id "ECM.1131" +solution Nb6 +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +id "ECM.1132" +solution Nb6 +go +setboard 1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - +id "ECM.1133" +solution Bxc5 +go +setboard 2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - +id "ECM.1134" +solution Rxd5 +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +id "ECM.1147" +solution Rb3 +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +id "ECM.1150" +solution Bf4 +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +id "ECM.1151" +solution Re7 +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +id "ECM.1152" +solution Re7 +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +id "ECM.1160" +solution Re7 +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +id "ECM.1161" +solution Bg7 +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +id "ECM.1176" +solution Qc1 +go +setboard 3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - +id "ECM.1177" +solution Rxc5 +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +id "ECM.1178" +solution Rxd6 +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +id "ECM.1179" +solution Rxd6 +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +id "ECM.1185" +solution Bh7+ +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +id "ECM.1188" +solution Bxf7+ +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +id "ECM.1189" +solution Bb7 +go +setboard 5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - +id "ECM.1193" +solution Rxd7 +go +setboard 2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - +id "ECM.1199" +solution Bxh6 +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +id "ECM.1200" +solution Rxh8+ +go +setboard r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - +id "ECM.1202" +solution Bh7+ +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1204" +solution Nxf7 +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1208" +solution Nxf7 +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1214" +solution Nxf7 +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +id "ECM.1217" +solution Nxf7 +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +id "ECM.1218" +solution Nxg7 +go +setboard b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - +id "ECM.1223" +solution Bxg6+ +go +setboard r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - +id "ECM.1224" +solution Qh6+ +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +id "ECM.1227" +solution Nxg7 +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +id "ECM.1229" +solution Nxg7 +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +id "ECM.1232" +solution Qxg6+ +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +id "ECM.1234" +solution Qxg6+ +go +setboard r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - +id "ECM.1249" +solution Re7 +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +id "ECM.1254" +solution R1b4 +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +id "ECM.1257" +solution R1b4 +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +id "ECM.1259" +solution Nd5 +go +setboard 5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - +id "ECM.1262" +solution Rxe7 +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +id "ECM.1265" +solution Rxd7 +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +id "ECM.1267" +solution Qh6 +go +setboard 3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - +id "ECM.1269" +solution Rxe6 +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +id "ECM.1270" +solution Rxc8+ +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +id "ECM.1271" +solution Rxe4 +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +id "ECM.1273" +solution Rxe4 +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +id "ECM.1274" +solution Rxe4 +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +id "ECM.1277" +solution Rxc5 +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +id "ECM.1278" +solution Rxc5 +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +id "ECM.1281" +solution Nxe6 +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +id "ECM.1285" +solution Nxe6 +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +id "ECM.1293" +solution Rxd7 +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +id "ECM.1294" +solution Rxd7 +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +id "ECM.1295" +solution Rxd4 +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +id "ECM.1304" +solution Rxd8 +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +id "ECM.1306" +solution Rxg6+ +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +id "ECM.1308" +solution Bd8 +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +id "ECM.1314" +solution Bd8 +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +id "ECM.1317" +solution Bxe5+ +go +setboard r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - +id "ECM.1318" +solution Bc3 +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +id "ECM.1321" +solution Rxc4 +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +id "ECM.1325" +solution Rxc4 +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +id "ECM.1327" +solution Nf6+ +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +id "ECM.1329" +solution Nf6+ +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +id "ECM.1332" +solution Rxa6 +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +id "ECM.1335" +solution Rxa6 +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +id "ECM.1336" +solution Rxd3 +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +id "ECM.1340" +solution e5 +go +setboard r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - +id "ECM.1341" +solution Rxh5 +go +setboard R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - +id "ECM.1344" +solution Nxe5 +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +id "ECM.1346" +solution Rxc4 +go +setboard 4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - +id "ECM.1347" +solution Rxf6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "ECM.1348" +solution e6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "ECM.1350" +solution e6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "ECM.1352" +solution e6 +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +id "ECM.1354" +solution Ng5 +go +setboard 1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - +id "ECM.1355" +solution bxc6 +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +id "ECM.1357" +solution Rxf6 +go +setboard 1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - +id "ECM.1371" +solution Bxh6 +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +id "ECM.1376" +solution Bh4 +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +id "ECM.1377" +solution Bf8 +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +id "ECM.1380" +solution Ng6+ +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +id "ECM.1381" +solution Qb2 +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +id "ECM.1383" +solution Qxg5+ +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +id "ECM.1387" +solution Qxg5+ +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +id "ECM.1394" +solution Qxg5+ +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +id "ECM.1398" +solution Bxh5 +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +id "ECM.1403" +solution Rxd5 +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +id "ECM.1405" +solution Rf6 +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +id "ECM.1408" +solution Rf6 +go +setboard 2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - +id "ECM.1409" +solution Nxf5+ +go +setboard 1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - +id "ECM.1410" +solution Ne6 +go +setboard r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - +id "ECM.1421" +solution Nxh6 +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +id "ECM.1423" +solution Bg5 +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +id "ECM.1426" +solution Bg5 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1433" +solution Nd6 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1434" +solution Nd6 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1438" +solution Nd6 +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +id "ECM.1439" +solution Nd6 +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +id "ECM.1448" +solution Rxe6 +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +id "ECM.1450" +solution Nxf5 +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +id "ECM.1452" +solution Nxf5 +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +id "ECM.1454" +solution Bxf6 +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +id "ECM.1457" +solution Bxf6 +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +id "ECM.1478" +solution Nf5+ +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +id "ECM.1495" +solution Nf5+ +go +setboard 1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - +id "ECM.1503" +solution Nxf7 +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +id "ECM.1504" +solution Rxc5 +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +id "ECM.1516" +solution Bh3 +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +id "ECM.1525" +solution Nxc6 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1527" +solution h3 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1529" +solution h3 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1533" +solution h3 +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +id "ECM.1536" +solution h3 +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +id "ECM.1546" +solution Rxc6 +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +id "ECM.1547" +solution f6 +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +id "ECM.1551" +solution e5 +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +id "ECM.1553" +solution b5 +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +id "ECM.1554" +solution Rxa6 +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +id "ECM.1561" +solution Rxa6 +go +setboard 2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - +id "ECM.1563" +solution Nxe6 +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +id "ECM.1564" +solution Ba6 +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +id "ECM.1573" +solution Nxa7 +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +id "ECM.1578" +solution Nxa7 +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +id "ECM.1579" +solution cxb6 +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +id "ECM.1582" +solution f5 +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +id "ECM.1584" +solution f5 +go +setboard r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - +id "ECM.1590" +solution Bxh7+ +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +id "ECM.1592" +solution Bxh7+ +go +setboard 1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - +id "ECM.1594" +solution Bxh7+ +go +setboard r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - +id "ECM.1597" +solution Bxh7+ +go +setboard 2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - +id "ECM.1600" +solution Rxh7+ +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +id "ECM.1601" +solution Rxh7 +go +setboard 4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - +id "ECM.1602" +solution Bxh7+ +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +id "ECM.1604" +solution Nxh7 +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +id "ECM.1605" +solution Nxh7 +go +setboard b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - +id "ECM.1606" +solution Bxh7+ +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +id "ECM.1607" +solution Qxh7+ +go +setboard 5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - +id "ECM.1610" +solution Bxh7+ +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +id "ECM.1612" +solution Nxh7 +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +id "ECM.1614" +solution Rxh7 +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +id "ECM.1617" +solution Nxh7 +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +id "ECM.1618" +solution Bxh7+ +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +id "ECM.1620" +solution Bxh7+ +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +id "ECM.1621" +solution Bxh7+ +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "ECM.1622" +solution Nxh7 +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +id "ECM.1623" +solution Rxh7 +go +setboard 1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - +solution Nxg4 +id "ECM.011" +go +setboard 2rr2k1/1b3p1p/p4qpb/2R1n3/3p4/BP2P3/P3QPPP/3R1BKN b - - +solution Rxc5 +id "ECM.016" +go +setboard r3rbk1/1pq2ppp/2ppbnn1/p3p3/P1PPN3/BP1BPN1P/2Q2PP1/R2R2K1 w - - +solution Nxd6 +id "ECM.018" +go +setboard b7/2q2kp1/p3pbr1/1pPpP2Q/1P1N3P/6P1/P7/5RK1 w - - +solution Rxf6+ +id "ECM.019" +go +setboard r1b2rk1/2q2ppp/2pbp3/p7/4Nn2/3B4/PPPBQ1PP/R4R1K w - - +solution Rxf4 +id "ECM.028" +go +setboard 3r2k1/1q1P1ppp/r2R2n1/p4Q2/1ppB2R1/6P1/PP3PP1/6K1 w - - +solution Rgxg6 +id "ECM.029" +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +solution Rxc8 +id "ECM.035" +go +setboard r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - +solution Rxa1 +id "ECM.039" +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +solution Nxc6 +id "ECM.040" +go +setboard 2rr4/5pk1/p1q3p1/3bpP1p/1p4nR/1N4Q1/PPP3PP/3NR2K b - - +solution Bxg2+ +id "ECM.043" +go +setboard r4rk1/pp4pp/2nqb3/3p4/8/2NB4/PP1Q1PPP/4RRK1 w - - +solution Bxh7+ +id "ECM.044" +go +setboard 3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - +solution d3 +id "ECM.048" +go +setboard 1k1r1b1r/p1p1q3/2p1p3/4Ppp1/4nP2/P2BQ3/1PP3PB/2KR3R b - - +solution Rxh2 +id "ECM.051" +go +setboard r1bq1rk1/pp3pbp/2pp1np1/2n3B1/2PNP3/2N2P2/PP1QB1PP/R4RK1 b - - +solution Nfxe4 +id "ECM.053" +go +setboard r4rk1/pp1b2pp/3bpq2/3p1p2/2PPn3/PP1B4/1BQN1PPP/R4RK1 b - - +solution Bxh2+ +id "ECM.060" +go +setboard 4nk2/r1r1bppp/pN2p3/2np4/8/BPN3PP/P3PPK1/2RR4 w - - +solution Ncxd5 +id "ECM.063" +go +setboard 3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - +solution Rxd4 +id "ECM.066" +go +setboard r1b2rk1/1p2bppp/p3pn2/4B3/1qBR4/2N5/P3QPPP/R5K1 w - - +solution Bd3 +id "ECM.068" +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +solution Qh6 +id "ECM.071" +go +setboard r1b2kr1/1p1p1pNp/p1n1p1p1/5P2/3QP3/2N5/PqP1B1PP/R4RK1 w - - +solution fxg6 +id "ECM.076" +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +solution Rd4 +id "ECM.080" +go +setboard Q7/p1r1ppk1/1qP4p/2Rb2p1/8/3N2P1/4PP1P/6K1 b - - +solution Qb1+ +id "ECM.081" +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +solution exf6 +id "ECM.082" +go +setboard 4r1k1/1b4pp/p7/1prP3q/2P1B3/5P2/P3Q2P/3RR2K w - - +solution Bg6 +id "ECM.084" +go +setboard rn1q1r2/4bpk1/p3p3/1pN1N1np/2pP4/4PpBb/PPQ4P/1B1RK1R1 w - - +solution Nc6 +id "ECM.091" +go +setboard 6k1/1pqb1p2/5bpB/r2n4/4N1P1/1P3P2/1P1Q4/1K5R w - - +solution Qxd5 +id "ECM.099" +go +setboard 2kr1r2/1pp3pp/1n2p1b1/pN2B3/P1q5/1Q1p3P/5PP1/R4R1K w - - +solution Rac1 +id "ECM.109" +go +setboard r1b1Q3/6pk/p6p/1pq1n3/4N3/8/PPP3PP/R6K b - - +solution Qc6 +id "ECM.112" +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +solution Nxh7 +id "ECM.115" +go +setboard 4qbk1/1R5n/p2pr1p1/2pQpNPp/P1P1P3/2P2P2/3B4/5K2 w - - +solution Ne7+ +id "ECM.117" +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +solution Rxf6 +id "ECM.119" +go +setboard 2b1rr1k/1p5p/1Ppp2q1/p3bN2/2P1n3/5R2/PBQ3BP/3R2K1 w - - +solution Nxd6 +id "ECM.123" +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +solution Nxh5 +id "ECM.128" +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +solution Rxe7 +id "ECM.130" +go +setboard 2rq1rk1/pp2bppp/1npp1n2/3PpN1b/2P5/2N3PP/PP2PPB1/R1BQ1RK1 w - - +solution c5 +id "ECM.131" +go +setboard 2n1rbk1/5pp1/7p/qP1pp3/4b1Q1/1B5P/1P1N1PP1/2B1R1K1 w - - +solution Rxe4 +id "ECM.133" +go +setboard 4k3/2R2p2/5p1p/8/rb6/1N6/5PPP/5K2 w - - +solution Rc4 +id "ECM.134" +go +setboard 2k3r1/pp2rp2/1np5/2Np1p2/P2P3p/1R2P1Pq/2Q2P1P/1R4K1 w - - +solution Nxb7 +id "ECM.135" +go +setboard 8/1Qp3pk/7p/5p2/5Pqn/1P1r4/P5PP/2B2RK1 b - - +solution c6 +id "ECM.137" +go +setboard b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - +solution d3+ +id "ECM.142" +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +solution Bd5+ +id "ECM.144" +go +setboard 6k1/4ppbp/p5p1/1B1Q4/2P2Pn1/8/qr4PP/2B2RK1 b - - +solution Bd4+ +id "ECM.145" +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +solution Ba3 +id "ECM.146" +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +solution g6 +id "ECM.147" +go +setboard 5r2/1b3pk1/pqrpp1p1/4n1Nn/1p2PP1P/8/PPPQB3/1NKR2R1 b - - +solution Rfc8 +id "ECM.148" +go +setboard 8/1bq3kp/p5p1/1pb1p3/4P2P/2PQ2P1/1P5B/5N1K b - - +solution Qd8 +id "ECM.153" +go +setboard 4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - +solution Ra8 +id "ECM.155" +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +solution Ba4 +id "ECM.160" +go +setboard r1bq3k/ppp2Qp1/2n1p2p/6N1/2BPN3/2P1n3/PP4PP/R5K1 w - - +solution Nf6 +id "ECM.161" +go +setboard 3R4/1p2kp2/p1b1nN2/6p1/8/6BP/2r1qPPK/Q7 w - - +solution Rd7+ +id "ECM.162" +go +setboard r1b3k1/ppp2r2/6p1/3n3p/6qP/3BQ3/PBP5/2KR3R w - - +solution Bd4 +id "ECM.180" +go +setboard 1R3b2/3r3k/2p1bp1p/r1q1pNpQ/2PpP2P/6B1/P4PP1/1R4K1 w - - +solution Nxh6 +id "ECM.186" +go +setboard r1b4r/pp2ppk1/2np1np1/3N3p/2B1P3/q3BP2/P1PQ2PP/1R3RK1 w - - +solution Nxe7 +id "ECM.187" +go +setboard 5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - +solution Ne4 +id "ECM.189" +go +setboard 5rk1/5pbp/b5p1/p1nNN3/1p2n3/1P4PP/P4PB1/2BR2K1 w - - +solution Nd7 +id "ECM.190" +go +setboard 2k1r1r1/ppb2p2/6b1/2qP4/2P2P2/4pP1p/P3Q2P/2RBRN1K b - - +solution Bd3 +id "ECM.191" +go +setboard 5r1k/pp1n1p1p/1b1qpP2/8/1PrN4/P1N1Q1P1/7P/3R1R1K w - - +solution Qh6 +id "ECM.192" +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +solution Nb6 +id "ECM.193" +go +setboard r1k3r1/pppnb1p1/4N3/3QP2p/3P3q/4B3/PPP2P2/R3KB2 w Q - +solution Ba6 +id "ECM.198" +go +setboard r1bq1rk1/pppn2bp/3p2p1/3N1p2/8/BP1BRQ1P/P1PP1PP1/4R1K1 w - - +solution Nxc7 +id "ECM.206" +go +setboard 2q1r1k1/1b3pbp/3p2p1/1Ppn3n/5P2/5B2/1P1B2PP/R2NNQ1K b - - +solution Ndxf4 +id "ECM.208" +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +solution Rb3 +id "ECM.209" +go +setboard r2qr1n1/p4pk1/1p1p2p1/4p3/4PQ2/1PN2P2/1PP3P1/2KR3R w - - +solution Rh7+ +id "ECM.210" +go +setboard r4rk1/ppp3b1/3p1qp1/3Pp3/2P1Bn2/4BP2/PP1Q4/2K3RR w - - +solution Rxg6 +id "ECM.211" +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +solution Re7 +id "ECM.213" +go +setboard r4n1r/ppq1nk2/1bpRpN2/4PpQ1/8/2B4P/PPP2PP1/2KR4 w - - +solution Rd7 +id "ECM.215" +go +setboard 3r2k1/p5pp/bpP1p3/3n1p2/2NQpP1q/P3P3/1B1R1R2/4KBr1 b - - +solution Rxf1+ +id "ECM.216" +go +setboard rnb1kr2/p4pQ1/8/1ppPpP2/2p1P3/N6P/Pq4B1/3R1RK1 w q - +solution Nxb5 +id "ECM.226" +go +setboard 5r1k/2p3pp/3pQ3/3P1rN1/pp5q/5PR1/P4PKP/B7 w - - +solution Bxg7+ +id "ECM.227" +go +setboard 8/pR3Bk1/3p2p1/5b1p/2P4P/6P1/P4bQK/4q3 b - - +solution Bg1+ +id "ECM.228" +go +setboard rq3r1k/p2n1p2/1pbb1np1/2p2BB1/8/2N2N2/PP3QPP/3R1RK1 w - - +solution Rxd6 +id "ECM.231" +go +setboard 3rr1k1/1b5p/p6p/1p3N2/6Pb/P1Q1p3/1PP4P/R5K1 b - - +solution Bf2+ +id "ECM.237" +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +solution Qc1 +id "ECM.238" +go +setboard 6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - +solution Rh4+ +id "ECM.241" +go +setboard 4rrk1/3b1ppp/pb6/1pqP4/P1p1PP2/1P2NK2/3QB2P/R2R4 b - - +solution Rxe4 +id "ECM.244" +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +solution Bh7+ +id "ECM.247" +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +solution Bxf7+ +id "ECM.250" +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +solution Bb7 +id "ECM.251" +go +setboard 2b3k1/p4ppp/7q/2Q5/8/P3r1P1/1r4BP/R3R1K1 b - - +solution Rxg2+ +id "ECM.259" +go +setboard r1b1rbk1/7p/2p1pBp1/p2pP1P1/5P2/1PqB4/P1P1Q3/1K4RR w - - +solution Rxh7 +id "ECM.260" +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +solution Rxh8+ +id "ECM.262" +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +solution Nxf7 +id "ECM.266" +go +setboard r1b1r1k1/1p1n1p2/p1nBp1p1/q2pP1Np/P7/R2B3Q/2P2PPP/5RK1 w - - +solution Nxf7 +id "ECM.267" +go +setboard 4n1q1/1k1b4/2p4R/2Pp4/1p1N1rpQ/3B4/PPP2P2/2K5 w - - +solution Nxc6 +id "ECM.271" +go +setboard r3r1k1/pp3pp1/2bb1q2/3p4/4n1Pp/2P1BB1P/PP2NPK1/R1Q4R b - - +solution Qxf3+ +id "ECM.274" +go +setboard rn4k1/pp2p1b1/4b3/q2p2Q1/2B2P2/8/P1P1K1P1/R6R w - - +solution Rh8+ +id "ECM.277" +go +setboard 2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - +solution Rxc3 +id "ECM.279" +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +solution Nxg7 +id "ECM.280" +go +setboard 4k3/p4ppp/nb1P4/4p3/1P6/P4BP1/3q1r1P/2R2QKR w - - +solution Qb5+ +id "ECM.287" +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +solution Nxg7 +id "ECM.289" +go +setboard 1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - +solution Rxb2 +id "ECM.291" +go +setboard 5rk1/ppp1q2p/1n1p1np1/3P2N1/1P1R2P1/2Q4P/P3r1B1/5RK1 b - - +solution Rxg2+ +id "ECM.292" +go +setboard 6k1/pp2p2p/3p2p1/4b1r1/2Pn1r1q/2B1N3/PP4B1/R3QRK1 b - - +solution Qh2+ +id "ECM.293" +go +setboard r2k3r/2pb1ppp/p1p1q3/2Q5/5B2/2N5/PPP2PPP/3R2K1 w - - +solution Bxc7+ +id "ECM.295" +go +setboard 2r1qrk1/pp1b1ppp/4pn2/n1b5/8/2NQ1NP1/PP1BPPBP/R2R2K1 w - - +solution b4 +id "ECM.297" +go +setboard 2b1qr1k/7p/p1pR2p1/1pP1p1Q1/4P3/1B6/PP4PP/6K1 w - - +solution Re6 +id "ECM.298" +go +setboard 8/2b2k1p/2N2pp1/P2p4/3KnP2/6BP/P5P1/8 w - - +solution Kxd5 +id "ECM.300" +go +setboard 3r1rk1/2p1qp1p/pnP3p1/4n3/PP1NpR2/1BQ4P/6P1/5RK1 w - - +solution Ne6 +id "ECM.307" +go +setboard r5rk/1p1bqpnp/3p1b1B/pBnPp2P/4P3/2N2Q2/PP3P2/R3KNR1 b Q - +solution Nf5 +id "ECM.310" +go +setboard r3r1k1/p1q2pp1/2p4p/7n/BPPP2N1/3Q1N2/P3n1P1/R1B4K b - - +solution Nhg3+ +id "ECM.312" +go +setboard r1b2rk1/p3bppp/2q5/8/2p1NR2/PnB1P3/1PB1Q1PP/3R2K1 w - - +solution Rd6 +id "ECM.315" +go +setboard 1rb2rk1/p1p2ppp/2q5/3R4/2P1N3/bP4B1/P1Q2P1P/1K5R w - - +solution Bd6 +id "ECM.318" +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +solution Rd5 +id "ECM.321" +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +solution Rxd7 +id "ECM.327" +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +solution Qh6 +id "ECM.329" +go +setboard 2r2r1k/1pq1b1p1/p1b1Qn1p/8/3B4/2NB4/PPP3PP/3R1R1K w - - +solution Rxf6 +id "ECM.330" +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +solution Rxc8+ +id "ECM.332" +go +setboard 8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - +solution Rxd4 +id "ECM.335" +go +setboard r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - +solution Rxe5 +id "ECM.336" +go +setboard r3r1k1/pbqn1ppp/1p3n2/1Pb5/2p5/5N1P/PBQ1BPP1/1N1R1RK1 b - - +solution Rxe2 +id "ECM.337" +go +setboard 2r2rbk/6bp/5qp1/1N1p1n2/4p3/1p5P/1P3PP1/RBBQ1RK1 b - - +solution Ng3 +id "ECM.338" +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +solution Rxc5 +id "ECM.339" +go +setboard 1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - +solution Rxe7 +id "ECM.340" +go +setboard r1b2r1R/1p2bpk1/4p1p1/4P1N1/p2p4/5Q2/qPP2PP1/1NKR4 w - - +solution Qf6+ +id "ECM.342" +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +solution Nxe6 +id "ECM.343" +go +setboard 2r1k2r/1pq1bppp/p3bn2/4N3/2pPN3/2P5/P3QPPP/R1B1R1K1 w k - +solution Nxf6+ +id "ECM.345" +go +setboard 1r3k1r/4Rn1p/pb1p1P2/1p1q2P1/5p2/7Q/PPP1B1RP/2K5 w - - +solution Rxf7+ +id "ECM.346" +go +setboard r3r1k1/pp3ppp/1qp5/2bbNQ2/5B2/2P5/PP3PPP/3RR1K1 w - - +solution Rxd5 +id "ECM.349" +go +setboard r2qn1k1/1p1b3p/2pp1b2/6pQ/p1P1P3/P1N3PB/1P6/3R1R1K w - - +solution Rxf6 +id "ECM.351" +go +setboard r4k1r/pp2pp2/3p1b2/q2PnQpp/3N4/1BP3P1/PP3PP1/3RR1K1 w - - +solution Rxe5 +id "ECM.353" +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +solution Rxd7 +id "ECM.355" +go +setboard 2r2rk1/p3p1bp/3qP1p1/1Q1p4/P4P2/3R4/1P4PP/2B2RK1 b - - +solution Rxc1 +id "ECM.356" +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +solution Rxd4 +id "ECM.357" +go +setboard 1r6/3b1pk1/pr1p1q1p/2pPb1p1/2B1P1P1/2N2PP1/1PQ3K1/RR6 b - - +solution Rxb2 +id "ECM.358" +go +setboard 2r3k1/p1r1ppb1/2bp1np1/q5N1/1p1BP2Q/3P4/PP2N1PP/2R2R1K w - - +solution Bxf6 +id "ECM.360" +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +solution Rxd8 +id "ECM.366" +go +setboard r4rk1/5p2/p1b1pQpq/8/1B2P3/2NR4/PPP3PP/1K6 w - - +solution Rd5 +id "ECM.367" +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +solution Rxg6+ +id "ECM.368" +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +solution Bd8 +id "ECM.370" +go +setboard 1k2rb1r/pbp1q1pp/2pp4/2PnpP2/Q7/1P3NP1/PB5P/2KR1B1R w - - +solution Rxd5 +id "ECM.371" +go +setboard 7k/p1p1r2p/1p1pnr1q/5pp1/2PPPp2/2PB1P1P/P2Q1PRK/7R b - - +solution g4 +id "ECM.372" +go +setboard 5qk1/p4p2/1p3Pp1/2p4Q/3rr3/7R/PP6/6RK b - - +solution Rh4 +id "ECM.373" +go +setboard 2b4B/1pp2k2/1p6/3P3n/5p1P/1P4p1/P2r2P1/R5KR b - - +solution f3 +id "ECM.375" +go +setboard r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b q - +solution Bh2 +id "ECM.376" +go +setboard r2q1r2/p1pbppbk/1p3npp/n2P2B1/7Q/2NB1N2/PPP3PP/4RRK1 w - - +solution d6 +id "ECM.377" +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +solution Bxe5+ +id "ECM.379" +go +setboard r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - +solution d4 +id "ECM.387" +go +setboard 2k1r3/Qp3pb1/2p4p/6q1/8/1P4PN/PBPn1P2/K2R4 b - - +solution Qe5 +id "ECM.390" +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +solution Rxa6 +id "ECM.394" +go +setboard r5kr/p3PR1p/1p1p2pq/4n3/8/3B4/P4QPP/4R1K1 w - - +solution Rxe5 +id "ECM.395" +go +setboard 2bq1b2/1p3k2/1r1p1p1p/pNpP1PpP/P1P3P1/6B1/1P5Q/2K1R3 w - - +solution Re6 +id "ECM.396" +go +setboard 2kr3r/pp3p1p/2b1p3/q3Q3/5P2/2P1B3/P1P3PP/1R3RK1 b - - +solution Rhg8 +id "ECM.397" +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +solution Rxd3 +id "ECM.398" +go +setboard 2r2nk1/6pp/p1rPqp2/1pP1p3/1P6/2B3R1/1P2Q1PP/5RK1 w - - +solution Rxf6 +id "ECM.399" +go +setboard r2rnbk1/pp3ppp/1q4n1/3p1N2/5P2/1PQB4/PBP3PP/4RR1K w - - +solution Nh6+ +id "ECM.401" +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +solution e5 +id "ECM.402" +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +solution Rxc4 +id "ECM.408" +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +solution e6 +id "ECM.410" +go +setboard r4rk1/1b4bp/p1npq1P1/R3p3/8/1N2BP2/1PPQ2P1/4KB1R w K - +solution Qxd6 +id "ECM.411" +go +setboard 6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - +solution Bd2 +id "ECM.412" +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +solution Ng5 +id "ECM.416" +go +setboard r3kbnr/1ppb3p/p1q1pp2/3p4/3P4/2N2N2/PPP2PPP/R1BQ1RK1 w kq - +solution Ne5 +id "ECM.418" +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +solution Rxf6 +id "ECM.419" +go +setboard 3rr1k1/1p1qb2p/pP4p1/2p2p2/4RQ2/3P4/1PPB2PP/4R1K1 w - - +solution Bc3 +id "ECM.420" +go +setboard 6k1/rnqb3p/5ppQ/2pPp3/p1N1P3/2PB3P/5PP1/1R4K1 w - - +solution f4 +id "ECM.422" +go +setboard 7r/pp4k1/3pn1p1/q1pB1b2/2P5/5NR1/1P3PP1/2Q3K1 w - - +solution b4 +id "ECM.423" +go +setboard 6k1/p4p1p/3pqp2/2p1r3/2Pnr1N1/P6P/1P1Q1PP1/3R1RK1 b - - +solution Ne2+ +id "ECM.427" +go +setboard r2b4/pb2q1k1/np1p2r1/1N1Pp2Q/PPN1Pp2/8/2R2BPp/2R4K w - - +solution Ncxd6 +id "ECM.434" +go +setboard r7/2qnb1kp/p2p1nP1/1p1Pp1p1/6N1/3BB2Q/PPP4P/5RK1 w - - +solution Qxh7+ +id "ECM.435" +go +setboard n1rqk3/1p2p3/1n1pP1p1/pP1P1p1r/3B3P/1BN3p1/3Q4/R3K2R w KQ - +solution Qg5 +id "ECM.436" +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +solution Bh4 +id "ECM.438" +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +solution Bf8 +id "ECM.439" +go +setboard 4rr1k/pbp3bp/3p4/1p5q/3n4/1B1Q2B1/PP1N1N1P/4RRK1 b - - +solution Rf3 +id "ECM.440" +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +solution Ng6+ +id "ECM.442" +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +solution Qb2 +id "ECM.443" +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +solution Qxg5+ +id "ECM.445" +go +setboard 2k5/1p1b4/2n1p1r1/7q/4RP2/3BQN2/2P2K1P/8 w - - +solution f5 +id "ECM.447" +go +setboard 2k3r1/1ppr3p/p1pB2q1/6n1/N3Pp2/8/PPP1Q1PP/3R1RK1 b - - +solution f3 +id "ECM.448" +go +setboard 6r1/6rk/3p3p/p2Rp3/R1PqPp1b/2N2Q2/6PP/7K b - - +solution Rxg2 +id "ECM.450" +go +setboard 2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - +solution h4 +id "ECM.456" +go +setboard 6nk/p4rrp/1p1p1p2/1q1Pp2R/4B1P1/1PP2Q1R/P6P/7K w - - +solution g5 +id "ECM.458" +go +setboard r1b1k2r/6pp/p1p1p3/3np1B1/1b2N3/8/q1PQB1PP/3RK2R w Kkq - +solution Qxb4 +id "ECM.459" +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +solution Bxh5 +id "ECM.460" +go +setboard 4r1kb/p2r4/1np1p1p1/3nP1Bp/1p3P1R/1B2qP2/PPPN3Q/2K4R w - - +solution Rxh5 +id "ECM.463" +go +setboard 2rq2k1/pp1bpp1p/3p1np1/8/3NPPnQ/1BP5/P1P3P1/1K1R3R w - - +solution e5 +id "ECM.464" +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +solution Rxd5 +id "ECM.465" +go +setboard 2r1kr2/p1qbbp1Q/3pp3/5p2/1p1N1PB1/6P1/PPP4P/K2RR3 w - - +solution Bxf5 +id "ECM.466" +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +solution Rf6 +id "ECM.467" +go +setboard 2rr2k1/5pn1/1b2q1pp/pP1pP3/2pP1PP1/2R1B2P/2Q3B1/3R3K w - - +solution f5 +id "ECM.468" +go +setboard 2Q2bkr/5p2/1rb5/1pN1n1qB/1P1pPN2/6P1/5P2/R1R3K1 w - - +solution Nce6 +id "ECM.469" +go +setboard 2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - +solution Nc3+ +id "ECM.470" +go +setboard r7/pp4pk/2n3qp/5p2/3p4/P4QB1/1PP1RPPP/6K1 b - - +solution d3 +id "ECM.473" +go +setboard 2r2r1k/1p3p1p/p2p1Pp1/3Pp3/1q2Bn1Q/8/1PP3PP/4RR1K w - - +solution Rxf4 +id "ECM.474" +go +setboard r4rk1/5ppp/p7/4PR2/P1qnp2Q/4B3/1P4PP/5RK1 w - - +solution Rh5 +id "ECM.475" +go +setboard 4r3/pb3pk1/6p1/8/6P1/1PNrB2K/P4P1P/2R5 b - - +solution Rexe3+ +id "ECM.476" +go +setboard 1r2k2r/1bq2pp1/pn2p2p/1p2P1b1/3N4/2N3Q1/PPP3PP/1K1R1BR1 w k - +solution Bxb5+ +id "ECM.482" +go +setboard 2r2r2/p4p1k/1p2pBpn/2p5/6N1/8/P4P2/R3R1K1 w - - +solution Kg2 +id "ECM.484" +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +solution Bg5 +id "ECM.485" +go +setboard 2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - +solution Bh3 +id "ECM.488" +go +setboard 2b3k1/5qp1/p2r1n1p/3p4/3B4/1RP3QP/P2Nr1P1/3R2K1 b - - +solution Ne4 +id "ECM.489" +go +setboard 1r2r1k1/p4ppb/q1pbnn1p/4p3/N1P1P3/pPB2NP1/2Q1RPBP/R5K1 b - - +solution Nxe4 +id "ECM.491" +go +setboard r4r2/1pnqb2k/3p1p1p/p1pPpPpP/2P1N1P1/4BP2/PP1Q4/R2R2K1 w - - +solution Bxc5 +id "ECM.492" +go +setboard 6kr/1p1r1p1p/p2pnPpQ/3Np2R/2q1P3/5P2/PPP5/2KR4 w - - +solution Rxe5 +id "ECM.494" +go +setboard rq1r2k1/3nbp1p/p2p2p1/1p1Pp1P1/3B1P2/3B3Q/PPP4P/2KR2R1 w - - +solution f5 +id "ECM.497" +go +setboard r4rk1/1bq1bppp/8/p2pPR2/3B4/1NnP3Q/1P4PP/4R1K1 w - - +solution Rh5 +id "ECM.498" +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +solution Nxh5 +id "ECM.499" +go +setboard r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - +solution f3 +id "ECM.500" +go +setboard 4rqk1/p5b1/3p3p/3Pn1p1/1pP1NrP1/4NP2/P3Q1P1/1K1RR3 b - - +solution Nxf3 +id "ECM.501" +go +setboard r3rk2/pb2bpp1/1n5p/q1pP1B2/1p3B2/5N2/PPQ2PPP/R2R2K1 w - - +solution Bc8 +id "ECM.503" +go +setboard r1bqr2k/ppp2p1p/5b2/3Pn1p1/1PP1Bp2/8/PB2N1PP/R2Q1RK1 w - - +solution Nxf4 +id "ECM.504" +go +setboard 1q4k1/p3rppp/3b1n2/8/5P2/4P3/PP1B3P/RNQ3K1 b - - +solution Bxf4 +id "ECM.505" +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +solution Rxe6 +id "ECM.510" +go +setboard 2bk3r/3r2pp/p2nQ3/q2R2P1/1p6/8/PPP2P1P/1K3B1R b - - +solution Qxd5 +id "ECM.525" +go +setboard 1kb3rr/1p2n2q/1Np2p2/1p6/1P1N1P1p/8/2P1RQPP/R6K w - - +solution Nxb5 +id "ECM.529" +go +setboard 6k1/5qp1/pN5p/3pRp2/3QnP2/2r4P/r5P1/6RK b - - +solution Qh5 +id "ECM.539" +go +setboard r1b2rk1/ppp2ppp/2n3q1/b2N2N1/2BP4/4p2P/PPP3P1/R2Q1RK1 w - - +solution Nxf7 +id "ECM.553" +go +setboard r6r/pR1nqkpp/2p1p3/3p4/6Q1/2b4P/P1PP1PP1/2B1R1K1 w - - +solution Rxe6 +id "ECM.555" +go +setboard 5rk1/p1p1br2/1p1p2qp/4p3/2PPn1pP/3Q2P1/PPN1P1K1/2RR2B1 b - - +solution Bxh4 +id "ECM.557" +go +setboard r1b2rk1/4bnpp/2p5/pp2q3/4N3/PQ2B1P1/1PP3BP/4RRK1 w - - +solution Ng5 +id "ECM.559" +go +setboard 2rr2k1/1p3p2/p2n2p1/P2PnNq1/3QP1p1/1RN5/6PP/5RK1 b - - +solution Nf3+ +id "ECM.560" +go +setboard r3k1r1/pb1qpp1p/1pnp1n1B/2p2R2/3PP3/2P3PN/P1P3BP/R2Q3K b q - +solution Nxe4 +id "ECM.561" +go +setboard 2r2rk1/pp2bppp/3q1n2/3nNRB1/3P4/1B5Q/PP4PP/3R2K1 w - - +solution Nxf7 +id "ECM.562" +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +solution Rxc5 +id "ECM.566" +go +setboard 2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - +solution Nxc1 +id "ECM.569" +go +setboard 5rk1/bp4p1/p2rp2p/8/8/2PN4/PP1R1PPP/3R2K1 b - - +solution e5 +id "ECM.577" +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +solution Bh3 +id "ECM.578" +go +setboard r3r1k1/p2n4/3p1pp1/qnp3B1/1p2P1P1/1P3P2/PP2N2Q/1K1R1B2 w - - +solution Nf4 +id "ECM.580" +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +solution Nxc6 +id "ECM.587" +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +solution h3 +id "ECM.589" +go +setboard 4r1k1/r1q2p1p/p5pB/1pbBpN1n/1n2P3/5Q2/PP3PPP/R1R3K1 w - - +solution Rxc5 +id "ECM.592" +go +setboard r1r3k1/ppnbb1pp/2ppp1q1/1P3p2/P1PPn3/2N2NP1/2Q1PPBP/1RB2RK1 w - - +solution Nxe4 +id "ECM.593" +go +setboard 1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - +solution Nxh2 +id "ECM.595" +go +setboard rnb2rk1/pp4pp/2pb1n2/3N1p1q/2P5/3N2P1/P1Q1PPBP/R1B2RK1 w - - +solution Bf4 +id "ECM.597" +go +setboard 8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - +solution f4 +id "ECM.598" +go +setboard 7k/8/1p1ppp1p/1Pp5/2P2P2/8/3P2PP/6K1 w - - +solution f5 +id "ECM.600" +go +setboard 8/p5k1/2p2p2/4p1p1/1p2P3/1P4PP/1PP5/5K2 b - - +solution g4 +id "ECM.601" +go +setboard 8/8/4b1p1/2Bp3p/5P1P/1pK1Pk2/8/8 b - - +solution g5 +id "ECM.605" +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +solution Bxg6 +id "ECM.607" +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +solution Rxc6 +id "ECM.608" +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +solution f6 +id "ECM.609" +go +setboard 2kr3r/ppp1qpp1/2p5/2b2b2/2P1pPP1/1P2P1p1/PBQPB3/RN2K1R1 b Q - +solution Rh1 +id "ECM.610" +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +solution e5 +id "ECM.613" +go +setboard 5r2/pp1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +id "ECM.614" +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +solution b5 +id "ECM.615" +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +solution Rxa6 +id "ECM.616" +go +setboard 3r2k1/p6p/b2r2p1/2qPQp2/2P2P2/8/6BP/R4R1K w - - +solution Rxa6 +id "ECM.617" +go +setboard 6B1/2p2pp1/2p5/p3K3/1k6/nP4P1/5P1P/8 b - - +solution Nc4+ +id "ECM.621" +go +setboard 6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - +solution Rc4 +id "ECM.623" +go +setboard 4r2k/3n1Qpp/1pRP1p2/p4P2/1p1P2P1/6rP/P3q1B1/6RK w - - +solution Qe6 +id "ECM.624" +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +solution Ba6 +id "ECM.626" +go +setboard 3rr1k1/pppRn1pp/4Pp2/1P5q/1QB5/4P3/P4P1P/4K1R1 w - - +solution Qxe7 +id "ECM.627" +go +setboard 8/6Bp/6p1/2k1p3/4PPP1/1pb4P/8/2K5 b - - +solution b2+ +id "ECM.629" +go +setboard 3qr1k1/p4ppp/1p1P4/2r1nN2/4P2n/P7/1B4P1/3QRRK1 w - - +solution d7 +id "ECM.632" +go +setboard 4r3/p4pk1/6p1/P1pB2Pp/2P3b1/2p1N1P1/Qb1r1P2/6K1 b - - +solution Rxe3 +id "ECM.634" +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +solution Nxa7 +id "ECM.635" +go +setboard r4rk1/ppq3pp/2p1Pn2/4p1Q1/8/2N5/PP4PP/2KR1R2 w - - +solution Rxf6 +id "ECM.636" +go +setboard r3qr1k/1b4pp/p2RQ3/Bp2p3/4p3/6P1/PPP2P1P/3R2K1 b - - +solution Qh5 +id "ECM.637" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "ECM.640" +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +solution f5 +id "ECM.644" +go +setboard 8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - +solution Bxb3 +id "ECM.646" +go +setboard 4r2k/p2qr1pp/1pp2p2/2p1nP1N/4R3/1P1P2RP/1PP2QP1/7K w - - +solution Rxg7 +id "ECM.648" +go +setboard 8/1R2P3/6k1/3B4/2P2P2/1p2r3/1Kb4p/8 w - - +solution Be6 +id "ECM.650" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Bb5 +id "ECM.653" +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +solution Bxh7+ +id "ECM.654" +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +solution Rxh7 +id "ECM.663" +go +setboard r1b2rk1/2q1bppp/p1n1p3/1p1np1P1/5P2/1NNBBQ2/PPP4P/R4RK1 w - - +solution Bxh7+ +id "ECM.665" +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +solution Nxh7 +id "ECM.666" +go +setboard 2rqr1k1/1p1bbppp/p3p3/n7/3P2Q1/2PB1N2/P4PPP/R1B1R1K1 w - - +solution Bxh7+ +id "ECM.673" +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +solution Nxh7 +id "ECM.674" +go +setboard rn1q1rk1/pb1p1ppp/4p3/2pnP3/1bp5/2N2N2/PP3PPP/RBBQK2R w KQ - +solution Bxh7+ +id "ECM.675" +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +solution Rxh7 +id "ECM.676" +go +setboard r1b2rk1/1pq2ppp/p1p1p3/2n1P3/2N2P2/3B4/PPP3PP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.677" +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +solution Nxh7 +id "ECM.679" +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +solution Bxh7+ +id "ECM.680" +go +setboard 1r2nrkb/2n2p1p/p2p1Pp1/P1pPp1P1/1pP1P1q1/1P1BB1N1/3Q4/2KR3R w - - +solution Rxh7 +id "ECM.681" +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +solution Bxh7+ +id "ECM.682" +go +setboard r2q3r/2pkb1p1/p2p1n2/4p1p1/Pp2P1P1/1QP5/1P1P2PP/RNB2RK1 b - - +solution Rxh2 +id "ECM.683" +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +solution Nxh7 +id "ECM.684" +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +solution Rxh7 +id "ECM.685" +go +setboard r2qn1k1/pb4Pp/1pn5/2p5/2P2p2/P1PB4/5PPP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.686" +go +setboard r4rk1/pp1n1ppp/3qp3/3nN1P1/b2P4/P2B1Q2/3B1P1P/1R2R1K1 w - - +solution Bxh7+ +id "ECM.687" +go +setboard r2r2k1/ppqbbppp/4pn2/6N1/n1P4P/3B1N2/PP2QPP1/1KBR3R w - - +solution Nxh7 +id "ECM.688" +go +setboard r6r/4ppk1/p2p1bp1/B2p4/3P2p1/QP2P3/P1R1qPPP/2R3K1 b - - +solution Rxh2 +id "ECM.690" +go +setboard 4nrk1/r4p1p/p2p2pQ/2pPpNPP/qpn1P3/5P1R/PPP1N3/2K3R1 w - - +solution Qxh7+ +id "ECM.691" +go +setboard r3k2r/1b1n1p2/pq1p1bp1/1p4p1/P3P3/1NN5/1PP3PP/R2QRB1K b kq - +solution Rxh2+ +id "ECM.692" +go +setboard r2qrnk1/4bppp/b1p5/1p1p2P1/p2P1N1P/2NBP3/PPQ2P2/2K3RR w - - +solution Bxh7+ +id "ECM.693" +go +setboard 3r1rk1/4qp1p/p1bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxh2+ +id "ECM.696" +go +setboard r2q1rk1/3n1ppp/8/1pbP2P1/p1N4P/PnBBPQ2/5P2/R3K2R w KQ - +solution Bxh7+ +id "ECM.697" +go +setboard 2k3r1/ppq2p1p/n1Pb1p2/8/6r1/4BN1b/PPQ2PPP/R3RBK1 b - - +solution Bxh2+ +id "ECM.698" +go +setboard 3qr1k1/1br2ppp/p2b4/8/PpNp4/3P4/1PP2PPP/R1BQ1RK1 b - - +solution Bxh2+ +id "ECM.699" +go +setboard r1b4r/3p1kp1/pp3q1p/4RP2/8/B7/P5PP/4QRK1 w - - +solution Qe4 +id "ECM.701" +go +setboard 1r2rnk1/2R2bpp/p2q4/1p1N2R1/5P2/1Q1B3P/PP4P1/7K w - - +solution Rxg7+ +id "ECM.702" +go +setboard 2r2r1k/3b1pb1/p3pp1p/q2p1P1B/8/2N2RR1/P1PQ2PP/7K w - - +solution Rxg7 +id "ECM.706" +go +setboard r2qr1k1/1p3ppp/2pb4/2Np4/1P1P2bn/3BP3/2QN1PPP/1RR3K1 b - - +solution Nxg2 +id "ECM.712" +go +setboard r3r1k1/pp3pp1/3p4/2q4p/2P5/1PB2Q1P/n4PP1/3R1RK1 w - - +solution Bxg7 +id "ECM.713" +go +setboard r5k1/pn1q1rpp/2pp4/5R1N/bP6/4BQ2/P4PPP/2R3K1 w - - +solution Nxg7 +id "ECM.714" +go +setboard 3r1rk1/5pp1/pq1n1n1p/2pPR3/2B2P2/1PBQ2RP/P5P1/6K1 w - - +solution Rxg7+ +id "ECM.715" +go +setboard rn3rk1/ppq2ppp/2pb1nb1/5N2/2BP4/8/PPP1N1P1/R1B1QR1K w - - +solution Nxg7 +id "ECM.716" +go +setboard r1qb1r1k/2p3pp/p1n1bp2/1p1Np2Q/P3P3/1BP3R1/1P3PPP/R1B3K1 w - - +solution Rxg7 +id "ECM.717" +go +setboard r4rk1/5ppp/p2pbb2/3B3Q/qp2p3/4B3/PPP2P1P/2KR2R1 w - - +solution Rxg7+ +id "ECM.718" +go +setboard 4q1k1/1b3r1p/p4pp1/1p6/2P2n2/1P3N2/1B3PPP/R2Q3K b - - +solution Nxg2 +id "ECM.719" +go +setboard 4rrk1/2pn2pb/p1p1qp2/1pb1pN2/P3P1PN/1P1P4/1BP2PK1/R2Q3R w - - +solution Nxg7 +id "ECM.721" +go +setboard r3r1k1/p3bppp/q1b2n2/5Q2/1p1B4/1BNR4/PPP3PP/2K2R2 w - - +solution Rg3 +id "ECM.722" +go +setboard 4kbr1/pp1bpp1p/3p1p2/3N4/1PBQP3/q7/P1r2PPP/R4RK1 b - - +solution Rxg2+ +id "ECM.725" +go +setboard rq1r1bk1/1b3pp1/3pn2p/1n2BN1P/1P2P3/3R1NP1/3Q1PB1/2R3K1 w - - +solution Bxg7 +id "ECM.728" +go +setboard 3q1r2/1p1b1pk1/pn5p/3pN1pQ/3P3P/2r3B1/P4PP1/3RR1K1 w - - +solution Nxf7 +id "ECM.730" +go +setboard 2r3k1/pbq1np1p/1p1b1Bp1/8/6QP/2P2N2/B4PP1/4R1K1 w - - +solution Bxf7+ +id "ECM.733" +go +setboard r3r1k1/1bqn1ppp/1pp2p2/8/3P4/1B4N1/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.734" +go +setboard r3r1k1/pp3ppp/8/1Nbp3q/3NnBn1/2P5/PPQ2PPP/3R1RK1 b - - +solution Ngxf2 +id "ECM.735" +go +setboard r2r2k1/1b2qpp1/1p2n3/p1b1p2p/4P1n1/PP1B2PP/1B1NQP2/R3NRK1 b - - +solution Nxf2 +id "ECM.736" +go +setboard r5k1/1pp3pp/1b1p1r2/pN1P1n2/P1P3nq/6N1/1P1B1PQP/4RRK1 b - - +solution Nxf2 +id "ECM.738" +go +setboard r2qr1k1/pb2bp1p/1pn1p1pB/8/2BP4/P1P2N2/4QPPP/3R1RK1 w - - +solution d5 +id "ECM.742" +go +setboard r2qr1k1/1b1nbp1p/p3pp2/1p2N3/3P4/3B1N2/PP2QPPP/R2R2K1 w - - +solution Nxf7 +id "ECM.745" +go +setboard r3kr2/1b2qp2/pp2p2N/4p2Q/8/2n5/P3B1PP/3R1R1K w q - +solution Nxf7 +id "ECM.752" +go +setboard rqb1k2r/1p1nbp1p/p4pp1/8/1PBN1P2/P1N1P3/7P/2RQ1RK1 w kq - +solution Bxf7+ +id "ECM.754" +go +setboard r2r2k1/4ppbp/5np1/p1q5/QnB1P3/5N2/1P3PPP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.755" +go +setboard 1r4k1/p4pp1/bqnrpn1p/2ppN3/2P2P1B/P3P3/1P2B1PP/1Q1R1RK1 w - - +solution Bxf6 +id "ECM.758" +go +setboard 2rqr1k1/pp2nppp/3p2b1/6B1/2BNn1Q1/P7/1PP2PPP/2KRR3 w - - +solution Bxf7+ +id "ECM.761" +go +setboard r3r1k1/pbq1ppbp/1pp2np1/4N3/3P4/2P5/PPB1QPPP/R1B1R1K1 w - - +solution Nxf7 +id "ECM.762" +go +setboard r1b2rk1/p6p/2p3Pb/3pp1q1/8/2PB4/PP3PP1/RN1Q1K1R b - - +solution Rxf2+ +id "ECM.763" +go +setboard r2rn3/1p3pk1/p1pNn1pp/q3P3/P7/1PN4P/2QR1PP1/3R2K1 w - - +solution Nxf7 +id "ECM.764" +go +setboard r1bqr1k1/1p1nnpb1/p5pp/2P1p1B1/B3N3/5N2/P4PPP/2RQR1K1 w - - +solution Nd6 +id "ECM.765" +go +setboard r1b1r1k1/pp2qpbp/2p3p1/2P5/3NnB2/7P/PPQ1PPB1/2RR2K1 b - - +solution Nxf2 +id "ECM.766" +go +setboard rn2r1k1/pp3p1p/3P2p1/2p1bbB1/2B5/2N5/Pq4PP/R2Q1RK1 w - - +solution Bxf7+ +id "ECM.767" +go +setboard 1bq2k2/1b1n1pp1/pp5p/2pBpN2/P3P2B/3Q1P2/1PP3PP/4K3 w - - +solution Bxf7 +id "ECM.769" +go +setboard rnb2rk1/pp3pbp/2p3pB/2q5/4P3/1BN5/PPP3PP/R2Q1R1K w - - +solution Rxf7 +id "ECM.770" +go +setboard 3qr1k1/1br1bp1p/p3p1pB/1p1nN3/3PB3/7Q/PP3PPP/3RR1K1 w - - +solution Nxf7 +id "ECM.771" +go +setboard rr1q2k1/1p2bpp1/2p1p2p/P1Pn4/2NP4/3Q1RP1/5PKP/2B1R3 w - - +solution Bxh6 +id "ECM.773" +go +setboard r2r2k1/pb1nbpp1/1qp1pn1p/1p2N3/3P1B2/P1N1P3/BPQ2PPP/2R2RK1 w - - +solution Bxh6 +id "ECM.774" +go +setboard r1b1r3/pp2Npbk/3pp2p/q5p1/2QNPP2/6P1/PPP3P1/2KR3R w - - +solution Ndf5 +id "ECM.776" +go +setboard 1rbqnr2/5p1k/p1np3p/1p1Np3/4P2P/1Q2B3/PPP1BP2/2KR3R w - - +solution Bxh6 +id "ECM.779" +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.780" +go +setboard 3r1r1k/p5p1/n1p2p1p/1qp2b2/N1R4R/1PB1P1P1/P2P3P/3Q2K1 w - - +solution Rxh6+ +id "ECM.781" +go +setboard 6rk/3b1n1p/1p1q3b/1PpNp3/2P1Pp2/2Q2NrP/5RP1/2R2B1K b - - +solution Bxh3 +id "ECM.783" +go +setboard 2r1r1k1/pb1n1pp1/1p1qpn1p/4N1B1/2PP4/3B4/P2Q1PPP/3RR1K1 w - - +solution Bxh6 +id "ECM.789" +go +setboard 2br2k1/4qppp/p5r1/2pBp3/2P1Pn2/4Q2P/RP3PPK/1N4R1 b - - +solution Bxh3 +id "ECM.791" +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +solution Bxh6 +id "ECM.792" +go +setboard 6k1/p4ppp/1pn1b1rr/8/PBpPp2q/2P1P1NP/5PP1/RR3QK1 b - - +solution Bxh3 +id "ECM.795" +go +setboard r1b2rk1/1p3pp1/p5Pp/2bpPp1Q/3N4/1Pq1B1R1/2P4P/3R2K1 w - - +solution Bxh6 +id "ECM.796" +go +setboard 2b1rk2/r6p/1pP1p1p1/p2pNnR1/5Q2/P1B4q/1PP2P1P/1K4R1 w - - +solution Nxg6+ +id "ECM.799" +go +setboard r6r/ppnqpk2/3pbpp1/5N2/1PP1P3/5RR1/P2QB1PP/6K1 w - - +solution Nh6+ +id "ECM.801" +go +setboard 2b2r1k/2p3pp/2Nb4/pP5q/2PP4/P4pP1/5P1P/R1BQ2K1 b - - +solution Bxg3 +id "ECM.803" +go +setboard r1bq2k1/pp3r1p/2n1p1p1/3pP3/6Q1/2PB2P1/P4PK1/R1B4R w - - +solution Bxg6 +id "ECM.804" +go +setboard 3q1rk1/2r4p/n1p1n1pQ/p2pP3/Np1P2R1/5PN1/PP3KP1/2R5 w - - +solution Rxg6+ +id "ECM.805" +go +setboard 2rqr1k1/pb2bp1p/1pn1pnpB/4N3/3P4/P1N3R1/1P3PPP/RB1Q2K1 w - - +solution Rxg6+ +id "ECM.810" +go +setboard 2r5/pp2qr1k/1nb3pp/2ppBp2/2P4P/3B2R1/P3QPP1/1R4K1 w - - +solution Rxg6 +id "ECM.811" +go +setboard 3rr3/3q1p1k/p2P2pp/1bp1b3/5N2/6QP/P1B3P1/3RR1K1 w - - +solution Bxg6+ +id "ECM.812" +go +setboard 1n1b1rk1/r4p1p/p1p2qpQ/P3Np2/2BP4/2P1R3/5PPP/R5K1 w - - +solution Rb1 +id "ECM.814" +go +setboard 6rk/pb3p1p/3bpPq1/3P4/1p1B3r/1B4P1/PPRQ1R1P/6K1 b - - +solution Bxg3 +id "ECM.815" +go +setboard 3rr1k1/pb2bp1p/3qp1pB/1p2N3/3P2Q1/2P1R3/P4PPP/4R1K1 w - - +solution Nxg6 +id "ECM.816" +go +setboard 1Q4R1/r2qbp2/3p1kp1/3Bp2p/8/3PP1P1/5PKP/8 w - - +solution Rxg6+ +id "ECM.818" +go +setboard k2r3r/ppq2p1p/n1pb1Pp1/4p3/2Q5/1R2B1P1/PPP2PBP/R5K1 w - - +solution Rxb7 +id "ECM.821" +go +setboard 1rb2rk1/p1p1qppp/2p2n2/3P4/1b3P2/2NB4/PPPBQ1PP/2KR3R b - - +solution Ba3 +id "ECM.822" +go +setboard 4rrk1/p5pp/1p4q1/3p2n1/2pP2P1/P1P1PP2/3B2K1/1R2QR2 b - - +solution Nxf3 +id "ECM.824" +go +setboard 1q1r3k/3P1pp1/ppBR1n1p/4Q2P/P4P2/8/5PK1/8 w - - +solution Rxf6 +id "ECM.825" +go +setboard 1rbq2k1/b1p3pp/p1Pp4/3Ppr2/8/5N2/PPQ2PPP/R1B2RK1 b - - +solution Rxf3 +id "ECM.826" +go +setboard 1r1q1r1k/2p3pp/1p1bQ3/p7/1PP5/Pn3B2/1B3PPP/R4RK1 b - - +solution Rxf3 +id "ECM.827" +go +setboard r1bq1rk1/1p2bppp/p3p3/n3P3/4N3/1P1P1N2/PB4PP/R3QR1K w - - +solution Nf6+ +id "ECM.829" +go +setboard 1n2r3/p1pq1kp1/1b1pNpp1/3P4/5RP1/3Q3P/1B3P2/6K1 w - - +solution Bxf6 +id "ECM.830" +go +setboard r1bq1rk1/ppp3p1/7p/3P2n1/2PQ1p2/1N5P/PPP2PPK/R1B2R2 b - - +solution Nf3+ +id "ECM.831" +go +setboard 3r1b2/p4bkp/1p1P1p2/r3p1p1/2q1N3/2N2P2/1P1R2PP/2QR3K w - - +solution Nxf6 +id "ECM.832" +go +setboard rqbn1rk1/1p3ppp/p3p3/8/4NP2/8/PPP1BQPP/1K1R3R w - - +solution Nf6+ +id "ECM.833" +go +setboard r1b1kb1r/1p4pp/p2ppn2/8/2qNP3/2N1B3/PPP3PP/R2Q1RK1 w kq - +solution Rxf6 +id "ECM.834" +go +setboard 2nr2k1/1pq1bppp/p1p5/2p1P1PQ/2P1NP2/1PNR4/P6P/6K1 w - - +solution Nf6+ +id "ECM.836" +go +setboard 6nk/pn2qr1r/1pbp1p1p/2p1pPpN/P1P1P1PP/2PP3R/7Q/2BBK2R w K - +solution Nxf6 +id "ECM.837" +go +setboard r1b1kb1r/1p1n1ppp/p2ppn2/6BB/2qNP3/2N5/PPP2PPP/R2Q1RK1 w kq - +solution Nxe6 +id "ECM.841" +go +setboard r1b1k1nr/3n1p1p/1qpBp1p1/pp2b3/4PN2/PBN2Q2/1PP2PPP/2KR3R w kq - +solution Nxe6 +id "ECM.842" +go +setboard 2r2rk1/1b3ppp/pq2p3/1pbn2N1/3B3P/1B4P1/P1P1QP2/2KRR3 w - - +solution Qh5 +id "ECM.843" +go +setboard r3k2r/pp1n1pb1/1qn1p1p1/2p3Pp/4R2P/2NP2QB/PPPB1P2/2K1R3 w kq - +solution Rxe6+ +id "ECM.844" +go +setboard r3k2r/1q3ppp/p3p3/2b1P3/p2N1Q2/P7/1PP3PP/3R1R1K w kq - +solution Nxe6 +id "ECM.845" +go +setboard 3qr1k1/rp3pbp/2p3p1/3p1b2/N1nP4/P2NP3/1PQ2PPP/1BRR2K1 b - - +solution Rxe3 +id "ECM.846" +go +setboard 1r3rk1/5pbp/p2Pp1p1/q1n3P1/2p2P1P/2N1Q2R/PP6/1BKR4 b - - +solution Rxb2 +id "ECM.852" +go +setboard rr4k1/5p1p/n2p1npQ/q1pP4/6P1/2N2P1N/PP1R3P/2K4R b - - +solution Rxb2 +id "ECM.853" +go +setboard 1k2bb1r/1p3p1p/p2qpP1p/3pN3/3P1Q2/2RB2P1/PP3P1P/6K1 w - - +solution Qc1 +id "ECM.854" +go +setboard 5rk1/5rp1/p2qb3/R2Np2Q/3bP2B/7P/P5PK/1R6 b - - +solution Rf1 +id "ECM.856" +go +setboard 3r1rk1/p3q1pp/2Rb4/3P4/8/1P2Qp2/PB3PPP/3R2K1 b - - +solution Bxh2+ +id "ECM.858" +go +setboard 1r4k1/1q3pb1/r1b3p1/pp1Qp3/P3P3/1B2BP2/1PP3P1/1K1R3R w - - +solution Qd8+ +id "ECM.860" +go +setboard 3r4/kb6/pp6/4R1pr/PPpq4/2N3Q1/2P3PP/3R3K b - - +solution Rf8 +id "ECM.862" +go +setboard 8/2q1np1k/6p1/1PPn3p/8/P2Q3P/6P1/2R4K b - - +solution Nf5 +id "ECM.864" +go +setboard 7R/1p1r4/2b2p2/2Pp1qk1/3P1bp1/3N4/2Q2PB1/6K1 w - - +solution Rg8+ +id "ECM.866" +go +setboard r6r/1pn1b1k1/2p1pq2/2Pp3p/p2P1Pp1/P2BP1P1/1P2QB2/3R2KR w - - +solution Rxh5 +id "ECM.867" +go +setboard 1r4k1/pp4pp/2n1b3/1Rq1p3/2P2r2/P1B2P2/2Q1B1PP/3R1K2 b - - +solution Rxf3+ +id "ECM.868" +go +setboard 2rq1rk1/5ppp/2b1pb2/np6/6N1/2NBB3/PP3PPP/R2Q2K1 w - - +solution Bb6 +id "ECM.872" +go +setboard 5r2/p2p2kp/3PnNp1/1qr1Pp2/2p5/P1R5/6PP/2Q1R1K1 w - - +solution Qh6+ +id "ECM.873" +go +setboard 2kr1br1/ppp2p1p/2n1p1q1/2Nn4/3P4/1Q2PB2/PP1B1P1P/2R1K2R b K - +solution Qg1+ +id "ECM.875" +go +setboard 2kr3r/1Rp1bpp1/p6q/Q3P3/2P5/3p1NP1/P3P2P/1R4K1 b - - +solution Qe3+ +id "ECM.877" +go +setboard 6k1/1R4pp/2p5/8/P1rNp3/6Pb/4PK2/8 w - - +solution a5 +id "ECM.878" +go +setboard r2r2k1/pp3ppp/2q5/2p5/2P1P1n1/P4P1b/1BQ1BP1P/R3R2K b - - +solution Rd2 +id "ECM.879" +gosetboard 2q1r1k1/1ppb4/r2p1Pp1/p4n1p/2P1n3/5NPP/PP3Q1K/2BRRB2 w - - +solution f7+ +id "ECM.001" +go +setboard 7r/1p2k3/2bpp3/p3np2/P1PR4/2N2PP1/1P4K1/3B4 b - - +solution Bxf3+ +id "ECM.002" +go +setboard 4k3/p1P3p1/2q1np1p/3N4/8/1Q3PP1/6KP/8 w - - +solution Qb5 +id "ECM.003" +go +setboard 2r1b1k1/R4pp1/4pb1p/1pBr4/1Pq2P2/3N4/2PQ2PP/5RK1 b - - +solution Rcxc5 +id "ECM.004" +go +setboard 6k1/p1qb1p1p/1p3np1/2b2p2/2B5/2P3N1/PP2QPPP/4N1K1 b - - +solution Bxf2+ +id "ECM.005" +go +setboard 3q4/pp3pkp/5npN/2bpr1B1/4r3/2P2Q2/PP3PPP/R4RK1 w - - +solution Bxf6+ +id "ECM.006" +go +setboard 3rr1k1/pb3pp1/1p1q1b1p/1P2NQ2/3P4/P1NB4/3K1P1P/2R3R1 w - - +solution Rxg7+ +id "ECM.007" +go +setboard r1b1r1k1/p1p3pp/2p2n2/2bp4/5P2/3BBQPq/PPPK3P/R4N1R b - - +solution Bg4 +id "ECM.008" +go +setboard 3r4/1b2k3/1pq1pp2/p3n1pr/2P5/5PPN/PP1N1QP1/R2R2K1 b - - +solution Rxh3 +id "ECM.009" +go +setboard 2r4k/pB4bp/6p1/6q1/1P1n4/2N5/P4PPP/2R1Q1K1 b - - +solution Qxc1 +id "ECM.010" +go +setboard 1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - +solution Nxg4 +id "ECM.011" +go +setboard 5rk1/7p/p1N5/3pNp2/2bPnqpQ/P7/1P3PPP/4R1K1 w - - +solution Ne7+ +id "ECM.012" +go +setboard rnb2rk1/pp2np1p/2p2q1b/8/2BPPN2/2P2Q2/PP4PP/R1B2RK1 w - - +solution Nd5 +id "ECM.013" +go +setboard 2k4r/1pp2ppp/p1p1bn2/4N3/1q1rP3/2N1Q3/PPP2PPP/R4RK1 w - - +solution Nd5 +id "ECM.014" +go +setboard r3kb1r/pp2pppp/3q4/3Pn3/6b1/2N1BN2/PP3PPP/R2QKB1R w KQkq - +solution Nxe5 +id "ECM.015" +go +setboard 2rr2k1/1b3p1p/p4qpb/2R1n3/3p4/BP2P3/P3QPPP/3R1BKN b - - +solution Rxc5 +id "ECM.016" +go +setboard r1b1k3/5p1p/p1p5/3np3/1b2N3/4B3/PPP1BPrP/2KR3R w q - +solution Rxd5 +id "ECM.017" +go +setboard r3rbk1/1pq2ppp/2ppbnn1/p3p3/P1PPN3/BP1BPN1P/2Q2PP1/R2R2K1 w - - +solution Nxd6 +id "ECM.018" +go +setboard b7/2q2kp1/p3pbr1/1pPpP2Q/1P1N3P/6P1/P7/5RK1 w - - +solution Rxf6+ +id "ECM.019" +go +setboard 1rr1nbk1/5ppp/3p4/1q1PpN2/np2P3/5Q1P/P1BB1PP1/2R1R1K1 w - - +solution Bxa4 +id "ECM.020" +go +setboard r7/5kp1/2p1p2p/1p1n3P/2rP4/2P3R1/PK2RPP1/2B5 b - - +solution Rxc3 +id "ECM.021" +go +setboard r1r3k1/p3qpp1/b1P4p/3p4/3Nn3/4P3/P1Q2PPP/1BR1K2R b K - +solution Qb4+ +id "ECM.022" +go +setboard rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - +solution Bxd5 +id "ECM.023" +go +setboard 6rk/1p1br2p/pqp5/3pNP2/3Pp3/P5PR/5PKR/Q7 w - - +solution Rxh7+ +id "ECM.024" +go +setboard 2b3k1/5p1p/7b/p2B3p/3P4/P2Q1N1P/1q3PP1/6K1 w - - +solution Bxf7+ +id "ECM.025" +go +setboard r1b5/4k3/p7/3p1n2/3Bp3/2P2r1P/PPBK1P2/4R2R w - - +solution Bc5+ +id "ECM.026" +go +setboard r4rk1/1b3Npp/p7/1p3Q2/3P4/1B2q3/P5PP/3n1R1K b - - +solution Bxg2+ +id "ECM.027" +go +setboard r1b2rk1/2q2ppp/2pbp3/p7/4Nn2/3B4/PPPBQ1PP/R4R1K w - - +solution Rxf4 +id "ECM.028" +go +setboard 3r2k1/1q1P1ppp/r2R2n1/p4Q2/1ppB2R1/6P1/PP3PP1/6K1 w - - +solution Rgxg6 +id "ECM.029" +go +setboard r2q1rk1/p3b1pp/2p5/1pn5/1n1Bp1b1/1P6/PQ1PPP2/2RNKBNR b K - +solution Bxe2 +id "ECM.030" +go +setboard 3r2k1/p2r1p1p/1p2p1p1/q4n2/3P4/PQ1R3P/1P2NPP1/3R2K1 b - - +solution Nxd4 +id "ECM.031" +go +setboard 2bnr1k1/2q2ppp/p7/2p1b3/2N1B3/R7/1P2QPPP/2B3K1 w - - +solution Nxe5 +id "ECM.032" +go +setboard r1b2r1k/3nN2p/p2Q1p2/8/4PP2/1R6/q1PK2PP/4R3 w - - +solution Qd5 +id "ECM.033" +go +setboard 1nk1r1r1/pp2n1pp/4p3/q2pPp1N/b1pP1P2/B1P2R2/2P1B1PP/R2Q2K1 w - - +solution Nf6 +id "ECM.034" +go +setboard 2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - +solution Rxc8 +id "ECM.035" +go +setboard br1r2k1/1q4p1/p2ppb1p/2p2p2/2P1n3/Pn2P2P/QPR2PPB/2NRNBK1 b - - +solution Nxc1 +id "ECM.036" +go +setboard 2k4r/ppp1n1p1/2n2qb1/2N5/Q1P3p1/P2r3P/1P3PB1/R1B2RK1 w - - +solution Qb5 +id "ECM.037" +go +setboard 8/6bk/1B1R4/6p1/2bNP3/4KP2/1r6/8 b - - +solution Be5 +id "ECM.038" +go +setboard r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - +solution Rxa1 +id "ECM.039" +go +setboard r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - +solution Nxc6 +id "ECM.040" +go +setboard 5rk1/1b3ppp/p3p3/1p1q2N1/4n3/6P1/PP2PPBP/2Q2RK1 b - - +solution Nxg3 +id "ECM.041" +go +setboard 2kr3r/pppq2p1/1bn1R3/6N1/1P6/1QN1B1p1/P4PP1/R5K1 b - - +solution gxf2+ +id "ECM.042" +go +setboard 2rr4/5pk1/p1q3p1/3bpP1p/1p4nR/1N4Q1/PPP3PP/3NR2K b - - +solution Bxg2+ +id "ECM.043" +go +setboard r4rk1/pp4pp/2nqb3/3p4/8/2NB4/PP1Q1PPP/4RRK1 w - - +solution Bxh7+ +id "ECM.044" +go +setboard 3rk1r1/3b1p1p/p2BpQ2/8/2q5/2P5/PP3PPP/3R2K1 b - - +solution Rxg2+ +id "ECM.045" +go +setboard 3r1rk1/4pp1p/p1Q1b1p1/3N4/3b4/5B2/Pq3PPP/R4RK1 b - - +solution Bxd5 +id "ECM.046" +go +setboard 5bk1/1bqn1r1p/p3Q1p1/4p3/1PN1Pp2/P1N4P/5PP1/R1BR2K1 w - - +solution Qxf7+ +id "ECM.047" +go +setboard 3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - +solution d3 +id "ECM.048" +go +setboard 5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - +solution Qxf7+ +id "ECM.049" +go +setboard 2kr1b1R/1b3pp1/p2pp3/1pq3P1/2nQPP2/P1N5/1PP1BB2/1K6 w - - +solution Rxf8 +id "ECM.050" +go +setboard 1k1r1b1r/p1p1q3/2p1p3/4Ppp1/4nP2/P2BQ3/1PP3PB/2KR3R b - - +solution Rxh2 +id "ECM.051" +go +setboard r3nb1Q/p1q2kr1/2p3p1/2ppnpP1/1P3N2/4P3/PB1P4/1R2KB1R w K - +solution Qxf8+ +id "ECM.052" +go +setboard r1bq1rk1/pp3pbp/2pp1np1/2n3B1/2PNP3/2N2P2/PP1QB1PP/R4RK1 b - - +solution Nfxe4 +id "ECM.053" +go +setboard 1rb1qn2/1p2nrbk/p2p2p1/P2Pp1Pp/NP2P2P/2RNB3/2QKB3/1R6 w - - +solution Ba7 +id "ECM.054" +go +setboard 5r2/1b2k2p/3bp3/5PP1/Bn1Q3P/1N6/1Pr5/1K3R2 b - - +solution Rxb2+ +id "ECM.055" +go +setboard r1b1r1k1/pp4bp/5np1/2qPB3/8/6NP/PPP1Q1B1/R4R1K w - - +solution Rxf6 +id "ECM.056" +go +setboard r1b2r1k/1pq3bp/8/3Qp2n/1P1n1pp1/2NP2P1/3BPPBP/1R2NRK1 b - - +solution Qxc3 +id "ECM.057" +go +setboard 4qk2/pp3pp1/1nbr3p/2p5/5N2/2P1Q3/PPB2PPP/2K1R3 w - - +solution Ng6+ +id "ECM.058" +go +setboard 3q2k1/pb3p1p/4pbp1/2r5/PpN2N2/1P2P2P/5PP1/Q2R2K1 b - - +solution Rd5 +id "ECM.059" +go +setboard r4rk1/pp1b2pp/3bpq2/3p1p2/2PPn3/PP1B4/1BQN1PPP/R4RK1 b - - +solution Bxh2+ +id "ECM.060" +go +setboard r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - +solution Nxf7 +id "ECM.061" +go +setboard 2rq1r2/pp3pnk/2n1b1pp/3pQ3/3P1N2/P1N5/1P3PPP/1BR2RK1 w - - +solution Bxg6+ +id "ECM.062" +go +setboard 4nk2/r1r1bppp/pN2p3/2np4/8/BPN3PP/P3PPK1/2RR4 w - - +solution Ncxd5 +id "ECM.063" +go +setboard r4r1k/2pqn1b1/p1bp2pp/1p2pn2/4N3/2PP1PPQ/PPB4P/R1B1RNK1 b - - +solution Nd4 +id "ECM.064" +go +setboard r1bQ1nk1/bp3ppp/p7/3B4/1P6/P3P1P1/2P4P/q1B2RK1 b - - +solution Bxe3+ +id "ECM.065" +go +setboard 3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - +solution Rxd4 +id "ECM.066" +go +setboard 2nq2k1/2r3pp/p1p1rp2/PpQ1N3/1P1PR3/8/5PPP/2R3K1 w - - +solution Nf7 +id "ECM.067" +go +setboard r1b2rk1/1p2bppp/p3pn2/4B3/1qBR4/2N5/P3QPPP/R5K1 w - - +solution Bd3 +id "ECM.068" +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +solution g6 +id "ECM.069" +go +setboard 5r1k/p6p/1p1p1qp1/2pQpr2/8/2PP2P1/PP2RPKP/5R2 b - - +solution e4 +id "ECM.070" +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +solution Qh6 +id "ECM.071" +go +setboard 2r2rk1/5pbp/p5p1/3P2q1/1QbN4/5P2/P4BPP/2RR2K1 b - - +solution Bf1 +id "ECM.072" +go +setboard r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - +solution Nh7 +id "ECM.073" +go +setboard 3nk3/3q1p2/1B3pr1/4p3/bP2P2p/r2B4/2Q2RPP/3R2K1 w - - +solution Bb5 +id "ECM.074" +go +setboard 3rnr1k/pp3ppp/4b3/2p1qNP1/P2pPR2/1P1P2Q1/2P3BP/5RK1 w - - +solution Nh6 +id "ECM.075" +go +setboard r1b2kr1/1p1p1pNp/p1n1p1p1/5P2/3QP3/2N5/PqP1B1PP/R4RK1 w - - +solution fxg6 +id "ECM.076" +go +setboard 5rk1/3r1p1p/3b2pQ/8/4q3/4B2P/3R1PP1/4R1K1 w - - +solution Rxd6 +id "ECM.077" +go +setboard 4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - +solution Nxc5 +id "ECM.078" +go +setboard 2rnrbnk/3q1ppp/p1p5/3p1P2/1p1PPN2/4BQ1R/PP1N2PP/3R2K1 w - - +solution Ng6+ +id "ECM.079" +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +solution Rd4 +id "ECM.080" +go +setboard Q7/p1r1ppk1/1qP4p/2Rb2p1/8/3N2P1/4PP1P/6K1 b - - +solution Qb1+ +id "ECM.081" +go +setboard 1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - +solution exf6 +id "ECM.082" +go +setboard r2qr1k1/pp3pbp/3p1np1/2pP1bB1/2P1N3/3Q1PN1/PP4PP/R4RK1 b - - +solution Nxe4 +id "ECM.083" +go +setboard 4r1k1/1b4pp/p7/1prP3q/2P1B3/5P2/P3Q2P/3RR2K w - - +solution Bg6 +id "ECM.084" +go +setboard r1br2k1/ppb1qpp1/2P4p/2n1p3/4B3/P1N2N2/1P3PPP/2RQ1RK1 w - - +solution Nd5 +id "ECM.085" +go +setboard 2r3k1/1nqbrp2/p5pp/1p1Pp1N1/8/1P5P/P1B2PP1/2RQR1K1 w - - +solution Nxf7 +id "ECM.086" +go +setboard 2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - +solution Nh6+ +id "ECM.087" +go +setboard r1b1rk2/3n1pbQ/2qp2p1/p2N2P1/2Bp3N/4P3/PP3PP1/2KR3R w - - +solution Nxg6+ +id "ECM.088" +go +setboard r1r2qkb/4pp1p/pBbp3P/3Nn1P1/4Q3/1B6/PPP5/1K1R2R1 w - - +solution g6 +id "ECM.089" +go +setboard r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - +solution Re7 +id "ECM.090" +go +setboard rn1q1r2/4bpk1/p3p3/1pN1N1np/2pP4/4PpBb/PPQ4P/1B1RK1R1 w - - +solution Nc6 +id "ECM.091" +go +setboard 5rk1/6pp/8/2Q4q/N2pP3/4b1Pb/4PP1K/1R3R2 b - - +solution Bxf1+ +id "ECM.092" +go +setboard 2r4k/pp2Q1pp/5r2/P2P4/3Pb1P1/4Ppq1/1P1R3N/3R3K b - - +solution Qe1+ +id "ECM.093" +go +setboard 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - +solution Qxh7+ +id "ECM.094" +go +setboard r1b4k/p2n1Bpp/1p1Q1n2/5p2/3P4/P3BqP1/1P3P1P/R4RK1 b - - +solution Bb7 +id "ECM.095" +go +setboard rn1r2k1/p4ppp/2p3b1/3PQ3/1B2Np1q/1B3P2/P1P3PP/4R1K1 w - - +solution Nf6+ +solution Qe8+ +id "ECM.096" +go +setboard 4r2k/5R1p/pp1Bq1pN/2p1P3/1n1b3Q/3P4/1P4KP/8 w - - +solution Rxh7+ +id "ECM.097" +go +setboard r2nk1r1/pb3q1p/4p3/3p2pQ/8/BP6/P4PPP/2R1R1K1 w q - +solution Rc7 +id "ECM.098" +go +setboard 6k1/1pqb1p2/5bpB/r2n4/4N1P1/1P3P2/1P1Q4/1K5R w - - +solution Qxd5 +id "ECM.099" +go +setboard rr4k1/2p1ppb1/3pbnpp/q1pP4/4P3/1PNNBP1P/P1KR2P1/2Q4R b - - +solution Qxc3+ +id "ECM.100" +go +setboard 1r3rk1/3Q2pp/p3p3/6B1/3np3/6R1/PqP1B2P/3K2R1 w - - +solution Qxg7+ +id "ECM.101" +go +setboard 2r5/p4Q2/k1bBp3/4P3/p1nq4/5B2/2Pr2P1/1R1RK3 w - - +solution Qb7+ +id "ECM.102" +go +setboard 5rk1/p1pb2pp/2p5/3p3q/2P3n1/1Q4BN/PP1Np1KP/R3R3 b - - +solution Qxh3+ +id "ECM.103" +go +setboard 2r1nk2/4qpbQ/4b3/1p2RpP1/4P3/p7/PBP5/1K5R w - - +solution Qxg7+ +id "ECM.104" +go +setboard 2kr4/1bpr3p/4R3/1pQ5/8/6B1/3q2PP/2R4K w - - +solution Qxc7+ +id "ECM.105" +go +setboard r4rk1/1pbb2pp/p1p1p2q/2Pp4/1P1Pn3/P3B2P/2Q1BPP1/R4RNK b - - +solution Qxe3 +id "ECM.106" +go +setboard r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - +solution Qxf5+ +id "ECM.107" +go +setboard 6r1/p4rkp/3RQ1n1/1pp1p1B1/2p1P3/2P3R1/P4qPK/8 w - - +solution Qxe5+ +id "ECM.108" +go +setboard 2kr1r2/1pp3pp/1n2p1b1/pN2B3/P1q5/1Q1p3P/5PP1/R4R1K w - - +solution Rac1 +id "ECM.109" +go +setboard 2kr1bnr/1ppq4/p3bp2/6pp/4p3/2N2NBP/PP3PP1/2RQ1RK1 w - - +solution Na4 +id "ECM.110" +go +setboard r2q2rk/p3bp1p/4b1p1/3pP2R/1p1B4/3BQ3/PPP3PP/5R1K w - - +solution Rxf7 +id "ECM.111" +go +setboard r1b1Q3/6pk/p6p/1pq1n3/4N3/8/PPP3PP/R6K b - - +solution Qc6 +id "ECM.112" +go +setboard q6r/pp3pkp/5np1/4Q3/4P3/6N1/P4PPP/5RK1 w - - +solution Nh5+ +id "ECM.113" +go +setboard r1b1rk2/pp3ppQ/1np5/4q3/2B4N/4P3/PP3PP1/2R2K1R w - - +solution Qg8+ +id "ECM.114" +go +setboard r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - +solution Nxh7 +id "ECM.115" +go +setboard r3r1k1/p2N1pp1/1pn1p3/q1n5/2PQ4/P3B3/4PPKP/R5R1 w - - +solution Nf6+ +id "ECM.116" +go +setboard 4qbk1/1R5n/p2pr1p1/2pQpNPp/P1P1P3/2P2P2/3B4/5K2 w - - +solution Ne7+ +id "ECM.117" +go +setboard 3qr1k1/1p1bppbp/p2p2p1/2rPn3/P2N4/4BP2/1PPQ2PP/R2R1BK1 w - - +solution Ne6 +id "ECM.118" +go +setboard 2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - +solution Rxf6 +id "ECM.119" +go +setboard 8/R5p1/6k1/pr2p1b1/4K3/7P/5P2/6R1 w - - +solution h4 +id "ECM.120" +go +setboard 5rk1/1b1r1p2/p1q1pQp1/1p2P2p/8/1BP1NR2/PP1n2PP/5R1K w - - +solution Bxe6 +id "ECM.121" +go +setboard 6k1/p1p2r2/1p1p1P1Q/3P4/2P5/5qr1/PP4RP/6RK w - - +solution Qh3 +id "ECM.122" +go +setboard 2b1rr1k/1p5p/1Ppp2q1/p3bN2/2P1n3/5R2/PBQ3BP/3R2K1 w - - +solution Nxd6 +id "ECM.123" +go +setboard 3b2rk/7p/p7/2pbqNrn/Pp1p1R2/1P1Q2P1/1BPN1R1P/6K1 w - - +solution Rxd4 +id "ECM.124" +go +setboard 1rbr2k1/1pq1bp1p/p1pNn1p1/2n1p3/2B1P2P/1NQ1BP2/PP4P1/1K1R3R w - - +solution Nxf7 +id "ECM.125" +go +setboard r4rk1/1pp1b1pp/p1q5/3pPp2/3Pn3/P3N3/1P3PPP/R1BQR1K1 w - - +solution Qb3 +id "ECM.126" +go +setboard rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - +solution Nf6+ +id "ECM.127" +go +setboard rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - +solution Nxh5 +id "ECM.128" +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +solution Re6 +id "ECM.129" +go +setboard r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - +solution Rxe7 +id "ECM.130" +go +setboard 2rq1rk1/pp2bppp/1npp1n2/3PpN1b/2P5/2N3PP/PP2PPB1/R1BQ1RK1 w - - +solution c5 +id "ECM.131" +go +setboard rnbq1rk1/pp2b1pp/5n2/2pPp3/2P1N3/3B1N2/PP4PP/R1BQK2R w KQ - +solution d6 +id "ECM.132" +go +setboard 2n1rbk1/5pp1/7p/qP1pp3/4b1Q1/1B5P/1P1N1PP1/2B1R1K1 w - - +solution Rxe4 +id "ECM.133" +go +setboard 4k3/2R2p2/5p1p/8/rb6/1N6/5PPP/5K2 w - - +solution Rc4 +id "ECM.134" +go +setboard 2k3r1/pp2rp2/1np5/2Np1p2/P2P3p/1R2P1Pq/2Q2P1P/1R4K1 w - - +solution Nxb7 +id "ECM.135" +go +setboard 2r1k3/p3nrR1/1p1p4/2p1p1p1/2P1B3/2PP1P2/P5K1/7R w - - +solution Rh8+ +id "ECM.136" +go +setboard 8/1Qp3pk/7p/5p2/5Pqn/1P1r4/P5PP/2B2RK1 b - - +solution c6 +id "ECM.137" +go +setboard 2rr1bk1/5p1p/pPN2np1/3Bp3/2Q1n3/1P2B1Pq/P3PP2/R2R2K1 b - - +solution Rxd5 +id "ECM.138" +go +setboard 3r2k1/1p4pp/p1q1p3/3p1B2/bP1B2P1/P4Q2/5PKP/2b2R2 w - - +solution Rxc1 +id "ECM.139" +go +setboard rnb1r1k1/pp5p/2pp2p1/4b3/2P1P2q/1NN1BPp1/PP1QB1P1/3RR1K1 b - - +solution Bf4 +id "ECM.140" +go +setboard 5n1r/1p2kp2/rB1Nb3/4p1Pp/4p2P/1PP5/8/1K1R1R2 w - - +solution Rxf7+ +id "ECM.141" +go +setboard b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - +solution d3+ +id "ECM.142" +go +setboard 4r1k1/3R1ppp/p2p4/5PP1/2q2P2/2n2B2/P1P3QP/1r3R1K w - - +solution Rxb1 +id "ECM.143" +go +setboard 2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - +solution Bd5+ +id "ECM.144" +go +setboard 6k1/4ppbp/p5p1/1B1Q4/2P2Pn1/8/qr4PP/2B2RK1 b - - +solution Bd4+ +id "ECM.145" +go +setboard 8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - +solution Ba3 +id "ECM.146" +go +setboard r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - +solution g6 +id "ECM.147" +go +setboard 5r2/1b3pk1/pqrpp1p1/4n1Nn/1p2PP1P/8/PPPQB3/1NKR2R1 b - - +solution Rfc8 +id "ECM.148" +go +setboard 1r2k2r/p5bp/4p1p1/q2pn3/1p2N1P1/6QP/PPP5/1KBR3R w k - +solution Bh6 +id "ECM.149" +go +setboard rn1q1rk1/pp3p1p/2p5/3p4/5Q1P/2NP3R/PPP3P1/4RK2 w - - +solution Rg3+ +id "ECM.150" +go +setboard 7r/kppQP1pp/p7/2qp1R2/4n3/1P2b2P/P1P3PK/R7 b - - +solution Re8 +id "ECM.151" +go +setboard r1b1kb1Q/qp2pp2/p3n1p1/2nN2Pp/2B4P/7N/PPP5/2KRR3 w q - +solution Nc7+ +id "ECM.152" +go +setboard 8/1bq3kp/p5p1/1pb1p3/4P2P/2PQ2P1/1P5B/5N1K b - - +solution Qd8 +id "ECM.153" +go +setboard 2r1q1r1/6bk/p2pN1pp/1p1N4/4P3/3R3Q/PnP4P/1K4R1 w - - +solution Nf6+ +id "ECM.154" +go +setboard 4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - +solution Ra8 +id "ECM.155" +go +setboard 6k1/p1q2pp1/2n2b2/3B2Pp/2P2P2/5N1P/Pr1Q2K1/4R3 w - - +solution Re8+ +id "ECM.156" +go +setboard r1r3k1/p4n2/3p4/5NpR/8/2q2P2/P1PQ4/2K4R w - - +solution Rh8+ +id "ECM.157" +go +setboard 8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - +solution g4+ +id "ECM.158" +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +solution Nd6 +id "ECM.159" +go +setboard 1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - +solution Ba4 +id "ECM.160" +go +setboard r1bq3k/ppp2Qp1/2n1p2p/6N1/2BPN3/2P1n3/PP4PP/R5K1 w - - +solution Nf6 +id "ECM.161" +go +setboard 3R4/1p2kp2/p1b1nN2/6p1/8/6BP/2r1qPPK/Q7 w - - +solution Rd7+ +id "ECM.162" +go +setboard 6k1/p5p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - +solution Rh8+ +id "ECM.163" +go +setboard 8/5P2/4K1kP/4R3/8/8/8/5r2 w - - +solution Rg5+ +id "ECM.164" +go +setboard 3r1rk1/p1p1qp1p/2p1b1p1/8/P2PRP2/2P1NQ2/6PP/R5K1 w - - +solution f5 +id "ECM.165" +go +setboard 6k1/pr3ppp/1p3qn1/5NQ1/2p5/8/P4PPP/4R1K1 w - - +solution Re8+ +id "ECM.166" +go +setboard Q7/1pq2kpp/4bp2/3r4/2B5/P3P3/1r3PPP/2R1K2R b K - +solution Rd1+ +id "ECM.167" +go +setboard 4r1k1/p4ppp/4q2r/1Q6/4p3/4P1P1/P4P1P/2RR2K1 w - - +solution Rd6 +id "ECM.168" +go +setboard 8/5p1k/4p1p1/3p2K1/3P1Q1P/P4P2/7q/8 b - - +solution f6+ +id "ECM.169" +go +setboard r4r2/6k1/3p4/2pPp2p/4Pqp1/3P1P2/1R2Q1KP/5R2 b - - +solution Ra1 +id "ECM.170" +go +setboard 4r1k1/1np1r1pp/1ppp1q2/6N1/1P3P2/4RQP1/7P/4R1K1 w - - +solution Qh5 +id "ECM.171" +go +setboard r4rk1/pp3p1p/3pq1p1/2nNp3/3R1P2/7Q/PP4PP/5RK1 w - - +solution f5 +id "ECM.172" +go +setboard 3qn2k/1p3Bp1/rbn4p/2p5/p1P2p2/P2b2PP/1BQNRP2/1R4K1 w - - +solution Qxd3 +id "ECM.173" +go +setboard 3r1rk1/1pp4p/1q3bp1/p3p3/P2n1P2/2BB3P/1PP2QP1/R4RK1 b - - +solution Bh4 +id "ECM.174" +go +setboard 4rrk1/2p2ppp/p2b4/1p1P4/3P2nq/2P4P/PPQ1RPP1/RNB3K1 b - - +solution Qxf2+ +id "ECM.175" +go +setboard 1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - +solution Nxf7 +id "ECM.176" +go +setboard r3kb1r/2q2p2/3p4/ppp1n1B1/P6P/1B3pQ1/1PP3b1/2KRR3 w kq - +solution Bd5 +id "ECM.177" +go +setboard r1b2rk1/1p4pp/p1n3q1/4ppN1/7Q/2P1B3/P1P2PPP/R2R2K1 w - - +solution Rd6 +id "ECM.178" +go +setboard 1rb2r2/1pR1N2p/p2R2pk/5p2/4pP2/1P1nP3/P4P1P/5BK1 w - - +solution Rf6 +id "ECM.179" +go +setboard r1b3k1/ppp2r2/6p1/3n3p/6qP/3BQ3/PBP5/2KR3R w - - +solution Bd4 +id "ECM.180" +go +setboard 3r2k1/p2q1r1p/1p1N2p1/1PpP4/3b1Bn1/1Q4Pb/1P2RP1P/R5KB b - - +solution Qxd6 +id "ECM.181" +go +setboard 4r1k1/1pbb3p/2pp2q1/p1n5/2P2R2/1PN1n1P1/PB2Q1B1/5RK1 w - - +solution Qxe3 +id "ECM.182" +go +setboard 3r2k1/p2r1p1p/1pR1p1qP/3P1pP1/3R4/1P2Q3/P4K2/8 w - - +solution dxe6 +id "ECM.183" +go +setboard 3r3k/p1Q3bp/2p3p1/8/2P1BRn1/1P4Pb/P1N1q2P/6BK b - - +solution Nf2+ +id "ECM.184" +go +setboard r4k2/p1pr1ppp/2q5/3PR2P/3Q4/8/6P1/5RK1 w - - +solution Re7 +id "ECM.185" +go +setboard 1R3b2/3r3k/2p1bp1p/r1q1pNpQ/2PpP2P/6B1/P4PP1/1R4K1 w - - +solution Nxh6 +id "ECM.186" +go +setboard r1b4r/pp2ppk1/2np1np1/3N3p/2B1P3/q3BP2/P1PQ2PP/1R3RK1 w - - +solution Nxe7 +id "ECM.187" +go +setboard r3k2r/pb1n1pbp/4p1p1/q1n1P3/Bp1N1N2/4B3/PP3PPP/R2Q1RK1 w kq - +solution Ndxe6 +id "ECM.188" +go +setboard 5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - +solution Ne4 +id "ECM.189" +go +setboard 5rk1/5pbp/b5p1/p1nNN3/1p2n3/1P4PP/P4PB1/2BR2K1 w - - +solution Nd7 +id "ECM.190" +go +setboard 2k1r1r1/ppb2p2/6b1/2qP4/2P2P2/4pP1p/P3Q2P/2RBRN1K b - - +solution Bd3 +id "ECM.191" +go +setboard 5r1k/pp1n1p1p/1b1qpP2/8/1PrN4/P1N1Q1P1/7P/3R1R1K w - - +solution Qh6 +id "ECM.192" +go +setboard r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - +solution Nb6 +id "ECM.193" +go +setboard 1r3rk1/p4pbp/q1p2pp1/3p1b2/1n1P1P1B/PB3N2/1PPQR1PP/2KR4 b - - +solution Bxc2 +id "ECM.194" +go +setboard 1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - +solution Bxc5 +id "ECM.195" +go +setboard 2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - +solution Rxd5 +id "ECM.196" +go +setboard rn3rk1/pp2ppbp/6p1/2R3N1/2B3b1/q3B3/P1P1Q1PP/5RK1 w - - +solution Rxf7 +id "ECM.197" +go +setboard r1k3r1/pppnb1p1/4N3/3QP2p/3P3q/4B3/PPP2P2/R3KB2 w Q - +solution Ba6 +id "ECM.198" +go +setboard r1nqr2k/1p1b1Q1p/p5p1/P1pPb3/5B2/2N5/BP4PP/R4RK1 w - - +solution Qf8+ +id "ECM.199" +go +setboard 8/k3r1b1/Pp2rpp1/1qpQ4/4nB2/2P2NP1/7P/R4RK1 w - - +solution Bb8+ +id "ECM.200" +go +setboard 1k1r4/ppq2p2/8/2pPb1r1/2P1Q1B1/6P1/PP3PK1/R4R2 b - - +solution f5 +id "ECM.201" +go +setboard r1b2nk1/2qn1p1p/1ppR2p1/8/1PP1NP2/4r1PP/1Q2N1B1/3R2K1 w - - +solution b5 +id "ECM.202" +go +setboard 8/5pk1/3q2p1/8/7P/5Q1K/6B1/6b1 b - - +solution Qh2+ +id "ECM.203" +go +setboard 6r1/ppp4k/3p2rp/3Pb3/PPP1Np1q/5P1b/3QRRBP/6K1 b - - +solution Bd4 +id "ECM.204" +go +setboard 4br1k/pR4bp/2r1B1pN/4npB1/3p4/P7/5PPP/4R1K1 w - - +solution Rxg7 +id "ECM.205" +go +setboard r1bq1rk1/pppn2bp/3p2p1/3N1p2/8/BP1BRQ1P/P1PP1PP1/4R1K1 w - - +solution Nxc7 +id "ECM.206" +go +setboard r6r/1p2kp2/3p1b2/pPpPpQ1P/1nP1P2P/6R1/1P2K3/1B6 w - - +solution Rg6 +id "ECM.207" +go +setboard 2q1r1k1/1b3pbp/3p2p1/1Ppn3n/5P2/5B2/1P1B2PP/R2NNQ1K b - - +solution Ndxf4 +id "ECM.208" +go +setboard 2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - +solution Rb3 +id "ECM.209" +go +setboard r2qr1n1/p4pk1/1p1p2p1/4p3/4PQ2/1PN2P2/1PP3P1/2KR3R w - - +solution Rh7+ +id "ECM.210" +go +setboard r4rk1/ppp3b1/3p1qp1/3Pp3/2P1Bn2/4BP2/PP1Q4/2K3RR w - - +solution Rxg6 +id "ECM.211" +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +solution Bf4 +id "ECM.212" +go +setboard k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - +solution Re7 +id "ECM.213" +go +setboard 1q3rk1/r5b1/pNp1bn1p/2Pp1n2/1P2p3/1N2P2P/PBQKB3/3R3R b - - +solution Nxe3 +id "ECM.214" +go +setboard r4n1r/ppq1nk2/1bpRpN2/4PpQ1/8/2B4P/PPP2PP1/2KR4 w - - +solution Rd7 +id "ECM.215" +go +setboard 3r2k1/p5pp/bpP1p3/3n1p2/2NQpP1q/P3P3/1B1R1R2/4KBr1 b - - +solution Rxf1+ +id "ECM.216" +go +setboard 1rq1r2k/5Rbp/p2p1p1B/2p1p3/2P1P2Q/1P6/P5PP/3b3K w - - +solution Bxg7+ +id "ECM.217" +go +setboard 5Q2/5p1p/3p2p1/4p1k1/4P1P1/3R1P1K/r6P/4q3 w - - +solution f4+ +id "ECM.218" +go +setboard 2b2r1k/ppq3pp/3b3r/n3NpN1/Q2PpP1B/2P1R3/PP5P/4R1K1 w - - +solution Ngf7+ +id "ECM.219" +go +setboard 2r1r1k1/1R4bp/p5p1/2pqn3/8/2B5/1PQ1B1PP/5RK1 w - - +solution Bc4 +id "ECM.220" +go +setboard 7k/pp1q2pp/3Nr1n1/3B2Q1/2pP4/B3P1Pb/P6P/6K1 w - - +solution Qd8+ +id "ECM.221" +go +setboard r5k1/5p1p/bq1p2p1/r2Pp3/1p2N1P1/1P3P2/1KPQ3P/3R3R b - - +solution Ra2+ +id "ECM.222" +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +solution Bg7 +id "ECM.223" +go +setboard 5nk1/2b1q1p1/2p5/3pP1pQ/1r1P2P1/3B1R2/5PP1/6K1 w - - +solution Rxf8+ +id "ECM.224" +go +setboard 1k1r3r/1pp2p2/p2b4/4n1p1/N3q1P1/1B2B3/PP3RP1/4RQK1 b - - +solution Rh1+ +id "ECM.225" +go +setboard rnb1kr2/p4pQ1/8/1ppPpP2/2p1P3/N6P/Pq4B1/3R1RK1 w q - +solution Nxb5 +id "ECM.226" +go +setboard 5r1k/2p3pp/3pQ3/3P1rN1/pp5q/5PR1/P4PKP/B7 w - - +solution Bxg7+ +id "ECM.227" +go +setboard 8/pR3Bk1/3p2p1/5b1p/2P4P/6P1/P4bQK/4q3 b - - +solution Bg1+ +id "ECM.228" +go +setboard r1b1Rnk1/6pp/p4q2/1pp2P2/3r4/2NB4/PP1Q2PP/4R1K1 w - - +solution Nd5 +id "ECM.229" +go +setboard 1Q6/pb3pk1/1p3qp1/1N3p1p/2Pr3P/3BR1PK/r7/6R1 b - - +solution Rh2+ +id "ECM.230" +go +setboard rq3r1k/p2n1p2/1pbb1np1/2p2BB1/8/2N2N2/PP3QPP/3R1RK1 w - - +solution Rxd6 +id "ECM.231" +go +setboard 2kr3r/Qpp1n1p1/2b2pp1/4b3/8/6N1/PPP2P2/R1B2RK1 b - - +solution Rh1+ +id "ECM.232" +go +setboard 8/2p2Q1p/1rp5/p3q1kp/P7/2P2RP1/5PK1/8 w - - +solution Rf5+ +id "ECM.233" +go +setboard 1r2b3/1p2q1bk/p1p1p1p1/P1PpP2r/1P1KpPQP/4P2N/6R1/4B2R b - - +solution Rxe5 +id "ECM.234" +go +setboard 6k1/3b1p1p/6p1/2BPR3/8/4Q2P/1q3rPK/8 w - - +solution Re8+ +id "ECM.235" +go +setboard 2R5/4ppkp/6p1/p2P4/4P2P/p3B1P1/qbR2PK1/8 w - - +solution Rg8+ +id "ECM.236" +go +setboard 3rr1k1/1b5p/p6p/1p3N2/6Pb/P1Q1p3/1PP4P/R5K1 b - - +solution Bf2+ +id "ECM.237" +go +setboard 6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - +solution Qc1 +id "ECM.238" +go +setboard 3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - +solution Bf3 +solution Rxc5 +id "ECM.239" +go +setboard 8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - +solution Rxd6 +id "ECM.240" +go +setboard 6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - +solution Rh4+ +id "ECM.241" +go +setboard 3r4/1pQ4R/p1b2kp1/P6p/2q5/7P/2P3P1/6K1 b - - +solution Rd1+ +id "ECM.242" +go +setboard 6rr/1b3k1p/pbqppPn1/1p5Q/4PN2/P6R/1PP3BP/2B2R1K w - - +solution Qxh7+ +id "ECM.243" +go +setboard 4rrk1/3b1ppp/pb6/1pqP4/P1p1PP2/1P2NK2/3QB2P/R2R4 b - - +solution Rxe4 +id "ECM.244" +go +setboard 2r1r1k1/1p4bp/p2p1qp1/1n1P4/2P1B2P/1N1Q4/PP2R3/1K5R b - - +solution Rxc4 +id "ECM.245" +go +setboard 6rr/ppqb1pkp/2pb1pn1/3p3Q/3P1P1N/3B1RN1/PPP3PP/5RK1 w - - +solution Qh6+ +id "ECM.246" +go +setboard r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - +solution Bh7+ +id "ECM.247" +go +setboard r2q1rk1/1b1nbpp1/p1p1p2p/1pPpN3/3P1N2/P2BP3/1PQ2PPP/R4RK1 w - - +solution Bh7+ +id "ECM.248" +go +setboard 2r2rk1/pb4pp/1p2p3/4Npq1/3P1n2/5P2/PP1R2PP/RB2Q1K1 b - - +solution Rc1 +id "ECM.249" +go +setboard 2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - +solution Bxf7+ +id "ECM.250" +go +setboard 1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - +solution Bb7 +id "ECM.251" +go +setboard r5k1/pp2ppb1/4qn2/r3B1p1/3P4/3QNP1R/PP2K1P1/7R w - - +solution Bxf6 +id "ECM.252" +go +setboard 1R2br1k/5r1p/p2p1P2/6RQ/3p1P2/4p2B/q6P/5N1K w - - +solution Rxe8 +id "ECM.253" +go +setboard kr1r4/7p/2bqp1p1/p7/1Pp1PP1P/K1B1nNPB/PP5R/RN2Q3 b - - +solution Qxb4+ +id "ECM.254" +go +setboard 5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - +solution Rxd7+ +id "ECM.255" +go +setboard kn5r/p2r2p1/1pqBp1np/1Q1pPp2/R2P4/1N6/2P2PPP/R5K1 w - - +solution Rxa7+ +id "ECM.256" +go +setboard 4Rnk1/2p2pp1/3r3p/p2P4/P5Q1/1B5P/5PK1/q7 w - - +solution Rxf8+ +id "ECM.257" +go +setboard 4r3/2k1p2q/pp1nR1p1/2pP1pP1/2P2P2/1P6/P1K3B1/4Q3 w - - +solution Rxd6 +id "ECM.258" +go +setboard 2b3k1/p4ppp/7q/2Q5/8/P3r1P1/1r4BP/R3R1K1 b - - +solution Rxg2+ +id "ECM.259" +go +setboard r1b1rbk1/7p/2p1pBp1/p2pP1P1/5P2/1PqB4/P1P1Q3/1K4RR w - - +solution Rxh7 +id "ECM.260" +go +setboard 2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - +solution Bxh6 +id "ECM.261" +go +setboard r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - +solution Rxh8+ +id "ECM.262" +go +setboard 3r2k1/p4rPp/1b1q3Q/n1p1pP2/1p6/3B1NR1/P4P1P/6RK w - - +solution Qxh7+ +id "ECM.263" +go +setboard r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - +solution Bh7+ +id "ECM.264" +go +setboard r2rn1k1/1bqn1ppp/p7/2bpP1P1/1p1N1Q2/1P3B2/PBP1NR1P/3R2K1 w - - +solution Qxf7+ +id "ECM.265" +go +setboard r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - +solution Nxf7 +id "ECM.266" +go +setboard r1b1r1k1/1p1n1p2/p1nBp1p1/q2pP1Np/P7/R2B3Q/2P2PPP/5RK1 w - - +solution Nxf7 +id "ECM.267" +go +setboard r1b1k2r/ppp3pp/1qp5/2b1Pp2/3Qn3/5N2/PPPBNPPP/2KR3R w kq - +solution Qd8+ +id "ECM.268" +go +setboard 1k6/1p4p1/P1p5/5Q2/2q2r2/P7/8/4R2K w - - +solution Re8+ +id "ECM.269" +go +setboard 6k1/1p3p2/4r1p1/1PPrbq1p/2QN4/P2R1P1P/R4KP1/8 b - - +solution Bg3+ +id "ECM.270" +go +setboard 4n1q1/1k1b4/2p4R/2Pp4/1p1N1rpQ/3B4/PPP2P2/2K5 w - - +solution Nxc6 +id "ECM.271" +go +setboard r2qk2r/1pp2ppp/p3pnn1/6N1/1B1P2P1/1Q2P2P/PP3PK1/R6R b kq - +solution Nh4+ +id "ECM.272" +go +setboard 2kr2r1/R2p3p/2n2p2/1R3P2/2P1p3/4BQ2/1Pq4P/4K3 w - - +solution Ra8+ +id "ECM.273" +go +setboard r3r1k1/pp3pp1/2bb1q2/3p4/4n1Pp/2P1BB1P/PP2NPK1/R1Q4R b - - +solution Qxf3+ +id "ECM.274" +go +setboard r1br4/ppq2pk1/3bpN2/8/2P5/3n2B1/PP2QPPP/R4K1R w - - +solution Qg4+ +id "ECM.275" +go +setboard 6kb/B1p2p2/5r2/1r1p2pR/6q1/3P2P1/P1P2PP1/2KR3Q b - - +solution Rb1+ +id "ECM.276" +go +setboard rn4k1/pp2p1b1/4b3/q2p2Q1/2B2P2/8/P1P1K1P1/R6R w - - +solution Rh8+ +id "ECM.277" +go +setboard 3k2r1/pp1b3Q/1b2pP1p/3pN2q/5B2/7B/PP2nP1K/2R5 b - - +solution Rg2+ +id "ECM.278" +go +setboard 2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - +solution Rxc3 +id "ECM.279" +go +setboard r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - +solution Nxg7 +id "ECM.280" +go +setboard 4k2r/1bqnbppp/p3p3/1p2P1N1/2r2BB1/8/PPP3PP/R2Q1R1K w k - +solution Nxf7 +id "ECM.281" +go +setboard 5r1k/1pqb3p/2n5/p1pB4/2Pp1r1P/1P5P/R2N2K1/3Q1R2 b - - +solution Bxh3+ +id "ECM.282" +go +setboard r4r2/pp2qk2/4pnp1/3pQ3/2p2P2/3B4/PPP2P2/2KR3R w - - +solution Bxg6+ +id "ECM.283" +go +setboard 3bq3/p1n2rk1/1pp1p1p1/3pPnPp/1P1P1N1P/2PN3K/P2BQR2/8 w - - +solution Nxg6 +id "ECM.284" +go +setboard b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - +solution Bxg6+ +id "ECM.285" +go +setboard r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - +solution Qh6+ +id "ECM.286" +go +setboard 4k3/p4ppp/nb1P4/4p3/1P6/P4BP1/3q1r1P/2R2QKR w - - +solution Qb5+ +id "ECM.287" +go +setboard r2q1rk1/pp2pp2/3pb3/3Qb2R/4P1p1/1BN1Bn2/PPP2P2/2K4R w - - +solution Rh8+ +id "ECM.288" +go +setboard 2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - +solution Nxg7 +id "ECM.289" +go +setboard 1rbk2nr/p1pp2b1/7p/2qP1pp1/2Bn4/2NKBP2/PP2N1PP/R2Q3R b - - +solution Qxc4+ +id "ECM.290" +go +setboard 1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - +solution Rxb2 +id "ECM.291" +go +setboard 5rk1/ppp1q2p/1n1p1np1/3P2N1/1P1R2P1/2Q4P/P3r1B1/5RK1 b - - +solution Rxg2+ +id "ECM.292" +go +setboard 6k1/pp2p2p/3p2p1/4b1r1/2Pn1r1q/2B1N3/PP4B1/R3QRK1 b - - +solution Qh2+ +id "ECM.293" +go +setboard r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - +solution Qxg6+ +id "ECM.294" +go +setboard r2k3r/2pb1ppp/p1p1q3/2Q5/5B2/2N5/PPP2PPP/3R2K1 w - - +solution Bxc7+ +id "ECM.295" +go +setboard 2r2r2/2N2pkp/2Q5/1N2p1b1/1p6/3P1qPb/PPR2P1P/4R1K1 b - - +solution e4 +id "ECM.296" +go +setboard 2r1qrk1/pp1b1ppp/4pn2/n1b5/8/2NQ1NP1/PP1BPPBP/R2R2K1 w - - +solution b4 +id "ECM.297" +go +setboard 2b1qr1k/7p/p1pR2p1/1pP1p1Q1/4P3/1B6/PP4PP/6K1 w - - +solution Re6 +id "ECM.298" +go +setboard 1r2k2r/2p2p1b/q1Pppb1N/p2p2P1/Q2P4/P3B3/1P5P/2KRR3 b k - +solution Rb4 +id "ECM.299" +go +setboard 8/2b2k1p/2N2pp1/P2p4/3KnP2/6BP/P5P1/8 w - - +solution Kxd5 +id "ECM.300" +go +setboard 4b1r1/1p3ppk/3r3p/p1p1qP1B/3pPN2/3P3R/nPPQ3P/6RK w - - +solution Ne6 +id "ECM.301" +go +setboard 4b2k/7p/3q3P/1p1pRpr1/1P1B4/2P2Q2/7K/8 w - - +solution Qg3 +id "ECM.302" +go +setboard 2kr2r1/pbp4p/1p4p1/1NqpNp2/4nQ2/8/PPPR1PPP/2K1R3 w - - +solution Nc6 +id "ECM.303" +go +setboard 1rr3k1/1p1bqpbp/1R1p2p1/pN1P4/P3P1n1/1Q6/3NB1PP/2B1R1K1 b - - +solution Rc3 +id "ECM.304" +go +setboard r1br4/1p3k2/p2q1p2/3N1Pp1/3Q4/8/PP4P1/4RR1K w - - +solution Re6 +id "ECM.305" +go +setboard r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - +solution Bd5 +id "ECM.306" +go +setboard 3r1rk1/2p1qp1p/pnP3p1/4n3/PP1NpR2/1BQ4P/6P1/5RK1 w - - +solution Ne6 +id "ECM.307" +go +setboard r1bq1k2/5pb1/p2p1n2/2pPrP2/2p4B/3B2R1/PP1Q2PP/R5K1 w - - +solution Qg5 +id "ECM.308" +go +setboard 2bq1rk1/p4pbp/p2p2p1/3P4/2p1QP2/2Pr3P/PP1N2P1/R1B2RK1 b - - +solution Bd4+ +id "ECM.309" +go +setboard r5rk/1p1bqpnp/3p1b1B/pBnPp2P/4P3/2N2Q2/PP3P2/R3KNR1 b Q - +solution Nf5 +id "ECM.310" +go +setboard r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - +solution Re7 +id "ECM.311" +go +setboard r3r1k1/p1q2pp1/2p4p/7n/BPPP2N1/3Q1N2/P3n1P1/R1B4K b - - +solution Nhg3+ +id "ECM.312" +go +setboard r2qrbk1/1p4pb/2n2p1p/pNpn4/2N5/PP1PPQPB/1B5P/2R2RK1 w - - +solution Nbd6 +id "ECM.313" +go +setboard 5r1k/1p1b1p1p/p2ppb2/5P1B/1q6/1Pr3R1/2PQ2PP/5R1K w - - +solution Qh6 +id "ECM.314" +go +setboard r1b2rk1/p3bppp/2q5/8/2p1NR2/PnB1P3/1PB1Q1PP/3R2K1 w - - +solution Rd6 +id "ECM.315" +go +setboard r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - +solution R1b4 +id "ECM.316" +go +setboard 4r3/pp1b3k/2p2qpp/2Pp4/1P6/PBbP1N1P/2R3P1/3Q3K b - - +solution Re1+ +id "ECM.317" +go +setboard 1rb2rk1/p1p2ppp/2q5/3R4/2P1N3/bP4B1/P1Q2P1P/1K5R w - - +solution Bd6 +id "ECM.318" +go +setboard 8/5k1p/5PpB/3PR3/2r4P/1p3K2/2b5/8 b - - +solution Re4 +id "ECM.319" +go +setboard 4r2k/3b3p/p2p4/2pP1p2/q1B2Q1P/2PK1P2/Pr1R4/7R b - - +solution Re4 +id "ECM.320" +go +setboard rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - +solution Rd5 +id "ECM.321" +go +setboard 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - +solution Rxh7+ +id "ECM.322" +go +setboard r1b1r1kb/p1qn1pnp/2p1p1p1/4P1N1/2p1NPP1/4B3/PPPQ3P/3RK2R w K - +solution Qxd7 +id "ECM.323" +go +setboard 5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - +solution Rxe7 +id "ECM.324" +go +setboard 5rk1/5p1p/8/3pNp2/RPrqn3/1Q5P/1P3PP1/4R1K1 w - - +solution Rxe4 +id "ECM.325" +go +setboard 2rr2k1/4qppp/bn6/p1bB4/4N3/6P1/PB2PP1P/2RQ1RK1 w - - +solution Rxc5 +id "ECM.326" +go +setboard 3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - +solution Rxd7 +id "ECM.327" +go +setboard 5rk1/r2nqpp1/p3p3/1p2P3/4N1pP/8/PPP3Q1/1K1R3R w - - +solution Rxd7 +id "ECM.328" +go +setboard 1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - +solution Qh6 +id "ECM.329" +go +setboard 2r2r1k/1pq1b1p1/p1b1Qn1p/8/3B4/2NB4/PPP3PP/3R1R1K w - - +solution Rxf6 +id "ECM.330" +go +setboard 3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - +solution Rxe6 +id "ECM.331" +go +setboard rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - +solution Rxc8+ +id "ECM.332" +go +setboard 2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - +solution Rxe4 +id "ECM.333" +go +setboard r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - +solution Rxe5 +id "ECM.334" +go +setboard 8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - +solution Rxd4 +id "ECM.335" +go +setboard r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - +solution Rxe5 +id "ECM.336" +go +setboard r3r1k1/pbqn1ppp/1p3n2/1Pb5/2p5/5N1P/PBQ1BPP1/1N1R1RK1 b - - +solution Rxe2 +id "ECM.337" +go +setboard 2r2rbk/6bp/5qp1/1N1p1n2/4p3/1p5P/1P3PP1/RBBQ1RK1 b - - +solution Ng3 +id "ECM.338" +go +setboard r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - +solution Rxc5 +id "ECM.339" +go +setboard 1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - +solution Rxe7 +id "ECM.340" +go +setboard r1k2n1r/2pb4/1p1p1qpp/p2P1p2/3N1P1P/2Q3P1/PPP1R3/2K1RB2 w - - +solution Re8+ +id "ECM.341" +go +setboard r1b2r1R/1p2bpk1/4p1p1/4P1N1/p2p4/5Q2/qPP2PP1/1NKR4 w - - +solution Qf6+ +id "ECM.342" +go +setboard rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - +solution Nxe6 +id "ECM.343" +go +setboard 4q1r1/5kpp/2p1nb2/2PpQp2/r4P2/1N3P2/1BP1R2P/6RK w - - +solution Rxg7+ +id "ECM.344" +go +setboard 2r1k2r/1pq1bppp/p3bn2/4N3/2pPN3/2P5/P3QPPP/R1B1R1K1 w k - +solution Nxf6+ +id "ECM.345" +go +setboard 1r3k1r/4Rn1p/pb1p1P2/1p1q2P1/5p2/7Q/PPP1B1RP/2K5 w - - +solution Rxf7+ +id "ECM.346" +go +setboard 4rrk1/ppn3pp/2pb1n1q/3p4/1P1P4/P3BNP1/2P1BPKP/R2Q1R2 b - - +solution Rxe3 +id "ECM.347" +go +setboard 2b1r2k/2Q4p/4q3/1pp5/3b4/4NP2/1P3BP1/3R2K1 w - - +solution Rxd4 +id "ECM.348" +go +setboard r3r1k1/pp3ppp/1qp5/2bbNQ2/5B2/2P5/PP3PPP/3RR1K1 w - - +solution Rxd5 +id "ECM.349" +go +setboard 7r/3qbk1r/3p1n2/p1pPp1p1/Pp1nPpP1/1P1Q1P1B/1NP3K1/R3B2R b - - +solution Nxg4 +id "ECM.350" +go +setboard r2qn1k1/1p1b3p/2pp1b2/6pQ/p1P1P3/P1N3PB/1P6/3R1R1K w - - +solution Rxf6 +id "ECM.351" +go +setboard 2rq3r/5p2/p3pkbQ/3p4/3N4/2P4R/P4PP1/4R1K1 w - - +solution Rf3+ +id "ECM.352" +go +setboard r4k1r/pp2pp2/3p1b2/q2PnQpp/3N4/1BP3P1/PP3PP1/3RR1K1 w - - +solution Rxe5 +id "ECM.353" +go +setboard 5rk1/2p3pp/p1p4r/2P1p3/3pPnq1/1P3R1P/PN1Q3K/R5N1 b - - +solution Qxf3 +id "ECM.354" +go +setboard r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - +solution Rxd7 +id "ECM.355" +go +setboard 2r2rk1/p3p1bp/3qP1p1/1Q1p4/P4P2/3R4/1P4PP/2B2RK1 b - - +solution Rxc1 +id "ECM.356" +go +setboard r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - +solution Rxd4 +id "ECM.357" +go +setboard 1r6/3b1pk1/pr1p1q1p/2pPb1p1/2B1P1P1/2N2PP1/1PQ3K1/RR6 b - - +solution Rxb2 +id "ECM.358" +go +setboard 2r2rk1/5ppp/1p2p3/p7/1n1R4/P1NnPN2/1P3PPP/1R4K1 b - - +solution Nxb2 +id "ECM.359" +go +setboard 2r3k1/p1r1ppb1/2bp1np1/q5N1/1p1BP2Q/3P4/PP2N1PP/2R2R1K w - - +solution Bxf6 +id "ECM.360" +go +setboard r3r1k1/p4ppp/2pp1b2/8/q2n1P2/2BQ3P/PPP3P1/1K1R2NR b - - +solution Re3 +id "ECM.361" +go +setboard rn1kr3/pppb4/3p1q2/3P1pNn/2P2P1p/1P2Q2P/P2NR1B1/4R1K1 w - - +solution Qxe8+ +id "ECM.362" +go +setboard r2q1rk1/ppp1b1pp/1nn1p3/4P3/2PP4/2N1B2P/PP1Q4/2KR1B1R b - - +solution Rxf1 +id "ECM.363" +go +setboard r3k3/1pqb1p2/p3p3/4n2r/3N1Q2/2P5/PP4B1/4RRK1 w q - +solution Rxe5 +id "ECM.364" +go +setboard 1rb2bk1/q4r2/pB1p1nn1/3Pp3/N3PpP1/8/1PQ1BNP1/R1R3K1 b - - +solution Rxb6 +id "ECM.365" +go +setboard 2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - +solution Rxd8 +id "ECM.366" +go +setboard r4rk1/5p2/p1b1pQpq/8/1B2P3/2NR4/PPP3PP/1K6 w - - +solution Rd5 +id "ECM.367" +go +setboard 3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - +solution Rxg6+ +id "ECM.368" +go +setboard 2rr2k1/5ppp/p1b1pn2/q1p5/P1B1PQ2/R1PN1P2/6PP/1R4K1 b - - +solution Rxd3 +id "ECM.369" +go +setboard 1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - +solution Bd8 +id "ECM.370" +go +setboard 1k2rb1r/pbp1q1pp/2pp4/2PnpP2/Q7/1P3NP1/PB5P/2KR1B1R w - - +solution Rxd5 +id "ECM.371" +go +setboard 7k/p1p1r2p/1p1pnr1q/5pp1/2PPPp2/2PB1P1P/P2Q1PRK/7R b - - +solution g4 +id "ECM.372" +go +setboard 5qk1/p4p2/1p3Pp1/2p4Q/3rr3/7R/PP6/6RK b - - +solution Rh4 +id "ECM.373" +go +setboard 5r1k/5Bb1/3p2Pp/p1pP4/1p2Q3/4P1P1/q7/3K3R w - - +solution Rxh6+ +id "ECM.374" +go +setboard 2b4B/1pp2k2/1p6/3P3n/5p1P/1P4p1/P2r2P1/R5KR b - - +solution f3 +id "ECM.375" +go +setboard r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b q - +solution Bh2 +id "ECM.376" +go +setboard r2q1r2/p1pbppbk/1p3npp/n2P2B1/7Q/2NB1N2/PPP3PP/4RRK1 w - - +solution d6 +id "ECM.377" +go +setboard 5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - +solution Nf7+ +id "ECM.378" +go +setboard r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - +solution Bxe5+ +id "ECM.379" +go +setboard r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - +solution Bc3 +id "ECM.380" +go +setboard 2r1k2r/3b1pb1/p2ppp2/2q2P2/2p1P2p/P1N2N2/1PP1Q1PP/3R1R1K w k - +solution e5 +id "ECM.381" +go +setboard 3r1rk1/1pq1bppp/p7/n2RN3/P7/1P6/1B2QPPP/R5K1 w - - +solution Nd7 +id "ECM.382" +go +setboard q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - +solution Rxc4 +id "ECM.383" +go +setboard r3bknr/1p4pp/p3Q3/q4pb1/P1Bn4/8/1PP2PPP/R1B1R1K1 w - - +solution Qd6+ +id "ECM.384" +go +setboard r1b1nrk1/p2n3p/2pp4/8/2P2q1N/1PB4P/P4PB1/R2QR1K1 w - - +solution Bd5+ +id "ECM.385" +go +setboard 7k/5rp1/p1bQB2p/1p4nN/4P3/1Pq5/P5PP/3R3K b - - +solution Bxe4 +id "ECM.386" +go +setboard r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - +solution d4 +id "ECM.387" +go +setboard r2r2k1/1bq2pb1/6pp/2P1p3/1nBpN2N/6PP/2Q2P2/3RR1K1 w - - +solution Nf6+ +id "ECM.388" +go +setboard r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - +solution Nf6+ +id "ECM.389" +go +setboard 2k1r3/Qp3pb1/2p4p/6q1/8/1P4PN/PBPn1P2/K2R4 b - - +solution Qe5 +id "ECM.390" +go +setboard r3r1k1/1pp2p1b/7p/2Q5/2PP2p1/2P1NpPq/P2R1P1P/6RK b - - +solution Rxe3 +id "ECM.391" +go +setboard 5bk1/5p1p/Q5p1/1B4n1/8/2q1p3/6PP/3R2K1 b - - +solution e2 +id "ECM.392" +go +setboard r5k1/1p3pp1/1p3q1p/1P1bQ3/P2P3n/8/3B1PPP/R3R1K1 b - - +solution Nf3+ +id "ECM.393" +go +setboard 2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - +solution Rxa6 +id "ECM.394" +go +setboard r5kr/p3PR1p/1p1p2pq/4n3/8/3B4/P4QPP/4R1K1 w - - +solution Rxe5 +id "ECM.395" +go +setboard 2bq1b2/1p3k2/1r1p1p1p/pNpP1PpP/P1P3P1/6B1/1P5Q/2K1R3 w - - +solution Re6 +id "ECM.396" +go +setboard 2kr3r/pp3p1p/2b1p3/q3Q3/5P2/2P1B3/P1P3PP/1R3RK1 b - - +solution Rhg8 +id "ECM.397" +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +solution Rxd3 +id "ECM.398" +go +setboard 2r2nk1/6pp/p1rPqp2/1pP1p3/1P6/2B3R1/1P2Q1PP/5RK1 w - - +solution Rxf6 +id "ECM.399" +go +setboard 3r2k1/pb3p1p/1q4p1/2b1P3/1Pp5/2P1p1P1/P3Q1BP/R1B4K b - - +solution Qc6 +id "ECM.400" +go +setboard r2rnbk1/pp3ppp/1q4n1/3p1N2/5P2/1PQB4/PBP3PP/4RR1K w - - +solution Nh6+ +id "ECM.401" +go +setboard r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - +solution e5 +id "ECM.402" +go +setboard r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - +solution Rxh5 +id "ECM.403" +go +setboard 5rr1/pp1kq1bp/2bppn2/2p3B1/4N3/2NP2P1/PPP4P/R3QRK1 b - - +solution Nxe4 +id "ECM.404" +go +setboard 1r1q1k2/R4pp1/5p1r/1p1p1n1p/3Pb2N/1BP5/2P1Q1PP/4R1K1 w - - +solution Qxe4 +id "ECM.405" +go +setboard R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - +solution Nxe5 +id "ECM.406" +go +setboard r1b3kr/bp3ppp/p1nNp3/4P3/P1Q2P2/BBP5/5qPP/R2R3K w - - +solution Nxc8 +id "ECM.407" +go +setboard 6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - +solution Rxc4 +id "ECM.408" +go +setboard 4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - +solution Rxf6 +id "ECM.409" +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +solution e6 +id "ECM.410" +go +setboard r4rk1/1b4bp/p1npq1P1/R3p3/8/1N2BP2/1PPQ2P1/4KB1R w K - +solution Qxd6 +id "ECM.411" +go +setboard 6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - +solution Bd2 +id "ECM.412" +go +setboard 6k1/2p3p1/2b4p/p4P2/2pR2PK/2P1r2P/1B6/8 b - - +solution Bg2 +id "ECM.413" +go +setboard r1b2rk1/pp2ppbp/2np1np1/q7/4P3/2N1BN2/PPPQBPPP/2KR3R b - - +solution Nxe4 +id "ECM.414" +go +setboard 3r1rk1/p1q4p/1p3bp1/3bnp2/3B4/1NPB3P/P1PQ2P1/1R2R2K b - - +solution Nf3 +id "ECM.415" +go +setboard r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - +solution Ng5 +id "ECM.416" +go +setboard 1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - +solution bxc6 +id "ECM.417" +go +setboard r3kbnr/1ppb3p/p1q1pp2/3p4/3P4/2N2N2/PPP2PPP/R1BQ1RK1 w kq - +solution Ne5 +id "ECM.418" +go +setboard r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - +solution Rxf6 +id "ECM.419" +go +setboard 3rr1k1/1p1qb2p/pP4p1/2p2p2/4RQ2/3P4/1PPB2PP/4R1K1 w - - +solution Bc3 +id "ECM.420" +go +setboard 2b2r2/rpp2pkp/3pq3/2pR2P1/2n1P1N1/2P2B2/1P3Q1P/1K5R b - - +solution Qxd5 +id "ECM.421" +go +setboard 6k1/rnqb3p/5ppQ/2pPp3/p1N1P3/2PB3P/5PP1/1R4K1 w - - +solution f4 +id "ECM.422" +go +setboard 7r/pp4k1/3pn1p1/q1pB1b2/2P5/5NR1/1P3PP1/2Q3K1 w - - +solution b4 +id "ECM.423" +go +setboard 5r2/4prkp/3q2p1/2pP1n2/N1Q2R2/1P4PP/P5K1/4R3 b - - +solution g5 +id "ECM.424" +go +setboard B1b1rbk1/5ppp/pq6/1p2n3/2p2P2/6PP/PPQ4K/R1BR4 b - - +solution Ng4+ +id "ECM.425" +go +setboard 8/2R4p/2R3bk/8/5N1P/1p3PP1/2pqP1K1/8 w - - +solution g4 +id "ECM.426" +go +setboard 6k1/p4p1p/3pqp2/2p1r3/2Pnr1N1/P6P/1P1Q1PP1/3R1RK1 b - - +solution Ne2+ +id "ECM.427" +go +setboard 1kqr3r/p1p4p/RpQP4/2P1p3/4B3/4Bp2/P4P1P/6K1 b - - +solution Rdg8+ +id "ECM.428" +go +setboard 6k1/3Q1pp1/4p2p/p2pP3/1p1P2P1/nP1R1N2/q1r2PKP/8 w - - +solution Qe8+ +id "ECM.429" +go +setboard 6k1/5pp1/p5r1/3Np2q/4P2p/1r3P1Q/n4P1P/3R2RK w - - +solution Rxg6 +id "ECM.430" +go +setboard nr2rb2/3q1kpp/3p4/pnpPpNBP/2N1P3/3Q4/PP3P2/2K3RR w - - +solution Nh6+ +id "ECM.431" +go +setboard r3k1r1/1pp2ppp/pb1p1qn1/4p2b/2B1P3/N1PP1NPP/PP2QPK1/R4R2 b q - +solution Nh4+ +id "ECM.432" +go +setboard 1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - +solution Bxh6 +id "ECM.433" +go +setboard r2b4/pb2q1k1/np1p2r1/1N1Pp2Q/PPN1Pp2/8/2R2BPp/2R4K w - - +solution Ncxd6 +id "ECM.434" +go +setboard r7/2qnb1kp/p2p1nP1/1p1Pp1p1/6N1/3BB2Q/PPP4P/5RK1 w - - +solution Qxh7+ +id "ECM.435" +go +setboard n1rqk3/1p2p3/1n1pP1p1/pP1P1p1r/3B3P/1BN3p1/3Q4/R3K2R w KQ - +solution Qg5 +id "ECM.436" +go +setboard rn2kr2/pp1b1pQp/3Pp3/qB1n4/3N4/P7/1PP2PPP/2KR3R w q - +solution Nxe6 +id "ECM.437" +go +setboard 3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - +solution Bh4 +id "ECM.438" +go +setboard r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - +solution Bf8 +id "ECM.439" +go +setboard 4rr1k/pbp3bp/3p4/1p5q/3n4/1B1Q2B1/PP1N1N1P/4RRK1 b - - +solution Rf3 +id "ECM.440" +go +setboard r3k2r/pp2ppbp/1qp5/2n2b2/2P5/4BN2/PP1QBP1P/2KR3R b kq - +solution Nb3+ +id "ECM.441" +go +setboard 4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - +solution Ng6+ +id "ECM.442" +go +setboard 2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - +solution Qb2 +id "ECM.443" +go +setboard 2r3k1/n3qppp/1B1r1n2/N7/N4P2/1Q4PP/P5B1/R1b4K b - - +solution Qe1+ +id "ECM.444" +go +setboard 7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - +solution Qxg5+ +id "ECM.445" +go +setboard rnb2k2/ppbp2p1/2p2pB1/8/1PN5/2P5/P4PPP/R1B3K1 w - - +solution Bf4 +id "ECM.446" +go +setboard 2k5/1p1b4/2n1p1r1/7q/4RP2/3BQN2/2P2K1P/8 w - - +solution f5 +id "ECM.447" +go +setboard 2k3r1/1ppr3p/p1pB2q1/6n1/N3Pp2/8/PPP1Q1PP/3R1RK1 b - - +solution f3 +id "ECM.448" +go +setboard r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - +solution Rxh2+ +id "ECM.449" +go +setboard 6r1/6rk/3p3p/p2Rp3/R1PqPp1b/2N2Q2/6PP/7K b - - +solution Rxg2 +id "ECM.450" +go +setboard 4r1k1/1p2rq1p/2bQpp2/p1Pp4/3P4/P3RN2/5PPP/4R1K1 w - - +solution Ne5 +id "ECM.451" +go +setboard b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1KP/8 w - - +solution g6 +id "ECM.452" +go +setboard 1k4q1/1p2Rprp/p1p5/2Pp4/1P1Q3P/6P1/P5K1/8 w - - +solution Qe5+ +id "ECM.453" +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +solution Ng6+ +id "ECM.454" +go +setboard r4r1k/p2bN2p/1p1p1p2/2q4P/3Q4/1P6/1PP3P1/1K2R2R w - - +solution Ng6+ +id "ECM.455" +go +setboard 2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - +solution h4 +id "ECM.456" +go +setboard r1b2k1r/1p2qp2/pN1p1n2/2pP2pp/P2bP1P1/2N5/1P2BPP1/R2Q1RK1 b - - +solution hxg4 +id "ECM.457" +go +setboard 6nk/p4rrp/1p1p1p2/1q1Pp2R/4B1P1/1PP2Q1R/P6P/7K w - - +solution g5 +id "ECM.458" +go +setboard r1b1k2r/6pp/p1p1p3/3np1B1/1b2N3/8/q1PQB1PP/3RK2R w Kkq - +solution Qxb4 +id "ECM.459" +go +setboard 3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - +solution Bxh5 +id "ECM.460" +go +setboard 2r3k1/4qpp1/2p1r3/pbQpN1Pp/3P1P1P/4P3/PP6/1KR3R1 w - - +solution Qxb5 +id "ECM.461" +go +setboard 4r2k/p2Q3p/2p1r1p1/4NpR1/3P4/2P1PP1b/P4q1P/6RK w - - +solution Nxg6+ +id "ECM.462" +go +setboard 4r1kb/p2r4/1np1p1p1/3nP1Bp/1p3P1R/1B2qP2/PPPN3Q/2K4R w - - +solution Rxh5 +id "ECM.463" +go +setboard 2rq2k1/pp1bpp1p/3p1np1/8/3NPPnQ/1BP5/P1P3P1/1K1R3R w - - +solution e5 +id "ECM.464" +go +setboard r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - +solution Rxd5 +id "ECM.465" +go +setboard 2r1kr2/p1qbbp1Q/3pp3/5p2/1p1N1PB1/6P1/PPP4P/K2RR3 w - - +solution Bxf5 +id "ECM.466" +go +setboard r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - +solution Rf6 +id "ECM.467" +go +setboard 2rr2k1/5pn1/1b2q1pp/pP1pP3/2pP1PP1/2R1B2P/2Q3B1/3R3K w - - +solution f5 +id "ECM.468" +go +setboard 2Q2bkr/5p2/1rb5/1pN1n1qB/1P1pPN2/6P1/5P2/R1R3K1 w - - +solution Nce6 +id "ECM.469" +go +setboard 2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - +solution Nc3+ +id "ECM.470" +go +setboard 2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - +solution Nxf5+ +id "ECM.471" +go +setboard 1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - +solution Ne6 +id "ECM.472" +go +setboard r7/pp4pk/2n3qp/5p2/3p4/P4QB1/1PP1RPPP/6K1 b - - +solution d3 +id "ECM.473" +go +setboard 2r2r1k/1p3p1p/p2p1Pp1/3Pp3/1q2Bn1Q/8/1PP3PP/4RR1K w - - +solution Rxf4 +id "ECM.474" +go +setboard r4rk1/5ppp/p7/4PR2/P1qnp2Q/4B3/1P4PP/5RK1 w - - +solution Rh5 +id "ECM.475" +go +setboard 4r3/pb3pk1/6p1/8/6P1/1PNrB2K/P4P1P/2R5 b - - +solution Rexe3+ +id "ECM.476" +go +setboard 1r3kr1/p3q1b1/3p2Q1/2p2p2/2P2N2/4Pn2/PB6/K2R3R w - - +solution Ne6+ +id "ECM.477" +go +setboard 5r1k/6bp/3p1q2/3Q1nP1/8/6P1/PP3BKP/R2N4 b - - +solution Ne3+ +id "ECM.478" +go +setboard 1r1q1k1r/Q4ppp/2B2n2/8/Pbbp4/1P4P1/2PP1P1P/R1B1K2R b KQ - +solution Qe8+ +id "ECM.479" +go +setboard 5rk1/p1p1R1p1/1p5p/8/2pP1P2/3n2P1/PP2Q2P/5KNq b - - +solution Nxf4 +id "ECM.480" +go +setboard r5k1/1N3ppp/4b3/1Nq5/Pn3pn1/5B2/1PPQ3P/R6K b - - +solution Qxb5 +id "ECM.481" +go +setboard 1r2k2r/1bq2pp1/pn2p2p/1p2P1b1/3N4/2N3Q1/PPP3PP/1K1R1BR1 w k - +solution Bxb5+ +id "ECM.482" +go +setboard r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - +solution Nxh6 +id "ECM.483" +go +setboard 2r2r2/p4p1k/1p2pBpn/2p5/6N1/8/P4P2/R3R1K1 w - - +solution Kg2 +id "ECM.484" +go +setboard r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - +solution Bg5 +id "ECM.485" +go +setboard 3rn1k1/pp3ppp/6b1/2p1Q3/2P1P3/P4P2/1B1qBP1P/1R5K w - - +solution Rd1 +id "ECM.486" +go +setboard 4r1k1/5ppp/p1q3b1/1ppNr3/2P1P3/1P4QP/P4PP1/4RRK1 w - - +solution f4 +id "ECM.487" +go +setboard 2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - +solution Bh3 +id "ECM.488" +go +setboard 2b3k1/5qp1/p2r1n1p/3p4/3B4/1RP3QP/P2Nr1P1/3R2K1 b - - +solution Ne4 +id "ECM.489" +go +setboard 6k1/5rp1/4Nb1p/2p5/4Q3/1r5P/q5P1/3R1R1K w - - +solution Rxf6 +id "ECM.490" +go +setboard 1r2r1k1/p4ppb/q1pbnn1p/4p3/N1P1P3/pPB2NP1/2Q1RPBP/R5K1 b - - +solution Nxe4 +id "ECM.491" +go +setboard r4r2/1pnqb2k/3p1p1p/p1pPpPpP/2P1N1P1/4BP2/PP1Q4/R2R2K1 w - - +solution Bxc5 +id "ECM.492" +go +setboard rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - +solution Nf6+ +id "ECM.493" +go +setboard 6kr/1p1r1p1p/p2pnPpQ/3Np2R/2q1P3/5P2/PPP5/2KR4 w - - +solution Rxe5 +id "ECM.494" +go +setboard 3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - +solution Nd6 +id "ECM.495" +go +setboard r2q1rk1/pp1n2pp/2pb4/1P1p3n/P1PPpP2/4P2b/1BNNBP1P/R2QR1K1 b - - +solution Nxf4 +id "ECM.496" +go +setboard rq1r2k1/3nbp1p/p2p2p1/1p1Pp1P1/3B1P2/3B3Q/PPP4P/2KR2R1 w - - +solution f5 +id "ECM.497" +go +setboard r4rk1/1bq1bppp/8/p2pPR2/3B4/1NnP3Q/1P4PP/4R1K1 w - - +solution Rh5 +id "ECM.498" +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +solution Nxh5 +id "ECM.499" +go +setboard r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - +solution f3 +id "ECM.500" +go +setboard 4rqk1/p5b1/3p3p/3Pn1p1/1pP1NrP1/4NP2/P3Q1P1/1K1RR3 b - - +solution Nxf3 +id "ECM.501" +go +setboard r2qkr2/1p3pQp/2p1b3/1B1pN3/1p6/8/1P1K1PPP/2B1R3 w q - +solution Nxc6 +id "ECM.502" +go +setboard r3rk2/pb2bpp1/1n5p/q1pP1B2/1p3B2/5N2/PPQ2PPP/R2R2K1 w - - +solution Bc8 +id "ECM.503" +go +setboard r1bqr2k/ppp2p1p/5b2/3Pn1p1/1PP1Bp2/8/PB2N1PP/R2Q1RK1 w - - +solution Nxf4 +id "ECM.504" +go +setboard 1q4k1/p3rppp/3b1n2/8/5P2/4P3/PP1B3P/RNQ3K1 b - - +solution Bxf4 +id "ECM.505" +go +setboard r3k2r/1p1b1p2/p3p3/2b3p1/4N1n1/1B5P/PPP3P1/R1B2R1K b kq - +solution Bc6 +id "ECM.506" +go +setboard r3kb1r/npqbpp1p/p3n1p1/P3P3/6N1/3B1NB1/1PP3PP/R3QRK1 w kq - +solution Ng5 +id "ECM.507" +go +setboard 7k/p6p/4bppb/1N6/P2p1p2/1PrP2P1/2r1P2P/1R1Q2K1 b - - +solution f3 +id "ECM.508" +go +setboard 2kr4/pp1r1pp1/4n1p1/4R3/2Pp1qP1/3P2QP/5PB1/1R4K1 w - - +solution Rc5+ +id "ECM.509" +go +setboard 3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - +solution Rxe6 +id "ECM.510" +go +setboard r2qkn1r/pb2bp2/1pp1p3/5p1p/2BPN3/5NQ1/PPP2PPP/1K1RR3 w kq - +solution d5 +id "ECM.511" +go +setboard 2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - +solution Nxf5 +id "ECM.512" +go +setboard 3r3k/p4npp/1p2qpb1/4P3/5P2/P3N3/1B2QP1P/6RK w - - +solution exf6 +id "ECM.513" +go +setboard 6rk/1b2bp1p/ppq1p3/2p1Pp2/P1Br1P2/1PNR2P1/2P1QK1P/6R1 b - - +solution Rxf4+ +id "ECM.514" +go +setboard r3r1k1/p1q2pp1/b1pb3p/n7/B3n3/2P1BN2/PP1N1PPP/R2QK2R b KQ - +solution Nxc3 +id "ECM.515" +go +setboard 4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - +solution Bxf6 +id "ECM.516" +go +setboard r5n1/pppb1B2/2k1pb2/3p2B1/5P2/2N5/PPP3P1/2KR4 w - - +solution Nxd5 +id "ECM.517" +go +setboard 2b2q2/r2n2kp/1n1p1pp1/p1pP4/1pP1NPN1/1P1B4/P5PP/Q3R1K1 w - - +solution Nexf6 +id "ECM.518" +go +setboard 1k1r2r1/p1p3q1/2p2p2/3pn3/1P1b2bB/1QN5/P4PPP/1R2RBK1 b - - +solution Nf3+ +id "ECM.519" +go +setboard r3k2r/1bq1bp1p/p2p1np1/1p2p3/3NP3/P1N2QB1/1PP2PPP/3RR1K1 w kq - +solution Ndxb5 +id "ECM.520" +go +setboard r2q4/5p1P/2p1bR2/ppk1p1P1/3pB2Q/8/PPP5/6K1 w - - +solution g6 +id "ECM.521" +go +setboard r3kb1r/pp1b1pp1/4p3/2q3Qp/5B2/2PB4/P4PPP/R3R1K1 w kq - +solution Rxe6+ +id "ECM.522" +go +setboard 1rbr2k1/p4pp1/5b1p/2p1p3/3qPP2/1PNB2PP/PKP2Q2/5R1R b - - +solution c4 +id "ECM.523" +go +setboard r3r1k1/p6p/bp4p1/2bPN3/6n1/6P1/PB2RPB1/3R2K1 w - - +solution d6 +id "ECM.524" +go +setboard 2bk3r/3r2pp/p2nQ3/q2R2P1/1p6/8/PPP2P1P/1K3B1R b - - +solution Qxd5 +id "ECM.525" +go +setboard 3r1k2/1q1r1pp1/3p2bp/p2N4/8/2P1RQ1P/P4PP1/4R1K1 w - - +solution Nf6 +id "ECM.526" +go +setboard 3q3r/p2r1pkp/bp1N1np1/n2p4/5Q2/B1P5/P4PPP/R3R1K1 w - - +solution Nf5+ +id "ECM.527" +go +setboard r4Nk1/1p2pp1p/p1np2p1/3N4/P3PPn1/8/1bPKBqPP/R2Q1R2 b - - +solution Qd4+ +id "ECM.528" +go +setboard 1kb3rr/1p2n2q/1Np2p2/1p6/1P1N1P1p/8/2P1RQPP/R6K w - - +solution Nxb5 +id "ECM.529" +go +setboard r3r1k1/p3Rp1p/1qp1bQ2/8/1p1P4/3R4/PP3PPP/6K1 w - - +solution Rg3+ +id "ECM.530" +go +setboard rn4k1/pp2rpb1/2pNb1pp/4p3/P3Pq2/2P2N1P/1PB1QPP1/R3R1K1 w - - +solution Nf5 +id "ECM.531" +go +setboard 3r1rk1/pp3ppp/8/2p5/4PB1n/P1P2qPP/Q3RP1K/6R1 b - - +solution Qg2+ +id "ECM.532" +go +setboard r4rn1/ppp1q3/2bp2kp/6P1/3QpP2/2N5/PPP1B3/2KR3R w - - +solution f5+ +id "ECM.533" +go +setboard 3qr2r/1p1bppk1/3p2p1/p1nP1PQp/3N3R/1P4PP/P1P3BK/4R3 w - - +solution Ne6+ +id "ECM.534" +go +setboard 2rq1rk1/1b1nbpp1/1p5p/p2pNB2/3p1N2/4P3/PPQ2PPP/2RR2K1 w - - +solution Bh7+ +id "ECM.535" +go +setboard 8/5pkp/2pp2p1/4P3/1P2P3/2QBq2P/2PnNnPK/8 b - - +solution Nf1+ +id "ECM.536" +go +setboard r3r2k/pb2q1p1/1p2Nn1p/2b5/2B5/2P2P2/PPQ3PP/4RR1K w - - +solution Nf4 +id "ECM.537" +go +setboard r1b2nk1/ppq2ppp/8/1BP1p1NQ/5p2/8/PP3PPP/3R2K1 w - - +solution Rd7 +id "ECM.538" +go +setboard 6k1/5qp1/pN5p/3pRp2/3QnP2/2r4P/r5P1/6RK b - - +solution Qh5 +id "ECM.539" +go +setboard 5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - +solution Nf5+ +id "ECM.540" +go +setboard 6rk/p2b4/3p1Nqp/2pPpn2/P1P4p/5P1P/Q2B1NP1/6RK b - - +solution Ng3+ +id "ECM.541" +go +setboard r4r1k/pppb2pp/8/3q4/2N5/P1P2nQ1/BP2R2P/R6K b - - +solution Ne1+ +id "ECM.542" +go +setboard r5rk/1pp1n1pp/p1n1b1q1/3p1p2/7R/2QB1N2/PB3PPP/4R1K1 w - - +solution Rxe6 +id "ECM.543" +go +setboard 8/4Ppk1/6p1/1p6/1Pb1Q3/6pq/8/6K1 w - - +solution Qe5+ +id "ECM.544" +go +setboard 3R4/4Qpk1/4p1p1/7p/7K/5rP1/5P2/2q5 w - - +solution Qf8+ +id "ECM.545" +go +setboard 8/5pk1/p6p/2R5/3q2p1/6P1/2Q3PK/4r3 w - - +solution Rg5+ +id "ECM.546" +go +setboard 1Q4R1/8/P1b2p2/2p2k2/2P5/5p2/1r5P/4R1K1 b - - +solution f2+ +id "ECM.547" +go +setboard 5r1k/1q2R3/8/6Q1/8/8/6P1/7K b - - +solution Rf1+ +id "ECM.548" +go +setboard 8/4p3/8/3P3p/P2pK3/6P1/7b/3k4 w - - +solution d6 +id "ECM.549" +go +setboard 3Q4/k3K3/q7/2N1P3/1P6/5r2/8/8 b - - +solution Rf7+ +id "ECM.550" +go +setboard 3k4/p1p5/8/2p1p3/4P3/PpPP2K1/1P6/8 b - - +solution c4 +id "ECM.551" +go +setboard 6r1/5p1k/4p3/3pQp2/1p1P1P1q/1P3RR1/7r/5K2 w - - +solution Rxg8 +id "ECM.552" +go +setboard r1b2rk1/ppp2ppp/2n3q1/b2N2N1/2BP4/4p2P/PPP3P1/R2Q1RK1 w - - +solution Nxf7 +id "ECM.553" +go +setboard 1r4k1/3qb2p/pr1pppn1/2p2N2/2P2PQ1/1P4P1/P2R2BP/R5K1 w - - +solution Bd5 +id "ECM.554" +go +setboard r6r/pR1nqkpp/2p1p3/3p4/6Q1/2b4P/P1PP1PP1/2B1R1K1 w - - +solution Rxe6 +id "ECM.555" +go +setboard 1k1r3r/ppq2pnp/1npbb1p1/3p4/3P1NP1/2NBP2P/PPQ2P1B/1KR4R w - - +solution Nb5 +id "ECM.556" +go +setboard 5rk1/p1p1br2/1p1p2qp/4p3/2PPn1pP/3Q2P1/PPN1P1K1/2RR2B1 b - - +solution Bxh4 +id "ECM.557" +go +setboard r5r1/4q2k/p2p3p/5p2/4p3/P2QR3/1PP2PPP/4R1K1 w - - +solution Rxe4 +id "ECM.558" +go +setboard r1b2rk1/4bnpp/2p5/pp2q3/4N3/PQ2B1P1/1PP3BP/4RRK1 w - - +solution Ng5 +id "ECM.559" +go +setboard 2rr2k1/1p3p2/p2n2p1/P2PnNq1/3QP1p1/1RN5/6PP/5RK1 b - - +solution Nf3+ +id "ECM.560" +go +setboard r3k1r1/pb1qpp1p/1pnp1n1B/2p2R2/3PP3/2P3PN/P1P3BP/R2Q3K b q - +solution Nxe4 +id "ECM.561" +go +setboard 2r2rk1/pp2bppp/3q1n2/3nNRB1/3P4/1B5Q/PP4PP/3R2K1 w - - +solution Nxf7 +id "ECM.562" +go +setboard r1bq1rk1/1pp2ppn/1pnp3p/3N4/2B1PN2/3P4/PPP3PP/R2Q1RK1 w - - +solution Ng6 +id "ECM.563" +go +setboard r1b2rk1/pp3p1p/2pq2pn/2nNN3/2B1QP2/8/P1PP2PP/R1B1K2R w KQ - +solution Nxf7 +id "ECM.564" +go +setboard 1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - +solution Nxf7 +id "ECM.565" +go +setboard 1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - +solution Rxc5 +id "ECM.566" +go +setboard r1b3k1/2pq2pp/p4p2/1p1Nr3/2n2R2/1B6/PPQ2PPP/R5K1 w - - +solution Rxc4 +id "ECM.567" +go +setboard 2rq1rk1/3bbppp/p3pn2/1p1pN3/2nP1B2/P1NBP2Q/1P3PPP/2R2RK1 w - - +solution Nxd5 +id "ECM.568" +go +setboard 2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - +solution Nxc1 +id "ECM.569" +go +setboard 1r4nk/3b2bp/3p4/3P3p/2pNPq2/P1N2p1P/1P3Q2/1R4KR b - - +solution Rxb2 +id "ECM.570" +go +setboard 2r5/p3kpp1/P2p4/1P2pP1p/1P2PqnP/6R1/r2N2P1/3RQ1K1 b - - +solution Rxd2 +id "ECM.571" +go +setboard 2br2k1/1p2qppp/r1n1p3/pQ1nN3/P2P4/2B3P1/1P3PBP/2RR2K1 w - - +solution Qxa6 +id "ECM.572" +go +setboard 5rk1/3q2bp/3pb2r/1p1n1p2/3p1P2/P2B1QN1/1P1B2PP/2R1R1K1 w - - +solution Nxf5 +id "ECM.573" +go +setboard 4r1k1/1ppQr1p1/1p1p1pP1/3P3p/7P/1P3q2/P1P5/1KRR4 w - - +solution Re1 +id "ECM.574" +go +setboard 2Rr2k1/7p/4pqp1/p4p2/1p1P1Q1P/8/PP3PP1/6K1 w - - +solution Qe5 +id "ECM.575" +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +solution Rc1 +id "ECM.576" +go +setboard 5rk1/bp4p1/p2rp2p/8/8/2PN4/PP1R1PPP/3R2K1 b - - +solution e5 +id "ECM.577" +go +setboard 2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - +solution Bh3 +id "ECM.578" +go +setboard n1bq3k/pp4bp/6p1/5pP1/3p1P2/1B1P4/PB3Q1P/4R1K1 w - - +solution Bxd4 +id "ECM.579" +go +setboard r3r1k1/p2n4/3p1pp1/qnp3B1/1p2P1P1/1P3P2/PP2N2Q/1K1R1B2 w - - +solution Nf4 +id "ECM.580" +go +setboard 6k1/pb3ppp/1p2p3/4P3/5P2/P1r5/1q4PP/1B2Q1RK b - - +solution Rc1 +id "ECM.581" +go +setboard 2rq1kbR/4R1p1/3p3r/pp1P1Pp1/6P1/3B4/PPP1Q3/6K1 w - - +solution f6 +id "ECM.582" +go +setboard 2r5/5kb1/4ppp1/pp1qB3/2rP4/1RP2R1Q/P4PP1/6K1 b - - +solution Rh8 +id "ECM.583" +go +setboard 4k3/4Bp2/1p2nP1P/2p5/2K1b1B1/8/P7/8 w - - +solution Bf3 +id "ECM.584" +go +setboard 3rr1k1/ppp1qp1p/3b2p1/4np1P/1P1N1Pn1/P1P4R/1B1NB3/R2Q1K2 b - - +solution Nf3 +id "ECM.585" +go +setboard 1k1r3r/ppqb4/5Ppp/3p4/P2np3/3BR1Q1/2PB1PPP/R5K1 w - - +solution Rxe4 +id "ECM.586" +go +setboard r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - +solution Nxc6 +id "ECM.587" +go +setboard 8/2R2pbk/6pp/1p2pq2/1P2Qn2/3P3P/3B1PP1/r3N1K1 b - - +solution Nxd3 +id "ECM.588" +go +setboard 2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - +solution h3 +id "ECM.589" +go +setboard r2b1rnk/1p4qp/p1p1b1p1/2PpNp2/PP1PnP1Q/3BB2R/4N1PP/R6K w - - +solution Qxh7+ +id "ECM.590" +go +setboard r1b2rk1/1p3pbp/2p3p1/p1q5/1P6/1Q4P1/1P2PPBP/R1B1R1K1 b - - +solution Be6 +id "ECM.591" +go +setboard 4r1k1/r1q2p1p/p5pB/1pbBpN1n/1n2P3/5Q2/PP3PPP/R1R3K1 w - - +solution Rxc5 +id "ECM.592" +go +setboard r1r3k1/ppnbb1pp/2ppp1q1/1P3p2/P1PPn3/2N2NP1/2Q1PPBP/1RB2RK1 w - - +solution Nxe4 +id "ECM.593" +go +setboard r1b1k2r/2q1bppp/p3p3/1p1nP1B1/3Q4/2N5/PPP1B1PP/2KR3R w kq - +solution Bxe7 +id "ECM.594" +go +setboard 1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - +solution Nxh2 +id "ECM.595" +go +setboard 2rqk1nr/pp3ppp/2n1p3/2b5/3N4/2NQB1P1/PP2PPKP/R4R2 w k - +solution Nxe6 +id "ECM.596" +go +setboard rnb2rk1/pp4pp/2pb1n2/3N1p1q/2P5/3N2P1/P1Q1PPBP/R1B2RK1 w - - +solution Bf4 +id "ECM.597" +go +setboard 8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - +solution f4 +id "ECM.598" +go +setboard 8/5pp1/7p/5P1P/2p3P1/2k5/5P2/2K5 w - - +solution f6 +id "ECM.599" +go +setboard 7k/8/1p1ppp1p/1Pp5/2P2P2/8/3P2PP/6K1 w - - +solution f5 +id "ECM.600" +go +setboard 8/p5k1/2p2p2/4p1p1/1p2P3/1P4PP/1PP5/5K2 b - - +solution g4 +id "ECM.601" +go +setboard 8/5K2/kp6/p1p5/P2p4/1P3P2/2P5/8 b - - +solution b5 +id "ECM.602" +go +setboard 8/2k3p1/2p4p/5P2/2K3PP/8/8/8 w - - +solution g5 +id "ECM.603" +go +setboard 8/1kp1b3/1p4K1/4P2p/P1P3p1/5pP1/P4P2/4B3 b - - +solution h4 +id "ECM.604" +go +setboard 8/8/4b1p1/2Bp3p/5P1P/1pK1Pk2/8/8 b - - +solution g5 +id "ECM.605" +go +setboard 8/8/3K1k2/5p1p/4p1p1/4P1P1/5PP1/8 b - - +solution f4 +id "ECM.606" +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +solution Bxg6 +id "ECM.607" +go +setboard 6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - +solution Rxc6 +id "ECM.608" +go +setboard 1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - +solution f6 +id "ECM.609" +go +setboard 2kr3r/ppp1qpp1/2p5/2b2b2/2P1pPP1/1P2P1p1/PBQPB3/RN2K1R1 b Q - +solution Rh1 +id "ECM.610" +go +setboard 1r3qk1/pb3p1p/1pn2PpQ/2pN4/3r4/5B2/PPP4P/4RRK1 w - - +solution Ne7+ +id "ECM.611" +go +setboard 4r1k1/5p1p/3q2p1/1p1P4/1P6/2p4P/2Q1nPB1/4RK2 b - - +solution Ng3+ +id "ECM.612" +go +setboard 6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - +solution e5 +id "ECM.613" +go +setboard 5r2/pp1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +id "ECM.614" +go +setboard 6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - +solution b5 +id "ECM.615" +go +setboard r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - +solution Rxa6 +id "ECM.616" +go +setboard 3r2k1/p6p/b2r2p1/2qPQp2/2P2P2/8/6BP/R4R1K w - - +solution Rxa6 +id "ECM.617" +go +setboard 8/p3q1k1/6p1/1p3nP1/2pp1QBr/P2P4/1PP2K2/R7 b - - +solution Qe3+ +id "ECM.618" +go +setboard 7k/4b2p/5p1P/5PP1/1pNp1P2/1P1B4/2P2K2/r7 w - - +solution g6 +id "ECM.619" +go +setboard 5r1k/1p1b2rP/p2p4/3P3B/P2P4/5pP1/1P2pP2/R3R1K1 b - - +solution Rxg3+ +id "ECM.620" +go +setboard 6B1/2p2pp1/2p5/p3K3/1k6/nP4P1/5P1P/8 b - - +solution Nc4+ +id "ECM.621" +go +setboard 3q1k2/5p2/p5pN/1b2Q2P/8/8/5PPK/8 w - - +solution Qh8+ +id "ECM.622" +go +setboard 6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - +solution Rc4 +id "ECM.623" +go +setboard 4r2k/3n1Qpp/1pRP1p2/p4P2/1p1P2P1/6rP/P3q1B1/6RK w - - +solution Qe6 +id "ECM.624" +go +setboard 2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - +solution Nxe6 +id "ECM.625" +go +setboard 3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - +solution Ba6 +id "ECM.626" +go +setboard 3rr1k1/pppRn1pp/4Pp2/1P5q/1QB5/4P3/P4P1P/4K1R1 w - - +solution Qxe7 +id "ECM.627" +go +setboard rn1q2k1/pp3pb1/3p2pp/2pP2N1/3r1P2/7Q/PP4PP/R1B2RK1 w - - +solution Nxf7 +id "ECM.628" +go +setboard 8/6Bp/6p1/2k1p3/4PPP1/1pb4P/8/2K5 b - - +solution b2+ +id "ECM.629" +go +setboard 5bk1/r4ppp/1r1P1n2/2p2N2/b7/2B3P1/5PBP/R3R1K1 w - - +solution Bxf6 +id "ECM.630" +go +setboard 8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - +solution a6 +id "ECM.631" +go +setboard 3qr1k1/p4ppp/1p1P4/2r1nN2/4P2n/P7/1B4P1/3QRRK1 w - - +solution d7 +id "ECM.632" +go +setboard 6k1/5pbp/6p1/2p1r3/1pPr4/3n2NP/1PB2PP1/1R1R2K1 b - - +solution Nxb2 +id "ECM.633" +go +setboard 4r3/p4pk1/6p1/P1pB2Pp/2P3b1/2p1N1P1/Qb1r1P2/6K1 b - - +solution Rxe3 +id "ECM.634" +go +setboard 2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - +solution Nxa7 +id "ECM.635" +go +setboard r4rk1/ppq3pp/2p1Pn2/4p1Q1/8/2N5/PP4PP/2KR1R2 w - - +solution Rxf6 +id "ECM.636" +go +setboard r3qr1k/1b4pp/p2RQ3/Bp2p3/4p3/6P1/PPP2P1P/3R2K1 b - - +solution Qh5 +id "ECM.637" +go +setboard 8/6kP/6p1/1p1pP3/pP6/P1n2K2/2N5/8 w - - +solution e6 +id "ECM.638" +go +setboard 8/Pb6/8/8/7K/5k1p/6pB/8 b - - +solution g1=Q +id "ECM.639" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "ECM.640" +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +solution cxb6 +id "ECM.641" +go +setboard 6k1/p4pbp/Bp2p1p1/n2P4/q3P3/B1rQP3/P5PP/5RK1 w - - +solution dxe6 +id "ECM.642" +go +setboard 5r2/R4p2/5P1k/4PK2/1p6/8/8/8 w - - +solution Rxf7 +id "ECM.643" +go +setboard 4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - +solution f5 +id "ECM.644" +go +setboard 1r6/3r1Pk1/p2p1np1/5q2/1p3P2/1B5R/PPP4Q/1K1R4 w - - +solution Rh8 +id "ECM.645" +go +setboard 8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - +solution Bxb3 +id "ECM.646" +go +setboard 2r5/1r5k/1P3p2/PR2pP1p/4P2p/2p1BP2/1p2n3/4R2K b - - +solution Nd4 +id "ECM.647" +go +setboard 4r2k/p2qr1pp/1pp2p2/2p1nP1N/4R3/1P1P2RP/1PP2QP1/7K w - - +solution Rxg7 +id "ECM.648" +go +setboard 6k1/p4p2/5Ppp/3RP3/Pr4P1/2p2K2/7P/8 w - - +solution Rd8+ +id "ECM.649" +go +setboard 8/1R2P3/6k1/3B4/2P2P2/1p2r3/1Kb4p/8 w - - +solution Be6 +id "ECM.650" +go +setboard 2kr2r1/pp2bQ1p/2b1P3/2qN4/8/1B2p2P/PPP3P1/3R1R1K b - - +solution e2 +id "ECM.651" +go +setboard r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - +solution Bxh7+ +id "ECM.652" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Bb5 +id "ECM.653" +go +setboard r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - +solution Bxh7+ +id "ECM.654" +go +setboard 6rk/3nrpbp/p1bq1npB/1p2p1N1/4P1PQ/P2B3R/1PP1N2P/5R1K w - - +solution Nxh7 +id "ECM.655" +go +setboard 1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - +solution Bxh7+ +id "ECM.656" +go +setboard 2k5/ppp3pp/8/NQ2n2q/2Pp1n2/R4bP1/1P3P1P/4R1K1 b - - +solution Qxh2+ +id "ECM.657" +go +setboard 5rrk/1p3qpp/p3pn2/2PpBp2/3P1P1Q/P1P1R2R/2b1B1PP/6K1 w - - +solution Qxh7+ +id "ECM.658" +go +setboard r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - +solution Bxh7+ +id "ECM.659" +go +setboard r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/1P3PPP/2R3K1 w - - +solution Bxh7+ +id "ECM.660" +go +setboard r5rk/1p1q1p1p/5pn1/p2p1N1Q/3P2P1/PP2R3/5P1P/5RK1 w - - +solution Qxh7+ +id "ECM.661" +go +setboard 2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - +solution Rxh7+ +id "ECM.662" +go +setboard 1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - +solution Rxh7 +id "ECM.663" +go +setboard 4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - +solution Bxh7+ +id "ECM.664" +go +setboard r1b2rk1/2q1bppp/p1n1p3/1p1np1P1/5P2/1NNBBQ2/PPP4P/R4RK1 w - - +solution Bxh7+ +id "ECM.665" +go +setboard 5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - +solution Nxh7 +id "ECM.666" +go +setboard r4rk1/pp2q1p1/4b2p/2ppb3/6n1/2P3N1/PPQBBPPP/R4RK1 b - - +solution Nxh2 +id "ECM.667" +go +setboard b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - +solution Bxh7+ +id "ECM.668" +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +solution Qxh7+ +id "ECM.669" +go +setboard r1b1rnk1/pp1nb1pp/2p1pp2/q3N3/2PP1P2/3BP1N1/PBQ3PP/R4RK1 w - - +solution Bxh7+ +id "ECM.670" +go +setboard 4r1k1/2q2r1p/p3bQ2/1p4Bp/2np4/8/PPB2PP1/3RR1K1 w - - +solution Bxh7+ +id "ECM.671" +go +setboard 5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - +solution Bxh7+ +id "ECM.672" +go +setboard 2rqr1k1/1p1bbppp/p3p3/n7/3P2Q1/2PB1N2/P4PPP/R1B1R1K1 w - - +solution Bxh7+ +id "ECM.673" +go +setboard r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - +solution Nxh7 +id "ECM.674" +go +setboard rn1q1rk1/pb1p1ppp/4p3/2pnP3/1bp5/2N2N2/PP3PPP/RBBQK2R w KQ - +solution Bxh7+ +id "ECM.675" +go +setboard r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - +solution Rxh7 +id "ECM.676" +go +setboard r1b2rk1/1pq2ppp/p1p1p3/2n1P3/2N2P2/3B4/PPP3PP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.677" +go +setboard rnq3rk/4bp1p/p1p3pQ/1p1pP3/1P1N1B2/2P3R1/1P3PPP/R5K1 w - - +solution e6 +id "ECM.678" +go +setboard rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - +solution Nxh7 +id "ECM.679" +go +setboard 3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - +solution Bxh7+ +id "ECM.680" +go +setboard 1r2nrkb/2n2p1p/p2p1Pp1/P1pPp1P1/1pP1P1q1/1P1BB1N1/3Q4/2KR3R w - - +solution Rxh7 +id "ECM.681" +go +setboard 2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - +solution Bxh7+ +id "ECM.682" +go +setboard r2q3r/2pkb1p1/p2p1n2/4p1p1/Pp2P1P1/1QP5/1P1P2PP/RNB2RK1 b - - +solution Rxh2 +id "ECM.683" +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +solution Nxh7 +id "ECM.684" +go +setboard 2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - +solution Rxh7 +id "ECM.685" +go +setboard r2qn1k1/pb4Pp/1pn5/2p5/2P2p2/P1PB4/5PPP/R2Q1RK1 w - - +solution Bxh7+ +id "ECM.686" +go +setboard r4rk1/pp1n1ppp/3qp3/3nN1P1/b2P4/P2B1Q2/3B1P1P/1R2R1K1 w - - +solution Bxh7+ +id "ECM.687" +go +setboard r2r2k1/ppqbbppp/4pn2/6N1/n1P4P/3B1N2/PP2QPP1/1KBR3R w - - +solution Nxh7 +id "ECM.688" +go +setboard r5k1/6bp/2q1p1p1/p2pP3/3P4/1rP2QP1/3B1PK1/2R4R w - - +solution Rxh7 +id "ECM.689" +go +setboard r6r/4ppk1/p2p1bp1/B2p4/3P2p1/QP2P3/P1R1qPPP/2R3K1 b - - +solution Rxh2 +id "ECM.690" +go +setboard 4nrk1/r4p1p/p2p2pQ/2pPpNPP/qpn1P3/5P1R/PPP1N3/2K3R1 w - - +solution Qxh7+ +id "ECM.691" +go +setboard r3k2r/1b1n1p2/pq1p1bp1/1p4p1/P3P3/1NN5/1PP3PP/R2QRB1K b kq - +solution Rxh2+ +id "ECM.692" +go +setboard r2qrnk1/4bppp/b1p5/1p1p2P1/p2P1N1P/2NBP3/PPQ2P2/2K3RR w - - +solution Bxh7+ +id "ECM.693" +go +setboard rn1q1rk1/pppbb1pp/4p3/3pP1p1/3P3P/2NB4/PPP2PP1/R2QK2R w KQ - +solution Bxh7+ +id "ECM.694" +go +setboard 1r2nr1k/6pp/pp1p1p2/2pPnN2/q1P1PB2/5PR1/4K1P1/2Q4R w - - +solution Bxe5 +id "ECM.695" +go +setboard 3r1rk1/4qp1p/p1bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxh2+ +id "ECM.696" +go +setboard r2q1rk1/3n1ppp/8/1pbP2P1/p1N4P/PnBBPQ2/5P2/R3K2R w KQ - +solution Bxh7+ +id "ECM.697" +go +setboard 2k3r1/ppq2p1p/n1Pb1p2/8/6r1/4BN1b/PPQ2PPP/R3RBK1 b - - +solution Bxh2+ +id "ECM.698" +go +setboard 3qr1k1/1br2ppp/p2b4/8/PpNp4/3P4/1PP2PPP/R1BQ1RK1 b - - +solution Bxh2+ +id "ECM.699" +go +setboard 3r2k1/p1R2p2/4pQp1/1q5p/5P1P/1PR5/2Pr2P1/6K1 b - - +solution Rxg2+ +id "ECM.700" +go +setboard r1b4r/3p1kp1/pp3q1p/4RP2/8/B7/P5PP/4QRK1 w - - +solution Qe4 +id "ECM.701" +go +setboard 1r2rnk1/2R2bpp/p2q4/1p1N2R1/5P2/1Q1B3P/PP4P1/7K w - - +solution Rxg7+ +id "ECM.702" +go +setboard 3r2k1/pb5p/1p2qpp1/8/2p5/1P1nP3/P1N2PPP/1Q1R1R1K b - - +solution Bxg2+ +id "ECM.703" +go +setboard 4rrk1/2qb2pp/p5P1/1p2p3/1b2P3/2N5/PPPQ4/1K1R2R1 w - - +solution gxh7+ +id "ECM.704" +go +setboard 3q1k2/pp3ppn/2p1n2p/4pN1N/P3P2P/5Q2/1PP2PP1/6K1 w - - +solution Nhxg7 +id "ECM.705" +go +setboard 2r2r1k/3b1pb1/p3pp1p/q2p1P1B/8/2N2RR1/P1PQ2PP/7K w - - +solution Rxg7 +id "ECM.706" +go +setboard 5bk1/1p4p1/4N1R1/3p4/p1r2P1q/Pr1QP2P/1P6/1K4R1 w - - +solution Rxg7+ +id "ECM.707" +go +setboard 2r1r1k1/5ppp/p3pn2/1pb1N3/2P5/1PQ3R1/PB2qPPP/3R2K1 w - - +solution Rxg7+ +id "ECM.708" +go +setboard 7k/1bp1P1p1/3p2rp/1pb2p1q/5P2/1BP2N1P/1P4P1/R1B2R1K b - - +solution Rxg2 +id "ECM.709" +go +setboard r1q1bk1r/1p3pp1/4pn1p/p3Q3/P1P2N2/1B4R1/1P3PPP/4R1K1 w - - +solution Rxg7 +id "ECM.710" +go +setboard r4rk1/p2n2p1/1q1Qpn1p/1P6/P6B/2p5/2B1KP1P/R5R1 w - - +solution Rxg7+ +id "ECM.711" +go +setboard r2qr1k1/1p3ppp/2pb4/2Np4/1P1P2bn/3BP3/2QN1PPP/1RR3K1 b - - +solution Nxg2 +id "ECM.712" +go +setboard r3r1k1/pp3pp1/3p4/2q4p/2P5/1PB2Q1P/n4PP1/3R1RK1 w - - +solution Bxg7 +id "ECM.713" +go +setboard r5k1/pn1q1rpp/2pp4/5R1N/bP6/4BQ2/P4PPP/2R3K1 w - - +solution Nxg7 +id "ECM.714" +go +setboard 3r1rk1/5pp1/pq1n1n1p/2pPR3/2B2P2/1PBQ2RP/P5P1/6K1 w - - +solution Rxg7+ +id "ECM.715" +go +setboard rn3rk1/ppq2ppp/2pb1nb1/5N2/2BP4/8/PPP1N1P1/R1B1QR1K w - - +solution Nxg7 +id "ECM.716" +go +setboard r1qb1r1k/2p3pp/p1n1bp2/1p1Np2Q/P3P3/1BP3R1/1P3PPP/R1B3K1 w - - +solution Rxg7 +id "ECM.717" +go +setboard r4rk1/5ppp/p2pbb2/3B3Q/qp2p3/4B3/PPP2P1P/2KR2R1 w - - +solution Rxg7+ +id "ECM.718" +go +setboard 4q1k1/1b3r1p/p4pp1/1p6/2P2n2/1P3N2/1B3PPP/R2Q3K b - - +solution Nxg2 +id "ECM.719" +go +setboard r2r3k/5bp1/2p2N2/5P1p/3q3Q/3B2R1/n5PP/3R3K w - - +solution Rxg7 +id "ECM.720" +go +setboard 4rrk1/2pn2pb/p1p1qp2/1pb1pN2/P3P1PN/1P1P4/1BP2PK1/R2Q3R w - - +solution Nxg7 +id "ECM.721" +go +setboard r3r1k1/p3bppp/q1b2n2/5Q2/1p1B4/1BNR4/PPP3PP/2K2R2 w - - +solution Rg3 +id "ECM.722" +go +setboard r4rk1/1p1q1ppp/p1b4B/8/2R3R1/P2P4/1b1N1QPP/6K1 w - - +solution Bxg7 +id "ECM.723" +go +setboard rq3rk1/3b1ppp/p2bp3/3pB2Q/8/1B5P/PP3PP1/2RR2K1 w - - +solution Bxg7 +id "ECM.724" +go +setboard 4kbr1/pp1bpp1p/3p1p2/3N4/1PBQP3/q7/P1r2PPP/R4RK1 b - - +solution Rxg2+ +id "ECM.725" +go +setboard 2r3k1/1p2R1p1/p3n2p/2pq4/7P/1P1P2P1/PB1Q3K/8 w - - +solution Bxg7 +id "ECM.726" +go +setboard 2rr2k1/4bppp/p1n1p3/3q4/1p1P2N1/2P3R1/P3QPPP/2B2RK1 w - - +solution Nh6+ +id "ECM.727" +go +setboard rq1r1bk1/1b3pp1/3pn2p/1n2BN1P/1P2P3/3R1NP1/3Q1PB1/2R3K1 w - - +solution Bxg7 +id "ECM.728" +go +setboard r1b5/ppqn2bk/3R2pp/2p2p2/2P1rN2/4BN2/PPQ2PPP/4R1K1 w - - +solution Rxg6 +id "ECM.729" +go +setboard 3q1r2/1p1b1pk1/pn5p/3pN1pQ/3P3P/2r3B1/P4PP1/3RR1K1 w - - +solution Nxf7 +id "ECM.730" +go +setboard r1bqkbnr/pp2ppp1/2p4p/3n2N1/2BP4/5N2/PPP2PPP/R1BQK2R w KQkq - +solution Nxf7 +id "ECM.731" +go +setboard r2qr1k1/1ppb1p1p/p1np2p1/7Q/3PP2b/1B2N2P/PP3PP1/R1B2RK1 w - - +solution Bxf7+ +id "ECM.732" +go +setboard 2r3k1/pbq1np1p/1p1b1Bp1/8/6QP/2P2N2/B4PP1/4R1K1 w - - +solution Bxf7+ +id "ECM.733" +go +setboard r3r1k1/1bqn1ppp/1pp2p2/8/3P4/1B4N1/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.734" +go +setboard r3r1k1/pp3ppp/8/1Nbp3q/3NnBn1/2P5/PPQ2PPP/3R1RK1 b - - +solution Ngxf2 +id "ECM.735" +go +setboard r2r2k1/1b2qpp1/1p2n3/p1b1p2p/4P1n1/PP1B2PP/1B1NQP2/R3NRK1 b - - +solution Nxf2 +id "ECM.736" +go +setboard r2qr1k1/1b2bp1p/p3p1p1/1p2N1Bn/3P4/P6Q/1P3PPP/RB2R1K1 w - - +solution Nxf7 +id "ECM.737" +go +setboard r5k1/1pp3pp/1b1p1r2/pN1P1n2/P1P3nq/6N1/1P1B1PQP/4RRK1 b - - +solution Nxf2 +id "ECM.738" +go +setboard 2rqnk1r/pp2bpp1/2p1pn1p/2P1N2P/3P1BP1/3BQ3/PP6/2K2R1R w - - +solution Nxf7 +id "ECM.739" +go +setboard 2rq1rk1/1b2bppp/p1n5/1p1BN3/5B2/P7/1P3PPP/R2Q1RK1 w - - +solution Nd7 +id "ECM.740" +go +setboard 3r1qrk/p1p5/bbp3pp/4p3/4Pp1N/2Pn3P/PPQN1PPB/R4RK1 b - - +solution Nxf2 +id "ECM.741" +go +setboard r2qr1k1/pb2bp1p/1pn1p1pB/8/2BP4/P1P2N2/4QPPP/3R1RK1 w - - +solution d5 +id "ECM.742" +go +setboard r3r1k1/1bq1nppp/p1np4/1ppBpN2/4P3/2PP1N2/PP3PPP/R2QR1K1 w - - +solution Bxf7+ +id "ECM.743" +go +setboard r5k1/p4ppp/3qpb2/1P2N3/1nBP4/1P5P/4QPP1/4R1K1 w - - +solution Nxf7 +id "ECM.744" +go +setboard r2qr1k1/1b1nbp1p/p3pp2/1p2N3/3P4/3B1N2/PP2QPPP/R2R2K1 w - - +solution Nxf7 +id "ECM.745" +go +setboard r3k2r/p1qb1p2/1p2p2p/3pPpN1/P1nP3Q/8/2P2PPP/R1B1R1K1 w kq - +solution Nxf7 +id "ECM.746" +go +setboard 3qNk2/5p1p/1r3p2/2p5/Q1pb4/3b2P1/P4PBP/4R1K1 b - - +solution Bxf2+ +id "ECM.747" +go +setboard 2r1r1k1/1pq1bp1p/p3pnp1/P2n2N1/7R/2P4P/1PB1QPP1/2B1R1K1 w - - +solution Nxf7 +id "ECM.748" +go +setboard r1bq2k1/pp1n1ppp/3b1n2/PQ1B3r/3N1P2/2N5/1PP3PP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.749" +go +setboard 2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - +solution Bxf7+ +id "ECM.750" +go +setboard r4rk1/ppRn1p2/6pb/2P1pq1p/3N4/P1QPn1Pb/1B1NPP1P/4R1KB b - - +solution Qxf2+ +id "ECM.751" +go +setboard r3kr2/1b2qp2/pp2p2N/4p2Q/8/2n5/P3B1PP/3R1R1K w q - +solution Nxf7 +id "ECM.752" +go +setboard b2r1rk1/pq2bpp1/1p2p2p/4N2n/2P2R2/1PB2N2/1P2QPPP/4R1K1 w - - +solution Rxf7 +id "ECM.753" +go +setboard rqb1k2r/1p1nbp1p/p4pp1/8/1PBN1P2/P1N1P3/7P/2RQ1RK1 w kq - +solution Bxf7+ +id "ECM.754" +go +setboard r2r2k1/4ppbp/5np1/p1q5/QnB1P3/5N2/1P3PPP/R1B2RK1 w - - +solution Bxf7+ +id "ECM.755" +go +setboard 1r2q1k1/p3pp2/3p1bp1/2pP2N1/8/P5PB/2Q2PK1/1rBR4 w - - +solution Nxf7 +id "ECM.756" +go +setboard 2rqrbk1/pb1n1p1p/1p2pnp1/4N3/2BP1N2/1P2Q3/PB3PPP/3R1RK1 w - - +solution Nxf7 +id "ECM.757" +go +setboard 1r4k1/p4pp1/bqnrpn1p/2ppN3/2P2P1B/P3P3/1P2B1PP/1Q1R1RK1 w - - +solution Bxf6 +id "ECM.758" +go +setboard r1bqrbk1/5p1p/2pp2nB/pp5Q/4P3/PBNPR2P/1P4P1/R5K1 w - - +solution Bxf7+ +id "ECM.759" +go +setboard r1bqkb1r/1p3ppp/pn1P1n2/4p3/2B5/2N2N2/PP3PPP/R1BQ1RK1 w kq - +solution Bxf7+ +id "ECM.760" +go +setboard 2rqr1k1/pp2nppp/3p2b1/6B1/2BNn1Q1/P7/1PP2PPP/2KRR3 w - - +solution Bxf7+ +id "ECM.761" +go +setboard r3r1k1/pbq1ppbp/1pp2np1/4N3/3P4/2P5/PPB1QPPP/R1B1R1K1 w - - +solution Nxf7 +id "ECM.762" +go +setboard r1b2rk1/p6p/2p3Pb/3pp1q1/8/2PB4/PP3PP1/RN1Q1K1R b - - +solution Rxf2+ +id "ECM.763" +go +setboard r2rn3/1p3pk1/p1pNn1pp/q3P3/P7/1PN4P/2QR1PP1/3R2K1 w - - +solution Nxf7 +id "ECM.764" +go +setboard r1bqr1k1/1p1nnpb1/p5pp/2P1p1B1/B3N3/5N2/P4PPP/2RQR1K1 w - - +solution Nd6 +id "ECM.765" +go +setboard r1b1r1k1/pp2qpbp/2p3p1/2P5/3NnB2/7P/PPQ1PPB1/2RR2K1 b - - +solution Nxf2 +id "ECM.766" +go +setboard rn2r1k1/pp3p1p/3P2p1/2p1bbB1/2B5/2N5/Pq4PP/R2Q1RK1 w - - +solution Bxf7+ +id "ECM.767" +go +setboard 5rk1/r2qnppp/p1nN4/2Q5/3PB3/4P3/6PP/R4RK1 w - - +solution Nxf7 +id "ECM.768" +go +setboard 1bq2k2/1b1n1pp1/pp5p/2pBpN2/P3P2B/3Q1P2/1PP3PP/4K3 w - - +solution Bxf7 +id "ECM.769" +go +setboard rnb2rk1/pp3pbp/2p3pB/2q5/4P3/1BN5/PPP3PP/R2Q1R1K w - - +solution Rxf7 +id "ECM.770" +go +setboard 3qr1k1/1br1bp1p/p3p1pB/1p1nN3/3PB3/7Q/PP3PPP/3RR1K1 w - - +solution Nxf7 +id "ECM.771" +go +setboard 1qr1b1k1/4bpp1/pn2p2p/1p1nN3/3P4/P2BBN1Q/1P3PPP/4R1K1 w - - +solution Bxh6 +id "ECM.772" +go +setboard rr1q2k1/1p2bpp1/2p1p2p/P1Pn4/2NP4/3Q1RP1/5PKP/2B1R3 w - - +solution Bxh6 +id "ECM.773" +go +setboard r2r2k1/pb1nbpp1/1qp1pn1p/1p2N3/3P1B2/P1N1P3/BPQ2PPP/2R2RK1 w - - +solution Bxh6 +id "ECM.774" +go +setboard 2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - +solution Rxh6+ +id "ECM.775" +go +setboard r1b1r3/pp2Npbk/3pp2p/q5p1/2QNPP2/6P1/PPP3P1/2KR3R w - - +solution Ndf5 +id "ECM.776" +go +setboard r1q3r1/1ppQ2pk/3bNp1p/p3pP2/P3P3/7R/1PP3PP/3R2K1 w - - +solution Rxh6+ +id "ECM.777" +go +setboard 4r1k1/p1pq1pp1/2p5/3p1b2/Q7/2P1B2P/P1P1rPP1/2R2RK1 b - - +solution Bxh3 +id "ECM.778" +go +setboard 1rbqnr2/5p1k/p1np3p/1p1Np3/4P2P/1Q2B3/PPP1BP2/2KR3R w - - +solution Bxh6 +id "ECM.779" +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.780" +go +setboard 3r1r1k/p5p1/n1p2p1p/1qp2b2/N1R4R/1PB1P1P1/P2P3P/3Q2K1 w - - +solution Rxh6+ +id "ECM.781" +go +setboard r4rk1/2q1b1p1/p4p1p/n3pP2/1p2Q1N1/4B3/PPP3PP/4RR1K w - - +solution Nxh6+ +id "ECM.782" +go +setboard 6rk/3b1n1p/1p1q3b/1PpNp3/2P1Pp2/2Q2NrP/5RP1/2R2B1K b - - +solution Bxh3 +id "ECM.783" +go +setboard r2q1rk1/ppp2pp1/1b2b2p/3n3Q/2Bp4/3P1N2/PPP2PPP/R1B1R1K1 w - - +solution Bxh6 +id "ECM.784" +go +setboard r3rbk1/1bp1qpp1/p6p/np2p2Q/4P2N/1BP4P/PP3PP1/R1B1R1K1 w - - +solution Bg5 +id "ECM.785" +go +setboard 4q3/p2r1ppk/R6p/3n4/3B1Q2/4P2P/5PP1/6K1 w - - +solution Rxh6+ +id "ECM.786" +go +setboard 7r/1p2qk2/pQ1p2p1/3Ppp2/P4b2/2P2PrP/1P2R1B1/4R2K b - - +solution Rhxh3+ +id "ECM.787" +go +setboard 5rk1/Qp5p/3pp1p1/4n3/2P1P2q/5r1P/P3NPP1/3R1RK1 b - - +solution Rxh3 +id "ECM.788" +go +setboard 2r1r1k1/pb1n1pp1/1p1qpn1p/4N1B1/2PP4/3B4/P2Q1PPP/3RR1K1 w - - +solution Bxh6 +id "ECM.789" +go +setboard 3q1rk1/p2bbpp1/1rn4p/1pp2P2/3pBBP1/3P3P/PPPQ3N/R4RK1 w - - +solution Bxh6 +id "ECM.790" +go +setboard 2br2k1/4qppp/p5r1/2pBp3/2P1Pn2/4Q2P/RP3PPK/1N4R1 b - - +solution Bxh3 +id "ECM.791" +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +solution Bxh6 +id "ECM.792" +go +setboard r5r1/pbn4k/1p1p1Ppp/2pPn3/4BQq1/1PN3P1/PB3PK1/3R1R2 w - - +solution Qxh6+ +id "ECM.793" +go +setboard r1b2rk1/pp2bpp1/4p2p/2q4Q/5nNB/2PB4/PP3PPP/2KR3R w - - +solution Nxh6+ +id "ECM.794" +go +setboard 6k1/p4ppp/1pn1b1rr/8/PBpPp2q/2P1P1NP/5PP1/RR3QK1 b - - +solution Bxh3 +id "ECM.795" +go +setboard r1b2rk1/1p3pp1/p5Pp/2bpPp1Q/3N4/1Pq1B1R1/2P4P/3R2K1 w - - +solution Bxh6 +id "ECM.796" +go +setboard r2r2k1/pp1n1bp1/2p2p1p/b4N2/q2BR3/2QB2PP/1PP5/2KR4 w - - +solution Nxh6+ +id "ECM.797" +go +setboard 3r2bk/1q4p1/p2P1N1p/2p1rP2/pb5R/7P/1P4P1/2Q2RK1 w - - +solution Rxh6+ +id "ECM.798" +go +setboard 2b1rk2/r6p/1pP1p1p1/p2pNnR1/5Q2/P1B4q/1PP2P1P/1K4R1 w - - +solution Nxg6+ +id "ECM.799" +go +setboard 6R1/6Q1/3q2p1/5p1p/P3p1k1/1P1r2P1/5PK1/8 b - - +solution Rxg3+ +id "ECM.800" +go +setboard r6r/ppnqpk2/3pbpp1/5N2/1PP1P3/5RR1/P2QB1PP/6K1 w - - +solution Nh6+ +id "ECM.801" +go +setboard 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - +solution Rfxg6+ +id "ECM.802" +go +setboard 2b2r1k/2p3pp/2Nb4/pP5q/2PP4/P4pP1/5P1P/R1BQ2K1 b - - +solution Bxg3 +id "ECM.803" +go +setboard r1bq2k1/pp3r1p/2n1p1p1/3pP3/6Q1/2PB2P1/P4PK1/R1B4R w - - +solution Bxg6 +id "ECM.804" +go +setboard 3q1rk1/2r4p/n1p1n1pQ/p2pP3/Np1P2R1/5PN1/PP3KP1/2R5 w - - +solution Rxg6+ +id "ECM.805" +go +setboard 2Nq1rk1/6pp/b1p2b2/p6Q/np1p4/6P1/PB3PBP/R3R1K1 w - - +solution Be4 +id "ECM.806" +go +setboard r2r4/p4pk1/2p3p1/1p1nPR2/5p1Q/2N5/PPPq4/1K4R1 w - - +solution e6 +id "ECM.807" +go +setboard 2kr3r/pbq3p1/1p2pp2/2b4n/2P1B3/1P1N2Pp/PB2QP1P/R4RK1 b - - +solution Nxg3 +id "ECM.808" +go +setboard r5k1/1p2Rpb1/3p1np1/2nP2B1/1qP5/1pN1Q2P/P5P1/1B4K1 w - - +solution Bxg6 +id "ECM.809" +go +setboard 2rqr1k1/pb2bp1p/1pn1pnpB/4N3/3P4/P1N3R1/1P3PPP/RB1Q2K1 w - - +solution Rxg6+ +id "ECM.810" +go +setboard 2r5/pp2qr1k/1nb3pp/2ppBp2/2P4P/3B2R1/P3QPP1/1R4K1 w - - +solution Rxg6 +id "ECM.811" +go +setboard 3rr3/3q1p1k/p2P2pp/1bp1b3/5N2/6QP/P1B3P1/3RR1K1 w - - +solution Bxg6+ +id "ECM.812" +go +setboard r2q1rk1/pp2ppb1/3pn1pQ/3R4/2P3B1/4BR2/PP4PP/6K1 w - - +solution Qxg6 +id "ECM.813" +go +setboard 1n1b1rk1/r4p1p/p1p2qpQ/P3Np2/2BP4/2P1R3/5PPP/R5K1 w - - +solution Rb1 +id "ECM.814" +go +setboard 6rk/pb3p1p/3bpPq1/3P4/1p1B3r/1B4P1/PPRQ1R1P/6K1 b - - +solution Bxg3 +id "ECM.815" +go +setboard 3rr1k1/pb2bp1p/3qp1pB/1p2N3/3P2Q1/2P1R3/P4PPP/4R1K1 w - - +solution Nxg6 +id "ECM.816" +go +setboard r2q1rk1/pb1nbp1p/1p2p1p1/4N1BQ/2PP4/P7/5PPP/RB2R1K1 w - - +solution Nxg6 +id "ECM.817" +go +setboard 1Q4R1/r2qbp2/3p1kp1/3Bp2p/8/3PP1P1/5PKP/8 w - - +solution Rxg6+ +id "ECM.818" +go +setboard r3r1k1/b1p2pn1/p2q1Bp1/1p1bN1Qp/3P4/2P4P/PPB2PP1/R3R1K1 w - - +solution Nxg6 +id "ECM.819" +go +setboard 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - +solution Nxe6 +id "ECM.820" +go +setboard k2r3r/ppq2p1p/n1pb1Pp1/4p3/2Q5/1R2B1P1/PPP2PBP/R5K1 w - - +solution Rxb7 +id "ECM.821" +go +setboard 1rb2rk1/p1p1qppp/2p2n2/3P4/1b3P2/2NB4/PPPBQ1PP/2KR3R b - - +solution Ba3 +id "ECM.822" +go +setboard k7/pp1N4/4P3/5P2/8/5p2/1R6/B4Knq w - - +solution Nb6+ +id "ECM.823" +go +setboard 4rrk1/p5pp/1p4q1/3p2n1/2pP2P1/P1P1PP2/3B2K1/1R2QR2 b - - +solution Nxf3 +id "ECM.824" +go +setboard 1q1r3k/3P1pp1/ppBR1n1p/4Q2P/P4P2/8/5PK1/8 w - - +solution Rxf6 +id "ECM.825" +go +setboard 1rbq2k1/b1p3pp/p1Pp4/3Ppr2/8/5N2/PPQ2PPP/R1B2RK1 b - - +solution Rxf3 +id "ECM.826" +go +setboard 1r1q1r1k/2p3pp/1p1bQ3/p7/1PP5/Pn3B2/1B3PPP/R4RK1 b - - +solution Rxf3 +id "ECM.827" +go +setboard r4rk1/2p1qpp1/p1p5/2Ppn2b/2PQ1N1p/4P3/PB3PPP/R4RK1 b - - +solution Nf3+ +id "ECM.828" +go +setboard r1bq1rk1/1p2bppp/p3p3/n3P3/4N3/1P1P1N2/PB4PP/R3QR1K w - - +solution Nf6+ +id "ECM.829" +go +setboard 1n2r3/p1pq1kp1/1b1pNpp1/3P4/5RP1/3Q3P/1B3P2/6K1 w - - +solution Bxf6 +id "ECM.830" +go +setboard r1bq1rk1/ppp3p1/7p/3P2n1/2PQ1p2/1N5P/PPP2PPK/R1B2R2 b - - +solution Nf3+ +id "ECM.831" +go +setboard 3r1b2/p4bkp/1p1P1p2/r3p1p1/2q1N3/2N2P2/1P1R2PP/2QR3K w - - +solution Nxf6 +id "ECM.832" +go +setboard rqbn1rk1/1p3ppp/p3p3/8/4NP2/8/PPP1BQPP/1K1R3R w - - +solution Nf6+ +id "ECM.833" +go +setboard r1b1kb1r/1p4pp/p2ppn2/8/2qNP3/2N1B3/PPP3PP/R2Q1RK1 w kq - +solution Rxf6 +id "ECM.834" +go +setboard 1rn5/p3Bk1p/1pq1bpp1/P3p3/1Q2P2P/2P3P1/5PB1/1R4K1 w - - +solution Bxf6 +id "ECM.835" +go +setboard 2nr2k1/1pq1bppp/p1p5/2p1P1PQ/2P1NP2/1PNR4/P6P/6K1 w - - +solution Nf6+ +id "ECM.836" +go +setboard 6nk/pn2qr1r/1pbp1p1p/2p1pPpN/P1P1P1PP/2PP3R/7Q/2BBK2R w K - +solution Nxf6 +id "ECM.837" +go +setboard 7r/4p1k1/p3Pppp/1p6/3N1R2/3PQ2P/qr4b1/5RK1 w - - +solution Rxf6 +id "ECM.838" +go +setboard r3k2r/1bq1bp2/p3p1pp/1p2P3/3NpP2/4B1Q1/PPP3PP/1K1R3R w kq - +solution Nxe6 +id "ECM.839" +go +setboard rnbqkb1r/pp1n1p2/4p1p1/1N1pP2p/1P4Q1/3B1N2/P1PB1PPP/R3K2R w KQkq - +solution Qxe6+ +id "ECM.840" +go +setboard r1b1kb1r/1p1n1ppp/p2ppn2/6BB/2qNP3/2N5/PPP2PPP/R2Q1RK1 w kq - +solution Nxe6 +id "ECM.841" +go +setboard r1b1k1nr/3n1p1p/1qpBp1p1/pp2b3/4PN2/PBN2Q2/1PP2PPP/2KR3R w kq - +solution Nxe6 +id "ECM.842" +go +setboard 2r2rk1/1b3ppp/pq2p3/1pbn2N1/3B3P/1B4P1/P1P1QP2/2KRR3 w - - +solution Qh5 +id "ECM.843" +go +setboard r3k2r/pp1n1pb1/1qn1p1p1/2p3Pp/4R2P/2NP2QB/PPPB1P2/2K1R3 w kq - +solution Rxe6+ +id "ECM.844" +go +setboard r3k2r/1q3ppp/p3p3/2b1P3/p2N1Q2/P7/1PP3PP/3R1R1K w kq - +solution Nxe6 +id "ECM.845" +go +setboard 3qr1k1/rp3pbp/2p3p1/3p1b2/N1nP4/P2NP3/1PQ2PPP/1BRR2K1 b - - +solution Rxe3 +id "ECM.846" +go +setboard rnbqkb1r/1p1n1pp1/p3p2p/3pP3/3p1NQP/2N5/P1PB1PP1/R3KB1R w KQkq - +solution Nxe6 +id "ECM.847" +go +setboard 3r1b1R/3bkpp1/1p1np3/1BqpPPP1/PQ1N4/8/1PP5/1K6 w - - +solution f6+ +id "ECM.848" +go +setboard 4r1k1/pp2n2p/1r1n1bp1/q2p1pB1/3P3N/P1NQ1P1P/1PP3R1/1K5R b - - +solution Rxb2+ +id "ECM.849" +go +setboard 3r2k1/2p1bppp/4b3/p2pP3/qr1N1B1P/8/1PPQ2P1/1K1RR3 b - - +solution Rxb2+ +id "ECM.850" +go +setboard 1k1r3r/ppR2ppp/1q2b3/1N6/4Q3/8/PP3PPP/4R1K1 w - - +solution Rxb7+ +id "ECM.851" +go +setboard 1r3rk1/5pbp/p2Pp1p1/q1n3P1/2p2P1P/2N1Q2R/PP6/1BKR4 b - - +solution Rxb2 +id "ECM.852" +go +setboard rr4k1/5p1p/n2p1npQ/q1pP4/6P1/2N2P1N/PP1R3P/2K4R b - - +solution Rxb2 +id "ECM.853" +go +setboard 1k2bb1r/1p3p1p/p2qpP1p/3pN3/3P1Q2/2RB2P1/PP3P1P/6K1 w - - +solution Qc1 +id "ECM.854" +go +setboard 1r4k1/1r3p2/p1p1b1pQ/q3P3/P7/bPN1R1P1/2P4P/1K1R1B2 b - - +solution Bxb3 +id "ECM.855" +go +setboard 5rk1/5rp1/p2qb3/R2Np2Q/3bP2B/7P/P5PK/1R6 b - - +solution Rf1 +id "ECM.856" +go +setboard 6k1/5p2/R3p1p1/1pq1PpB1/4nP2/5Q1P/P2r2PK/8 w - - +solution Ra8+ +id "ECM.857" +go +setboard 3r1rk1/p3q1pp/2Rb4/3P4/8/1P2Qp2/PB3PPP/3R2K1 b - - +solution Bxh2+ +id "ECM.858" +go +setboard 1r6/5pk1/p1b2qpp/P1P1n3/1N6/Q5NP/5PP1/3R2K1 b - - +solution Bxg2 +id "ECM.859" +go +setboard 1r4k1/1q3pb1/r1b3p1/pp1Qp3/P3P3/1B2BP2/1PP3P1/1K1R3R w - - +solution Qd8+ +id "ECM.860" +go +setboard 2R5/p3q1kp/6p1/3p4/b2P2p1/Pr4N1/5Q2/3K3R w - - +solution Nf5+ +id "ECM.861" +go +setboard 3r4/kb6/pp6/4R1pr/PPpq4/2N3Q1/2P3PP/3R3K b - - +solution Rf8 +id "ECM.862" +go +setboard 4r1k1/5p1p/4q1p1/8/Q5n1/3B2P1/P4P1P/2R3K1 b - - +solution Nxf2 +id "ECM.863" +go +setboard 8/2q1np1k/6p1/1PPn3p/8/P2Q3P/6P1/2R4K b - - +solution Nf5 +id "ECM.864" +go +setboard r1bq1rk1/ppp1n1bn/3p2p1/3Pp1Pp/1PP1Pp1P/2NN1P2/P3B3/R1BQ1RK1 b - - +solution Nxg5 +id "ECM.865" +go +setboard 7R/1p1r4/2b2p2/2Pp1qk1/3P1bp1/3N4/2Q2PB1/6K1 w - - +solution Rg8+ +id "ECM.866" +go +setboard r6r/1pn1b1k1/2p1pq2/2Pp3p/p2P1Pp1/P2BP1P1/1P2QB2/3R2KR w - - +solution Rxh5 +id "ECM.867" +go +setboard 1r4k1/pp4pp/2n1b3/1Rq1p3/2P2r2/P1B2P2/2Q1B1PP/3R1K2 b - - +solution Rxf3+ +id "ECM.868" +go +setboard 7k/1p4p1/2p4r/5p2/p1QP1q2/2P2PR1/r4P1P/4R2K b - - +solution Rxh2+ +id "ECM.869" +go +setboard 1r3r2/6kp/3p1pp1/qnp1pP2/1p2P2N/3P4/PPPQ1P1P/1K1R2R1 w - - +solution fxg6 +id "ECM.870" +go +setboard 5rk1/1rP3pp/p4n2/3Pp3/1P2Pq2/2Q4P/P5P1/R3R1K1 b - - +solution Rxc7 +id "ECM.871" +go +setboard 2rq1rk1/5ppp/2b1pb2/np6/6N1/2NBB3/PP3PPP/R2Q2K1 w - - +solution Bb6 +id "ECM.872" +go +setboard 5r2/p2p2kp/3PnNp1/1qr1Pp2/2p5/P1R5/6PP/2Q1R1K1 w - - +solution Qh6+ +id "ECM.873" +go +setboard 2Qbq1k1/6p1/1p4Np/4p2P/3rP3/8/3p2PK/3R4 w - - +solution Rf1 +id "ECM.874" +go +setboard 2kr1br1/ppp2p1p/2n1p1q1/2Nn4/3P4/1Q2PB2/PP1B1P1P/2R1K2R b K - +solution Qg1+ +id "ECM.875" +go +setboard 2K5/6p1/kp2P3/1p6/1P6/2P1P2p/8/1r6 w - - +solution e7 +id "ECM.876" +go +setboard 2kr3r/1Rp1bpp1/p6q/Q3P3/2P5/3p1NP1/P3P2P/1R4K1 b - - +solution Qe3+ +id "ECM.877" +go +setboard 6k1/1R4pp/2p5/8/P1rNp3/6Pb/4PK2/8 w - - +solution a5 +id "ECM.878" +go +setboard r2r2k1/pp3ppp/2q5/2p5/2P1P1n1/P4P1b/1BQ1BP1P/R3R2K b - - +solution Rd2 +id "ECM.879" +gosetboard 8/6p1/7k/8/1K6/8/1P6/8 w - - +id "MES.0001" +solution Kc5 +go +setboard 8/8/8/2p5/8/8/1kP5/3K4 w - - +id "MES.0002" +solution c4 +go +setboard 7K/8/k1P5/7p/8/8/8/8 w - - +id "MES.0003" +solution Kg7 +go +setboard 8/8/1p6/8/8/P7/8/5k1K w - - +id "MES.0004" +solution Kh2 +go +setboard 8/8/8/8/8/P4p2/k6K/8 w - - +id "MES.0005" +solution a4 +go +setboard 8/8/6p1/1k6/4K3/8/5P2/8 w - - +id "MES.0006" +solution Kd4 +go +setboard 5k2/6p1/7p/8/7P/7K/8/8 w - - +id "MES.0007" +solution Kg3 +go +setboard 8/8/1kpp4/8/2P5/2K5/8/8 w - - +id "MES.0008" +solution Kc2 +go +setboard 8/5p2/1p6/1P2K2k/8/8/8/8 w - - +id "MES.0009" +solution Kf5 +go +setboard 8/8/8/4p1p1/8/5P2/6K1/3k4 w - - +id "MES.0010" +solution Kh1 +go +setboard 8/2p4K/8/7k/8/8/6PP/8 w - - +id "MES.0011" +solution g4+ +go +setboard 4k3/4p3/4P3/4P3/8/8/2K5/8 w - - +id "MES.0012" +solution Kd3 +go +setboard K7/8/1k6/1p6/8/2P5/1P6/8 w - - +id "MES.0013" +solution b3 +go +setboard 7k/5K2/7P/6pP/8/8/8/8 w - - +id "MES.0014" +solution Kf6 +go +setboard 8/p7/P7/8/8/4k3/4P3/4K3 w - - +id "MES.0015" +solution Kf1 +go +setboard 8/k7/3p4/6K1/2P1P3/8/8/8 w - - +id "MES.0016" +solution Kg6 +go +setboard K1k5/7p/8/2P5/8/8/P7/8 w - - +id "MES.0017" +solution c6 +go +setboard 8/5p2/5p2/5p2/8/4K3/7P/7k w - - +id "MES.0018" +solution h4 +go +setboard 8/6p1/k1P2p1p/7K/8/8/8/8 w - - +id "MES.0019" +solution Kg6 +go +setboard 2k5/3p4/P7/Pp6/8/4K3/8/8 w - - +id "MES.0020" +solution Kd4 +go +setboard 8/1p2pk2/1P6/8/4P3/8/6K1/8 w - - +id "MES.0021" +solution Kg3 +go +setboard 8/3Pk1p1/8/1K3Pp1/8/8/8/8 w - - +id "MES.0022" +solution Kc6 +go +setboard 8/5p2/7k/6p1/5P1P/8/8/7K w - - +id "MES.0023" +solution hxg5+ +go +setboard 4k3/8/3p4/p6K/P5P1/8/8/8 w - - +id "MES.0024" +solution Kg5 +go +setboard 8/2p1Pk2/5P2/8/3p1K2/8/8/8 w - - +id "MES.0025" +solution Kf3 +go +setboard 1k1K4/1p5P/1P6/8/8/8/p7/8 w - - +id "MES.0026" +solution h8=Q +go +setboard k7/5K2/8/8/7p/p6P/P7/8 w - - +id "MES.0027" +solution Ke6 +go +setboard 8/p2p4/8/8/8/k7/5P1P/7K w - - +id "MES.0028" +solution f4 +go +setboard 8/8/1k1p4/8/P1P5/p7/8/3K4 w - - +id "MES.0029" +solution Kc2 +go +setboard 8/K3p3/5p2/5P2/8/8/2k1P3/8 w - - +id "MES.0030" +solution Kb6 +go +setboard 8/2K5/1p6/1P4k1/5p2/8/6P1/8 w - - +id "MES.0031" +solution Kc6 +go +setboard 8/5p2/5p2/8/5KP1/8/6P1/3k4 w - - +id "MES.0032" +solution Kf5 +go +setboard 8/8/4k1P1/4p1p1/4K3/3P4/8/8 w - - +id "MES.0033" +solution g7 +go +setboard 8/8/7p/p7/k1P2K2/8/P7/8 w - - +id "MES.0034" +solution a3 +go +setboard 8/8/1p1K4/Pp6/2k1p3/8/1P6/8 w - - +id "MES.0035" +solution a6 +go +setboard 3k4/3p3p/3p4/PK6/4P3/8/8/8 w - - +id "MES.0036" +solution Kb6 +go +setboard 7k/3p2p1/2p5/5P2/2P5/K7/8/8 w - - +id "MES.0037" +solution Kb4 +go +setboard 8/7p/3p4/8/6pP/8/4PK2/7k w - - +id "MES.0038" +solution Kg3 +go +setboard 8/8/K7/2p1k3/8/1p1p4/1P1P4/8 w - - +id "MES.0039" +solution Kb5 +go +setboard 8/8/2p5/k1p1K3/p1P5/P7/8/8 w - - +id "MES.0040" +solution Kf5 +go +setboard 8/8/1p1p3p/3P4/4K3/8/4P2k/8 w - - +id "MES.0041" +solution Kf3 +go +setboard 6K1/8/pp5p/8/7k/3PP3/8/8 w - - +id "MES.0042" +solution d4 +go +setboard K7/8/k7/6p1/6Pp/7p/7P/8 w - - +id "MES.0043" +solution Kb8 +go +setboard 2k5/3p2p1/2p5/2K5/5P2/8/2P5/8 w - - +id "MES.0044" +solution Kd6 +go +setboard 6k1/p7/3K2p1/1P5p/7P/8/8/8 w - - +id "MES.0045" +solution Kd5 +go +setboard 8/1K6/8/k4p2/4pp2/8/4PP2/8 w - - +id "MES.0046" +solution Kc6 +go +setboard 8/6p1/4K3/6k1/6P1/6pP/6P1/8 w - - +id "MES.0047" +solution Ke5 +go +setboard 8/K7/3pk3/8/p3P3/P7/1P6/8 w - - +id "MES.0048" +solution Kb8 +go +setboard 1k6/1p6/3p4/1P6/1P6/1P6/8/7K w - - +id "MES.0049" +solution Kg2 +go +setboard 8/6p1/8/5p1P/5P2/6P1/8/5K1k w - - +id "MES.0050" +solution Ke1 +go +setboard 8/2p5/3k4/1p1p1K2/8/1P1P4/2P5/8 w - - +id "MES.0051" +solution b4 +go +setboard 4K3/pk6/2p5/2P5/1pP4P/1P6/8/8 w - - +id "MES.0052" +solution Kd7 +go +setboard 8/2p5/3k3P/5pp1/5p2/1p5K/8/8 w - - +id "MES.0053" +solution h7 +go +setboard 8/8/6K1/k2p4/2p5/2P4p/3P3P/8 w - - +id "MES.0054" +solution Kf7 +go +setboard 8/8/1p3P1k/4P3/8/1p6/pK2P3/8 w - - +id "MES.0055" +solution e6 +go +setboard 8/4Pk2/5p2/8/K7/3p2p1/3P2P1/8 w - - +id "MES.0056" +solution Kb5 +go +setboard 8/1p6/8/5k1p/P1P3p1/8/5PK1/8 w - - +id "MES.0057" +solution a5 +go +setboard 4k3/5p1p/1p5P/6P1/P7/8/8/4K3 w - - +id "MES.0058" +solution Kd2 +go +setboard 5k2/5p1p/7P/6P1/p7/P7/8/1K6 w - - +id "MES.0059" +solution Kc2 +go +setboard K7/3p3p/3k4/8/6pP/8/P5P1/8 w - - +id "MES.0060" +solution Kb7 +go +setboard 1k6/1P6/2P5/P7/5ppp/8/6K1/8 w - - +id "MES.0061" +solution Kg1 +go +setboard 8/6p1/6pp/8/k4P2/6K1/6PP/8 w - - +id "MES.0062" +solution f5 +go +setboard 1k6/p3pp2/p7/P2KP3/P7/8/8/8 w - - +id "MES.0063" +solution e6 +go +setboard 8/1p6/8/P7/7p/1P2p2P/4P1k1/4K3 w - - +id "MES.0064" +solution b4 +go +setboard k7/P2K4/p7/1p4p1/1P4P1/6P1/8/8 w - - +id "MES.0065" +solution Kd6 +go +setboard 8/2p2p2/1p6/3P1k1K/P1P2P2/8/8/8 w - - +id "MES.0066" +solution c5 +go +setboard 2k2K2/2p5/P7/Pp1P4/8/7p/7P/8 w - - +id "MES.0067" +solution Ke7 +go +setboard 8/2pp4/8/2PP3k/4pPp1/4P1K1/8/8 w - - +id "MES.0068" +solution d6 +go +setboard 8/3p4/3P4/3p2pp/3P4/k4K1P/7P/8 w - - +id "MES.0069" +solution h4 +go +setboard 8/2p5/pp6/kP1P4/p3K3/P1P5/8/8 w - - +id "MES.0070" +solution d6 +go +setboard 8/5pp1/8/k2p1Pp1/P5P1/3P4/8/3K4 w - - +id "MES.0071" +solution Kc2 +go +setboard 8/2pp1k2/2p1pP2/4P3/5P2/6K1/5P2/8 w - - +id "MES.0072" +solution f5 +go +setboard 8/8/7p/2p2PP1/p1P5/p1K5/k2P4/8 w - - +id "MES.0073" +solution Kc2 +go +setboard 8/1p6/1p6/1k2K3/2p1p3/PpP1P3/1P6/8 w - - +id "MES.0074" +solution a4+ +go +setboard 7k/8/5PpK/Pp1P2pp/3P4/8/5p2/8 w - - +id "MES.0075" +solution a6 +go +setboard 8/1p5k/1P1p4/3p4/3Pp2p/2K1P2p/7P/8 w - - +id "MES.0076" +solution Kb2 +go +setboard 8/2pp2pp/8/2PP1P2/1p5k/8/PP4p1/6K1 w - - +id "MES.0077" +solution f6 +go +setboard 8/5k2/2p5/1pPp4/p2P2p1/P2P2P1/P5K1/8 w - - +id "MES.0078" +solution Kf1 +go +setboard 8/4p1p1/1k2p1p1/p3P1P1/P1p2P2/2P5/5P2/4K3 w - - +id "MES.0079" +solution Kd1 +go +setboard 3k4/1pp5/p4P1p/P1p1KP1P/2P4p/7P/2P5/8 w - - +id "MES.0080" +solution Ke6 +go +setboard 8/pp1pppp1/3p2p1/PP2P1P1/K1P4P/8/k7/8 w - - +id "MES.0081" +solution h5 +go +setboard K7/8/8/7p/N2k4/8/8/8 w - - +id "MES.0082" +solution Nb2 +go +setboard 7N/2K5/8/8/7p/2k5/8/8 w - - +id "MES.0083" +solution Nf7 +go +setboard 8/4k2N/7p/8/1p6/8/4K3/8 w - - +id "MES.0084" +solution Kd3 +go +setboard 7K/3k4/8/pN6/8/8/1P6/8 w - - +id "MES.0085" +solution Nd4 +go +setboard 8/8/8/8/5p2/4k1p1/4N1P1/5K2 w - - +id "MES.0086" +solution Ng1 +go +setboard 8/8/8/8/3p4/2k1p3/2N1P3/3K4 w - - +id "MES.0087" +solution Ne1 +go +setboard 5K2/5P2/8/8/kp3n2/8/P7/8 w - - +id "MES.0088" +solution Ke7 +go +setboard 8/8/8/4P3/3pp1K1/N2k4/8/8 w - - +id "MES.0089" +solution e6 +go +setboard 8/7K/6p1/7P/p7/8/3kN3/8 w - - +id "MES.0090" +solution h6 +go +setboard 8/8/5N2/6P1/5k2/5pp1/8/4K3 w - - +id "MES.0091" +solution g6 +go +setboard 8/3p4/3k1Np1/P4p2/5K2/8/8/8 w - - +id "MES.0092" +solution a6 +go +setboard 8/2p5/1p6/1K6/7k/7P/7P/6N1 w - - +id "MES.0093" +solution Kc6 +go +setboard 8/2kp1K2/6N1/3P4/p6P/8/8/8 w - - +id "MES.0094" +solution d6+ +go +setboard 4k3/7N/4P3/6P1/8/4p1p1/8/6K1 w - - +id "MES.0095" +solution Kf1 +go +setboard 8/8/p6k/8/3N4/PP1K4/7p/8 w - - +id "MES.0096" +solution Nf5+ +go +setboard 8/8/8/4N3/5p2/p4p2/5P1p/5K1k w - - +id "MES.0097" +solution Nd3 +go +setboard 1k6/p7/8/1p5P/8/2pK4/1P5n/8 w - - +id "MES.0098" +solution h6 +go +setboard 2k5/2P4K/1P3p2/6p1/6n1/8/5P2/8 w - - +id "MES.0099" +solution f3 +go +setboard 2n5/1k6/4pP2/4P3/2K5/7p/6P1/8 w - - +id "MES.0100" +solution f7 +go +setboard 2n5/8/1PkP4/P4p2/1K6/7P/8/8 w - - +id "MES.0101" +solution d7 +go +setboard 4k3/4Pp1p/3P1K2/6P1/8/p2n4/8/8 w - - +id "MES.0102" +solution g6 +go +setboard 8/6p1/6Pp/5p2/5P1K/2p5/3k3P/7N w - - +id "MES.0103" +solution Ng3 +go +setboard 4n2k/7P/5P1p/6p1/2K3P1/5P2/8/8 w - - +id "MES.0104" +solution Kd5 +go +setboard 6K1/p7/4ppkp/7p/2PP1P1p/7P/P2P4/4n3 w - - +id "MES.0105" +solution d5 +go +setboard 8/7K/7P/1P6/2n4k/4n3/1P6/8 w - - +id "MES.0106" +solution Kg6 +go +setboard 8/p2P4/k7/P4P2/nKPn4/8/8/8 w - - +id "MES.0107" +solution d8=N +go +setboard 8/5N1N/8/8/1P6/2K4k/6p1/8 w - - +id "MES.0108" +solution Nhg5+ +go +setboard 1K6/N7/k7/8/6N1/1pp5/1P6/8 w - - +id "MES.0109" +solution Ne5 +go +setboard 5K2/7k/8/6P1/8/pp1N3N/8/8 w - - +id "MES.0110" +solution Ndf4 +go +setboard 8/3N4/5p2/8/4PK2/8/5Pp1/1N2k3 w - - +id "MES.0111" +solution Nd2 +go +setboard 8/8/7p/3KNN1k/2p4p/8/3P2p1/8 w - - +id "MES.0112" +solution Kc6 +go +setboard 8/6p1/7p/6PN/3NK1k1/6Pp/6p1/8 w - - +id "MES.0113" +solution gxh6 +go +setboard 8/1p3p2/8/1KP1P3/3NkpP1/7p/2N2P2/8 w - - +id "MES.0114" +solution e6 +go +setboard 8/8/8/6K1/8/4N2p/5n1k/8 w - - +id "MES.0115" +solution Kh4 +go +setboard K2n4/8/P7/8/2k5/8/2N5/8 w - - +id "MES.0116" +solution Ka7 +go +setboard 8/1K6/P7/kn6/4N3/8/8/8 w - - +id "MES.0117" +solution Nc5 +go +setboard 8/K7/8/2P1N3/n3k3/2p5/8/8 w - - +id "MES.0118" +solution c6 +go +setboard 7k/4np2/8/4K2p/8/4N3/P7/8 w - - +id "MES.0119" +solution Kd6 +go +setboard 8/N1k1n3/6P1/1P2K3/8/1p6/8/8 w - - +id "MES.0120" +solution b6+ +go +setboard 8/2Pp4/1n1N4/8/8/K4Pk1/8/8 w - - +id "MES.0121" +solution Kb2 +go +setboard K7/8/1Np5/8/6k1/n7/P5P1/8 w - - +id "MES.0122" +solution Kb7 +go +setboard 3n4/8/2P5/8/5p2/p2N3k/7p/5K2 w - - +id "MES.0123" +solution Nf2+ +go +setboard 8/6N1/p5k1/3K4/1p1p4/1P6/8/2n5 w - - +id "MES.0124" +solution Ne6 +go +setboard 2n5/8/Pp5p/5N2/8/5k2/3P4/7K w - - +id "MES.0125" +solution d4 +go +setboard 7n/8/6pP/6P1/k1K5/p7/8/1N6 w - - +id "MES.0126" +solution Kd5 +go +setboard 3n4/3K4/8/1p6/pkN5/1P6/PP6/8 w - - +id "MES.0127" +solution Ne5 +go +setboard 4Nn2/8/3P4/kP2P3/5p2/5p2/8/2K5 w - - +id "MES.0128" +solution Kd1 +go +setboard 4k3/2p2nKP/3p4/3Ppp1N/8/8/8/8 w - - +id "MES.0129" +solution Nf6+ +go +setboard 1n4N1/8/4p1P1/kp2p3/p3P3/8/K7/8 w - - +id "MES.0130" +solution Ne7 +go +setboard n7/K5PP/2k5/8/8/1P1p2Np/6p1/8 w - - +id "MES.0131" +solution Ne2 +go +setboard 6N1/8/3P4/3n1P2/5p2/3K1k2/6n1/8 w - - +id "MES.0132" +solution f6 +go +setboard 4NN2/8/8/6Pk/8/5nK1/8/8 w - - +id "MES.0133" +solution g6 +go +setboard 8/8/2n1n3/8/6N1/5N2/K3p3/5k2 w - - +id "MES.0134" +solution Nf6 +go +setboard 7k/3NN3/8/4K3/8/nP1p4/1n4P1/8 w - - +id "MES.0135" +solution Kf6 +go +setboard 6K1/3p4/7k/3N4/4N2P/5nP1/8/4n3 w - - +id "MES.0136" +solution Nf4 +go +setboard 4k1N1/5n2/1P1p2P1/2n5/3N4/p7/8/3K4 w - - +id "MES.0137" +solution b7 +go +setboard 8/8/8/2k5/p1b5/8/1P1K4/8 w - - +id "MES.0138" +solution Kc2 +go +setboard 5K2/k7/4P1p1/8/8/8/4b3/8 w - - +id "MES.0139" +solution Ke7 +go +setboard 8/6b1/5k2/8/P3K1P1/8/8/8 w - - +id "MES.0140" +solution a5 +go +setboard 5K2/8/7P/5p2/1P6/8/3b4/k7 w - - +id "MES.0141" +solution h7 +go +setboard 3b4/5k2/3P1p1P/3K4/8/8/8/8 w - - +id "MES.0142" +solution Kc6 +go +setboard 8/8/1b5P/kP6/8/5K2/1P6/8 w - - +id "MES.0143" +solution Ke4 +go +setboard 1b6/5K2/7P/1kp5/1p6/8/3P4/8 w - - +id "MES.0144" +solution Ke6 +go +setboard K7/1P6/1kP5/3P4/8/8/1p5b/8 w - - +id "MES.0145" +solution d6 +go +setboard 8/1p6/8/P1K5/1P6/5b1P/4k3/8 w - - +id "MES.0146" +solution Kd4 +go +setboard 8/p7/8/1P2K3/P6P/5b2/5k2/8 w - - +id "MES.0147" +solution Kf5 +go +setboard K7/2P5/b4k1p/3P4/6P1/8/8/8 w - - +id "MES.0148" +solution d6 +go +setboard 8/p3p3/K2PkP2/1P6/5b2/8/8/8 w - - +id "MES.0149" +solution f7 +go +setboard 8/3k2K1/2p1p3/b5P1/3P1P2/8/8/8 w - - +id "MES.0150" +solution Kf7 +go +setboard 8/3Pb1p1/8/3P2P1/5P2/7k/4K3/8 w - - +id "MES.0151" +solution Kd3 +go +setboard 8/2p1p3/4Pb2/1P1P3k/4K2P/8/8/8 w - - +id "MES.0152" +solution d6 +go +setboard 8/b7/3K1p2/7P/1p5k/1P6/1PP4P/8 w - - +id "MES.0153" +solution h6 +go +setboard 5k2/8/5PP1/8/1p3p2/6P1/P4PpK/7b w - - +id "MES.0154" +solution Kg1 +go +setboard 4k1K1/3p2pP/p2P3P/P7/8/1p6/1p6/b7 w - - +id "MES.0155" +solution h8=R +go +setboard 8/8/2PK2p1/7p/p1b2P2/P5P1/2P2kP1/8 w - - +id "MES.0156" +solution g4 +go +setboard 7k/3K2pP/pb4P1/8/P6p/2p1p3/2P1P1P1/8 w - - +id "MES.0157" +solution Kd6 +go +setboard 8/5p1b/4pPkp/3pP2p/1p1P3P/1p2K2P/1P6/8 w - - +id "MES.0158" +solution Ke2 +go +setboard 6k1/3p4/8/8/8/B7/P7/7K w - - +id "MES.0159" +solution Bb4 +go +setboard 5k2/4p2p/6P1/3K4/8/4B3/8/8 w - - +id "MES.0160" +solution Bh6+ +go +setboard 8/5p1B/7P/1K6/1p6/p7/1k6/8 w - - +id "MES.0161" +solution Bc2 +go +setboard 5B2/p7/3p4/PPk5/8/8/4K3/8 w - - +id "MES.0162" +solution b6 +go +setboard 8/2p2B2/5PK1/3Pk3/8/7p/8/8 w - - +id "MES.0163" +solution d6 +go +setboard 8/B1p2p1P/8/4p3/8/k7/p2K4/8 w - - +id "MES.0164" +solution Bd4 +go +setboard 8/8/3p4/8/3B4/p7/p1P4p/5K1k w - - +id "MES.0165" +solution Ba1 +go +setboard 8/8/5p2/3P4/p1PK4/p7/k7/3B4 w - - +id "MES.0166" +solution Kc3 +go +setboard 8/8/5p2/5p2/5P2/3p3B/5k1P/3K4 w - - +id "MES.0167" +solution Bg2 +go +setboard 8/8/2pp4/2p2kp1/2K5/6P1/6P1/2B5 w - - +id "MES.0168" +solution Be3 +go +setboard 8/7p/6pP/1B4P1/pp6/1k1K4/8/8 w - - +id "MES.0169" +solution Be8 +go +setboard k7/pp1K4/P2B4/p7/P7/P7/8/8 w - - +id "MES.0170" +solution Kc8 +go +setboard 8/1p6/1P1p4/1K1p2B1/P2P4/6pp/1P6/5k2 w - - +id "MES.0171" +solution Bd2 +go +setboard 1k6/1p1p4/PK2p3/5p1p/6pP/8/8/5B2 w - - +id "MES.0172" +solution a7+ +go +setboard 5kB1/3p1P2/7K/2Pp1P1P/p6p/4P3/7P/8 w - - +id "MES.0173" +solution Kg6 +go +setboard 3k4/3p4/3P1P2/P6B/1p1p4/1KPP3p/1P3p2/8 w - - +id "MES.0174" +solution a6 +go +setboard 8/1p6/1P6/3p1p1p/p2PpPpk/2p1P2P/2P1B1P1/6K1 w - - +id "MES.0175" +solution Kf2 +go +setboard 8/8/8/2P4B/8/5K2/3k4/5b2 w - - +id "MES.0176" +solution c6 +go +setboard 8/8/2B5/7b/7k/2K5/1P6/8 w - - +id "MES.0177" +solution b4 +go +setboard 8/8/8/1P6/7b/7k/7B/7K w - - +id "MES.0178" +solution b6 +go +setboard B3K3/8/8/P1p5/8/8/2b4k/8 w - - +id "MES.0179" +solution a6 +go +setboard 8/8/B3P3/3k4/5K2/2P4b/8/8 w - - +id "MES.0180" +solution Bc8 +go +setboard 1K6/3p4/3P4/8/k7/1p6/8/1b5B w - - +id "MES.0181" +solution Bc6+ +go +setboard 8/8/7B/2P5/1p4p1/3k4/7K/4b3 w - - +id "MES.0182" +solution c6 +go +setboard k7/8/8/1p2P1p1/bK6/8/B7/8 w - - +id "MES.0183" +solution Bf7 +go +setboard 3B4/6b1/6P1/2p5/P1k5/8/8/5K2 w - - +id "MES.0184" +solution Ba5 +go +setboard 8/pB4Pb/4k3/8/K2P4/8/8/8 w - - +id "MES.0185" +solution Be4 +go +setboard 8/8/p7/p3b1B1/8/p7/1p2k3/1K6 w - - +id "MES.0186" +solution Be7 +go +setboard k2K4/8/6P1/2B5/5P2/p7/4p2b/8 w - - +id "MES.0187" +solution g7 +go +setboard B6k/6p1/2K3PP/8/4p3/8/6b1/8 w - - +id "MES.0188" +solution Kd6 +go +setboard 8/4k3/6b1/2p5/2BP4/p4K2/4P3/8 w - - +id "MES.0189" +solution Kf4 +go +setboard 8/8/2p2K2/5B1p/k7/8/2P1P3/1b6 w - - +id "MES.0190" +solution e4 +go +setboard 8/p7/P7/P7/P4B2/8/5k2/6bK w - - +id "MES.0191" +solution Bc7 +go +setboard 8/KPb5/8/P5p1/5p2/3k4/7P/2B5 w - - +id "MES.0192" +solution Ba3 +go +setboard 8/1k6/1b6/p3p2P/1B5p/P7/5P2/2K5 w - - +id "MES.0193" +solution h6 +go +setboard 5k2/P4P1K/1Pb2PB1/8/3p3p/8/8/8 w - - +id "MES.0194" +solution Bf5 +go +setboard 8/3p4/pp1B4/k7/p1P5/P1bp4/8/3K4 w - - +id "MES.0195" +solution Kc1 +go +setboard 1B6/3k4/3p4/1P6/p4b2/Pp6/1P1pK3/8 w - - +id "MES.0196" +solution b6 +go +setboard 1b6/3k3p/P1p5/2Pp3p/K2P3P/8/8/6B1 w - - +id "MES.0197" +solution a7 +go +setboard 8/8/8/3pk1K1/1p1p4/1PpP3b/2P1B2P/8 w - - +id "MES.0198" +solution Bg4 +go +setboard 7k/2b5/6P1/2p2P1K/2Pp4/p2P4/2p5/2B5 w - - +id "MES.0199" +solution f6 +go +setboard 6k1/4b2p/7B/6p1/3p2P1/3Pp1p1/2K1P1P1/8 w - - +id "MES.0200" +solution Kb3 +go +setboard 8/2p2b2/Pp1p4/4pp2/k7/2P5/1P2BPK1/8 w - - +id "MES.0201" +solution b3+ +go +setboard B4k1K/4pP1p/PP2P2P/8/8/p7/1p6/3b4 w - - +id "MES.0202" +solution Be4 +go +setboard 5k1K/7p/1Pb2P2/5P1B/p2Pp3/4P3/4P3/8 w - - +id "MES.0203" +solution Be8 +go +setboard 8/6p1/4ppb1/P1p1p3/1k6/3PP3/1PK3P1/5B2 w - - +id "MES.0204" +solution a6 +go +setboard 8/p1p2pp1/1pP3p1/7k/3PPb2/5P1P/8/3K2B1 w - - +id "MES.0205" +solution d5 +go +setboard 8/5b1P/8/4K1B1/1k6/8/p7/8 w - - +id "MES.0206" +solution Bd2+ +go +setboard 5b2/1B6/1P4k1/4P3/8/8/8/K7 w - - +id "MES.0207" +solution Be4+ +go +setboard 7B/7k/3p1Kp1/6P1/8/8/8/1b6 w - - +id "MES.0208" +solution Bg7 +go +setboard 8/1p6/8/8/4p3/1k1P4/5b2/KB6 w - - +id "MES.0209" +solution Ba2+ +go +setboard 3k4/1K6/1P6/5p2/B1p5/8/3b4/8 w - - +id "MES.0210" +solution Ka6 +go +setboard b7/8/3p4/P7/6p1/8/4KBk1/8 w - - +id "MES.0211" +solution Be3 +go +setboard 8/pkP3P1/3B4/8/3K4/1b6/8/8 w - - +id "MES.0212" +solution Kc3 +go +setboard 3k4/8/1p1P4/1B6/7b/5K2/7P/8 w - - +id "MES.0213" +solution Kf4 +go +setboard 4B3/8/4k3/P5p1/1PK5/8/8/4b3 w - - +id "MES.0214" +solution Kc5 +go +setboard 3K1k2/8/2P5/2p5/5P2/8/1B4p1/3b4 w - - +id "MES.0215" +solution c7 +go +setboard 8/2B3k1/2P5/6P1/4b2p/7K/7P/8 w - - +id "MES.0216" +solution Be5+ +go +setboard 8/1K6/1P6/8/4P3/1p1k4/5P2/6bB w - - +id "MES.0217" +solution Ka8 +go +setboard 3K4/3P1p1B/4k1p1/7p/5P2/b7/8/8 w - - +id "MES.0218" +solution f5+ +go +setboard 8/K3p3/8/1k1P1b2/1P6/BP6/1P6/8 w - - +id "MES.0219" +solution Kb8 +go +setboard 8/3pk3/6P1/P5Pp/5B2/1p5b/pP6/K7 w - - +id "MES.0220" +solution a6 +go +setboard 8/B4p2/2p5/P2p4/5P2/1K1k1P2/3P4/5b2 w - - +id "MES.0221" +solution a6 +go +setboard 8/2KB4/5pp1/1Pk1p1p1/4p3/7P/4P3/2b5 w - - +id "MES.0222" +solution b6 +go +setboard 8/3p3p/3B3k/P1Pp1p1P/8/8/5P2/1b5K w - - +id "MES.0223" +solution c6 +go +setboard 8/3p2p1/3P4/p1PkpP1P/K7/6B1/8/5b2 w - - +id "MES.0224" +solution h6 +go +setboard 8/5pp1/3k2p1/1p6/pPB5/P4Kb1/5PP1/8 w - - +id "MES.0225" +solution fxg3 +go +setboard 7b/1K2p3/7P/p4P2/1pk5/4P2p/1PP5/3B4 w - - +id "MES.0226" +solution Kc6 +go +setboard 8/pp3pb1/P1p5/2K1k2B/5p1p/3P4/3P2P1/8 w - - +id "MES.0227" +solution d4+ +go +setboard 1b6/5p1p/3k4/8/2Bp1pP1/1p1P4/1KPP3P/8 w - - +id "MES.0228" +solution Ba6 +go +setboard 8/p2p1Bp1/P2p4/1Pp3pP/4K1kp/8/6P1/6b1 w - - +id "MES.0229" +solution h6 +go +setboard 8/4B1pp/8/pp1PppP1/b3p3/P7/P3KP1P/2k5 w - - +id "MES.0230" +solution g6 +go +setboard 4B2K/6B1/8/8/8/8/2p5/3k4 w - - +id "MES.0231" +solution Bh5+ +go +setboard 3k2B1/p7/1p2K3/8/6P1/2P1p2p/1B6/8 w - - +id "MES.0232" +solution c4 +go +setboard 8/2B5/1p2p1B1/1P6/2K5/8/2p1pP2/2k5 w - - +id "MES.0233" +solution Kb3 +go +setboard Bk6/1Pp5/1p2p3/4P3/P7/1pK4p/8/B7 w - - +id "MES.0234" +solution a5 +go +setboard 1K6/2Pb4/1B5k/7P/5b2/2p5/8/8 w - - +id "MES.0235" +solution Bd4 +go +setboard 8/8/P2K1k2/7b/8/5B2/4P2p/2b5 w - - +id "MES.0236" +solution a7 +go +setboard b7/2k5/P5P1/8/8/b2B1p1K/7P/8 w - - +id "MES.0237" +solution g7 +go +setboard 8/3PP1P1/2b3P1/8/8/5kPp/5p1p/5BbK w - - +id "MES.0238" +solution d8=N +go +setboard 8/8/7k/5K1P/8/B1b5/B7/8 w - - +id "MES.0239" +solution Bc1+ +go +setboard 2b5/K7/4p1p1/1p6/1B2B3/8/8/3k4 w - - +id "MES.0240" +solution Kb8 +go +setboard 8/2B5/7k/3p4/8/1p2P3/6K1/b6B w - - +id "MES.0241" +solution Bf4+ +go +setboard 8/6p1/6p1/5k1P/3Bp3/4PPP1/3p1PBK/4b3 w - - +id "MES.0242" +solution h6 +go +setboard 8/6k1/1B6/4n3/8/7p/8/3K4 w - - +id "MES.0243" +solution Bg1 +go +setboard n6k/8/8/6P1/3K4/3B4/8/8 w - - +id "MES.0244" +solution Kc5 +go +setboard 6B1/5P2/5Knk/8/7P/8/8/8 w - - +id "MES.0245" +solution Ke6 +go +setboard 4k1B1/8/4P2p/3K4/7P/6np/8/8 w - - +id "MES.0246" +solution e7 +go +setboard 8/8/4p3/3k1P2/3p4/8/2P5/Bn3K2 w - - +id "MES.0247" +solution f6 +go +setboard 8/b7/k7/2P3pP/4p3/3N4/2K5/8 w - - +id "MES.0248" +solution h6 +go +setboard K6k/1p5B/6P1/1p6/8/4n3/2P5/8 w - - +id "MES.0249" +solution c3 +go +setboard 8/2P2n1B/8/5K2/8/3p4/3Pkp2/8 w - - +id "MES.0250" +solution Ke6 +go +setboard 8/B1p4p/2p5/8/P6k/8/2n2pK1/8 w - - +id "MES.0251" +solution Bc5 +go +setboard 6nk/2p4p/3B1P1P/5KpP/8/8/8/8 w - g6 +id "MES.0252" +solution hxg6 +go +setboard B1k5/5n1P/3P3P/4p2K/4p3/4p3/8/8 w - - +id "MES.0253" +solution Bb7+ +go +setboard 3B4/pp6/5p2/1P5n/k1K1pp2/7p/1P6/8 w - - +id "MES.0254" +solution Be7 +go +setboard 4nk2/2p2p2/7P/4B2p/2K2P1p/7p/5P2/8 w - - +id "MES.0255" +solution h7 +go +setboard 8/2p1p1pp/2P1P2k/6pP/p7/P4Bp1/1P4P1/n5K1 w - - +id "MES.0256" +solution Bd1 +go +setboard 3N4/8/8/3b3K/5p2/8/8/7k w - - +id "MES.0257" +solution Kg4 +go +setboard 8/2K5/bP4k1/3p4/3N4/8/8/8 w - - +id "MES.0258" +solution Nc6 +go +setboard 2b5/4N3/5P2/8/2k1K3/8/3p4/8 w - - +id "MES.0259" +solution Nd5 +go +setboard b7/2K5/8/N2P4/pk6/8/8/8 w - - +id "MES.0260" +solution d6 +go +setboard N2k4/p7/8/8/4K3/8/P7/6b1 w - - +id "MES.0261" +solution Kd5 +go +setboard 5b1N/8/5k2/8/K1P1nP2/8/8/8 w - - +id "MES.0262" +solution f5 +go +setboard 8/1p6/1Pb5/8/8/N5pk/8/6K1 w - - +id "MES.0263" +solution Nc2 +go +setboard 8/8/4p3/2bP4/8/8/p7/k2KN3 w - - +id "MES.0264" +solution Kc1 +go +setboard 8/8/2k4b/P7/8/8/2N2PKp/8 w - - +id "MES.0265" +solution Nd4+ +go +setboard 4k3/3p1N2/8/P1P4b/8/8/7K/8 w - - +id "MES.0266" +solution c6 +go +setboard 8/2k5/8/2P5/6N1/2K2p2/5P2/6b1 w - - +id "MES.0267" +solution Kd3 +go +setboard 8/pk6/pp6/5b2/2P5/8/3N1K2/8 w - - +id "MES.0268" +solution Nb3 +go +setboard 8/N4k2/2P2p1P/8/7p/5K2/2b5/8 w - - +id "MES.0269" +solution c7 +go +setboard K2b4/3P2pp/8/5PN1/8/6k1/8/8 w - - +id "MES.0270" +solution f6 +go +setboard 8/1pN2p2/1P6/8/2P5/5k2/b7/6K1 w - - +id "MES.0271" +solution c5 +go +setboard 8/8/8/P5PN/8/8/2bPK2p/6k1 w - - +id "MES.0272" +solution Ng3 +go +setboard 7k/7b/1P5N/6P1/7p/6pp/8/6K1 w - - +id "MES.0273" +solution Nf7+ +go +setboard 8/3k1p2/P1p4P/1p6/8/N1b5/5K2/8 w - - +id "MES.0274" +solution Nxb5 +go +setboard 7N/1pp5/8/P1P1k3/1p6/4K3/8/1b6 w - - +id "MES.0275" +solution c6 +go +setboard 8/2p3Kp/1p2P3/8/k7/8/1PN3b1/8 w - - +id "MES.0276" +solution b3+ +go +setboard 8/3pk3/5p2/P1P1P3/8/1b6/N7/6K1 w - - +id "MES.0277" +solution c6 +go +setboard 7k/7P/1p1P4/1p4pp/8/5P2/3N4/b1K5 w - - +id "MES.0278" +solution f4 +go +setboard 5b1k/4p1pP/4P1P1/1p6/8/1N6/2pP4/2K5 w - - +id "MES.0279" +solution d4 +go +setboard 8/5p2/p3p1P1/7b/Pk6/1p6/8/1KN5 w - - +id "MES.0280" +solution g7 +go +setboard 8/3pPp2/3p1k1K/5p2/1b1P3N/2P5/5p2/8 w - - +id "MES.0281" +solution Ng6 +go +setboard 8/8/P1p3N1/2Pb4/6p1/1P3pPp/8/2k2K2 w - - +id "MES.0282" +solution Ne5 +go +setboard 8/8/5b1P/1p1Pk3/1Pp1P3/6p1/3N2p1/6K1 w - - +id "MES.0283" +solution h7 +go +setboard 1k6/2p1NbP1/PpP5/1K6/2p3p1/3P4/8/8 w - - +id "MES.0284" +solution Nc8 +go +setboard 8/2k4N/p6p/5p1P/5p2/2p1pP1b/2P1P2P/6K1 w - - +id "MES.0285" +solution Ng5 +go +setboard 8/3k4/1K6/PP6/2b5/8/8/5n2 w - - +id "MES.0286" +solution Kb7 +go +setboard 1b2K3/1P6/6n1/1P2k3/8/8/8/8 w - - +id "MES.0287" +solution Kd8 +go +setboard 3n4/6k1/6P1/1KP5/8/8/8/3b4 w - - +id "MES.0288" +solution c6 +go +setboard 1n6/2k4K/5P2/3P1P2/8/8/8/4b3 w - - +id "MES.0289" +solution d6+ +go +setboard 8/P1n1kP2/4P3/2K5/8/8/8/3b4 w - - +id "MES.0290" +solution Kb6 +go +setboard 8/3n4/P4P2/4p3/K1p5/8/2k4b/8 w - - +id "MES.0291" +solution a7 +go +setboard 8/7P/2n1P1KP/3k4/8/3P4/1b6/8 w - - +id "MES.0292" +solution d4 +go +setboard 8/4K3/8/3k4/8/1N1B4/6p1/8 w - - +id "MES.0293" +solution Bc4+ +go +setboard 1NBk4/p2p4/8/3K4/8/8/8/8 w - - +id "MES.0294" +solution Bb7 +go +setboard 8/6B1/8/8/8/2N1p3/p7/k5K1 w - - +id "MES.0295" +solution Kf1 +go +setboard 8/6B1/8/1N6/8/4p3/p1k3K1/8 w - - +id "MES.0296" +solution Kf3 +go +setboard N7/1K6/8/8/2p5/5k1p/3B3P/8 w - - +id "MES.0297" +solution Kc6 +go +setboard 8/8/5N2/B1pK4/1p6/k7/8/8 w - - +id "MES.0298" +solution Ke4 +go +setboard 8/1p6/8/5N2/p1K4B/p7/2k5/8 w - - +id "MES.0299" +solution Nd4+ +go +setboard 8/1B6/8/8/6pp/7p/4K2k/1N6 w - - +id "MES.0300" +solution Ke1 +go +setboard 8/8/4k3/8/1p6/3BP3/2K3Np/8 w - - +id "MES.0301" +solution Nf4+ +go +setboard 8/8/8/1p6/2k3N1/4B3/p2PK3/8 w - - +id "MES.0302" +solution d3+ +go +setboard 8/8/8/3N4/8/p4K2/1pP5/3B2k1 w - - +id "MES.0303" +solution Nc3 +go +setboard 8/8/2P5/p7/K2p4/3k2N1/B1p5/8 w - - +id "MES.0304" +solution Bc4+ +go +setboard 8/1p1K4/1P4NB/6p1/8/4k3/6p1/8 w - - +id "MES.0305" +solution Bf8 +go +setboard 1N6/8/K7/3k4/3p3B/p7/2PP4/8 w - - +id "MES.0306" +solution Nc6 +go +setboard 2K2N2/2B5/p1p4p/2k5/2P5/7p/8/8 w - - +id "MES.0307" +solution Kb7 +go +setboard 8/8/B7/4p2N/5pp1/1kpK4/6P1/8 w - - +id "MES.0308" +solution Ng3 +go +setboard 8/8/8/4N3/8/B1k2p1p/4Pp1P/2K5 w - - +id "MES.0309" +solution Bb4+ +go +setboard 8/4B2p/8/3p3P/8/3Pk1K1/p7/6N1 w - - +id "MES.0310" +solution Bf6 +go +setboard 8/1kpB1p2/3p4/4pK2/N1P3p1/7p/5P2/8 w - - +id "MES.0311" +solution Nc5+ +go +setboard 8/4KBp1/1pp3p1/4k1P1/PP3p1N/P2p4/3P1pPP/8 w - - +id "MES.0312" +solution Nf3+ +go +setboard 7k/4p3/5p2/1p1p1p2/1PpP1PpB/1pP3P1/7P/6NK w - - +id "MES.0313" +solution Bxf6+ +go +setboard b7/7P/4P1kb/3PK3/8/n7/8/8 w - - +id "MES.0314" +solution h8=N+ +go +setboard 1k1K2n1/2p5/2PP1P2/bP6/P7/2n5/8/8 w - - +id "MES.0315" +solution b6 +go +setboard 4N3/2n5/1b6/8/k5p1/8/6P1/7K w - - +id "MES.0316" +solution Nf6 +go +setboard 5k2/1K4b1/5np1/P7/8/8/8/6N1 w - - +id "MES.0317" +solution a6 +go +setboard b6k/4n3/5P1K/3p4/5N2/8/8/8 w - - +id "MES.0318" +solution f7 +go +setboard 8/3b3p/pn2p3/6PP/PN3k1K/5P2/8/8 w - - +id "MES.0319" +solution g6 +go +setboard N7/P4n1P/p7/k4p2/1p2p1p1/7b/2P2K2/8 w - - +id "MES.0320" +solution Nb6 +go +setboard 3n4/8/4P3/7p/P3PP1p/3Pbk1P/2p4P/2N1K3 w - - +id "MES.0321" +solution e7 +go +setboard 8/8/8/7N/P5bb/K7/8/2k5 w - - +id "MES.0322" +solution Nf4 +go +setboard 8/8/1p6/k5P1/1p6/1p1N2b1/bK6/8 w - - +id "MES.0323" +solution Ka1 +go +setboard 8/4p3/P3p1NP/7p/K1kb4/7b/P4P2/8 w - - +id "MES.0324" +solution Nh4 +go +setboard 8/8/b5pn/4K3/8/5k2/B7/8 w - - +id "MES.0325" +solution Kf6 +go +setboard K6b/8/8/k3P3/7B/8/4n3/8 w - - +id "MES.0326" +solution e6 +go +setboard 5k2/3B2bK/6P1/8/2n5/8/6P1/8 w - - +id "MES.0327" +solution g3 +go +setboard 1kb5/3p4/P6p/1KB5/8/7P/8/n7 w - - +id "MES.0328" +solution Bd6+ +go +setboard 8/6p1/n4b1P/7P/p7/B3K3/8/4k3 w - - +id "MES.0329" +solution h7 +go +setboard 8/1B3pk1/3P4/6pP/n7/5K2/8/2b5 w - - +id "MES.0330" +solution d7 +go +setboard B5k1/6P1/7P/n3K2p/2b4P/8/8/8 w - - +id "MES.0331" +solution Kf6 +go +setboard 8/5P1K/3b4/8/6k1/1n4P1/1P4PB/8 w - - +id "MES.0332" +solution Kg8 +go +setboard 7b/B7/p2P4/7P/7k/8/P1n2KP1/8 w - - +id "MES.0333" +solution d7 +go +setboard 2b5/1pkp4/P1P1p3/1P3n2/8/6pp/6P1/6K1 w - - +id "MES.0334" +solution a7 +go +setboard 7B/1p3p1P/7n/7p/3K2p1/1P2P1Pp/1k2b3/8 w - - +id "MES.0335" +solution Kc5+ +go +setboard 8/pp5P/1p1p1P2/1K3b2/P2k4/8/p1pP4/1nB5 w - - +id "MES.0336" +solution f7 +go +setboard 2b5/P1n1Ppp1/P2p4/3P2PK/5k1P/8/4B2P/8 w - - +id "MES.0337" +solution g6 +go +setboard 8/2n2b1B/4p1pP/PP4p1/p5P1/3p2PK/3P4/7k w - - +id "MES.0338" +solution Bg8 +go +setboard 6k1/6pb/N5p1/K5N1/8/8/8/8 w - - +id "MES.0339" +solution Kb4 +go +setboard 8/8/N2b4/8/K2N4/pPk5/8/8 w - - +id "MES.0340" +solution Nb5+ +go +setboard K3b2N/8/2k3Np/7P/8/8/8/8 w - - +id "MES.0341" +solution Nf7 +go +setboard k4N2/8/1p3P2/pp6/8/K4b2/1N6/8 w - - +id "MES.0342" +solution Nc4 +go +setboard 1k6/2b5/p1Kpp3/P3PN2/8/2N5/8/8 w - - +id "MES.0343" +solution exd6 +go +setboard 8/7N/4p2P/p3p2P/P3P1k1/2p5/7p/2b1K2N w - - +id "MES.0344" +solution Nf6+ +go +setboard 1k4B1/8/8/n1K3N1/8/8/8/8 w - - +id "MES.0345" +solution Kb6 +go +setboard 8/8/8/8/1B2N3/8/k1K1n3/8 w - - +id "MES.0346" +solution Bc5 +go +setboard 8/8/4N1k1/8/5K2/8/B2n4/8 w - - +id "MES.0347" +solution Nd4 +go +setboard 8/8/7p/8/8/2N2K2/8/1B3nk1 w - - +id "MES.0348" +solution Ne2+ +go +setboard 8/8/8/NB6/8/5k2/2np3K/8 w - - +id "MES.0349" +solution Be8 +go +setboard n7/7k/4p3/B7/6N1/8/8/6K1 w - - +id "MES.0350" +solution Ne5 +go +setboard 8/8/8/8/8/p5pK/5B2/1Nn4k w - - +id "MES.0351" +solution Bd4 +go +setboard 8/4K2p/6kP/8/4N3/7B/8/n7 w - - +id "MES.0352" +solution Be6 +go +setboard 8/3N4/8/5K2/5B2/8/5Pp1/k3n3 w - - +id "MES.0353" +solution Bh2 +go +setboard 3N2n1/4p3/3P4/4k3/6K1/8/2B5/8 w - - +id "MES.0354" +solution Nf7+ +go +setboard 8/2N1k3/8/n7/B7/6p1/6Pp/7K w - - +id "MES.0355" +solution Ne8 +go +setboard 5B1k/7p/6P1/4NnP1/8/8/K4p2/8 w - - +id "MES.0356" +solution g7+ +go +setboard 8/8/p7/Pk6/p6p/3P1N2/8/K1n3B1 w - - +id "MES.0357" +solution Kb2 +go +setboard B7/1P1p2p1/k2n1P2/8/N5K1/8/6p1/8 w - - +id "MES.0358" +solution b8=N+ +go +setboard 8/3pB3/n4K1k/6N1/1p2P2p/1p6/1P4Pp/8 w - - +id "MES.0359" +solution Bf8+ +go +setboard 2n5/1P1p4/3P4/2B1P3/3P4/6p1/pp4P1/Nk5K w - - +id "MES.0360" +solution Ba3 +go +setboard nK6/2p3pk/1pp5/1P3NP1/5P2/1P4P1/p1B5/8 w - - +id "MES.0361" +solution Ne3+ +go +setboard 8/6B1/8/8/3N4/4k3/8/2b1K3 w - - +id "MES.0362" +solution Kd1 +go +setboard 1b5B/8/8/1N6/8/3k4/2p5/2K5 w - - +id "MES.0363" +solution Nc7 +go +setboard 3K4/8/8/4k3/8/N2bB3/p7/8 w - - +id "MES.0364" +solution Nb5 +go +setboard 1b6/8/1N4Pk/8/8/B6K/8/8 w - - +id "MES.0365" +solution Nd7 +go +setboard 7K/1b6/8/8/3P4/4k3/1B1N2p1/8 w - - +id "MES.0366" +solution d5 +go +setboard b6k/7p/2p5/8/8/2N5/3B4/1K6 w - - +id "MES.0367" +solution Bh6 +go +setboard 8/8/7k/8/7P/2p5/4KN2/3B2b1 w - - +id "MES.0368" +solution Nd3 +go +setboard 8/6P1/8/8/4k2K/8/2b4p/2N1B3 w - - +id "MES.0369" +solution g8=Q +go +setboard k7/8/B3P3/8/1K5b/8/4N2p/8 w - - +id "MES.0370" +solution Ng3 +go +setboard 8/5b2/8/6B1/3k4/K7/1P4p1/1N6 w - - +id "MES.0371" +solution Nd2 +go +setboard 1k6/2p5/B7/4Np2/8/8/6p1/6Kb w - - +id "MES.0372" +solution Nc6+ +go +setboard 8/4K1p1/3N4/5P2/4B3/1k6/3pb3/8 w - - +id "MES.0373" +solution f6 +go +setboard K7/2b5/3p1p2/4k3/4P3/4N3/8/2B5 w - - +id "MES.0374" +solution Kb7 +go +setboard 8/8/pp6/8/kb3Np1/7P/1K6/4B3 w - - +id "MES.0375" +solution Bxb4 +go +setboard 8/5N2/5pP1/7b/p7/8/1Pk5/4BK2 w - - +id "MES.0376" +solution Nh8 +go +setboard 8/8/6p1/7p/pb6/k6P/2P1pB2/NK6 w - - +id "MES.0377" +solution c3 +go +setboard 4K3/2k1Bp1N/6p1/5PP1/8/7p/b7/8 w - - +id "MES.0378" +solution Bf6 +go +setboard 4Bk2/1pp2p1K/3p4/P5Pb/4P3/5N2/8/8 w - - +id "MES.0379" +solution Bc6 +go +setboard 1b6/4P3/1P2PN2/8/2P5/P1k5/P1p2P2/K5B1 w - - +id "MES.0380" +solution Ne4+ +go +setboard 6b1/2p1B1P1/p1K5/k7/p6p/p1Np2p1/8/8 w - - +id "MES.0381" +solution Na2 +go +setboard 3k4/3p4/P2P2P1/p1p1P3/K3p3/3P3B/P3p2P/3N3b w - - +id "MES.0382" +solution Nc3 +go +setboard 8/1p1p4/1p1PPp2/1P1K1k1P/2PP4/4B2P/5pp1/6Nb w - - +id "MES.0383" +solution e7 +go +setboard 8/5BK1/8/8/p7/4B3/pn6/1k6 w - - +id "MES.0384" +solution Bg6+ +go +setboard 6K1/8/6B1/8/8/2B5/pP6/k2n4 w - - +id "MES.0385" +solution Bh8 +go +setboard 8/8/8/3kp3/3p4/P2B4/K1N3Np/8 w - - +id "MES.0386" +solution Nf4+ +go +setboard 8/B4p2/4Np2/8/3K1P2/7N/4p2k/8 w - - +id "MES.0387" +solution Ng1 +go +setboard 2N1k3/4p3/3pKp2/5p2/4NB2/pp6/8/8 w - - +id "MES.0388" +solution Nexd6+ +go +setboard 5N2/8/7B/8/2K5/1p1B4/p7/k7 w - - +id "MES.0389" +solution Bd2 +go +setboard 8/8/6bk/8/4nP2/4K3/4N3/4n3 w - - +id "MES.0390" +solution f5 +go +setboard 3kn1K1/1p6/P4b2/N2Pn3/8/6P1/8/8 w - - +id "MES.0391" +solution a7 +go +setboard 8/8/7N/1k5b/3P4/K3P3/2P5/n5b1 w - - +id "MES.0392" +solution Kb2 +go +setboard 8/8/P6P/5p2/8/1b6/nN4P1/k3b2K w - - +id "MES.0393" +solution Nd1 +go +setboard 2N2n2/8/1P4P1/1P3KP1/1b6/p7/8/k6b w - - +id "MES.0394" +solution g7 +go +setboard 2nn4/B7/KP1P4/8/3p3k/8/8/4b3 w - - +id "MES.0395" +solution b7 +go +setboard 6K1/8/Pp3p1k/1Pb4P/p2p3N/3P1PP1/4P3/3b4 w - - +id "MES.0396" +solution Nf5+ +go +setboard b7/7P/2p3np/2P3p1/1P4PP/2B3Pk/7p/6bK w - - +id "MES.0397" +solution h5 +go +setboard 3n2k1/3N4/7P/6N1/8/K7/7P/4b3 w - - +id "MES.0398" +solution Nf6+ +go +setboard 8/8/p5Pb/1kpbP3/5p2/1N6/1KPN4/8 w - - +id "MES.0399" +solution c4+ +go +setboard 2N5/5B2/8/4nk1K/6n1/4p3/8/8 w - - +id "MES.0400" +solution Ne7+ +go +setboard r3rnk1/4qpp1/p5np/4pQ2/Pb2N3/1B5P/1P3PP1/R1BR2K1 w - - +id "IQ.894" +solution Bxh6 +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +id "IQ.895" +solution Bxh6 +go +setboard 6rk/1p1br2p/pqp5/3pNP2/1P1Pp3/P5PR/5PKR/Q7 w - - +id "IQ.915" +solution Rxh7+ +go +setboard r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/5PPP/2R3K1 w - - +id "IQ.916" +solution Bxh7+ +go +setboard 3rk1nr/1p3q2/p1n2P1p/P1ppp3/3b4/2N2QPB/1PP4P/R1B2R1K w k - +id "IQ.917" +solution Nxd5 +go +setboard 3rk1nr/1p3q2/p1n2P1p/P1ppp3/3b4/2N2QPB/1PP4P/R1B2R1K w k - +id "IQ.918" +solution Nxd5 +go +setboard 6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - +id "IQ.919" +solution Rxh7+ +go +setboard 6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - +id "IQ.920" +solution Rxh7+ +go +setboard 6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - +id "IQ.921" +solution Rxh7+ +go +setboard r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - +id "IQ.922" +solution Nf5+ +go +setboard r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - +id "IQ.923" +solution Nf5+ +go +setboard r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - +id "IQ.924" +solution Nf5+ +go +setboard 3r2k1/5pp1/R2B3q/2Q5/1p2rP2/6Pp/1bP2K1P/3R4 w - - +id "IQ.925" +solution Be5 +go +setboard 1rb2r2/1p1nppk1/2p1n1p1/p3P2p/2qP3R/2N3NP/PP1Q2B1/5RK1 w - - +id "IQ.926" +solution Bd5 +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +id "IQ.927" +solution g6 +go +setboard 2qrrb2/pb3ppk/1npp3p/5N2/1p2n3/1P3NPB/PBPQ1P1P/3RR1K1 w - - +id "IQ.928" +solution Rxe4 Qf4 +go +setboard 3r2k1/1p3pp1/1p6/7p/q2NP1P1/2Q2P1b/rP5P/2RR2K1 w - - +id "IQ.929" +solution Nf5 +go +setboard 3r2k1/1p3pp1/1p6/7p/q2NP1P1/2Q2P1b/rP5P/2RR2K1 w - - +id "IQ.930" +solution Nf5 +go +setboard 2q1r2k/5R1p/pp1B2pN/2p1P3/1n1b4/3P2Q1/1P4K1/8 w - - +id "IQ.931" +solution Qh4 +go +setboard 2rr2k1/pb3p1p/1pq3p1/4R1N1/2n5/P4P2/BP2Q1PP/4R2K w - - +id "IQ.932" +solution Nxf7 Re7 +go +setboard 2r1b1k1/p1q1brp1/1p2p1QB/4p3/4N3/2PBR3/P4PPP/6K1 w - - +id "IQ.933" +solution Qh7+ +go +setboard 2r1b1k1/p1q1brp1/1p2p1QB/4p3/4N3/2PBR3/P4PPP/6K1 w - - +id "IQ.934" +solution Qh7+ +go +setboard r1b1rnk1/pp3ppp/3qp3/2pnNPB1/2BP4/2P5/P1P1Q1PP/3R1RK1 w - - +id "IQ.935" +solution Nxf7 +go +setboard 2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - +id "IQ.936" +solution Qxc7+ +go +setboard 2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - +id "IQ.937" +solution Qxc7+ +go +setboard 2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - +id "IQ.938" +solution Qxc7+ +go +setboard r1bq1rk1/pp1n1pp1/5n1p/2b1pN2/2B4B/2N1P3/PPQ2PPP/2KR3R w - - +id "IQ.939" +solution Nxh6+ +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +id "IQ.940" +solution Re6 +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +id "IQ.941" +solution Re6 +go +setboard 5rk1/q5pp/4p3/r1bp1p2/1p1B1P2/1P1QP3/P4RPP/2R3K1 w - - +id "IQ.943" +solution Rxc5 +go +setboard 5rk1/q5pp/4p3/r1bp1p2/1p1B1P2/1P1QP3/P4RPP/2R3K1 w - - +id "IQ.944" +solution Rxc5 +go +setboard 2R4Q/pp1bkp2/4p1r1/qN1p4/Pb6/4B3/1P3PPP/6K1 w - - +id "IQ.945" +solution Bb6 +go +setboard 2R4Q/pp1bkp2/4p1r1/qN1p4/Pb6/4B3/1P3PPP/6K1 w - - +id "IQ.946" +solution Bb6 +go +setboard 6k1/6p1/p3br2/1p2Q3/5r2/1P1B2R1/1P3qPP/2R4K w - - +id "IQ.947" +solution Rc8+ +go +setboard 6k1/6p1/p3br2/1p2Q3/5r2/1P1B2R1/1P3qPP/2R4K w - - +id "IQ.948" +solution Rc8+ +go +setboard 5r1k/1b1P3p/4Q1pb/8/P7/4N1PP/1P2r3/R2R2K1 w - - +id "IQ.949" +solution Qf6+ +go +setboard 5r1k/1b1P3p/4Q1pb/8/P7/4N1PP/1P2r3/R2R2K1 w - - +id "IQ.950" +solution Qf6+ +go +setboard 4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - +id "IQ.951" +solution Bd3 +go +setboard 4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - +id "IQ.952" +solution Bd3 +go +setboard 4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - +id "IQ.953" +solution Bd3 +go +setboard 2rq1r2/pp1b1pkp/8/P2Q2P1/n1nN4/2P5/2P3BP/R1B2RK1 w - - +id "IQ.954" +solution Rxa4 +go +setboard 2rq1r2/pp1b1pkp/8/P2Q2P1/n1nN4/2P5/2P3BP/R1B2RK1 w - - +id "IQ.955" +solution Rxa4 +go +setboard 2qr1r2/p2n1ppk/1p2p2p/5b2/2PP2NQ/1B4R1/P4PPP/R5K1 w - - +id "IQ.956" +solution Bc2 +go +setboard 2qr1r2/p2n1ppk/1p2p2p/5b2/2PP2NQ/1B4R1/P4PPP/R5K1 w - - +id "IQ.957" +solution Bc2 +go +setboard 1r2q1k1/1p6/pN2p1p1/P3p3/2PbQ3/1P5P/6P1/5R1K w - - +id "IQ.958" +solution Nd7 +go +setboard 1r2q1k1/1p6/pN2p1p1/P3p3/2PbQ3/1P5P/6P1/5R1K w - - +id "IQ.959" +solution Nd7 +go +setboard 6k1/pp2q2r/2r1p3/1RPpPpp1/3P4/P5P1/3Q1PK1/7R w - - +id "IQ.960" +solution Rxb7 +go +setboard k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - +id "IQ.961" +solution Qxc3 +go +setboard k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - +id "IQ.962" +solution Qxc3 +go +setboard k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - +id "IQ.963" +solution Qxc3 +go +setboard 2r1k1nr/3bbpp1/p2p2P1/4pP2/1pqNP3/2N1B3/PPP3Q1/1K1R2R1 w k - +id "IQ.964" +solution b3 Nd5 +go +setboard r6r/p1kn4/2p1b3/q3p1Qp/4P3/2PBB2P/P5P1/3R1RK1 w - - +id "IQ.965" +solution Bc4 +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +id "IQ.966" +solution Bf4 +go +setboard 4rk2/1p3r2/3q1nQp/1R1P2p1/P2pp3/3B2PP/1P3P2/2R3K1 w - - +id "IQ.967" +solution Qxh6+ Rxb7 +go +setboard r5k1/1p3pbp/2q1p1p1/p1p1P3/n1P5/P1B2N1P/1P2QPP1/3R2K1 w - - +id "IQ.968" +solution Bxa5 +go +setboard 1rb1r2k/3nq1b1/2p2pp1/p3p2p/P1B1P3/1P1RB1N1/2P2QPP/3R3K w - - +id "IQ.969" +solution Nf5 Rd6 +go +setboard 1rb1r2k/3nq1b1/2p2pp1/p3p2p/P1B1P3/1P1RB1N1/2P2QPP/3R3K w - - +id "IQ.970" +solution Nf5 Rd6 +go +setboard 4q1k1/p6p/1p2n2B/2p2rp1/2P5/2P2P2/P2Q2PP/4R1K1 w - - +id "IQ.971" +solution Rxe6 +go +setboard 4q1k1/p6p/1p2n2B/2p2rp1/2P5/2P2P2/P2Q2PP/4R1K1 w - - +id "IQ.972" +solution Rxe6 +go +setboard 4rbk1/1q3ppp/2Rr4/1p1P1B2/2b1PR2/p5P1/5P1P/B1Q3K1 w - - +id "IQ.973" +solution Bxh7+ Rxd6 Rh4 Bxg7 +go +setboard 6k1/p1p2pp1/2p1n1q1/1r2P3/4N1PQ/5P2/P6P/3R3K w - - +id "IQ.974" +solution Rd8+ +go +setboard r1b2r2/4ppkp/p2p1np1/qpn5/2PNP1P1/2N2P2/PP1QB2P/R3K2R w KQ - +id "IQ.975" +solution g5 cxb5 +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.976" +solution Qh6+ +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.977" +solution Qh6+ +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.978" +solution Qh6+ +go +setboard 2r3k1/pR5p/2ppNb2/1Q1P1ppP/4q3/4P1P1/5P2/6K1 w - - +id "IQ.979" +solution Rg7+ Qa6 +go +setboard 7R/5Q2/6pp/4rp1k/P3P3/5Pb1/4KPq1/3R4 w - - +id "IQ.980" +solution Rxh6+ +go +setboard rnb4r/p1pq1Pkp/1pn1p1p1/3p2N1/3P4/P1PB3Q/2P2PPP/R1B1K2R w KQ - +id "IQ.981" +solution Qh6+ +go +setboard r1r5/p2qnkbp/bp2ppp1/3p4/3P1P2/1Q1N1N1B/PP2PP1P/2R2RK1 w - - +id "IQ.982" +solution Nde5+ +go +setboard r1b2rk1/1p3pbn/p2p2p1/q1nPp2p/P3P3/2NBBPN1/1P1Q2PP/R4RK1 w - - +id "IQ.983" +solution b4 +go +setboard b3k3/2q1b1p1/p3p2r/1pPpP2p/1P1N3P/6P1/P3Q3/1BR3K1 w - - +id "IQ.984" +solution Bg6+ +go +setboard 8/2bP1Q1p/6pk/p3p3/P1Bp4/1P1R2KP/5PP1/2q4r w - - +id "IQ.985" +solution Re3 +go +setboard 8/2bP1Q1p/6pk/p3p3/P1Bp4/1P1R2KP/5PP1/2q4r w - - +id "IQ.987" +solution Re3 +go +setboard 2b1rqk1/2R2ppp/1p1P4/p3Q3/7P/P7/B4PP1/6K1 w - - +id "IQ.989" +solution Qxe8 +go +setboard r3k2r/pppqnpbp/4p1p1/3nP1B1/Q2PN2P/5P2/PP2BP2/2R1K1R1 w - - +id "IQ.990" +solution Nd6+ +go +setboard r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - +id "IQ.991" +solution Rxe5 +go +setboard 1q1rr1k1/pn5p/1p3pp1/1Q2b1B1/1P6/5B1P/P4PP1/2R1R1K1 w - - +id "IQ.992" +solution Rxe5 Bxf6 +go +setboard r2qrbk1/p2b2pp/1pn1pn2/3p4/2pP1P2/2P2NN1/PPQ3PP/RBB2RK1 w - - +id "IQ.993" +solution Ng5 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.994" +solution Bxa6 Bxf6 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.995" +solution Bxa6 Bxf6 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.996" +solution Bxa6 Bxf6 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.997" +solution Bxa6 Bxf6 +go +setboard r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - +id "IQ.998" +solution Rxd6 +go +setboard r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - +id "IQ.999" +solution Rxd6 +go +setboard r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - +id "IQ.1000" +solution Rxd6 +go +setboard r4rk1/5pp1/p2R1Bb1/1pq1Pp1p/7Q/1Bn5/P5PP/5R1K w - - +id "IQ.1001" +solution Bxg7 +go +setboard r4rk1/5pp1/p2R1Bb1/1pq1Pp1p/7Q/1Bn5/P5PP/5R1K w - - +id "IQ.1002" +solution Bxg7 +go +setboard 5r2/p4pkp/3bpNp1/q3n3/1r3B1Q/3p4/PPP2PPP/R4K1R w - - +id "IQ.1003" +solution Qh6+ +go +setboard r3r3/pp2bBkp/6p1/q3p2Q/4n3/2N2R2/PPP3PP/2KR4 w - - +id "IQ.1005" +solution Bxg6 +go +setboard r3r3/pp2bBkp/6p1/q3p2Q/4n3/2N2R2/PPP3PP/2KR4 w - - +id "IQ.1006" +solution Bxg6 +go +setboard 5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - +id "IQ.1007" +solution Nf7+ +go +setboard r2q1rk1/1p1bbppp/p1n1p3/2p1P2Q/4N3/6P1/PPPB1PBP/3RR1K1 w - - +id "IQ.1008" +solution Nf6+ +go +setboard r2q1rk1/1p1bbppp/p1n1p3/2p1P2Q/4N3/6P1/PPPB1PBP/3RR1K1 w - - +id "IQ.1009" +solution Nf6+ +go +setboard r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - +id "IQ.1010" +solution Rxh6 Nd3 +go +setboard r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - +id "IQ.1011" +solution Rxh6 Nd3 +go +setboard r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - +id "IQ.1012" +solution Rxh6 Nd3 +go +setboard r1b1rb2/1p3kpQ/p1p1p3/q1P1P3/3P4/4P1R1/PP4PP/R1B3K1 w - - +id "IQ.1013" +solution Bd2 +go +setboard 3r1r2/p4pk1/bp2p1P1/4P2p/Pq1N1P2/2p4Q/2P3P1/3RK2R w - - +id "IQ.1014" +solution Qxh5 +go +setboard 4Q2r/1b4pk/p1n1pr1p/1p2P2B/1qn5/5N2/PPP2PP1/2KRR3 w - - +id "IQ.1015" +solution Ng5+ +go +setboard 3q1rk1/p1r2pp1/1p2p2p/6bn/3PNn2/1B2BP2/PP1Q1P1R/6RK w - - +id "IQ.1016" +solution Rxh5 +go +setboard rr4k1/2q2ppp/p1b1p3/2b1pPPN/1p2P1R1/3B3Q/PPP4P/1K1R4 w - - +id "IQ.1017" +solution Nf6+ +go +setboard 4r3/1r2ppk1/p2p1np1/2qP4/PpP5/1P1Q4/2B1R1PP/5R1K w - - +id "IQ.1018" +solution Rxf6 +go +setboard 4r3/1r2ppk1/p2p1np1/2qP4/PpP5/1P1Q4/2B1R1PP/5R1K w - - +id "IQ.1019" +solution Rxf6 +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +id "IQ.1020" +solution Nxh5 +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +id "IQ.1021" +solution Qxh7+ +go +setboard r1r2k2/1q1n1p2/3PpPp1/4P2p/pbpN3R/2N3K1/1P2Q2P/3R4 w - - +id "IQ.1022" +solution Rxh5 +go +setboard 6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - +id "IQ.1023" +solution Rf5 +go +setboard 6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - +id "IQ.1024" +solution Rf5 +go +setboard 6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - +id "IQ.1025" +solution Rf5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1026" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1027" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1028" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1029" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1030" +solution Rxh5 +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "IQ.1031" +solution Nxh7 +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "IQ.1032" +solution Nxh7 +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "IQ.1033" +solution Nxh7 +go +setboard r2qrnk1/1b2bppp/2p5/1p1pN1Pn/p2P1B2/3BP2P/PPQ2P2/2K3RR w - - +id "IQ.1034" +solution Bxh7+ +go +setboard 3r2k1/2nqprb1/1p2p1Np/p2nP3/3pBP2/PP4RQ/1B5P/6RK w - - +id "IQ.1035" +solution Nf8 Nh8 +go +setboard r4rk1/pppq2pp/1nbpp3/6B1/2PP2P1/3B3P/P1P2P2/1R1QR1K1 w - - +id "IQ.1036" +solution d5 +go +setboard r4rk1/pppq2pp/1nbpp3/6B1/2PP2P1/3B3P/P1P2P2/1R1QR1K1 w - - +id "IQ.1037" +solution d5 +go +setboard r1r1q2k/pp3pbp/4p3/2npPp1Q/3P1P1N/2P2RR1/P1P3PP/6K1 w - - +id "IQ.1038" +solution Rxg7 +go +setboard r1r1q2k/pp3pbp/4p3/2npPp1Q/3P1P1N/2P2RR1/P1P3PP/6K1 w - - +id "IQ.1039" +solution Rxg7 +go +setboard r4r1k/pbpq1p1B/1p2pp2/8/1b1P2Q1/8/PPP2PPP/2KR3R w - - +id "IQ.1040" +solution d5 +go +setboard r4r1k/pbpq1p1B/1p2pp2/8/1b1P2Q1/8/PPP2PPP/2KR3R w - - +id "IQ.1041" +solution d5 +go +setboard 2R5/r3b1k1/p2p4/P1pPp2p/6q1/2P2N1r/4Q1P1/5RK1 w - - +id "IQ.1042" +solution Nxe5 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1043" +solution f4 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1044" +solution f4 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1045" +solution f4 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1046" +solution f4 +go +setboard 2q3k1/1p3pp1/4rbn1/r1pp1Np1/p2P4/4PN1R/PPQ2PP1/2K4R w - - +id "IQ.1047" +solution Ne7+ +go +setboard 2q3k1/1p3pp1/4rbn1/r1pp1Np1/p2P4/4PN1R/PPQ2PP1/2K4R w - - +id "IQ.1048" +solution Ne7+ +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "IQ.1049" +solution Rxh7+ e6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "IQ.1050" +solution Rxh7+ e6 +go +setboard 4r3/pbrq1p1k/1p3Bpp/3pPn2/5PQ1/P6R/1P4PP/1B3RK1 w - - +id "IQ.1051" +solution Rh5 Qg5 +go +setboard r1bn1r2/1pp3k1/p2p3p/6p1/2qNB3/2P2PP1/P1Q2KP1/1R5R w - - +id "IQ.1052" +solution Rxh6 +go +setboard r1bn1r2/1pp3k1/p2p3p/6p1/2qNB3/2P2PP1/P1Q2KP1/1R5R w - - +id "IQ.1053" +solution Rxh6 +go +setboard r4rk1/3bpp1p/pqp3p1/4P2n/2B5/1P6/PBPbQ1PP/4RR1K w - - +id "IQ.1054" +solution e6 +go +setboard r4rk1/3bpp1p/pqp3p1/4P2n/2B5/1P6/PBPbQ1PP/4RR1K w - - +id "IQ.1055" +solution e6 +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +id "IQ.1056" +solution Rxd3 +go +setboard r3qrk1/1b3p2/1p1npnp1/2b1N1N1/p1P5/P1B5/1PB1QP1P/R2R2K1 w - - +id "IQ.1057" +solution Nd7 +go +setboard r3nrk1/pp1q2pp/4R3/6p1/2PP4/1B3Q2/P4P1P/3R2K1 w - - +id "IQ.1058" +solution c5 +go +setboard r5k1/4p2p/pp1qNnp1/2pPb3/2P1p1P1/4B3/PP1Q2P1/5R1K w - - +id "IQ.1059" +solution Bxc5 +go +setboard r7/pp2pkbp/2pq2p1/8/2P2N2/1P2R1PP/P3QPK1/8 w - - +id "IQ.1060" +solution c5 +go +setboard 2krb2r/p1q5/np2pPpp/n2pP3/2pP2P1/2P1N1B1/2P1Q1BK/RR6 w - - +id "IQ.1061" +solution Nxd5 +go +setboard 2krb2r/p1q5/np2pPpp/n2pP3/2pP2P1/2P1N1B1/2P1Q1BK/RR6 w - - +id "IQ.1062" +solution Nxd5 +go +setboard r7/1pqbr1pk/p1n4p/5p1P/2P1p3/2B3R1/PP1Q1PP1/1B2R1K1 w - - +id "IQ.1063" +solution Rxe4 +go +setboard 2rq1r2/pb4k1/1p1p1p1p/n1pP1RpQ/2P1P2B/P1PB4/6PP/R5K1 w - - +id "IQ.1064" +solution e5 +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +id "IQ.1065" +solution Nd6 +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +id "IQ.1066" +solution Nd6 +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +id "IQ.1067" +solution Bg7 +go +setboard 5qk1/2p2r1p/p1p4P/1p6/3P4/1Q6/P1P3P1/5RK1 w - - +id "IQ.1068" +solution Qg3+ +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +id "IQ.1069" +solution Ng6+ +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +id "IQ.1070" +solution Ng6+ +go +setboard r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - +id "IQ.1071" +solution Bf6 +go +setboard r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - +id "IQ.1072" +solution Bf6 +go +setboard r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - +id "IQ.1073" +solution Bf6 +go +setboard 2b2rk1/pp2R1bp/1qpp2p1/6N1/2P2PP1/3Q1B2/PP4PK/8 w - - +id "IQ.1074" +solution Bd5+ +go +setboard 1q3rnk/5p2/3p1P1p/p3n3/Np1r2P1/1P1B4/1PP4Q/1K1R3R w - - +id "IQ.1075" +solution Qxh6+ +go +setboard 2r3k1/1rq2p1p/pp1p1bp1/2pP2N1/2P1R3/1Q6/PP3PP1/4R1K1 w - - +id "IQ.1076" +solution Nxh7 +go +setboard 3r3k/p5qp/bp2B1p1/n2P1p2/5N2/Q1R5/P4PPP/6K1 w - - +id "IQ.1077" +solution Qb2 +go +setboard 3r3k/p5qp/bp2B1p1/n2P1p2/5N2/Q1R5/P4PPP/6K1 w - - +id "IQ.1078" +solution Qb2 +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +id "IQ.1079" +solution Rc1 +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +id "IQ.1080" +solution Rc1 +go +setboard 4k3/pp2pp2/4n1p1/3RP1P1/2r1N3/P1P5/1P2q3/1K5Q w - - +id "IQ.1081" +solution Nc5 +go +setboard 5rk1/1b3p1p/4pb2/2p1N2Q/1pP2p2/1P1R3P/qB3PP1/6K1 w - - +id "IQ.1082" +solution Rd8 +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +id "IQ.1083" +solution Rd4 +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +id "IQ.1084" +solution Rd4 +go +setboard k1n1r3/p2R2bb/2p2qpp/4pp2/2P5/2B1Q1P1/PP3PBP/6K1 w - - +id "IQ.1085" +solution Qc5 Bxe5 +go +setboard rr4k1/3nbp1p/p3p1p1/q2pPPP1/bp1B3R/1B2Q3/PPP4P/2K3R1 w - - +id "IQ.1086" +solution fxe6 +go +setboard 7k/p2rq2p/1p3R1P/2p5/2P2P1Q/8/6PK/8 w - - +id "IQ.1087" +solution Qe1 +go +setboard 7k/p2rq2p/1p3R1P/2p5/2P2P1Q/8/6PK/8 w - - +id "IQ.1088" +solution Qe1 +go +setboard b1R2nk1/5ppp/1p3n2/5N2/1b2p3/1P2BP2/q3BQPP/6K1 w - - +id "IQ.1089" +solution Bc5 +go +setboard 6k1/1p3ppp/1PbNp3/3rP1q1/2Q5/8/5PPP/1R4K1 w - - +id "IQ.1090" +solution Qxc6 +go +setboard 6k1/1p3ppp/1PbNp3/3rP1q1/2Q5/8/5PPP/1R4K1 w - - +id "IQ.1091" +solution Qxc6 +go +setboard 3r2k1/pqrP1p1p/6p1/1p6/n2Qp3/B1P1P3/P5PP/3R1RK1 w - - +id "IQ.1092" +solution Qf6 Bf8 +go +setboard 4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - +id "IQ.1093" +solution Bxf7+ +go +setboard 4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - +id "IQ.1094" +solution Bxf7+ +go +setboard 4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - +id "IQ.1095" +solution Bxf7+ +go +setboard 2b1r1k1/1r1n1pp1/q2p3p/1p1P4/1P1N1RPP/2Q1P3/5PBK/2R5 w - - +id "IQ.1096" +solution Qxc8 +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +id "IQ.1097" +solution Qh6 Kg2 +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +id "IQ.1098" +solution Qh6 Kg2 +go +setboard 4r1k1/p4ppp/1p2q3/n2R4/2r1p3/Pn2B1P1/1Q2PPBP/3R2K1 w - - +id "IQ.1099" +solution Re5 +go +setboard rnb3k1/6pp/p4q2/3p1N2/1p3Q2/1P6/1PP3PP/5R1K w - - +id "IQ.1100" +solution Nh6+ +go +setboard r1b2r1k/2q2pp1/2pb3p/p1n1NB2/1pP5/1P5P/PBQ2PP1/3RR1K1 w - - +id "IQ.1101" +solution Rxd6 +go +setboard r1b2r1k/2q2pp1/2pb3p/p1n1NB2/1pP5/1P5P/PBQ2PP1/3RR1K1 w - - +id "IQ.1102" +solution Rxd6 +go +setboard 2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - +id "IQ.1103" +solution Ra8+ +go +setboard 2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - +id "IQ.1104" +solution Ra8+ +go +setboard 2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - +id "IQ.1105" +solution Ra8+ +go +setboard 1q4r1/3Q1Npk/p6p/1p5N/8/7P/Pn3PP1/6K1 w - - +id "IQ.1106" +solution Qf5+ +go +setboard 1q4r1/3Q1Npk/p6p/1p5N/8/7P/Pn3PP1/6K1 w - - +id "IQ.1107" +solution Qf5+ +go +setboard r1q1r1k1/p1n1R1bp/1pp2pp1/5b2/2P2P1Q/P4NN1/1P1B2PP/2KR4 w - - +id "IQ.1108" +solution Nxf5 +go +setboard r1q1r1k1/p1n1R1bp/1pp2pp1/5b2/2P2P1Q/P4NN1/1P1B2PP/2KR4 w - - +id "IQ.1109" +solution Nxf5 +go +setboard 2r1k2r/1p2pp1p/2bp1p1b/p1qN4/4P3/6Q1/PPPR1PPP/1K3B1R w k - +id "IQ.1110" +solution Qh3 +go +setboard 2r1k2r/1p2pp1p/2bp1p1b/p1qN4/4P3/6Q1/PPPR1PPP/1K3B1R w k - +id "IQ.1111" +solution Qh3 +go +setboard r1br2k1/1pq2ppp/p3pP2/8/1n3PP1/1NpB4/PPP2Q1P/2KR2R1 w - - +id "IQ.1112" +solution Bxh7+ +go +setboard 5k2/1pp2b1p/2p5/r3PPR1/pr6/2N5/1PP4P/2KR4 w - - +id "IQ.1113" +solution f6 +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +id "IQ.1114" +solution Bxg6 +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +id "IQ.1115" +solution Bxg6 +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +id "IQ.1116" +solution Bxg6 +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1117" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1118" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1119" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1120" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1121" +solution g5+ +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +id "IQ.1122" +solution cxb6 +go +setboard 5b2/pr4pk/4P1Rp/1pppBPP1/8/1P2P3/P6K/8 w - - +id "IQ.1123" +solution Rxh6+ gxh6 +go +setboard 5b2/pr4pk/4P1Rp/1pppBPP1/8/1P2P3/P6K/8 w - - +id "IQ.1124" +solution Rxh6+ gxh6 +go +setboard 8/kp6/4R3/1P2K3/8/3pp3/8/8 w - - +id "IQ.1125" +solution Kd6 +go +setboard 5rk1/2rnqp1p/b3p1pP/2ppP3/1p3QN1/pP1P1BP1/P1P2P2/R3R1K1 w - - +id "IQ.1126" +solution Bxd5 +go +setboard 5r1k/p5bp/1p6/4P3/P2B4/3n2PB/1PR4K/8 w - - +id "IQ.1127" +solution e6 +go +setboard 4R3/5Bq1/7p/5p2/1n3k1B/7P/6PK/8 w - - +id "IQ.1128" +solution g3+ +go +setboard 8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - +id "IQ.1129" +solution a6 +go +setboard 1r1q1rk1/Nb1n1pbp/p5p1/3P4/PPB2p2/4B3/6PP/2RQ1RK1 w - - +id "IQ.1130" +solution Nc6 +go +setboard b2rr1k1/P3pp2/3p2p1/1Q1Pb2p/2P4P/1R2B1P1/4qPBK/1R6 w - - +id "IQ.1131" +solution Qxe8+ +go +setboard 8/5pk1/3P2p1/pQ6/P2p4/5pP1/3rqP1P/5RK1 w - - +id "IQ.1132" +solution d7 +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1133" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1134" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1135" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1136" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1137" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1138" +solution Bxd4+ +go +setboard 8/5p1p/1n2p2P/1k1pPpP1/3K4/4N3/2P5/8 w - - +id "IQ.1139" +solution Nxf5 +go +setboard 8/1p1b4/4p1k1/1PPp4/P4P1p/4n1p1/8/4BBK1 w - - +id "IQ.1140" +solution a5 +go +setboard 8/1p1b4/4p1k1/1PPp4/P4P1p/4n1p1/8/4BBK1 w - - +id "IQ.1141" +solution a5 +go +setboard 2q1n1kr/6b1/1r1p2B1/2p2pP1/2P1bP1N/1P1QB2P/6RK/1R6 w - - +id "IQ.1142" +solution Qxe4 +go +setboard 5brk/2q2p1p/p3pP1B/4Pp2/8/1P1R1Q1K/P6P/8 w - - +id "IQ.1143" +solution Bxf8 +go +setboard 1q4rk/6r1/2RP3p/1NR3p1/p3Qn2/P6P/6P1/6K1 w - - +id "IQ.1144" +solution d7 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1145" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1146" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1147" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1148" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1149" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1150" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1151" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1152" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1153" +solution Nxd5 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1154" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1155" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1156" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1157" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1158" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1159" +solution Bc8 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1160" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1163" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1164" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1165" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1166" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1168" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1169" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1170" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1171" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1172" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1173" +solution Rb5 +go +setboard 3r2k1/pp2qppp/4bn2/4p3/4P3/P1Nr4/1PQN1PPP/R4RK1 w - - +id "IQ.1175" +avoid Nd5 +go +setboard 3r2k1/pp2qppp/4bn2/4p3/4P3/P1Nr4/1PQN1PPP/R4RK1 w - - +id "IQ.1178" +avoid Nd5 +go +setboard r2q1rk1/3nbppp/p1bpp3/6PQ/1p1BP3/1BN5/PPP2P1P/2KR2R1 w - - +id "IQ.1179" +solution Rd3 +go +setboard r3r1k1/1pq2pp1/p2pbb1p/P3n3/3NP3/2N5/1PP1B1PP/R2Q1R1K w - - +id "IQ.1180" +solution Rxf6 +go +setboard r3r1k1/1pq2pp1/p2pbb1p/P3n3/3NP3/2N5/1PP1B1PP/R2Q1R1K w - - +id "IQ.1181" +solution Rxf6 +go +setboard 1rb1r1k1/3n1ppp/p1p1p3/q3P3/7P/2N1Q1R1/PPP3P1/2KR1B2 w - - +id "IQ.1182" +solution Rxd7 +go +setboard r2q1rk1/pp1n1p1p/2p2np1/4bQB1/3pNP2/1B5P/PP4P1/R3R1K1 w - - +id "IQ.1183" +solution Qxe5 +go +setboard 2rnr2k/2qbp3/pp1p2p1/3P1p1p/1PPN1P2/5B1P/P2Q2P1/2R1R1K1 w - - +id "IQ.1184" +solution Bxh5 +go +setboard 2r1r3/3qppkp/pp1p2p1/3PnP2/2PN4/1P5P/P2Q2P1/4RRK1 w - - +id "IQ.1185" +solution Rxe5 +go +setboard 1n2rk2/1qr1pp2/pp1p1npp/3P4/1PPN1P2/P2QR1P1/7P/4RBK1 w - - +id "IQ.1186" +solution Ne6+ +go +setboard 1r1r1n2/5pkp/4pNp1/2PpP1P1/p1bP1PP1/1qB1K3/p2Q4/3R3R w - - +id "IQ.1187" +solution f5 +go +setboard 1r1r1n2/5pkp/4pNp1/2PpP1P1/p1bP1PP1/1qB1K3/p2Q4/3R3R w - - +id "IQ.1188" +solution f5 +go +setboard 3r2k1/3rppb1/p1R1b1p1/qp1NP3/8/1P2QB2/P5PP/5RK1 w - - +id "IQ.1190" +solution Rxe6 +go +setboard r2qnrk1/pp2ppb1/3p3B/2p5/7Q/1PNP3b/1PP3PP/R4RK1 w - - +id "IQ.1191" +solution Ne4 +go +setboard r4bk1/pbq2pp1/1pn1p2p/8/4N3/1P2P1P1/PB2QPBP/3R2K1 w - - +id "IQ.1192" +solution Nf6+ +go +setboard r4bk1/pbq2pp1/1pn1p2p/8/4N3/1P2P1P1/PB2QPBP/3R2K1 w - - +id "IQ.1194" +solution Nf6+ +go +setboard rq2r1k1/pp2RNp1/1bp2n1p/8/1Q6/7P/PPB2PP1/5RK1 w - - +id "IQ.1195" +solution Nxh6+ +go +setboard r4rk1/p1p2pp1/1bp1b2p/3q2B1/Pn1PN3/5N2/1P1Q1PPP/R3R1K1 w - - +id "IQ.1196" +solution Bxh6 Be7 +go +setboard r4rk1/p1p2pp1/1bp1b2p/3q2B1/Pn1PN3/5N2/1P1Q1PPP/R3R1K1 w - - +id "IQ.1197" +solution Bxh6 Be7 +go +setboard r1b2rk1/2q1bppp/p2pp3/2n3PQ/1p1BP3/1BN5/PPP2P1P/2KR2R1 w - - +id "IQ.1198" +solution Bf6 +go +setboard r3k2r/1bqnBppp/p3p3/1p2P3/3N2Q1/3B4/PPP3PP/2KnR3 w kq - +id "IQ.1199" +solution Nxe6 +go +setboard r1bqkn1r/p3bpp1/1p2pn1p/2pPN1B1/2P5/3B2N1/PP3PPP/R2QR1K1 w kq - +id "IQ.1200" +solution Nf5 Nh5 dxe6 +go +setboard r3kb1r/2q2ppp/pn2p3/4P3/pPPN4/P3BQ2/6PP/R4RK1 w kq - +id "IQ.1201" +solution Nxe6 Rf2 Rad1 +go +setboard r4k1r/pp3pb1/2p3p1/3nNb1q/7p/1BB1Q2P/PP3PP1/3RR1K1 w - - +id "IQ.1202" +solution Rxd5 Bxd5 Qc5+ +go +setboard 4k1r1/1q1r1p2/4pQp1/3pP1B1/2p3P1/1nP2BP1/1P5K/3R4 w - - +id "IQ.1203" +solution Bxd5 +go +setboard 4k1r1/1q1r1p2/4pQp1/3pP1B1/2p3P1/1nP2BP1/1P5K/3R4 w - - +id "IQ.1204" +solution Bxd5 +go +setboard 2b2k1r/5ppp/1b6/q1p1PP2/3Np1Q1/1PP5/6PP/1N3RK1 w - - +id "IQ.1205" +solution Ne6+ +go +setboard 1r5r/p2bbk1p/4pnp1/q1ppQ1B1/7P/2N3P1/PPP2PB1/1K1R3R w - - +id "IQ.1206" +solution Nxd5 +go +setboard r2qk2r/1b1n1p2/p6n/1pp1p1Np/4P2P/2QBNP2/PPP5/2KR2R1 w kq - +id "IQ.1210" +solution Bxb5 Bc4 Bf1 +go +setboard rn1qk2r/pbp2p2/1p3ppb/7p/2BP1N1P/2N1P3/PP3PP1/R2QK2R w KQkq - +id "IQ.1211" +solution Bxf7+ +go +setboard r1b2k1r/p2n1pp1/1q2p3/2ppP1B1/1b1N1Q1P/2N5/PPP2P2/R3K1R1 w Q - +id "IQ.1212" +solution Bd8 +go +setboard r4b1r/pp3kpp/1qp1Rn2/8/8/5Q1P/PPPB1PP1/2KR4 w - - +id "IQ.1213" +solution Rxf6+ +go +setboard 7r/1Qrk1pbp/p2pp1p1/6P1/5PB1/1P6/q1P4P/2KR2BR w - - +id "IQ.1214" +solution Rxd6+ +go +setboard r3k2r/2pb1npp/ppp5/2q1p3/2N1P3/1QP2N1P/PP3PP1/R2R2K1 w kq - +id "IQ.1215" +solution Rxd7 Qb4 +go +setboard r3kb1r/pp3p1p/4pp2/q2pN3/2P5/8/PP3PPP/R2QR1K1 w kq - +id "IQ.1216" +solution Nxf7 +go +setboard r3kbnr/p4p2/1p2p2p/3qP1p1/3Nn1QB/8/PP2NPPP/R4RK1 w kq - +id "IQ.1217" +solution Nxe6 +go +setboard r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - +id "IQ.1218" +solution b3 Nd6+ +go +setboard r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - +id "IQ.1219" +solution b3 Nd6+ +go +setboard r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - +id "IQ.1221" +solution b3 Nd6+ +go +setboard r1bqr1k1/1p1nbppp/p1n1p3/3pP2Q/3N1P2/1BN1B3/PPP3PP/R4RK1 w - - +id "IQ.1222" +solution Nxd5 +go +setboard 2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - +id "IQ.1223" +solution Bxf7+ +go +setboard rn1q1rk1/1b2bppp/p3p3/1pn1P2Q/3N4/1BN1B3/PPP3PP/R4RK1 w - - +id "IQ.1224" +solution Rxf7 +go +setboard 2r1r3/pbq1bpk1/1pn3p1/6Bp/4Q3/PB3N2/1P3PPP/R3R1K1 w - - +id "IQ.1225" +solution Bxf7 +go +setboard 2rq1rk1/1b3pb1/5np1/1pn1p1Np/4P2Q/2N1B3/BPP3PP/R4R1K w - - +id "IQ.1226" +solution Nxf7 +go +setboard 4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - +id "IQ.1227" +solution Rxg6+ +go +setboard 4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - +id "IQ.1228" +solution Rxg6+ +go +setboard 4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - +id "IQ.1229" +solution Rxg6+ +go +setboard r5k1/1p3p1p/p1pqrPp1/3bN3/8/P1P3Q1/1P4PP/4RRK1 w - - +id "IQ.1231" +solution Nxf7 +go +setboard rnb2rk1/pp3p1p/3q2pQ/3pN3/2pP4/2PB4/P1P2PPP/4RRK1 w - - +id "IQ.1232" +solution Nxf7 +go +setboard r2r1bk1/1ppq2pp/2p2B2/p1n2N1b/P3P1R1/3PN3/2P3PP/R2Q2K1 w - - +id "IQ.1233" +solution Ne7+ +go +setboard r2r1bk1/1ppq2pp/2p2B2/p1n2N1b/P3P1R1/3PN3/2P3PP/R2Q2K1 w - - +id "IQ.1234" +solution Ne7+ +go +setboard r4rk1/pp2bpp1/1qp1b2p/4B2Q/n7/3B4/PPP2PPP/3RR1K1 w - - +id "IQ.1236" +solution Bxg7 +go +setboard r4rk1/pp2bpp1/1qp1b2p/4B2Q/n7/3B4/PPP2PPP/3RR1K1 w - - +id "IQ.1237" +solution Bxg7 +go +setboard 5Q2/pp1b2pk/1n1p2rp/2pP1p2/2P2P2/q1BB4/6PP/4R1K1 w - - +id "IQ.1238" +solution Bxg7 +go +setboard 5Q2/pp1b2pk/1n1p2rp/2pP1p2/2P2P2/q1BB4/6PP/4R1K1 w - - +id "IQ.1239" +solution Bxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1240" +solution Rxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1241" +solution Rxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1242" +solution Rxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1243" +solution Rxg7 +go +setboard r1b2k1r/1p4pp/p4B2/2bpN3/8/q2n4/P1P2PPP/1R1QR1K1 w - - +id "IQ.1244" +solution Bxg7+ Qh5 +go +setboard 1r3r1k/1b2bppp/p1qp4/5PP1/1p1B3Q/1PN2R2/1PP4P/5RK1 w - - +id "IQ.1245" +solution Bxg7+ +go +setboard r2b1rk1/2q2ppp/p3b3/1pn1pNB1/4Pn1Q/P1NB4/1PP3PP/R4R1K w - - +id "IQ.1246" +solution Nxg7 +go +setboard 6k1/5rpp/8/2Np4/1Pn3R1/4Q2P/q2r1PP1/5RK1 w - - +id "IQ.1247" +solution Qe8+ +go +setboard r4rk1/1bpq1ppp/3p1b2/2nP1N2/8/1p3Q1P/PPB2PP1/R1B1R1K1 w - - +id "IQ.1248" +solution Nxg7 +go +setboard r2q1rk1/pp1b1Rp1/4p2p/4PnNQ/2pP4/2P1B3/P5PP/5RK1 w - - +id "IQ.1249" +solution R1xf5 +go +setboard r4r1k/pbq2pp1/1p2p2p/4P3/2pP3Q/P1P3RP/R4P1P/1B4K1 w - - +id "IQ.1250" +solution Rxg7 +go +setboard 2r2bk1/1bq1rppp/pp1p4/4n1P1/Pn1BP1N1/2N3Q1/1PP2RBP/5RK1 w - - +id "IQ.1251" +solution Bxe5 +go +setboard r1b2rk1/pppn2bp/3p1qp1/3p2N1/3P4/3BB3/PPP2PPP/R2QR1K1 w - - +id "IQ.1252" +solution Nxh7 +go +setboard rnb3kr/1p1nqppp/p3p3/2ppP3/3P1N2/2NB1Q2/PPP2PP1/R3K2R w KQ - +id "IQ.1253" +solution Bxh7+ +go +setboard r1qr2k1/p3bppp/b1p5/3nN3/NP1P4/P3B3/5PPP/1B1QR1K1 w - - +id "IQ.1254" +solution Bxh7+ +go +setboard 3r1rk1/1bq1bp1p/p3p1p1/3pP3/3N1P2/2PBB2R/n1P1Q1PP/5RK1 w - - +id "IQ.1255" +solution Rxh7 +go +setboard r1qb1rk1/5ppp/p1n5/1ppNP1P1/2p2P1P/P4Q2/1P6/1B1R1RK1 w - - +id "IQ.1256" +solution Bxh7+ +go +setboard 2r1r1k1/pbq2ppp/1p2pn2/2b1N3/2P5/2B5/PPB1QPPP/3RR1K1 w - - +id "IQ.1257" +solution Bxh7+ +go +setboard 1q1r2k1/pb2b1pp/1p3p2/3P4/1n1QB3/5N2/PB3PPP/2R4K w - - +id "IQ.1258" +solution Bxh7+ +go +setboard 1q1r2k1/pb2b1pp/1p3p2/3P4/1n1QB3/5N2/PB3PPP/2R4K w - - +id "IQ.1259" +solution Bxh7+ +go +setboard 2r5/3nr1pk/p2qpp1p/1p5Q/3P1PN1/2P3RP/P5PK/4R3 w - - +id "IQ.1260" +solution Nxh6 +go +setboard r1q2r1k/p1ppb1p1/1p2p1Qp/3n3P/3PN3/2P1B3/PP3PP1/3R1RK1 w - - +id "IQ.1261" +solution Bxh6 +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.1262" +solution Qh6+ +go +setboard r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - +id "IQ.1263" +solution Bxh6 +go +setboard 2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - +id "IQ.1264" +solution Rxh6+ +go +setboard 2r2rk1/1bq1bpp1/pn2p2p/1pn3P1/3NNP1Q/P6R/1PP3BP/R1B4K w - - +id "IQ.1265" +solution Nf6+ +go +setboard 4rb2/1p1q1ppk/p1n1p2p/2p1Pn2/3PNR2/2P2K2/P2QBP2/6R1 w - - +id "IQ.1266" +solution Rxf5 +go +setboard r6r/pb1R1pk1/1p2p1pp/3nP3/4N2Q/4B3/P3qPPP/3R2K1 w - - +id "IQ.1267" +solution Bxh6+ +go +setboard rq1n1bk1/3b1pp1/3p3p/pppP3N/8/1P4PP/PBPQ1PB1/4R1K1 w - - +id "IQ.1268" +solution Qxh6 +go +setboard 2rq1rk1/pp3pp1/4pb1p/3bN3/3P4/PnPB3R/2Q2PPP/R1B3K1 w - - +id "IQ.1269" +solution Bh7+ +go +setboard 2r2rk1/p1n3pp/1p2p3/1q1pQP2/3Pn3/6N1/PP4PP/R1B2RK1 w - - +id "IQ.1270" +solution Bh6 +go +setboard 4rr1k/pp4b1/4P2p/5p1R/3q4/3B2P1/PP1R4/1K5Q w - - +id "IQ.1271" +solution Rxh6+ +go +setboard 1r2b3/pp1rqppk/3b3p/3Bp2Q/4P1N1/5R1P/PP3PP1/3R2K1 w - - +id "IQ.1272" +solution Rf6 +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +id "IQ.1273" +solution Bxh6 +go +setboard r2q1rk1/3nbpp1/4p2p/p1p1P3/1p1P3P/3B1b1R/PPQB1PP1/R3K3 w - - +id "IQ.1274" +solution Bxh6 +go +setboard r1r1n3/5p1k/1n1P2pp/ppq1pN2/2p1P3/1PP1R2P/P1B2QPK/5R2 w - - +id "IQ.1275" +solution Nxh6 +go +setboard r1n1nrk1/p4p1p/1q4pQ/2p1pN2/1pB1P1P1/5P2/PPP4P/1K1R3R w - - +id "IQ.1276" +solution Rd6 Rhg1 +go +setboard r3r3/2qn1Qbk/b2p2pp/1npP4/1p6/3NB1NP/1P1R2P1/1B2R1K1 w - - +id "IQ.1277" +solution Qxg6+ +go +setboard 1b4k1/1pnq1r1p/4p1p1/1pPpP2Q/1P5B/3BPP2/7P/6RK w - - +id "IQ.1278" +solution Bxg6 +go +setboard 2r2rn1/p3q1bk/n2p2pp/1b1PPp2/1pp2P1N/1P2N1P1/P1QB2BP/4RRK1 w - - +id "IQ.1279" +solution Nxg6 +go +setboard r2q1r1k/p3pn1p/3p2pQ/1ppP1p1n/4P3/2N2P2/PPP1BP2/2K3RR w - - +id "IQ.1280" +solution Qxg6 +go +setboard 4Q3/p4pk1/2p3p1/8/3P1N2/4PBR1/q4P1K/r3r3 w - - +id "IQ.1281" +solution Rxg6+ Qe5+ +go +setboard 2r1r1k1/4qpb1/p2p2p1/1p1Pn1P1/3BB3/P1P5/1P4Q1/1K2R2R w - - +id "IQ.1282" +solution Bxg6 Qh2 Qh3 +go +setboard 2r1r1k1/4qpb1/p2p2p1/1p1Pn1P1/3BB3/P1P5/1P4Q1/1K2R2R w - - +id "IQ.1283" +solution Bxg6 Qh2 Qh3 +go +setboard 5r2/1pr1ppk1/1n1q2p1/p2P3p/5R2/1BP1RQ2/5PP1/6K1 w - - +id "IQ.1284" +solution Re6 +go +setboard 4rbk1/n2n3p/b1q1p1p1/1p1pP1B1/1PrP1N2/1R3NP1/3Q1PB1/R5K1 w - - +id "IQ.1285" +solution Nxg6 Bf1 +go +setboard 4rbk1/n2n3p/b1q1p1p1/1p1pP1B1/1PrP1N2/1R3NP1/3Q1PB1/R5K1 w - - +id "IQ.1286" +solution Nxg6 Bf1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1287" +solution Nxf6+ Rg1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1288" +solution Nxf6+ Rg1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1289" +solution Nxf6+ Rg1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1290" +solution Nxf6+ Rg1 +go +setboard 8/7p/2k1Pp2/pp1p2p1/3P2P1/4P3/P3K2P/8 w - - +solution e4 +id "PET001: Pawn endgame" +go +setboard 8/1p4kP/5pP1/3p4/8/4P3/7K/8 w - - +solution e4 +id "PET002: Pawn endgame" +go +setboard 8/8/8/pPk3pp/2P1p3/1pK3P1/5PP1/8 w - - +solution g4 +id "PET003: Pawn endgame" +go +setboard 6k1/3p4/3p4/3P4/4P1p1/6P1/8/K7 w - - +solution Kb1 +id "PET004: Pawn endgame" +go +setboard 8/p7/1p2k1p1/8/1p2p1Pp/3pP2P/PP6/5K2 w - - +solution b3 +id "PET005: Pawn endgame" +go +setboard 8/p7/1p2k1p1/8/1p2p1Pp/3pP2P/PP6/5K2 b - - +solution b3 +id "PET006: Pawn endgame" +go +setboard 8/7p/p3pk2/1p5P/3K1P2/1P6/P7/8 w - - +solution a4 +id "PET007: Pawn endgame" +go +setboard 8/8/1p3p2/p3k1pp/4P2P/P3K1P1/1P6/8 w - - +solution g4 +id "PET008: Pawn endgame" +go +setboard 8/8/p3k1p1/1pp5/4KP2/1P6/P5P1/8 w - - +solution g4 +id "PET009: Pawn endgame" +go +setboard 8/1p3p2/p4kpp/1PPp4/P7/7P/5K1P/8 b - - +solution Ke6 +solution Ke7 +id "PET010: Pawn endgame" +go +setboard 8/6p1/7p/p1N5/6PP/2k5/8/3K4 b - - +solution a4 +id "PET011: pawns vs N" +go +setboard 8/8/8/5Bp1/7k/8/4pPKP/8 w - - +solution Bg4 +id "PET012: pawns vs B" +go +setboard 8/8/2p5/pkp3R1/7B/P7/2p3K1/8 w - - +solution a4+ +id "PET013: pawns vs R+B" +go +setboard 8/6k1/6p1/2n2PP1/3N3p/3pK3/8/8 b - - +solution d2 +id "PET014: Knight endgame" +go +setboard 8/1N6/1p1P1n2/p1p1p3/P1P5/1P2k3/2K5/8 w - - +solution Nxc5 +id "PET015: Knight endgame" +go +setboard 4k3/B1p4p/8/p2n1p2/5P2/5P2/1P2K2P/8 w - - +avoid Be3 +id "PET016: bishop vs knight" +go +setboard 8/8/p2k1p2/1p1p3p/1P1P3p/P3NPP1/5K2/1b6 w - - +solution Ng2 +id "PET017: bishop vs knight" +go +setboard 8/3k4/3b4/1K6/7p/5B1P/PP6/8 w - - +solution b4 +id "PET018: opposite bishops" +go +setboard 8/8/4kpp1/3p1b2/p6P/2B5/6P1/6K1 b - - +solution Bh3 +id "PET019: opposite bishops" +go +setboard 8/4k1p1/1p2B2p/4p3/8/4P2P/1PP1KbP1/8 b - - +avoid Bxe3 +id "PET020: opposite bishops" +go +setboard 5k2/8/4b3/1B5P/8/8/5pPP/5K2 b - - +solution Bh3 +id "PET021: bishop endgame" +go +setboard 8/2B5/1p1p4/1PkP1p2/P4P2/5P2/1p6/bK6 w - - +solution Bd8 +id "PET022: bishop endgame" +go +setboard 8/2p1bpp1/2Pp4/p2P1P1p/2K2B1P/k5P1/8/8 w - - +solution f6 +id "PET023: bishop endgame" +go +setboard 8/4ppbk/p5pp/3pP3/3B4/5P1P/PP3P2/6K1 b - - +avoid g5 +id "PET024: bishop endgame" +go +setboard 4K3/2k1Bp1N/6p1/5PP1/8/7p/b7/8 w - - +solution Bf6 +id "PET025: BN vs B" +go +setboard 8/5k2/4p3/4Pp1p/5P1P/3Rn2K/6p1/8 b - - +solution g1=B +id "PET026: rook vs knight" +go +setboard 5k2/8/8/3R4/6K1/8/3b2pP/8 w - - +solution Rf5+ +id "PET027: rook vs bishop" +go +setboard 8/4kp2/4p1p1/2p1r3/PpP5/3R4/1P1K1PP1/8 w - - +solution g4 +id "PET028: rook endgame" +go +setboard 1r3k2/5pp1/3p2p1/8/3P4/P6P/2R2P1K/8 b - - +solution Ra8 +id "PET029: rook endgame" +go +setboard 5k2/p1p4R/1pr5/3p1pP1/P2P1P2/2P2K2/8/8 w - - +solution Kg3 +id "PET030: rook endgame" +go +setboard 8/1r3pkp/8/5p2/8/5PP1/1P1R3P/6K1 b - - +solution f4 +id "PET031: rook endgame" +go +setboard 8/5pk1/r5pp/P7/3R3P/6P1/5PK1/8 w - - +solution Ra4 +id "PET032: rook endgame" +go +setboard 8/4k3/2P2p2/6p1/1P4R1/4K3/7r/8 w - - +solution Rd4 +id "PET033: rook endgame" +go +setboard 3r4/7p/Rp4k1/5p2/4p3/2P5/PP3P1P/5K2 b - - +solution Rd2 +id "PET034: rook endgame" +go +setboard 8/8/p2k3p/1P1p1pp1/P1r5/1R1K1PP1/7P/8 b - - +solution a5 +id "PET035: rook endgame" +go +setboard 8/1r3pkp/R7/6Pp/8/4P3/5PK1/8 b - - +solution Re7 +id "PET036: rook endgame" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "PET037: RN vs RB" +go +setboard 4k3/2p1b3/4p1p1/1pp1P3/5PP1/1PBK4/r1P2R2/8 b - - +solution c4+ +id "PET038: RB vs RB" +go +setboard 1r6/1pb1k1p1/4p2p/1p1p4/3Pp2P/1R2P1PB/1P2PK2/8 b - - +solution b4 +id "PET039: RB vs RB" +go +setboard 8/8/5P1k/8/2K5/pr2r3/4R3/2R5 w - - +solution f7 +id "PET042: double rook endgame" +go +r5k1/5pp1/1P5p/3R4/2r5/P3P3/2p2PPP/2R3K1 b - - +solution Rxa3 +id "PET043: double rook endgame" +go +setboard 1r6/Rp2rp2/1Pp2kp1/N1Pp3p/3Pp1nP/4P1P1/R4P2/6K1 w - - +solution Nxb7 +solution Rxb7 +id "PET044: RRN vs RRN" +go +setboard 5k2/4p3/3p2Q1/3Pq1pP/5pP1/2P4K/8/8 w - - +solution Qf5+ +id "PET045: Queen endgame" +go +setboard 8/8/1P1k2p1/8/5P1p/4Qb2/1q4PK/8 w - - +solution Qe5+ +id "PET046: Q+B vs Q" +go +setboard 8/p4k2/1p1p1qp1/1P1P4/P5P1/7P/4Q1K1/2b5 b - - +avoid Qb2 +id "PET047: Q+B vs Q" +go +setboard 6qk/1p4pn/8/3p4/2P5/p3P1P1/P1Q3K1/1B6 w - - +avoid Qxh7+ +id "PET048: Q+B vs Q+N" +go +setboard 1Q6/Nn3pbp/2N2p2/1Pqk1P1P/8/8/6P1/7K w - - +avoid Qxb7 +id "PET049: QNN vs QBN" +go +setboard 7k/7p/1p4p1/n2p4/1K1p3R/2NB4/3Q1P2/q1r5 w - - +solution Rxh7+ +id "PET050: QNBR vs QNR" +go +version + +setboard 1n1r1rk1/ppq2ppp/3p2b1/3B1NP1/4PB1R/bP2P2P/P1P5/3KQ1R1 w - - +id Quick-01 +solution Qc3 +go +setboard 1n1r1rk1/ppq2ppp/3p2b1/3B1NP1/4PB1R/bP2P2P/P1P5/3KQ1R1 w - - +id Quick-02 +solution Qc3 +go +setboard 3Q4/3p4/P2p4/N2b4/8/4P3/5p1p/5Kbk w - - +id Quick-03 +solution Qa8 +go +setboard 4qrk1/3nppb1/R1Np2p1/3P2P1/1Pr5/4B3/5Q1P/5R1K w - - +id Quick-04 +solution Ra8 +go +setboard r3r3/2R2pk1/p2p1bpp/3P4/q2pQ3/5N1P/5PP1/1R4K1 w - - +id Quick-05 +solution Rxf7+ +go +setboard r3r3/2R2pk1/p2p1bpp/3P4/q2pQ3/5N1P/5PP1/1R4K1 w - - +id Quick-06 +solution Rxf7+ +go +setboard r5k1/Rb4p1/2q2pBp/1pp5/1b4QN/1P2P2P/5PP1/6K1 w - - +id Quick-07 +solution Rxb7 +go +setboard 3R4/5r1p/5ppk/8/1Q3PPq/5P2/6K1/8 w - - +id Quick-08 +solution Rg8 +go +setboard 2kr3r/ppp3pp/2pbbn2/4N3/3Pp3/2P3Pq/PP1NQP1P/R1B2RK1 w - - +id Quick-09 +avoid Nxe4 +go +setboard 2r3k1/pp1bpp1p/3p1npQ/q1r5/4P1P1/2NR1P2/PPP1N3/2K4R w - - +id Quick-10 +solution g5 +go +setboard r1b2rk1/pp3p2/2p2bpQ/8/1q1P4/2N2N2/Pn3PPP/1B1RR1K1 w - - +id Quick-11 +solution Bxg6 +go +setboard r2qk2r/1p1bbp2/1P2p3/p2pPp2/n2N1N1p/3PB3/5QPP/R4RK1 w kq - +id Quick-12 +solution Rxa4 +go +setboard 3r1n1r/1p2q1k1/p1p1P1p1/3n4/5Pp1/P5N1/1P3QP1/1BR1R1K1 w - - +id Quick-13 +solution Bxg6 +go +setboard r2q1rk1/p1p3pp/b2bp3/2pp4/6p1/2NPPN2/PPP2PP1/R1BQR1K1 w - - +id Quick-14 +solution Ne5 +go +setboard r2q1rk1/p1p3pp/b2bp3/2pp4/6p1/2NPPN2/PPP2PP1/R1BQR1K1 w - - +id Quick-15 +solution Ne5 +go +setboard 3k4/p7/K3BP2/8/7p/8/2P4P/8 w - - +id Quick-16 +solution Kb7 +go +setboard rq4k1/pp1nrppp/4bn2/6R1/3QP3/P4PN1/4B1PP/2B2RK1 w - - +id Quick-17 +solution Rxg7+ +go +setboard 2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - +id Quick-18 +solution Qb4 +go +setboard 2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - +id Quick-19 +solution Qb4 +go +setboard 2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - +id Quick-20 +solution Qb4 +go +setboard r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - +id Quick-21 +solution Bxb5+ +go +setboard r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - +id Quick-22 +solution Bxb5+ +go +setboard r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - +id Quick-23 +solution Bxb5+ +go +setboard 3B4/1R3p1k/2p4p/2Pp3r/3P4/4Q1K1/6P1/3b1q2 w - - +id Quick-24 +solution Bf6 +go +setboard +id "ST3_01 - Entwicklung" + +go +setboard +id "ST3_02 - Entwicklung" + +go +setboard +id "ST3_03 - Entwicklung" + +go +setboard +id "ST3_04 - Koenigssicherheit" + +go +setboard r2qr1k1/pp3pbp/2n3p1/1N1p4/2P2Pb1/5N2/PP1QBPPP/2KR3R w - - +id "ST3_05 - Koenigssicherheit" +avoid cxd5 +go +setboard r2qr1k1/pp3pbp/2n3p1/1N1p4/2P2Pb1/5N2/PP1QBPPP/2KR3R w - - +id "ST3_06 - Koenigssicherheit" +avoid cxd5 +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_07 - Koenigssicherheit" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_08 - Koenigssicherheit" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_09 - Koenigssicherheit" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_10 - Trojaner" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_11 - Trojaner" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_12 - Vergifteter Bauer" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_13 - Vergifteter Bauer" +avoid O-O +go +setboard 3r1rk1/4bppp/p1pq1n2/3p1P2/4p2B/2N5/PPP1QPPP/R3R1K1 w - - +id "ST3_14 - Vergifteter Bauer" +avoid Qxa6 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_15 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_16 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_17 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_18 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r1bq1rk1/ppp1n1bp/3p4/3Ppnp1/2P1N3/1Q4BP/PP1NBPP1/R3K2R w KQ - +id "ST3_19 - Vergifteter Bauer" +avoid Nxg5 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_20 - Dame vs Tuerme" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_21 - Dame vs Tuerme" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_22 - Laeuferopfer" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_23 - Laeuferopfer" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_24 - Springeropfer" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_25 - Springeropfer" +avoid Qxa8 +go +setboard r5k1/1qr1bpp1/3pb1n1/4p1Pp/Np2P2P/1P1B1P2/P1P1Q3/BK1R3R w - - +id "ST3_26 - Qualitaetsopfer" +avoid Qe3 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_27 - Qualitaetsopfer" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_28 - Qualitaetsopfer" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_29 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_30 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_31 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_32 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_33 - Verteidigung" +avoid Qxb7 +go +setboard 2r1qrk1/p3b1pp/4b3/1pP5/PQpP1p2/4B3/4BPPP/R4RK1 w - - +id "ST3_34 - Verteidigung" +avoid Bd2 +go +setboard 1r5r/4qp1k/pn2p1b1/4P3/P4Q2/1R5P/1P2NPP1/3R2K1 w - - +id "ST3_35 - Verteidigung" +avoid Nd4 Qg4 +go +setboard r1bqkb1r/ppp2p1p/2n3p1/3np1NQ/2B5/8/PPPP1PPP/RNB1K2R w KQkq - +id "ST3_36 - Verteidigung" +avoid Qf3 +go +setboard N4bk1/5pp1/6qp/2n5/6b1/6P1/PP3KBP/2R1Q3 w - - +id "ST3_37 - Verteidigung" +avoid Qe3 +go +setboard 4rrk1/q6p/8/p2P1p2/2PbB3/8/PPQ2N1P/5RK1 w - - +id "ST3_38 - Verteidigung" +avoid Bd3 +go +setboard 2kr1b1r/pp1b3p/1qn1pp2/3p3n/2pPP1p1/2P2NB1/PPBN1PPP/RQ2K2R w KQ - +id "ST3_39 - Verteidigung" +avoid Nh4 +go +setboard 3r1rk1/2q3p1/8/1p1bp3/8/PP4P1/4Q2P/R1B1R1K1 w - - +id "ST3_40 - Verteidigung" +avoid Bg5 +go +setboard 1r2r1k1/Nb1n1ppp/4q3/8/2p1n3/P4Q2/BB3PPP/1R1R2K1 w - - +id "ST3_41 - Verteidigung" +avoid Nb5 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_42 - Verteidigung" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_43 - Verteidigung" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_44 - Endspiel B vs B" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_45 - Endspiel B vs B" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_46 - Endspiel B vs S" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_47 - Endspiel D vs D" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_48 - Endspiel D vs D" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_49 - Endspiel D&T vs D&T" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_50 - Endspiel L vs B" +avoid Qa3 +go +setboard 8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - +id "ST3_51 - Endspiel L vs L" +avoid Kd7 +go +setboard 8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - +id "ST3_52 - Endspiel L vs L" +avoid Kd7 +go +setboard 8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - +id "ST3_53 - Endspiel L vs L" +avoid Kd7 +go +setboard 6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - +id "ST3_54 - Endspiel S vs L" +avoid Ng5 +go +setboard 6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - +id "ST3_55 - Endspiel S&B vs L&S" +avoid Ng5 +go +setboard 6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - +id "ST3_56 - Endspiel T vs T" +avoid Ng5 +go +setboard 8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - +id "ST3_57 - Endspiel T vs T" +avoid Rh6 +go +setboard 8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - +id "ST3_58 - Endspiel T vs T" +avoid Rh6 +go +setboard 8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - +id "ST3_59 - Endspiel T vs T" +avoid Rh6 +go +setboard 2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - +id "ST3_60 - Endspiel T vs T" +avoid f8=Q +go +setboard 2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - +id "ST3_61 - Endspiel T vs T" +avoid f8=Q +go +setboard 2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - +id "ST3_62 - Endspiel T&L vs T&L" +avoid f8=Q +go +setboard 8/3b1p2/3Pk3/R1K4p/8/6r1/8/2B5 w - - +id "ST3_63 - Endspiel T&L vs T&L" +avoid Ra3 +go +setboard 8/3b1p2/3Pk3/R1K4p/8/6r1/8/2B5 w - - +id "ST3_64 - Endspiel T&L vs T&S" +avoid Ra3 +go +setboard 2rr3k/pp3pp1/1nnqbN1p/3pN3/2pP4/2P3Q1/PPB4P/R4RK1 w - - +solution Qg6 +id "WAC.001" +go +setboard 8/7p/5k2/5p2/p1p2P2/Pr1pPK2/1P1R3P/8 b - - +solution Rxb2 +id "WAC.002" +go +setboard 5rk1/1ppb3p/p1pb4/6q1/3P1p1r/2P1R2P/PP1BQ1P1/5RKN w - - +solution Rg3 +id "WAC.003" +go +setboard r1bq2rk/pp3pbp/2p1p1pQ/7P/3P4/2PB1N2/PP3PPR/2KR4 w - - +solution Qxh7+ +id "WAC.004" +go +setboard 5k2/6pp/p1qN4/1p1p4/3P4/2PKP2Q/PP3r2/3R4 b - - +solution Qc4+ +id "WAC.005" +go +setboard 7k/p7/1R5K/6r1/6p1/6P1/8/8 w - - +solution Rb7 +id "WAC.006" +go +setboard rnbqkb1r/pppp1ppp/8/4P3/6n1/7P/PPPNPPP1/R1BQKBNR b KQkq - +solution Ne3 +id "WAC.007" +go +setboard r4q1k/p2bR1rp/2p2Q1N/5p2/5p2/2P5/PP3PPP/R5K1 w - - +solution Rf7 +id "WAC.008" +go +setboard 3q1rk1/p4pp1/2pb3p/3p4/6Pr/1PNQ4/P1PB1PP1/4RRK1 b - - +solution Bh2+ +id "WAC.009" +go +setboard 2br2k1/2q3rn/p2NppQ1/2p1P3/Pp5R/4P3/1P3PPP/3R2K1 w - - +solution Rxh7 +id "WAC.010" +go +setboard r1b1kb1r/3q1ppp/pBp1pn2/8/Np3P2/5B2/PPP3PP/R2Q1RK1 w kq - +solution Bxc6 +id "WAC.011" +go +setboard 4k1r1/2p3r1/1pR1p3/3pP2p/3P2qP/P4N2/1PQ4P/5R1K b - - +solution Qxf3+ +id "WAC.012" +go +setboard 5rk1/pp4p1/2n1p2p/2Npq3/2p5/6P1/P3P1BP/R4Q1K w - - +solution Qxf8+ +id "WAC.013" +go +setboard r2rb1k1/pp1q1p1p/2n1p1p1/2bp4/5P2/PP1BPR1Q/1BPN2PP/R5K1 w - - +solution Qxh7+ +id "WAC.014" +go +setboard 1R6/1brk2p1/4p2p/p1P1Pp2/P7/6P1/1P4P1/2R3K1 w - - +solution Rxb7 +id "WAC.015" +go +setboard r4rk1/ppp2ppp/2n5/2bqp3/8/P2PB3/1PP1NPPP/R2Q1RK1 w - - +solution Nc3 +id "WAC.016" +go +setboard 1k5r/pppbn1pp/4q1r1/1P3p2/2NPp3/1QP5/P4PPP/R1B1R1K1 w - - +solution Ne5 +id "WAC.017" +go +setboard R7/P4k2/8/8/8/8/r7/6K1 w - - +solution Rh8 +id "WAC.018" +go +setboard r1b2rk1/ppbn1ppp/4p3/1QP4q/3P4/N4N2/5PPP/R1B2RK1 w - - +solution c6 +id "WAC.019" +go +setboard r2qkb1r/1ppb1ppp/p7/4p3/P1Q1P3/2P5/5PPP/R1B2KNR b kq - +solution Bb5 +id "WAC.020" +go +setboard 5rk1/1b3p1p/pp3p2/3n1N2/1P6/P1qB1PP1/3Q3P/4R1K1 w - - +solution Qh6 +id "WAC.021" +go +setboard r1bqk2r/ppp1nppp/4p3/n5N1/2BPp3/P1P5/2P2PPP/R1BQK2R w KQkq - +solution Ba2 +solution Nxf7 +id "WAC.022" +go +setboard r3nrk1/2p2p1p/p1p1b1p1/2NpPq2/3R4/P1N1Q3/1PP2PPP/4R1K1 w - - +solution g4 +id "WAC.023" +go +setboard 6k1/1b1nqpbp/pp4p1/5P2/1PN5/4Q3/P5PP/1B2B1K1 b - - +solution Bd4 +id "WAC.024" +go +setboard 3R1rk1/8/5Qpp/2p5/2P1p1q1/P3P3/1P2PK2/8 b - - +solution Qh4+ +id "WAC.025" +go +setboard 3r2k1/1p1b1pp1/pq5p/8/3NR3/2PQ3P/PP3PP1/6K1 b - - +solution Bf5 +id "WAC.026" +go +setboard 7k/pp4np/2p3p1/3pN1q1/3P4/Q7/1r3rPP/2R2RK1 w - - +solution Qf8+ +id "WAC.027" +go +setboard 1r1r2k1/4pp1p/2p1b1p1/p3R3/RqBP4/4P3/1PQ2PPP/6K1 b - - +solution Qe1+ +id "WAC.028" +go +setboard r2q2k1/pp1rbppp/4pn2/2P5/1P3B2/6P1/P3QPBP/1R3RK1 w - - +solution c6 +id "WAC.029" +go +setboard 1r3r2/4q1kp/b1pp2p1/5p2/pPn1N3/6P1/P3PPBP/2QRR1K1 w - - +solution Nxd6 +id "WAC.030" +go +setboard rb3qk1/pQ3ppp/4p3/3P4/8/1P3N2/1P3PPP/3R2K1 w - - +solution Qxa8 +solution d6 +solution dxe6 +id "WAC.031" +go +setboard 6k1/p4p1p/1p3np1/2q5/4p3/4P1N1/PP3PPP/3Q2K1 w - - +solution Qd8+ +id "WAC.032" +go +setboard 8/p1q2pkp/2Pr2p1/8/P3Q3/6P1/5P1P/2R3K1 w - - +solution Qe5+ +solution Qf4 +id "WAC.033" +go +setboard 7k/1b1r2p1/p6p/1p2qN2/3bP3/3Q4/P5PP/1B1R3K b - - +solution Bg1 +id "WAC.034" +go +setboard r3r2k/2R3pp/pp1q1p2/8/3P3R/7P/PP3PP1/3Q2K1 w - - +solution Rxh7+ +id "WAC.035" +go +setboard 3r4/2p1rk2/1pQq1pp1/7p/1P1P4/P4P2/6PP/R1R3K1 b - - +solution Re1+ +id "WAC.036" +go +setboard 2r5/2rk2pp/1pn1pb2/pN1p4/P2P4/1N2B3/nPR1KPPP/3R4 b - - +solution Nxd4+ +id "WAC.037" +go +setboard 4k3/p4prp/1p6/2b5/8/2Q3P1/P2R1PKP/4q3 w - - +solution Rd8+ +id "WAC.038" +go +setboard r1br2k1/pp2bppp/2nppn2/8/2P1PB2/2N2P2/PqN1B1PP/R2Q1R1K w - - +solution Na4 +id "WAC.039" +go +setboard 3r1r1k/1p4pp/p4p2/8/1PQR4/6Pq/P3PP2/2R3K1 b - - +solution Rc8 +id "WAC.040" +go +setboard 1k6/5RP1/1P6/1K6/6r1/8/8/8 w - - +solution Ka5 +solution Kc5 +id "WAC.041" +go +setboard r1b1r1k1/pp1n1pbp/1qp3p1/3p4/1B1P4/Q3PN2/PP2BPPP/R4RK1 w - - +solution Ba5 +id "WAC.042" +go +setboard r2q3k/p2P3p/1p3p2/3QP1r1/8/B7/P5PP/2R3K1 w - - +solution Be7 +solution Qxa8 +id "WAC.043" +go +setboard 3rb1k1/pq3pbp/4n1p1/3p4/2N5/2P2QB1/PP3PPP/1B1R2K1 b - - +solution dxc4 +id "WAC.044" +go +setboard 7k/2p1b1pp/8/1p2P3/1P3r2/2P3Q1/1P5P/R4qBK b - - +solution Qxa1 +id "WAC.045" +go +setboard r1bqr1k1/pp1nb1p1/4p2p/3p1p2/3P4/P1N1PNP1/1PQ2PP1/3RKB1R w K - +solution Nb5 +id "WAC.046" +go +setboard r1b2rk1/pp2bppp/2n1pn2/q5B1/2BP4/2N2N2/PP2QPPP/2R2RK1 b - - +solution Nxd4 +id "WAC.047" +go +setboard 1rbq1rk1/p1p1bppp/2p2n2/8/Q1BP4/2N5/PP3PPP/R1B2RK1 b - - +solution Rb4 +id "WAC.048" +go +setboard 2b3k1/4rrpp/p2p4/2pP2RQ/1pP1Pp1N/1P3P1P/1q6/6RK w - - +solution Qxh7+ +id "WAC.049" +go +setboard k4r2/1R4pb/1pQp1n1p/3P4/5p1P/3P2P1/r1q1R2K/8 w - - +solution Rxb6+ +id "WAC.050" +go +setboard r1bq1r2/pp4k1/4p2p/3pPp1Q/3N1R1P/2PB4/6P1/6K1 w - - +solution Rg4+ +id "WAC.051" +go +setboard r1k5/1p3q2/1Qpb4/3N1p2/5Pp1/3P2Pp/PPPK3P/4R3 w - - +solution Re7 +id "WAC.052" +go +setboard 6k1/6p1/p7/3Pn3/5p2/4rBqP/P4RP1/5QK1 b - - +solution Re1 +id "WAC.053" +go +setboard r3kr2/1pp4p/1p1p4/7q/4P1n1/2PP2Q1/PP4P1/R1BB2K1 b q - +solution Qh1+ +id "WAC.054" +go +setboard r3r1k1/pp1q1pp1/4b1p1/3p2B1/3Q1R2/8/PPP3PP/4R1K1 w - - +solution Qxg7+ +id "WAC.055" +go +setboard r1bqk2r/pppp1ppp/5n2/2b1n3/4P3/1BP3Q1/PP3PPP/RNB1K1NR b KQkq - +solution Bxf2+ +id "WAC.056" +go +setboard r3q1kr/ppp5/3p2pQ/8/3PP1b1/5R2/PPP3P1/5RK1 w - - +solution Rf8+ +id "WAC.057" +go +setboard 8/8/2R5/1p2qp1k/1P2r3/2PQ2P1/5K2/8 w - - +solution Qd1+ +id "WAC.058" +go +setboard r1b2rk1/2p1qnbp/p1pp2p1/5p2/2PQP3/1PN2N1P/PB3PP1/3R1RK1 w - - +solution Nd5 +id "WAC.059" +go +setboard rn1qr1k1/1p2np2/2p3p1/8/1pPb4/7Q/PB1P1PP1/2KR1B1R w - - +solution Qh8+ +id "WAC.060" +go +setboard 3qrbk1/ppp1r2n/3pP2p/3P4/2P4P/1P3Q2/PB6/R4R1K w - - +solution Qf7+ +id "WAC.061" +go +setboard 6r1/3Pn1qk/p1p1P1rp/2Q2p2/2P5/1P4P1/P3R2P/5RK1 b - - +solution Rxg3+ +id "WAC.062" +go +setboard r1brnbk1/ppq2pp1/4p2p/4N3/3P4/P1PB1Q2/3B1PPP/R3R1K1 w - - +solution Nxf7 +id "WAC.063" +go +setboard 8/6pp/3q1p2/3n1k2/1P6/3NQ2P/5PP1/6K1 w - - +solution g4+ +id "WAC.064" +go +setboard 1r1r1qk1/p2n1p1p/bp1Pn1pQ/2pNp3/2P2P1N/1P5B/P6P/3R1RK1 w - - +solution Ne7+ +id "WAC.065" +go +setboard 1k1r2r1/ppq5/1bp4p/3pQ3/8/2P2N2/PP4P1/R4R1K b - - +solution Qxe5 +id "WAC.066" +go +setboard 3r2k1/p2q4/1p4p1/3rRp1p/5P1P/6PK/P3R3/3Q4 w - - +solution Rxd5 +id "WAC.067" +go +setboard 6k1/5ppp/1q6/2b5/8/2R1pPP1/1P2Q2P/7K w - - +solution Qxe3 +id "WAC.068" +go +setboard 2k5/pppr4/4R3/4Q3/2pp2q1/8/PPP2PPP/6K1 w - - +solution f3 +solution h3 +id "WAC.069" +go +setboard 2kr3r/pppq1ppp/3p1n2/bQ2p3/1n1PP3/1PN1BN1P/1PP2PP1/2KR3R b - - +solution Na2+ +id "WAC.070" +go +setboard 2kr3r/pp1q1ppp/5n2/1Nb5/2Pp1B2/7Q/P4PPP/1R3RK1 w - - +solution Nxa7+ +id "WAC.071" +go +setboard r3r1k1/pp1n1ppp/2p5/4Pb2/2B2P2/B1P5/P5PP/R2R2K1 w - - +solution e6 +id "WAC.072" +go +setboard r1q3rk/1ppbb1p1/4Np1p/p3pP2/P3P3/2N4R/1PP1Q1PP/3R2K1 w - - +solution Qd2 +id "WAC.073" +go +setboard 5r1k/pp4pp/2p5/2b1P3/4Pq2/1PB1p3/P3Q1PP/3N2K1 b - - +solution Qf1+ +id "WAC.074" +go +setboard r3r1k1/pppq1ppp/8/8/1Q4n1/7P/PPP2PP1/RNB1R1K1 b - - +solution Qd6 +id "WAC.075" +go +setboard r1b1qrk1/2p2ppp/pb1pnn2/1p2pNB1/3PP3/1BP5/PP2QPPP/RN1R2K1 w - - +solution Bxf6 +id "WAC.076" +go +setboard 3r2k1/ppp2ppp/6q1/b4n2/3nQB2/2p5/P4PPP/RN3RK1 b - - +solution Ng3 +id "WAC.077" +go +setboard r2q3r/ppp2k2/4nbp1/5Q1p/2P1NB2/8/PP3P1P/3RR1K1 w - - +solution Ng5+ +id "WAC.078" +go +setboard r3k2r/pbp2pp1/3b1n2/1p6/3P3p/1B2N1Pq/PP1PQP1P/R1B2RK1 b kq - +solution Qxh2+ +id "WAC.079" +go +setboard r4rk1/p1B1bpp1/1p2pn1p/8/2PP4/3B1P2/qP2QP1P/3R1RK1 w - - +solution Ra1 +id "WAC.080" +go +setboard r4rk1/1bR1bppp/4pn2/1p2N3/1P6/P3P3/4BPPP/3R2K1 b - - +solution Bd6 +id "WAC.081" +go +setboard 3rr1k1/pp3pp1/4b3/8/2P1B2R/6QP/P3q1P1/5R1K w - - +solution Bh7+ +id "WAC.082" +go +setboard 3rr1k1/ppqbRppp/2p5/8/3Q1n2/2P3N1/PPB2PPP/3R2K1 w - - +solution Qxd7 +id "WAC.083" +go +setboard r2q1r1k/2p1b1pp/p1n5/1p1Q1bN1/4n3/1BP1B3/PP3PPP/R4RK1 w - - +solution Qg8+ +id "WAC.084" +go +setboard kr2R3/p4r2/2pq4/2N2p1p/3P2p1/Q5P1/5P1P/5BK1 w - - +solution Na6 +id "WAC.085" +go +setboard 8/p7/1ppk1n2/5ppp/P1PP4/2P1K1P1/5N1P/8 b - - +solution Ng4+ +id "WAC.086" +go +setboard 8/p3k1p1/4r3/2ppNpp1/PP1P4/2P3KP/5P2/8 b - - +solution Rxe5 +id "WAC.087" +go +setboard r6k/p1Q4p/2p1b1rq/4p3/B3P3/4P3/PPP3P1/4RRK1 b - - +solution Rxg2+ +id "WAC.088" +go +setboard 1r3b1k/p4rpp/4pp2/3q4/2ppbPPQ/6RK/PP5P/2B1NR2 b - - +solution g5 +id "WAC.089" +go +setboard 3qrrk1/1pp2pp1/1p2bn1p/5N2/2P5/P1P3B1/1P4PP/2Q1RRK1 w - - +solution Nxg7 +id "WAC.090" +go +setboard 2qr2k1/4b1p1/2p2p1p/1pP1p3/p2nP3/PbQNB1PP/1P3PK1/4RB2 b - - +solution Be6 +id "WAC.091" +go +setboard r4rk1/1p2ppbp/p2pbnp1/q7/3BPPP1/2N2B2/PPP4P/R2Q1RK1 b - - +solution Bxg4 +id "WAC.092" +go +setboard r1b1k1nr/pp3pQp/4pq2/3pn3/8/P1P5/2P2PPP/R1B1KBNR w KQkq - +solution Bh6 +id "WAC.093" +go +setboard 8/k7/p7/3Qp2P/n1P5/3KP3/1q6/8 b - - +solution e4+ +id "WAC.094" +go +setboard 2r5/1r6/4pNpk/3pP1qp/8/2P1QP2/5PK1/R7 w - - +solution Ng4+ +id "WAC.095" +go +setboard r1b4k/ppp2Bb1/6Pp/3pP3/1qnP1p1Q/8/PPP3P1/1K1R3R w - - +solution Qd8+ +id "WAC.096" +go +setboard 6k1/5p2/p5np/4B3/3P4/1PP1q3/P3r1QP/6RK w - - +solution Qa8+ +id "WAC.097" +go +setboard 1r3rk1/5pb1/p2p2p1/Q1n1q2p/1NP1P3/3p1P1B/PP1R3P/1K2R3 b - - +solution Nxe4 +id "WAC.098" +go +setboard r1bq1r1k/1pp1Np1p/p2p2pQ/4R3/n7/8/PPPP1PPP/R1B3K1 w - - +solution Rh5 +id "WAC.099" +go +setboard 8/k1b5/P4p2/1Pp2p1p/K1P2P1P/8/3B4/8 w - - +solution b6+ +id "WAC.100" +go +setboard 5rk1/p5pp/8/8/2Pbp3/1P4P1/7P/4RN1K b - - +solution Bc3 +id "WAC.101" +go +setboard 2Q2n2/2R4p/1p1qpp1k/8/3P3P/3B2P1/5PK1/r7 w - - +solution Qxf8+ +id "WAC.102" +go +setboard 6k1/2pb1r1p/3p1PpQ/p1nPp3/1q2P3/2N2P2/PrB5/2K3RR w - - +solution Qxg6+ +id "WAC.103" +go +setboard b4r1k/pq2rp2/1p1bpn1p/3PN2n/2P2P2/P2B3K/1B2Q2N/3R2R1 w - - +solution Qxh5 +id "WAC.104" +go +setboard r2r2k1/pb3ppp/1p1bp3/7q/3n2nP/PP1B2P1/1B1N1P2/RQ2NRK1 b - - +solution Qxh4 +id "WAC.105" +go +setboard 4rrk1/pppb4/7p/3P2pq/3Qn3/P5P1/1PP4P/R3RNNK b - - +solution Nf2+ +id "WAC.106" +go +setboard 5n2/pRrk2p1/P4p1p/4p3/3N4/5P2/6PP/6K1 w - - +solution Nb5 +id "WAC.107" +go +setboard r5k1/1q4pp/2p5/p1Q5/2P5/5R2/4RKPP/r7 w - - +solution Qe5 +id "WAC.108" +go +setboard rn2k1nr/pbp2ppp/3q4/1p2N3/2p5/QP6/PB1PPPPP/R3KB1R b KQkq - +solution c3 +id "WAC.109" +go +setboard 2kr4/bp3p2/p2p2b1/P7/2q5/1N4B1/1PPQ2P1/2KR4 b - - +solution Be3 +id "WAC.110" +go +setboard 6k1/p5p1/5p2/2P2Q2/3pN2p/3PbK1P/7P/6q1 b - - +solution Qf1+ +id "WAC.111" +go +setboard r4kr1/ppp5/4bq1b/7B/2PR1Q1p/2N3P1/PP3P1P/2K1R3 w - - +solution Rxe6 +id "WAC.112" +go +setboard rnbqkb1r/1p3ppp/5N2/1p2p1B1/2P5/8/PP2PPPP/R2QKB1R b KQkq - +solution Qxf6 +id "WAC.113" +go +setboard r1b1rnk1/1p4pp/p1p2p2/3pN2n/3P1PPq/2NBPR1P/PPQ5/2R3K1 w - - +solution Bxh7+ +id "WAC.114" +go +setboard 4N2k/5rpp/1Q6/p3q3/8/P5P1/1P3P1P/5K2 w - - +solution Nd6 +id "WAC.115" +go +setboard r2r2k1/2p2ppp/p7/1p2P1n1/P6q/5P2/1PB1QP1P/R5RK b - - +solution Rd2 +id "WAC.116" +go +setboard 3r1rk1/q4ppp/p1Rnp3/8/1p6/1N3P2/PP3QPP/3R2K1 b - - +solution Ne4 +id "WAC.117" +go +setboard r5k1/pb2rpp1/1p6/2p4q/5R2/2PB2Q1/P1P3PP/5R1K w - - +solution Rh4 +id "WAC.118" +go +setboard r2qr1k1/p1p2ppp/2p5/2b5/4nPQ1/3B4/PPP3PP/R1B2R1K b - - +solution Qxd3 +id "WAC.119" +go +setboard r4rk1/1bn2qnp/3p1B1Q/p2P1pP1/1pp5/5N1P/PPB2P2/2KR3R w - - +solution g6 +id "WAC.120" +go +setboard 6k1/5p1p/2bP2pb/4p3/2P5/1p1pNPPP/1P1Q1BK1/1q6 b - - +solution Bxf3+ +id "WAC.121" +go +setboard 1k6/ppp4p/1n2pq2/1N2Rb2/2P2Q2/8/P4KPP/3r1B2 b - - +solution Rxf1+ +id "WAC.122" +go +setboard 6k1/1b2rp2/1p4p1/3P4/PQ4P1/2N2q2/5P2/3R2K1 b - - +solution Bxd5 +solution Rc7 +id "WAC.123" +go +setboard 6k1/3r4/2R5/P5P1/1P4p1/8/4rB2/6K1 b - - +solution g3 +id "WAC.124" +go +setboard r1bqr1k1/pp3ppp/1bp5/3n4/3B4/2N2P1P/PPP1B1P1/R2Q1RK1 b - - +solution Bxd4+ +id "WAC.125" +go +setboard r5r1/pQ5p/1qp2R2/2k1p3/4P3/2PP4/P1P3PP/6K1 w - - +solution Rxc6+ +id "WAC.126" +go +setboard 2k4r/1pr1n3/p1p1q2p/5pp1/3P1P2/P1P1P3/1R2Q1PP/1RB3K1 w - - +solution Rxb7 +id "WAC.127" +go +setboard 6rk/1pp2Qrp/3p1B2/1pb1p2R/3n1q2/3P4/PPP3PP/R6K w - - +solution Qg6 +id "WAC.128" +go +setboard 3r1r1k/1b2b1p1/1p5p/2p1Pp2/q1B2P2/4P2P/1BR1Q2K/6R1 b - - +solution Bf3 +id "WAC.129" +go +setboard 6k1/1pp3q1/5r2/1PPp4/3P1pP1/3Qn2P/3B4/4R1K1 b - - +solution Qh6 +solution Qh8 +id "WAC.130" +go +setboard 2rq1bk1/p4p1p/1p4p1/3b4/3B1Q2/8/P4PpP/3RR1K1 w - - +solution Re8 +id "WAC.131" +go +setboard 4r1k1/5bpp/2p5/3pr3/8/1B3pPq/PPR2P2/2R2QK1 b - - +solution Re1 +id "WAC.132" +go +setboard r1b1k2r/1pp1q2p/p1n3p1/3QPp2/8/1BP3B1/P5PP/3R1RK1 w kq - +solution Bh4 +id "WAC.133" +go +setboard 3r2k1/p6p/2Q3p1/4q3/2P1p3/P3Pb2/1P3P1P/2K2BR1 b - - +solution Rd1+ +id "WAC.134" +go +setboard 3r1r1k/N2qn1pp/1p2np2/2p5/2Q1P2N/3P4/PP4PP/3R1RK1 b - - +solution Nd4 +id "WAC.135" +go +setboard 6kr/1q2r1p1/1p2N1Q1/5p2/1P1p4/6R1/7P/2R3K1 w - - +solution Rc8+ +id "WAC.136" +go +setboard 3b1rk1/1bq3pp/5pn1/1p2rN2/2p1p3/2P1B2Q/1PB2PPP/R2R2K1 w - - +solution Rd7 +id "WAC.137" +go +setboard r1bq3r/ppppR1p1/5n1k/3P4/6pP/3Q4/PP1N1PP1/5K1R w - - +solution h5 +id "WAC.138" +go +setboard rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - +solution Nf6+ +id "WAC.139" +go +setboard r2b1rk1/pq4p1/4ppQP/3pB1p1/3P4/2R5/PP3PP1/5RK1 w - - +solution Rc7 +id "WAC.140" +go +setboard 4r1k1/p1qr1p2/2pb1Bp1/1p5p/3P1n1R/1B3P2/PP3PK1/2Q4R w - - +solution Qxf4 +id "WAC.141" +go +setboard r2q3n/ppp2pk1/3p4/5Pr1/2NP1Qp1/2P2pP1/PP3K2/4R2R w - - +solution Re8 +solution f6+ +id "WAC.142" +go +setboard 5b2/pp2r1pk/2pp1pRp/4rP1N/2P1P3/1P4QP/P3q1P1/5R1K w - - +solution Rxh6+ +id "WAC.143" +go +setboard r2q1rk1/pp3ppp/2p2b2/8/B2pPPb1/7P/PPP1N1P1/R2Q1RK1 b - - +solution d3 +id "WAC.144" +go +setboard r1bq4/1p4kp/3p1n2/p4pB1/2pQ4/8/1P4PP/4RRK1 w - - +solution Re8 +id "WAC.145" +go +setboard 8/8/2Kp4/3P1B2/2P2k2/5p2/8/8 w - - +solution Bc8 +id "WAC.146" +go +setboard r2r2k1/ppqbppbp/2n2np1/2pp4/6P1/1P1PPNNP/PBP2PB1/R2QK2R b KQ - +solution Nxg4 +id "WAC.147" +go +setboard 2r1k3/6pr/p1nBP3/1p3p1p/2q5/2P5/P1R4P/K2Q2R1 w - - +solution Rxg7 +id "WAC.148" +go +setboard 6k1/6p1/2p4p/4Pp2/4b1qP/2Br4/1P2RQPK/8 b - - +solution Bxg2 +id "WAC.149" +go +setboard r3r1k1/5p2/pQ1b2pB/1p6/4p3/6P1/Pq2BP1P/2R3K1 b - - +solution Ba3 +solution Bf8 +solution e3 +id "WAC.150" +go +setboard 8/3b2kp/4p1p1/pr1n4/N1N4P/1P4P1/1K3P2/3R4 w - - +solution Nc3 +id "WAC.151" +go +setboard 1br2rk1/1pqb1ppp/p3pn2/8/1P6/P1N1PN1P/1B3PP1/1QRR2K1 w - - +solution Ne4 +id "WAC.152" +go +setboard 2r3k1/q4ppp/p3p3/pnNp4/2rP4/2P2P2/4R1PP/2R1Q1K1 b - - +solution Nxd4 +id "WAC.153" +go +setboard r1b2rk1/2p2ppp/p7/1p6/3P3q/1BP3bP/PP3QP1/RNB1R1K1 w - - +solution Qxf7+ +id "WAC.154" +go +setboard 5bk1/1rQ4p/5pp1/2pP4/3n1PP1/7P/1q3BB1/4R1K1 w - - +solution d6 +id "WAC.155" +go +setboard r1b1qN1k/1pp3p1/p2p3n/4p1B1/8/1BP4Q/PP3KPP/8 w - - +solution Qxh6+ +id "WAC.156" +go +setboard 5rk1/p4ppp/2p1b3/3Nq3/4P1n1/1p1B2QP/1PPr2P1/1K2R2R w - - +solution Ne7+ +id "WAC.157" +go +setboard 5rk1/n1p1R1bp/p2p4/1qpP1QB1/7P/2P3P1/PP3P2/6K1 w - - +solution Rxg7+ +id "WAC.158" +go +setboard r1b2r2/5P1p/ppn3pk/2p1p1Nq/1bP1PQ2/3P4/PB4BP/1R3RK1 w - - +solution Ne6+ +id "WAC.159" +go +setboard qn1kr2r/1pRbb3/pP5p/P2pP1pP/3N1pQ1/3B4/3B1PP1/R5K1 w - - +solution Qxd7+ +id "WAC.160" +go +setboard 3r3k/3r1P1p/pp1Nn3/2pp4/7Q/6R1/Pq4PP/5RK1 w - - +solution Qxd8+ +id "WAC.161" +go +setboard r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - +solution Bd5 +id "WAC.162" +go +setboard 5rk1/2p4p/2p4r/3P4/4p1b1/1Q2NqPp/PP3P1K/R4R2 b - - +solution Qg2+ +id "WAC.163" +go +setboard 8/6pp/4p3/1p1n4/1NbkN1P1/P4P1P/1PR3K1/r7 w - - +solution Rxc4+ +id "WAC.164" +go +setboard 1r5k/p1p3pp/8/8/4p3/P1P1R3/1P1Q1qr1/2KR4 w - - +solution Re2 +id "WAC.165" +go +setboard r3r1k1/5pp1/p1p4p/2Pp4/8/q1NQP1BP/5PP1/4K2R b K - +solution d4 +id "WAC.166" +go +setboard 7Q/ppp2q2/3p2k1/P2Ppr1N/1PP5/7R/5rP1/6K1 b - - +solution Rxg2+ +id "WAC.167" +go +setboard r3k2r/pb1q1p2/8/2p1pP2/4p1p1/B1P1Q1P1/P1P3K1/R4R2 b kq - +solution Qd2+ +id "WAC.168" +go +setboard 5rk1/1pp3bp/3p2p1/2PPp3/1P2P3/2Q1B3/4q1PP/R5K1 b - - +solution Bh6 +id "WAC.169" +go +setboard 5r1k/6Rp/1p2p3/p2pBp2/1qnP4/4P3/Q4PPP/6K1 w - - +solution Qxc4 +id "WAC.170" +go +setboard 2rq4/1b2b1kp/p3p1p1/1p1nNp2/7P/1B2B1Q1/PP3PP1/3R2K1 w - - +solution Bh6+ +id "WAC.171" +go +setboard 5r1k/p5pp/8/1P1pq3/P1p2nR1/Q7/5BPP/6K1 b - - +solution Qe1+ +id "WAC.172" +go +setboard 2r1b3/1pp1qrk1/p1n1P1p1/7R/2B1p3/4Q1P1/PP3PP1/3R2K1 w - - +solution Qh6+ +id "WAC.173" +go +setboard 2r2rk1/6p1/p3pq1p/1p1b1p2/3P1n2/PP3N2/3N1PPP/1Q2RR1K b - - +solution Nxg2 +id "WAC.174" +go +setboard r5k1/pppb3p/2np1n2/8/3PqNpP/3Q2P1/PPP5/R4RK1 w - - +solution Nh5 +id "WAC.175" +go +setboard r1bq3r/ppp2pk1/3p1pp1/8/2BbPQ2/2NP2P1/PPP4P/R4R1K b - - +solution Rxh2+ +id "WAC.176" +go +setboard r1b3r1/4qk2/1nn1p1p1/3pPp1P/p4P2/1p3BQN/PKPBN3/3R3R b - - +solution Qa3+ +id "WAC.177" +go +setboard 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - +solution Nxe6 +id "WAC.178" +go +setboard r1b2r1k/pp4pp/3p4/3B4/8/1QN3Pn/PP3q1P/R3R2K b - - +solution Qg1+ +id "WAC.179" +go +setboard r1q2rk1/p3bppb/3p1n1p/2nPp3/1p2P1P1/6NP/PP2QPB1/R1BNK2R b KQ - +solution Nxd5 +id "WAC.180" +go +setboard r3k2r/2p2p2/p2p1n2/1p2p3/4P2p/1PPPPp1q/1P5P/R1N2QRK b kq - +solution Ng4 +id "WAC.181" +go +setboard r1b2rk1/ppqn1p1p/2n1p1p1/2b3N1/2N5/PP1BP3/1B3PPP/R2QK2R w KQ - +solution Qh5 +id "WAC.182" +go +setboard 1r2k1r1/5p2/b3p3/1p2b1B1/3p3P/3B4/PP2KP2/2R3R1 w - - +solution Bf6 +id "WAC.183" +go +setboard 4kn2/r4p1r/p3bQ2/q1nNP1Np/1p5P/8/PPP3P1/2KR3R w - - +solution Qe7+ +id "WAC.184" +go +setboard 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - +solution Qxh7+ +id "WAC.185" +go +setboard r5r1/p1q2p1k/1p1R2pB/3pP3/6bQ/2p5/P1P1NPPP/6K1 w - - +solution Bf8+ +id "WAC.186" +go +setboard 6k1/5p2/p3p3/1p3qp1/2p1Qn2/2P1R3/PP1r1PPP/4R1K1 b - - +solution Nh3+ +id "WAC.187" +go +setboard 3RNbk1/pp3p2/4rQpp/8/1qr5/7P/P4P2/3R2K1 w - - +solution Qg7+ +id "WAC.188" +go +setboard 3r1k2/1ppPR1n1/p2p1rP1/3P3p/4Rp1N/5K2/P1P2P2/8 w - - +solution Re8+ +id "WAC.189" +go +setboard 8/p2b2kp/1q1p2p1/1P1Pp3/4P3/3B2P1/P2Q3P/2Nn3K b - - +solution Bh3 +id "WAC.190" +go +setboard 2r1Rn1k/1p1q2pp/p7/5p2/3P4/1B4P1/P1P1QP1P/6K1 w - - +solution Qc4 +id "WAC.191" +go +setboard r3k3/ppp2Npp/4Bn2/2b5/1n1pp3/N4P2/PPP3qP/R2QKR2 b Qq - +solution Nd3+ +id "WAC.192" +go +setboard 5bk1/p4ppp/Qp6/4B3/1P6/Pq2P1P1/2rr1P1P/R4RK1 b - - +solution Qxe3 +id "WAC.193" +go +setboard 5rk1/ppq2ppp/2p5/4bN2/4P3/6Q1/PPP2PPP/3R2K1 w - - +solution Nh6+ +id "WAC.194" +go +setboard 3r1rk1/1p3p2/p3pnnp/2p3p1/2P2q2/1P5P/PB2QPPN/3RR1K1 w - - +solution g3 +id "WAC.195" +go +setboard rr4k1/p1pq2pp/Q1n1pn2/2bpp3/4P3/2PP1NN1/PP3PPP/R1B1K2R b KQ - +solution Nb4 +id "WAC.196" +go +setboard 7k/1p4p1/7p/3P1n2/4Q3/2P2P2/PP3qRP/7K b - - +solution Qf1+ +id "WAC.197" +go +setboard 2br2k1/ppp2p1p/4p1p1/4P2q/2P1Bn2/2Q5/PP3P1P/4R1RK b - - +solution Rd3 +id "WAC.198" +go +setboard r1br2k1/pp2nppp/2n5/1B1q4/Q7/4BN2/PP3PPP/2R2RK1 w - - +solution Bxc6 +solution Rfd1 +id "WAC.199" +go +setboard 2rqrn1k/pb4pp/1p2pp2/n2P4/2P3N1/P2B2Q1/1B3PPP/2R1R1K1 w - - +solution Bxf6 +id "WAC.200" +go +setboard 2b2r1k/4q2p/3p2pQ/2pBp3/8/6P1/1PP2P1P/R5K1 w - - +solution Ra7 +id "WAC.201" +go +setboard QR2rq1k/2p3p1/3p1pPp/8/4P3/8/P1r3PP/1R4K1 b - - +solution Rxa2 +id "WAC.202" +go +setboard r4rk1/5ppp/p3q1n1/2p2NQ1/4n3/P3P3/1B3PPP/1R3RK1 w - - +solution Qh6 +id "WAC.203" +go +setboard r1b1qrk1/1p3ppp/p1p5/3Nb3/5N2/P7/1P4PQ/K1R1R3 w - - +solution Rxe5 +id "WAC.204" +go +setboard r3rnk1/1pq2bb1/p4p2/3p1Pp1/3B2P1/1NP4R/P1PQB3/2K4R w - - +solution Qxg5 +id "WAC.205" +go +setboard 1Qq5/2P1p1kp/3r1pp1/8/8/7P/p4PP1/2R3K1 b - - +solution Rc6 +id "WAC.206" +go +setboard r1bq2kr/p1pp1ppp/1pn1p3/4P3/2Pb2Q1/BR6/P4PPP/3K1BNR w - - +solution Qxg7+ +id "WAC.207" +go +setboard 3r1bk1/ppq3pp/2p5/2P2Q1B/8/1P4P1/P6P/5RK1 w - - +solution Bf7+ +id "WAC.208" +go +setboard 4kb1r/2q2p2/r2p4/pppBn1B1/P6P/6Q1/1PP5/2KRR3 w k - +solution Rxe5+ +id "WAC.209" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Rh1 +id "WAC.210" +go +setboard r1bqrk2/pp1n1n1p/3p1p2/P1pP1P1Q/2PpP1NP/6R1/2PB4/4RBK1 w - - +solution Qxf7+ +id "WAC.211" +go +setboard rn1qr2Q/pbppk1p1/1p2pb2/4N3/3P4/2N5/PPP3PP/R4RK1 w - - +solution Qxg7+ +id "WAC.212" +go +setboard 3r1r1k/1b4pp/ppn1p3/4Pp1R/Pn5P/3P4/4QP2/1qB1NKR1 w - - +solution Rxh7+ +id "WAC.213" +go +setboard r2r2k1/1p2qpp1/1np1p1p1/p3N3/2PPN3/bP5R/4QPPP/4R1K1 w - - +solution Ng5 +id "WAC.214" +go +setboard 3r2k1/pb1q1pp1/1p2pb1p/8/3N4/P2QB3/1P3PPP/1Br1R1K1 w - - +solution Qh7+ +id "WAC.215" +go +setboard r2qr1k1/1b1nbppp/p3pn2/1p1pN3/3P1B2/2PB1N2/PP2QPPP/R4RK1 w - - +solution Nxf7 +id "WAC.216" +go +setboard r3kb1r/1pp3p1/p3bp1p/5q2/3QN3/1P6/PBP3P1/3RR1K1 w kq - +solution Qd7+ +id "WAC.217" +go +setboard 6k1/pp5p/2p3q1/6BP/2nPr1Q1/8/PP3R1K/8 w - - +solution Bh6 +id "WAC.218" +go +setboard 7k/p4q1p/1pb5/2p5/4B2Q/2P1B3/P6P/7K b - - +solution Qf1+ +id "WAC.219" +go +setboard 3rr1k1/ppp2ppp/8/5Q2/4n3/1B5R/PPP1qPP1/5RK1 b - - +solution Qxf1+ +id "WAC.220" +go +setboard r3k3/P5bp/2N1bp2/4p3/2p5/6NP/1PP2PP1/3R2K1 w q - +solution Rd8+ +id "WAC.221" +go +setboard 2r1r2k/1q3ppp/p2Rp3/2p1P3/6QB/p3P3/bP3PPP/3R2K1 w - - +solution Bf6 +id "WAC.222" +go +setboard r1bqk2r/pp3ppp/5n2/8/1b1npB2/2N5/PP1Q2PP/1K2RBNR w kq - +solution Nxe4 +id "WAC.223" +go +setboard 5rk1/p1q3pp/1p1r4/2p1pp1Q/1PPn1P2/3B3P/P2R2P1/3R2K1 b - - +solution Rh6 +solution e4 +id "WAC.224" +go +setboard 4R3/4q1kp/6p1/1Q3b2/1P1b1P2/6KP/8/8 b - - +solution Qh4+ +id "WAC.225" +go +setboard 2b2rk1/p1p4p/2p1p1p1/br2N1Q1/1p2q3/8/PB3PPP/3R1RK1 w - - +solution Nf7 +id "WAC.226" +go +setboard 2k1rb1r/ppp3pp/2np1q2/5b2/2B2P2/2P1BQ2/PP1N1P1P/2KR3R b - - +solution d5 +id "WAC.227" +go +setboard r4rk1/1bq1bp1p/4p1p1/p2p4/3BnP2/1N1B3R/PPP3PP/R2Q2K1 w - - +solution Bxe4 +id "WAC.228" +go +setboard 8/8/8/1p5r/p1p1k1pN/P2pBpP1/1P1K1P2/8 b - - +solution Rxh4 +solution b4 +id "WAC.229" +go +setboard 2b5/1r6/2kBp1p1/p2pP1P1/2pP4/1pP3K1/1R3P2/8 b - - +solution Rb4 +id "WAC.230" +go +setboard r4rk1/1b1nqp1p/p5p1/1p2PQ2/2p5/5N2/PP3PPP/R1BR2K1 w - - +solution Bg5 +id "WAC.231" +go +setboard 1R2rq1k/2p3p1/Q2p1pPp/8/4P3/8/P1r3PP/1R4K1 w - - +solution Qb5 +solution Rxe8 +id "WAC.232" +go +setboard 5rk1/p1p2r1p/2pp2p1/4p3/PPPnP3/3Pq1P1/1Q1R1R1P/4NK2 b - - +solution Nb3 +id "WAC.233" +go +setboard 2kr1r2/p6p/5Pp1/2p5/1qp2Q1P/7R/PP6/1KR5 w - - +solution Rb3 +id "WAC.234" +go +setboard 5r2/1p1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +solution Rxf7+ +id "WAC.235" +go +setboard 1R6/p5pk/4p2p/4P3/8/2r3qP/P3R1b1/4Q1K1 b - - +solution Rc1 +id "WAC.236" +go +setboard r5k1/pQp2qpp/8/4pbN1/3P4/6P1/PPr4P/1K1R3R b - - +solution Rc1+ +id "WAC.237" +go +setboard 1k1r4/pp1r1pp1/4n1p1/2R5/2Pp1qP1/3P2QP/P4PB1/1R4K1 w - - +solution Bxb7 +id "WAC.238" +go +setboard 8/6k1/5pp1/Q6p/5P2/6PK/P4q1P/8 b - - +solution Qf1+ +id "WAC.239" +go +setboard 2b4k/p1b2p2/2p2q2/3p1PNp/3P2R1/3B4/P1Q2PKP/4r3 w - - +solution Qxc6 +id "WAC.240" +go +setboard 2rq1rk1/pp3ppp/2n2b2/4NR2/3P4/PB5Q/1P4PP/3R2K1 w - - +solution Qxh7+ +id "WAC.241" +go +setboard r1b1r1k1/pp1nqp2/2p1p1pp/8/4N3/P1Q1P3/1P3PPP/1BRR2K1 w - - +solution Rxd7 +id "WAC.242" +go +setboard 1r3r1k/3p4/1p1Nn1R1/4Pp1q/pP3P1p/P7/5Q1P/6RK w - - +solution Qe2 +id "WAC.243" +go +setboard r6r/pp3ppp/3k1b2/2pb4/B4Pq1/2P1Q3/P5PP/1RBR2K1 w - - +solution Qxc5+ +id "WAC.244" +go +setboard 4rrn1/ppq3bk/3pPnpp/2p5/2PB4/2NQ1RPB/PP5P/5R1K w - - +solution Qxg6+ +id "WAC.245" +go +setboard 6R1/4qp1p/ppr1n1pk/8/1P2P1QP/6N1/P4PP1/6K1 w - - +solution Qh5+ +id "WAC.246" +go +setboard 2k1r3/1p2Bq2/p2Qp3/Pb1p1p1P/2pP1P2/2P5/2P2KP1/1R6 w - - +solution Rxb5 +id "WAC.247" +go +setboard 5r1k/1p4pp/3q4/3Pp1R1/8/8/PP4PP/4Q1K1 b - - +solution Qc5+ +id "WAC.248" +go +setboard r4rk1/pbq2pp1/1ppbpn1p/8/2PP4/1P1Q1N2/PBB2PPP/R3R1K1 w - - +solution c5 +solution d5 +id "WAC.249" +go +setboard 1b5k/7P/p1p2np1/2P2p2/PP3P2/4RQ1R/q2r3P/6K1 w - - +solution Re8+ +id "WAC.250" +go +setboard k7/p4p2/P1q1b1p1/3p3p/3Q4/7P/5PP1/1R4K1 w - - +solution Qe5 +solution Qf4 +id "WAC.251" +go +setboard 1rb1r1k1/p1p2ppp/5n2/2pP4/5P2/2QB4/qNP3PP/2KRB2R b - - +solution Re2 +id "WAC.252" +go +setboard k5r1/p4b2/2P5/5p2/3P1P2/4QBrq/P5P1/4R1K1 w - - +solution Qe8+ +id "WAC.253" +go +setboard r6k/pp3p1p/2p1bp1q/b3p3/4Pnr1/2PP2NP/PP1Q1PPN/R2B2RK b - - +solution Nxh3 +id "WAC.254" +go +setboard 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - +solution Rfxg6+ +id "WAC.255" +go +setboard 3r1rk1/1pb1qp1p/2p3p1/p7/P2Np2R/1P5P/1BP2PP1/3Q1BK1 w - - +solution Nf5 +id "WAC.256" +go +setboard 4r1k1/pq3p1p/2p1r1p1/2Q1p3/3nN1P1/1P6/P1P2P1P/3RR1K1 w - - +solution Rxd4 +id "WAC.257" +go +setboard r3brkn/1p5p/2p2Ppq/2Pp3B/3Pp2Q/4P1R1/6PP/5R1K w - - +solution Bxg6 +id "WAC.258" +go +setboard r1bq1rk1/ppp2ppp/2np4/2bN1PN1/2B1P3/3p4/PPP2nPP/R1BQ1K1R w - - +solution Qh5 +id "WAC.259" +go +setboard 2r2b1r/p1Nk2pp/3p1p2/N2Qn3/4P3/q6P/P4PP1/1R3K1R w - - +solution Qe6+ +id "WAC.260" +go +setboard r5k1/1bp3pp/p2p4/1p6/5p2/1PBP1nqP/1PP3Q1/R4R1K b - - +solution Nd4 +id "WAC.261" +go +setboard 6k1/p1B1b2p/2b3r1/2p5/4p3/1PP1N1Pq/P2R1P2/3Q2K1 b - - +solution Rh6 +id "WAC.262" +go +setboard rnbqr2k/pppp1Qpp/8/b2NN3/2B1n3/8/PPPP1PPP/R1B1K2R w KQ - +solution Qg8+ +id "WAC.263" +go +setboard r2r2k1/1R2qp2/p5pp/2P5/b1PN1b2/P7/1Q3PPP/1B1R2K1 b - - +solution Rab8 +id "WAC.264" +go +setboard 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - +solution exf6 +id "WAC.265" +go +setboard r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - +solution Rxh2+ +id "WAC.266" +go +setboard 2r1kb1r/pp3ppp/2n1b3/1q1N2B1/1P2Q3/8/P4PPP/3RK1NR w Kk - +solution Nc7+ +id "WAC.267" +go +setboard 2r3kr/ppp2n1p/7B/5q1N/1bp5/2Pp4/PP2RPPP/R2Q2K1 w - - +solution Re8+ +id "WAC.268" +go +setboard 2kr2nr/pp1n1ppp/2p1p3/q7/1b1P1B2/P1N2Q1P/1PP1BPP1/R3K2R w KQ - +solution axb4 +id "WAC.269" +go +setboard 2r1r1k1/pp1q1ppp/3p1b2/3P4/3Q4/5N2/PP2RPPP/4R1K1 w - - +solution Qg4 +id "WAC.270" +go +setboard 2kr4/ppp3Pp/4RP1B/2r5/5P2/1P6/P2p4/3K4 w - - +solution Rd6 +id "WAC.271" +go +setboard nrq4r/2k1p3/1p1pPnp1/pRpP1p2/P1P2P2/2P1BB2/1R2Q1P1/6K1 w - - +solution Bxc5 +id "WAC.272" +go +setboard 2k4B/bpp1qp2/p1b5/7p/1PN1n1p1/2Pr4/P5PP/R3QR1K b - - +solution Ng3+ +id "WAC.273" +go +setboard 8/1p6/p5R1/k7/Prpp4/K7/1NP5/8 w - - +solution Rb6 +id "WAC.274" +go +setboard r1b2rk1/1p1n1ppp/p1p2q2/4p3/P1B1Pn2/1QN2N2/1P3PPP/3R1RK1 b - - +solution Nxg2 +solution b5 +id "WAC.275" +go +setboard r5k1/pp1RR1pp/1b6/6r1/2p5/B6P/P4qPK/3Q4 w - - +solution Qd5+ +id "WAC.276" +go +setboard 1r4r1/p2kb2p/bq2p3/3p1p2/5P2/2BB3Q/PP4PP/3RKR2 b - - +solution Rg3 +solution Rxg2 +id "WAC.277" +go +setboard r2qkb1r/pppb2pp/2np1n2/5pN1/2BQP3/2N5/PPP2PPP/R1B1K2R w KQkq - +solution Bf7+ +id "WAC.278" +go +setboard r7/4b3/2p1r1k1/1p1pPp1q/1P1P1P1p/PR2NRpP/2Q3K1/8 w - - +solution Nxf5 +id "WAC.279" +go +setboard r1r2bk1/5p1p/pn4p1/N2b4/3Pp3/B3P3/2q1BPPP/RQ3RK1 b - - +solution Bxa3 +id "WAC.280" +go +setboard 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - +solution Rxh7+ +id "WAC.281" +go +setboard 6k1/2p3p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - +solution Rh8+ +id "WAC.282" +go +setboard 3q1rk1/4bp1p/1n2P2Q/3p1p2/6r1/Pp2R2N/1B4PP/7K w - - +solution Ng5 +id "WAC.283" +go +setboard 3r3k/pp4pp/8/1P6/3N4/Pn2P1qb/1B1Q2B1/2R3K1 w - - +solution Nf5 +id "WAC.284" +go +setboard 2rr3k/1b2bppP/p2p1n2/R7/3P4/1qB2P2/1P4Q1/1K5R w - - +solution Qxg7+ +id "WAC.285" +go +setboard 3r1k2/1p6/p4P2/2pP2Qb/8/1P1KB3/P6r/8 b - - +solution Rxd5+ +id "WAC.286" +go +setboard rn3k1r/pp2bBpp/2p2n2/q5N1/3P4/1P6/P1P3PP/R1BQ1RK1 w - - +solution Qh5 +id "WAC.287" +go +setboard r1b2rk1/p4ppp/1p1Qp3/4P2N/1P6/8/P3qPPP/3R1RK1 w - - +solution Nf6+ +id "WAC.288" +go +setboard 2r3k1/5p1p/p3q1p1/2n3P1/1p1QP2P/1P4N1/PK6/2R5 b - - +solution Qe5 +id "WAC.289" +go +setboard 2k2r2/2p5/1pq5/p1p1n3/P1P2n1B/1R4Pp/2QR4/6K1 b - - +solution Ne2+ +id "WAC.290" +go +setboard 5r1k/3b2p1/p6p/1pRpR3/1P1P2q1/P4pP1/5QnP/1B4K1 w - - +solution h3 +id "WAC.291" +go +setboard 4r3/1Q1qk2p/p4pp1/3Pb3/P7/6PP/5P2/4R1K1 w - - +solution d6+ +id "WAC.292" +go +setboard 1nbq1r1k/3rbp1p/p1p1pp1Q/1p6/P1pPN3/5NP1/1P2PPBP/R4RK1 w - - +solution Nfg5 +id "WAC.293" +go +setboard 3r3k/1r3p1p/p1pB1p2/8/p1qNP1Q1/P6P/1P4P1/3R3K w - - +solution Bf8 +solution Nf5 +solution Qf4 +id "WAC.294" +go +setboard 4r3/p4r1p/R1p2pp1/1p1bk3/4pNPP/2P1K3/2P2P2/3R4 w - - +solution Rxd5+ +id "WAC.295" +go +setboard 3r4/1p2k2p/p1b1p1p1/4Q1Pn/2B3KP/4pP2/PP2R1N1/6q1 b - - +solution Rd4+ +solution Rf8 +id "WAC.296" +go +setboard 3r1rk1/p3qp1p/2bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxg2 +solution Bxh2+ +id "WAC.297" +go +setboard 3Q4/p3b1k1/2p2rPp/2q5/4B3/P2P4/7P/6RK w - - +solution Qh8+ +id "WAC.298" +go +setboard 1n2rr2/1pk3pp/pNn2p2/2N1p3/8/6P1/PP2PPKP/2RR4 w - - +solution Nca4 +id "WAC.299" +go +setboard b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1K1/8 w - - +solution g6 +id "WAC.300" +go +version +quit diff --git a/tests/mes400.ep_ b/tests/mes400.ep_ new file mode 100644 index 0000000..def6be7 --- /dev/null +++ b/tests/mes400.ep_ @@ -0,0 +1,1600 @@ +setboard 8/6p1/7k/8/1K6/8/1P6/8 w - - +id "MES.0001" +solution Kc5 +go +setboard 8/8/8/2p5/8/8/1kP5/3K4 w - - +id "MES.0002" +solution c4 +go +setboard 7K/8/k1P5/7p/8/8/8/8 w - - +id "MES.0003" +solution Kg7 +go +setboard 8/8/1p6/8/8/P7/8/5k1K w - - +id "MES.0004" +solution Kh2 +go +setboard 8/8/8/8/8/P4p2/k6K/8 w - - +id "MES.0005" +solution a4 +go +setboard 8/8/6p1/1k6/4K3/8/5P2/8 w - - +id "MES.0006" +solution Kd4 +go +setboard 5k2/6p1/7p/8/7P/7K/8/8 w - - +id "MES.0007" +solution Kg3 +go +setboard 8/8/1kpp4/8/2P5/2K5/8/8 w - - +id "MES.0008" +solution Kc2 +go +setboard 8/5p2/1p6/1P2K2k/8/8/8/8 w - - +id "MES.0009" +solution Kf5 +go +setboard 8/8/8/4p1p1/8/5P2/6K1/3k4 w - - +id "MES.0010" +solution Kh1 +go +setboard 8/2p4K/8/7k/8/8/6PP/8 w - - +id "MES.0011" +solution g4+ +go +setboard 4k3/4p3/4P3/4P3/8/8/2K5/8 w - - +id "MES.0012" +solution Kd3 +go +setboard K7/8/1k6/1p6/8/2P5/1P6/8 w - - +id "MES.0013" +solution b3 +go +setboard 7k/5K2/7P/6pP/8/8/8/8 w - - +id "MES.0014" +solution Kf6 +go +setboard 8/p7/P7/8/8/4k3/4P3/4K3 w - - +id "MES.0015" +solution Kf1 +go +setboard 8/k7/3p4/6K1/2P1P3/8/8/8 w - - +id "MES.0016" +solution Kg6 +go +setboard K1k5/7p/8/2P5/8/8/P7/8 w - - +id "MES.0017" +solution c6 +go +setboard 8/5p2/5p2/5p2/8/4K3/7P/7k w - - +id "MES.0018" +solution h4 +go +setboard 8/6p1/k1P2p1p/7K/8/8/8/8 w - - +id "MES.0019" +solution Kg6 +go +setboard 2k5/3p4/P7/Pp6/8/4K3/8/8 w - - +id "MES.0020" +solution Kd4 +go +setboard 8/1p2pk2/1P6/8/4P3/8/6K1/8 w - - +id "MES.0021" +solution Kg3 +go +setboard 8/3Pk1p1/8/1K3Pp1/8/8/8/8 w - - +id "MES.0022" +solution Kc6 +go +setboard 8/5p2/7k/6p1/5P1P/8/8/7K w - - +id "MES.0023" +solution hxg5+ +go +setboard 4k3/8/3p4/p6K/P5P1/8/8/8 w - - +id "MES.0024" +solution Kg5 +go +setboard 8/2p1Pk2/5P2/8/3p1K2/8/8/8 w - - +id "MES.0025" +solution Kf3 +go +setboard 1k1K4/1p5P/1P6/8/8/8/p7/8 w - - +id "MES.0026" +solution h8=Q +go +setboard k7/5K2/8/8/7p/p6P/P7/8 w - - +id "MES.0027" +solution Ke6 +go +setboard 8/p2p4/8/8/8/k7/5P1P/7K w - - +id "MES.0028" +solution f4 +go +setboard 8/8/1k1p4/8/P1P5/p7/8/3K4 w - - +id "MES.0029" +solution Kc2 +go +setboard 8/K3p3/5p2/5P2/8/8/2k1P3/8 w - - +id "MES.0030" +solution Kb6 +go +setboard 8/2K5/1p6/1P4k1/5p2/8/6P1/8 w - - +id "MES.0031" +solution Kc6 +go +setboard 8/5p2/5p2/8/5KP1/8/6P1/3k4 w - - +id "MES.0032" +solution Kf5 +go +setboard 8/8/4k1P1/4p1p1/4K3/3P4/8/8 w - - +id "MES.0033" +solution g7 +go +setboard 8/8/7p/p7/k1P2K2/8/P7/8 w - - +id "MES.0034" +solution a3 +go +setboard 8/8/1p1K4/Pp6/2k1p3/8/1P6/8 w - - +id "MES.0035" +solution a6 +go +setboard 3k4/3p3p/3p4/PK6/4P3/8/8/8 w - - +id "MES.0036" +solution Kb6 +go +setboard 7k/3p2p1/2p5/5P2/2P5/K7/8/8 w - - +id "MES.0037" +solution Kb4 +go +setboard 8/7p/3p4/8/6pP/8/4PK2/7k w - - +id "MES.0038" +solution Kg3 +go +setboard 8/8/K7/2p1k3/8/1p1p4/1P1P4/8 w - - +id "MES.0039" +solution Kb5 +go +setboard 8/8/2p5/k1p1K3/p1P5/P7/8/8 w - - +id "MES.0040" +solution Kf5 +go +setboard 8/8/1p1p3p/3P4/4K3/8/4P2k/8 w - - +id "MES.0041" +solution Kf3 +go +setboard 6K1/8/pp5p/8/7k/3PP3/8/8 w - - +id "MES.0042" +solution d4 +go +setboard K7/8/k7/6p1/6Pp/7p/7P/8 w - - +id "MES.0043" +solution Kb8 +go +setboard 2k5/3p2p1/2p5/2K5/5P2/8/2P5/8 w - - +id "MES.0044" +solution Kd6 +go +setboard 6k1/p7/3K2p1/1P5p/7P/8/8/8 w - - +id "MES.0045" +solution Kd5 +go +setboard 8/1K6/8/k4p2/4pp2/8/4PP2/8 w - - +id "MES.0046" +solution Kc6 +go +setboard 8/6p1/4K3/6k1/6P1/6pP/6P1/8 w - - +id "MES.0047" +solution Ke5 +go +setboard 8/K7/3pk3/8/p3P3/P7/1P6/8 w - - +id "MES.0048" +solution Kb8 +go +setboard 1k6/1p6/3p4/1P6/1P6/1P6/8/7K w - - +id "MES.0049" +solution Kg2 +go +setboard 8/6p1/8/5p1P/5P2/6P1/8/5K1k w - - +id "MES.0050" +solution Ke1 +go +setboard 8/2p5/3k4/1p1p1K2/8/1P1P4/2P5/8 w - - +id "MES.0051" +solution b4 +go +setboard 4K3/pk6/2p5/2P5/1pP4P/1P6/8/8 w - - +id "MES.0052" +solution Kd7 +go +setboard 8/2p5/3k3P/5pp1/5p2/1p5K/8/8 w - - +id "MES.0053" +solution h7 +go +setboard 8/8/6K1/k2p4/2p5/2P4p/3P3P/8 w - - +id "MES.0054" +solution Kf7 +go +setboard 8/8/1p3P1k/4P3/8/1p6/pK2P3/8 w - - +id "MES.0055" +solution e6 +go +setboard 8/4Pk2/5p2/8/K7/3p2p1/3P2P1/8 w - - +id "MES.0056" +solution Kb5 +go +setboard 8/1p6/8/5k1p/P1P3p1/8/5PK1/8 w - - +id "MES.0057" +solution a5 +go +setboard 4k3/5p1p/1p5P/6P1/P7/8/8/4K3 w - - +id "MES.0058" +solution Kd2 +go +setboard 5k2/5p1p/7P/6P1/p7/P7/8/1K6 w - - +id "MES.0059" +solution Kc2 +go +setboard K7/3p3p/3k4/8/6pP/8/P5P1/8 w - - +id "MES.0060" +solution Kb7 +go +setboard 1k6/1P6/2P5/P7/5ppp/8/6K1/8 w - - +id "MES.0061" +solution Kg1 +go +setboard 8/6p1/6pp/8/k4P2/6K1/6PP/8 w - - +id "MES.0062" +solution f5 +go +setboard 1k6/p3pp2/p7/P2KP3/P7/8/8/8 w - - +id "MES.0063" +solution e6 +go +setboard 8/1p6/8/P7/7p/1P2p2P/4P1k1/4K3 w - - +id "MES.0064" +solution b4 +go +setboard k7/P2K4/p7/1p4p1/1P4P1/6P1/8/8 w - - +id "MES.0065" +solution Kd6 +go +setboard 8/2p2p2/1p6/3P1k1K/P1P2P2/8/8/8 w - - +id "MES.0066" +solution c5 +go +setboard 2k2K2/2p5/P7/Pp1P4/8/7p/7P/8 w - - +id "MES.0067" +solution Ke7 +go +setboard 8/2pp4/8/2PP3k/4pPp1/4P1K1/8/8 w - - +id "MES.0068" +solution d6 +go +setboard 8/3p4/3P4/3p2pp/3P4/k4K1P/7P/8 w - - +id "MES.0069" +solution h4 +go +setboard 8/2p5/pp6/kP1P4/p3K3/P1P5/8/8 w - - +id "MES.0070" +solution d6 +go +setboard 8/5pp1/8/k2p1Pp1/P5P1/3P4/8/3K4 w - - +id "MES.0071" +solution Kc2 +go +setboard 8/2pp1k2/2p1pP2/4P3/5P2/6K1/5P2/8 w - - +id "MES.0072" +solution f5 +go +setboard 8/8/7p/2p2PP1/p1P5/p1K5/k2P4/8 w - - +id "MES.0073" +solution Kc2 +go +setboard 8/1p6/1p6/1k2K3/2p1p3/PpP1P3/1P6/8 w - - +id "MES.0074" +solution a4+ +go +setboard 7k/8/5PpK/Pp1P2pp/3P4/8/5p2/8 w - - +id "MES.0075" +solution a6 +go +setboard 8/1p5k/1P1p4/3p4/3Pp2p/2K1P2p/7P/8 w - - +id "MES.0076" +solution Kb2 +go +setboard 8/2pp2pp/8/2PP1P2/1p5k/8/PP4p1/6K1 w - - +id "MES.0077" +solution f6 +go +setboard 8/5k2/2p5/1pPp4/p2P2p1/P2P2P1/P5K1/8 w - - +id "MES.0078" +solution Kf1 +go +setboard 8/4p1p1/1k2p1p1/p3P1P1/P1p2P2/2P5/5P2/4K3 w - - +id "MES.0079" +solution Kd1 +go +setboard 3k4/1pp5/p4P1p/P1p1KP1P/2P4p/7P/2P5/8 w - - +id "MES.0080" +solution Ke6 +go +setboard 8/pp1pppp1/3p2p1/PP2P1P1/K1P4P/8/k7/8 w - - +id "MES.0081" +solution h5 +go +setboard K7/8/8/7p/N2k4/8/8/8 w - - +id "MES.0082" +solution Nb2 +go +setboard 7N/2K5/8/8/7p/2k5/8/8 w - - +id "MES.0083" +solution Nf7 +go +setboard 8/4k2N/7p/8/1p6/8/4K3/8 w - - +id "MES.0084" +solution Kd3 +go +setboard 7K/3k4/8/pN6/8/8/1P6/8 w - - +id "MES.0085" +solution Nd4 +go +setboard 8/8/8/8/5p2/4k1p1/4N1P1/5K2 w - - +id "MES.0086" +solution Ng1 +go +setboard 8/8/8/8/3p4/2k1p3/2N1P3/3K4 w - - +id "MES.0087" +solution Ne1 +go +setboard 5K2/5P2/8/8/kp3n2/8/P7/8 w - - +id "MES.0088" +solution Ke7 +go +setboard 8/8/8/4P3/3pp1K1/N2k4/8/8 w - - +id "MES.0089" +solution e6 +go +setboard 8/7K/6p1/7P/p7/8/3kN3/8 w - - +id "MES.0090" +solution h6 +go +setboard 8/8/5N2/6P1/5k2/5pp1/8/4K3 w - - +id "MES.0091" +solution g6 +go +setboard 8/3p4/3k1Np1/P4p2/5K2/8/8/8 w - - +id "MES.0092" +solution a6 +go +setboard 8/2p5/1p6/1K6/7k/7P/7P/6N1 w - - +id "MES.0093" +solution Kc6 +go +setboard 8/2kp1K2/6N1/3P4/p6P/8/8/8 w - - +id "MES.0094" +solution d6+ +go +setboard 4k3/7N/4P3/6P1/8/4p1p1/8/6K1 w - - +id "MES.0095" +solution Kf1 +go +setboard 8/8/p6k/8/3N4/PP1K4/7p/8 w - - +id "MES.0096" +solution Nf5+ +go +setboard 8/8/8/4N3/5p2/p4p2/5P1p/5K1k w - - +id "MES.0097" +solution Nd3 +go +setboard 1k6/p7/8/1p5P/8/2pK4/1P5n/8 w - - +id "MES.0098" +solution h6 +go +setboard 2k5/2P4K/1P3p2/6p1/6n1/8/5P2/8 w - - +id "MES.0099" +solution f3 +go +setboard 2n5/1k6/4pP2/4P3/2K5/7p/6P1/8 w - - +id "MES.0100" +solution f7 +go +setboard 2n5/8/1PkP4/P4p2/1K6/7P/8/8 w - - +id "MES.0101" +solution d7 +go +setboard 4k3/4Pp1p/3P1K2/6P1/8/p2n4/8/8 w - - +id "MES.0102" +solution g6 +go +setboard 8/6p1/6Pp/5p2/5P1K/2p5/3k3P/7N w - - +id "MES.0103" +solution Ng3 +go +setboard 4n2k/7P/5P1p/6p1/2K3P1/5P2/8/8 w - - +id "MES.0104" +solution Kd5 +go +setboard 6K1/p7/4ppkp/7p/2PP1P1p/7P/P2P4/4n3 w - - +id "MES.0105" +solution d5 +go +setboard 8/7K/7P/1P6/2n4k/4n3/1P6/8 w - - +id "MES.0106" +solution Kg6 +go +setboard 8/p2P4/k7/P4P2/nKPn4/8/8/8 w - - +id "MES.0107" +solution d8=N +go +setboard 8/5N1N/8/8/1P6/2K4k/6p1/8 w - - +id "MES.0108" +solution Nhg5+ +go +setboard 1K6/N7/k7/8/6N1/1pp5/1P6/8 w - - +id "MES.0109" +solution Ne5 +go +setboard 5K2/7k/8/6P1/8/pp1N3N/8/8 w - - +id "MES.0110" +solution Ndf4 +go +setboard 8/3N4/5p2/8/4PK2/8/5Pp1/1N2k3 w - - +id "MES.0111" +solution Nd2 +go +setboard 8/8/7p/3KNN1k/2p4p/8/3P2p1/8 w - - +id "MES.0112" +solution Kc6 +go +setboard 8/6p1/7p/6PN/3NK1k1/6Pp/6p1/8 w - - +id "MES.0113" +solution gxh6 +go +setboard 8/1p3p2/8/1KP1P3/3NkpP1/7p/2N2P2/8 w - - +id "MES.0114" +solution e6 +go +setboard 8/8/8/6K1/8/4N2p/5n1k/8 w - - +id "MES.0115" +solution Kh4 +go +setboard K2n4/8/P7/8/2k5/8/2N5/8 w - - +id "MES.0116" +solution Ka7 +go +setboard 8/1K6/P7/kn6/4N3/8/8/8 w - - +id "MES.0117" +solution Nc5 +go +setboard 8/K7/8/2P1N3/n3k3/2p5/8/8 w - - +id "MES.0118" +solution c6 +go +setboard 7k/4np2/8/4K2p/8/4N3/P7/8 w - - +id "MES.0119" +solution Kd6 +go +setboard 8/N1k1n3/6P1/1P2K3/8/1p6/8/8 w - - +id "MES.0120" +solution b6+ +go +setboard 8/2Pp4/1n1N4/8/8/K4Pk1/8/8 w - - +id "MES.0121" +solution Kb2 +go +setboard K7/8/1Np5/8/6k1/n7/P5P1/8 w - - +id "MES.0122" +solution Kb7 +go +setboard 3n4/8/2P5/8/5p2/p2N3k/7p/5K2 w - - +id "MES.0123" +solution Nf2+ +go +setboard 8/6N1/p5k1/3K4/1p1p4/1P6/8/2n5 w - - +id "MES.0124" +solution Ne6 +go +setboard 2n5/8/Pp5p/5N2/8/5k2/3P4/7K w - - +id "MES.0125" +solution d4 +go +setboard 7n/8/6pP/6P1/k1K5/p7/8/1N6 w - - +id "MES.0126" +solution Kd5 +go +setboard 3n4/3K4/8/1p6/pkN5/1P6/PP6/8 w - - +id "MES.0127" +solution Ne5 +go +setboard 4Nn2/8/3P4/kP2P3/5p2/5p2/8/2K5 w - - +id "MES.0128" +solution Kd1 +go +setboard 4k3/2p2nKP/3p4/3Ppp1N/8/8/8/8 w - - +id "MES.0129" +solution Nf6+ +go +setboard 1n4N1/8/4p1P1/kp2p3/p3P3/8/K7/8 w - - +id "MES.0130" +solution Ne7 +go +setboard n7/K5PP/2k5/8/8/1P1p2Np/6p1/8 w - - +id "MES.0131" +solution Ne2 +go +setboard 6N1/8/3P4/3n1P2/5p2/3K1k2/6n1/8 w - - +id "MES.0132" +solution f6 +go +setboard 4NN2/8/8/6Pk/8/5nK1/8/8 w - - +id "MES.0133" +solution g6 +go +setboard 8/8/2n1n3/8/6N1/5N2/K3p3/5k2 w - - +id "MES.0134" +solution Nf6 +go +setboard 7k/3NN3/8/4K3/8/nP1p4/1n4P1/8 w - - +id "MES.0135" +solution Kf6 +go +setboard 6K1/3p4/7k/3N4/4N2P/5nP1/8/4n3 w - - +id "MES.0136" +solution Nf4 +go +setboard 4k1N1/5n2/1P1p2P1/2n5/3N4/p7/8/3K4 w - - +id "MES.0137" +solution b7 +go +setboard 8/8/8/2k5/p1b5/8/1P1K4/8 w - - +id "MES.0138" +solution Kc2 +go +setboard 5K2/k7/4P1p1/8/8/8/4b3/8 w - - +id "MES.0139" +solution Ke7 +go +setboard 8/6b1/5k2/8/P3K1P1/8/8/8 w - - +id "MES.0140" +solution a5 +go +setboard 5K2/8/7P/5p2/1P6/8/3b4/k7 w - - +id "MES.0141" +solution h7 +go +setboard 3b4/5k2/3P1p1P/3K4/8/8/8/8 w - - +id "MES.0142" +solution Kc6 +go +setboard 8/8/1b5P/kP6/8/5K2/1P6/8 w - - +id "MES.0143" +solution Ke4 +go +setboard 1b6/5K2/7P/1kp5/1p6/8/3P4/8 w - - +id "MES.0144" +solution Ke6 +go +setboard K7/1P6/1kP5/3P4/8/8/1p5b/8 w - - +id "MES.0145" +solution d6 +go +setboard 8/1p6/8/P1K5/1P6/5b1P/4k3/8 w - - +id "MES.0146" +solution Kd4 +go +setboard 8/p7/8/1P2K3/P6P/5b2/5k2/8 w - - +id "MES.0147" +solution Kf5 +go +setboard K7/2P5/b4k1p/3P4/6P1/8/8/8 w - - +id "MES.0148" +solution d6 +go +setboard 8/p3p3/K2PkP2/1P6/5b2/8/8/8 w - - +id "MES.0149" +solution f7 +go +setboard 8/3k2K1/2p1p3/b5P1/3P1P2/8/8/8 w - - +id "MES.0150" +solution Kf7 +go +setboard 8/3Pb1p1/8/3P2P1/5P2/7k/4K3/8 w - - +id "MES.0151" +solution Kd3 +go +setboard 8/2p1p3/4Pb2/1P1P3k/4K2P/8/8/8 w - - +id "MES.0152" +solution d6 +go +setboard 8/b7/3K1p2/7P/1p5k/1P6/1PP4P/8 w - - +id "MES.0153" +solution h6 +go +setboard 5k2/8/5PP1/8/1p3p2/6P1/P4PpK/7b w - - +id "MES.0154" +solution Kg1 +go +setboard 4k1K1/3p2pP/p2P3P/P7/8/1p6/1p6/b7 w - - +id "MES.0155" +solution h8=R +go +setboard 8/8/2PK2p1/7p/p1b2P2/P5P1/2P2kP1/8 w - - +id "MES.0156" +solution g4 +go +setboard 7k/3K2pP/pb4P1/8/P6p/2p1p3/2P1P1P1/8 w - - +id "MES.0157" +solution Kd6 +go +setboard 8/5p1b/4pPkp/3pP2p/1p1P3P/1p2K2P/1P6/8 w - - +id "MES.0158" +solution Ke2 +go +setboard 6k1/3p4/8/8/8/B7/P7/7K w - - +id "MES.0159" +solution Bb4 +go +setboard 5k2/4p2p/6P1/3K4/8/4B3/8/8 w - - +id "MES.0160" +solution Bh6+ +go +setboard 8/5p1B/7P/1K6/1p6/p7/1k6/8 w - - +id "MES.0161" +solution Bc2 +go +setboard 5B2/p7/3p4/PPk5/8/8/4K3/8 w - - +id "MES.0162" +solution b6 +go +setboard 8/2p2B2/5PK1/3Pk3/8/7p/8/8 w - - +id "MES.0163" +solution d6 +go +setboard 8/B1p2p1P/8/4p3/8/k7/p2K4/8 w - - +id "MES.0164" +solution Bd4 +go +setboard 8/8/3p4/8/3B4/p7/p1P4p/5K1k w - - +id "MES.0165" +solution Ba1 +go +setboard 8/8/5p2/3P4/p1PK4/p7/k7/3B4 w - - +id "MES.0166" +solution Kc3 +go +setboard 8/8/5p2/5p2/5P2/3p3B/5k1P/3K4 w - - +id "MES.0167" +solution Bg2 +go +setboard 8/8/2pp4/2p2kp1/2K5/6P1/6P1/2B5 w - - +id "MES.0168" +solution Be3 +go +setboard 8/7p/6pP/1B4P1/pp6/1k1K4/8/8 w - - +id "MES.0169" +solution Be8 +go +setboard k7/pp1K4/P2B4/p7/P7/P7/8/8 w - - +id "MES.0170" +solution Kc8 +go +setboard 8/1p6/1P1p4/1K1p2B1/P2P4/6pp/1P6/5k2 w - - +id "MES.0171" +solution Bd2 +go +setboard 1k6/1p1p4/PK2p3/5p1p/6pP/8/8/5B2 w - - +id "MES.0172" +solution a7+ +go +setboard 5kB1/3p1P2/7K/2Pp1P1P/p6p/4P3/7P/8 w - - +id "MES.0173" +solution Kg6 +go +setboard 3k4/3p4/3P1P2/P6B/1p1p4/1KPP3p/1P3p2/8 w - - +id "MES.0174" +solution a6 +go +setboard 8/1p6/1P6/3p1p1p/p2PpPpk/2p1P2P/2P1B1P1/6K1 w - - +id "MES.0175" +solution Kf2 +go +setboard 8/8/8/2P4B/8/5K2/3k4/5b2 w - - +id "MES.0176" +solution c6 +go +setboard 8/8/2B5/7b/7k/2K5/1P6/8 w - - +id "MES.0177" +solution b4 +go +setboard 8/8/8/1P6/7b/7k/7B/7K w - - +id "MES.0178" +solution b6 +go +setboard B3K3/8/8/P1p5/8/8/2b4k/8 w - - +id "MES.0179" +solution a6 +go +setboard 8/8/B3P3/3k4/5K2/2P4b/8/8 w - - +id "MES.0180" +solution Bc8 +go +setboard 1K6/3p4/3P4/8/k7/1p6/8/1b5B w - - +id "MES.0181" +solution Bc6+ +go +setboard 8/8/7B/2P5/1p4p1/3k4/7K/4b3 w - - +id "MES.0182" +solution c6 +go +setboard k7/8/8/1p2P1p1/bK6/8/B7/8 w - - +id "MES.0183" +solution Bf7 +go +setboard 3B4/6b1/6P1/2p5/P1k5/8/8/5K2 w - - +id "MES.0184" +solution Ba5 +go +setboard 8/pB4Pb/4k3/8/K2P4/8/8/8 w - - +id "MES.0185" +solution Be4 +go +setboard 8/8/p7/p3b1B1/8/p7/1p2k3/1K6 w - - +id "MES.0186" +solution Be7 +go +setboard k2K4/8/6P1/2B5/5P2/p7/4p2b/8 w - - +id "MES.0187" +solution g7 +go +setboard B6k/6p1/2K3PP/8/4p3/8/6b1/8 w - - +id "MES.0188" +solution Kd6 +go +setboard 8/4k3/6b1/2p5/2BP4/p4K2/4P3/8 w - - +id "MES.0189" +solution Kf4 +go +setboard 8/8/2p2K2/5B1p/k7/8/2P1P3/1b6 w - - +id "MES.0190" +solution e4 +go +setboard 8/p7/P7/P7/P4B2/8/5k2/6bK w - - +id "MES.0191" +solution Bc7 +go +setboard 8/KPb5/8/P5p1/5p2/3k4/7P/2B5 w - - +id "MES.0192" +solution Ba3 +go +setboard 8/1k6/1b6/p3p2P/1B5p/P7/5P2/2K5 w - - +id "MES.0193" +solution h6 +go +setboard 5k2/P4P1K/1Pb2PB1/8/3p3p/8/8/8 w - - +id "MES.0194" +solution Bf5 +go +setboard 8/3p4/pp1B4/k7/p1P5/P1bp4/8/3K4 w - - +id "MES.0195" +solution Kc1 +go +setboard 1B6/3k4/3p4/1P6/p4b2/Pp6/1P1pK3/8 w - - +id "MES.0196" +solution b6 +go +setboard 1b6/3k3p/P1p5/2Pp3p/K2P3P/8/8/6B1 w - - +id "MES.0197" +solution a7 +go +setboard 8/8/8/3pk1K1/1p1p4/1PpP3b/2P1B2P/8 w - - +id "MES.0198" +solution Bg4 +go +setboard 7k/2b5/6P1/2p2P1K/2Pp4/p2P4/2p5/2B5 w - - +id "MES.0199" +solution f6 +go +setboard 6k1/4b2p/7B/6p1/3p2P1/3Pp1p1/2K1P1P1/8 w - - +id "MES.0200" +solution Kb3 +go +setboard 8/2p2b2/Pp1p4/4pp2/k7/2P5/1P2BPK1/8 w - - +id "MES.0201" +solution b3+ +go +setboard B4k1K/4pP1p/PP2P2P/8/8/p7/1p6/3b4 w - - +id "MES.0202" +solution Be4 +go +setboard 5k1K/7p/1Pb2P2/5P1B/p2Pp3/4P3/4P3/8 w - - +id "MES.0203" +solution Be8 +go +setboard 8/6p1/4ppb1/P1p1p3/1k6/3PP3/1PK3P1/5B2 w - - +id "MES.0204" +solution a6 +go +setboard 8/p1p2pp1/1pP3p1/7k/3PPb2/5P1P/8/3K2B1 w - - +id "MES.0205" +solution d5 +go +setboard 8/5b1P/8/4K1B1/1k6/8/p7/8 w - - +id "MES.0206" +solution Bd2+ +go +setboard 5b2/1B6/1P4k1/4P3/8/8/8/K7 w - - +id "MES.0207" +solution Be4+ +go +setboard 7B/7k/3p1Kp1/6P1/8/8/8/1b6 w - - +id "MES.0208" +solution Bg7 +go +setboard 8/1p6/8/8/4p3/1k1P4/5b2/KB6 w - - +id "MES.0209" +solution Ba2+ +go +setboard 3k4/1K6/1P6/5p2/B1p5/8/3b4/8 w - - +id "MES.0210" +solution Ka6 +go +setboard b7/8/3p4/P7/6p1/8/4KBk1/8 w - - +id "MES.0211" +solution Be3 +go +setboard 8/pkP3P1/3B4/8/3K4/1b6/8/8 w - - +id "MES.0212" +solution Kc3 +go +setboard 3k4/8/1p1P4/1B6/7b/5K2/7P/8 w - - +id "MES.0213" +solution Kf4 +go +setboard 4B3/8/4k3/P5p1/1PK5/8/8/4b3 w - - +id "MES.0214" +solution Kc5 +go +setboard 3K1k2/8/2P5/2p5/5P2/8/1B4p1/3b4 w - - +id "MES.0215" +solution c7 +go +setboard 8/2B3k1/2P5/6P1/4b2p/7K/7P/8 w - - +id "MES.0216" +solution Be5+ +go +setboard 8/1K6/1P6/8/4P3/1p1k4/5P2/6bB w - - +id "MES.0217" +solution Ka8 +go +setboard 3K4/3P1p1B/4k1p1/7p/5P2/b7/8/8 w - - +id "MES.0218" +solution f5+ +go +setboard 8/K3p3/8/1k1P1b2/1P6/BP6/1P6/8 w - - +id "MES.0219" +solution Kb8 +go +setboard 8/3pk3/6P1/P5Pp/5B2/1p5b/pP6/K7 w - - +id "MES.0220" +solution a6 +go +setboard 8/B4p2/2p5/P2p4/5P2/1K1k1P2/3P4/5b2 w - - +id "MES.0221" +solution a6 +go +setboard 8/2KB4/5pp1/1Pk1p1p1/4p3/7P/4P3/2b5 w - - +id "MES.0222" +solution b6 +go +setboard 8/3p3p/3B3k/P1Pp1p1P/8/8/5P2/1b5K w - - +id "MES.0223" +solution c6 +go +setboard 8/3p2p1/3P4/p1PkpP1P/K7/6B1/8/5b2 w - - +id "MES.0224" +solution h6 +go +setboard 8/5pp1/3k2p1/1p6/pPB5/P4Kb1/5PP1/8 w - - +id "MES.0225" +solution fxg3 +go +setboard 7b/1K2p3/7P/p4P2/1pk5/4P2p/1PP5/3B4 w - - +id "MES.0226" +solution Kc6 +go +setboard 8/pp3pb1/P1p5/2K1k2B/5p1p/3P4/3P2P1/8 w - - +id "MES.0227" +solution d4+ +go +setboard 1b6/5p1p/3k4/8/2Bp1pP1/1p1P4/1KPP3P/8 w - - +id "MES.0228" +solution Ba6 +go +setboard 8/p2p1Bp1/P2p4/1Pp3pP/4K1kp/8/6P1/6b1 w - - +id "MES.0229" +solution h6 +go +setboard 8/4B1pp/8/pp1PppP1/b3p3/P7/P3KP1P/2k5 w - - +id "MES.0230" +solution g6 +go +setboard 4B2K/6B1/8/8/8/8/2p5/3k4 w - - +id "MES.0231" +solution Bh5+ +go +setboard 3k2B1/p7/1p2K3/8/6P1/2P1p2p/1B6/8 w - - +id "MES.0232" +solution c4 +go +setboard 8/2B5/1p2p1B1/1P6/2K5/8/2p1pP2/2k5 w - - +id "MES.0233" +solution Kb3 +go +setboard Bk6/1Pp5/1p2p3/4P3/P7/1pK4p/8/B7 w - - +id "MES.0234" +solution a5 +go +setboard 1K6/2Pb4/1B5k/7P/5b2/2p5/8/8 w - - +id "MES.0235" +solution Bd4 +go +setboard 8/8/P2K1k2/7b/8/5B2/4P2p/2b5 w - - +id "MES.0236" +solution a7 +go +setboard b7/2k5/P5P1/8/8/b2B1p1K/7P/8 w - - +id "MES.0237" +solution g7 +go +setboard 8/3PP1P1/2b3P1/8/8/5kPp/5p1p/5BbK w - - +id "MES.0238" +solution d8=N +go +setboard 8/8/7k/5K1P/8/B1b5/B7/8 w - - +id "MES.0239" +solution Bc1+ +go +setboard 2b5/K7/4p1p1/1p6/1B2B3/8/8/3k4 w - - +id "MES.0240" +solution Kb8 +go +setboard 8/2B5/7k/3p4/8/1p2P3/6K1/b6B w - - +id "MES.0241" +solution Bf4+ +go +setboard 8/6p1/6p1/5k1P/3Bp3/4PPP1/3p1PBK/4b3 w - - +id "MES.0242" +solution h6 +go +setboard 8/6k1/1B6/4n3/8/7p/8/3K4 w - - +id "MES.0243" +solution Bg1 +go +setboard n6k/8/8/6P1/3K4/3B4/8/8 w - - +id "MES.0244" +solution Kc5 +go +setboard 6B1/5P2/5Knk/8/7P/8/8/8 w - - +id "MES.0245" +solution Ke6 +go +setboard 4k1B1/8/4P2p/3K4/7P/6np/8/8 w - - +id "MES.0246" +solution e7 +go +setboard 8/8/4p3/3k1P2/3p4/8/2P5/Bn3K2 w - - +id "MES.0247" +solution f6 +go +setboard 8/b7/k7/2P3pP/4p3/3N4/2K5/8 w - - +id "MES.0248" +solution h6 +go +setboard K6k/1p5B/6P1/1p6/8/4n3/2P5/8 w - - +id "MES.0249" +solution c3 +go +setboard 8/2P2n1B/8/5K2/8/3p4/3Pkp2/8 w - - +id "MES.0250" +solution Ke6 +go +setboard 8/B1p4p/2p5/8/P6k/8/2n2pK1/8 w - - +id "MES.0251" +solution Bc5 +go +setboard 6nk/2p4p/3B1P1P/5KpP/8/8/8/8 w - g6 +id "MES.0252" +solution hxg6 +go +setboard B1k5/5n1P/3P3P/4p2K/4p3/4p3/8/8 w - - +id "MES.0253" +solution Bb7+ +go +setboard 3B4/pp6/5p2/1P5n/k1K1pp2/7p/1P6/8 w - - +id "MES.0254" +solution Be7 +go +setboard 4nk2/2p2p2/7P/4B2p/2K2P1p/7p/5P2/8 w - - +id "MES.0255" +solution h7 +go +setboard 8/2p1p1pp/2P1P2k/6pP/p7/P4Bp1/1P4P1/n5K1 w - - +id "MES.0256" +solution Bd1 +go +setboard 3N4/8/8/3b3K/5p2/8/8/7k w - - +id "MES.0257" +solution Kg4 +go +setboard 8/2K5/bP4k1/3p4/3N4/8/8/8 w - - +id "MES.0258" +solution Nc6 +go +setboard 2b5/4N3/5P2/8/2k1K3/8/3p4/8 w - - +id "MES.0259" +solution Nd5 +go +setboard b7/2K5/8/N2P4/pk6/8/8/8 w - - +id "MES.0260" +solution d6 +go +setboard N2k4/p7/8/8/4K3/8/P7/6b1 w - - +id "MES.0261" +solution Kd5 +go +setboard 5b1N/8/5k2/8/K1P1nP2/8/8/8 w - - +id "MES.0262" +solution f5 +go +setboard 8/1p6/1Pb5/8/8/N5pk/8/6K1 w - - +id "MES.0263" +solution Nc2 +go +setboard 8/8/4p3/2bP4/8/8/p7/k2KN3 w - - +id "MES.0264" +solution Kc1 +go +setboard 8/8/2k4b/P7/8/8/2N2PKp/8 w - - +id "MES.0265" +solution Nd4+ +go +setboard 4k3/3p1N2/8/P1P4b/8/8/7K/8 w - - +id "MES.0266" +solution c6 +go +setboard 8/2k5/8/2P5/6N1/2K2p2/5P2/6b1 w - - +id "MES.0267" +solution Kd3 +go +setboard 8/pk6/pp6/5b2/2P5/8/3N1K2/8 w - - +id "MES.0268" +solution Nb3 +go +setboard 8/N4k2/2P2p1P/8/7p/5K2/2b5/8 w - - +id "MES.0269" +solution c7 +go +setboard K2b4/3P2pp/8/5PN1/8/6k1/8/8 w - - +id "MES.0270" +solution f6 +go +setboard 8/1pN2p2/1P6/8/2P5/5k2/b7/6K1 w - - +id "MES.0271" +solution c5 +go +setboard 8/8/8/P5PN/8/8/2bPK2p/6k1 w - - +id "MES.0272" +solution Ng3 +go +setboard 7k/7b/1P5N/6P1/7p/6pp/8/6K1 w - - +id "MES.0273" +solution Nf7+ +go +setboard 8/3k1p2/P1p4P/1p6/8/N1b5/5K2/8 w - - +id "MES.0274" +solution Nxb5 +go +setboard 7N/1pp5/8/P1P1k3/1p6/4K3/8/1b6 w - - +id "MES.0275" +solution c6 +go +setboard 8/2p3Kp/1p2P3/8/k7/8/1PN3b1/8 w - - +id "MES.0276" +solution b3+ +go +setboard 8/3pk3/5p2/P1P1P3/8/1b6/N7/6K1 w - - +id "MES.0277" +solution c6 +go +setboard 7k/7P/1p1P4/1p4pp/8/5P2/3N4/b1K5 w - - +id "MES.0278" +solution f4 +go +setboard 5b1k/4p1pP/4P1P1/1p6/8/1N6/2pP4/2K5 w - - +id "MES.0279" +solution d4 +go +setboard 8/5p2/p3p1P1/7b/Pk6/1p6/8/1KN5 w - - +id "MES.0280" +solution g7 +go +setboard 8/3pPp2/3p1k1K/5p2/1b1P3N/2P5/5p2/8 w - - +id "MES.0281" +solution Ng6 +go +setboard 8/8/P1p3N1/2Pb4/6p1/1P3pPp/8/2k2K2 w - - +id "MES.0282" +solution Ne5 +go +setboard 8/8/5b1P/1p1Pk3/1Pp1P3/6p1/3N2p1/6K1 w - - +id "MES.0283" +solution h7 +go +setboard 1k6/2p1NbP1/PpP5/1K6/2p3p1/3P4/8/8 w - - +id "MES.0284" +solution Nc8 +go +setboard 8/2k4N/p6p/5p1P/5p2/2p1pP1b/2P1P2P/6K1 w - - +id "MES.0285" +solution Ng5 +go +setboard 8/3k4/1K6/PP6/2b5/8/8/5n2 w - - +id "MES.0286" +solution Kb7 +go +setboard 1b2K3/1P6/6n1/1P2k3/8/8/8/8 w - - +id "MES.0287" +solution Kd8 +go +setboard 3n4/6k1/6P1/1KP5/8/8/8/3b4 w - - +id "MES.0288" +solution c6 +go +setboard 1n6/2k4K/5P2/3P1P2/8/8/8/4b3 w - - +id "MES.0289" +solution d6+ +go +setboard 8/P1n1kP2/4P3/2K5/8/8/8/3b4 w - - +id "MES.0290" +solution Kb6 +go +setboard 8/3n4/P4P2/4p3/K1p5/8/2k4b/8 w - - +id "MES.0291" +solution a7 +go +setboard 8/7P/2n1P1KP/3k4/8/3P4/1b6/8 w - - +id "MES.0292" +solution d4 +go +setboard 8/4K3/8/3k4/8/1N1B4/6p1/8 w - - +id "MES.0293" +solution Bc4+ +go +setboard 1NBk4/p2p4/8/3K4/8/8/8/8 w - - +id "MES.0294" +solution Bb7 +go +setboard 8/6B1/8/8/8/2N1p3/p7/k5K1 w - - +id "MES.0295" +solution Kf1 +go +setboard 8/6B1/8/1N6/8/4p3/p1k3K1/8 w - - +id "MES.0296" +solution Kf3 +go +setboard N7/1K6/8/8/2p5/5k1p/3B3P/8 w - - +id "MES.0297" +solution Kc6 +go +setboard 8/8/5N2/B1pK4/1p6/k7/8/8 w - - +id "MES.0298" +solution Ke4 +go +setboard 8/1p6/8/5N2/p1K4B/p7/2k5/8 w - - +id "MES.0299" +solution Nd4+ +go +setboard 8/1B6/8/8/6pp/7p/4K2k/1N6 w - - +id "MES.0300" +solution Ke1 +go +setboard 8/8/4k3/8/1p6/3BP3/2K3Np/8 w - - +id "MES.0301" +solution Nf4+ +go +setboard 8/8/8/1p6/2k3N1/4B3/p2PK3/8 w - - +id "MES.0302" +solution d3+ +go +setboard 8/8/8/3N4/8/p4K2/1pP5/3B2k1 w - - +id "MES.0303" +solution Nc3 +go +setboard 8/8/2P5/p7/K2p4/3k2N1/B1p5/8 w - - +id "MES.0304" +solution Bc4+ +go +setboard 8/1p1K4/1P4NB/6p1/8/4k3/6p1/8 w - - +id "MES.0305" +solution Bf8 +go +setboard 1N6/8/K7/3k4/3p3B/p7/2PP4/8 w - - +id "MES.0306" +solution Nc6 +go +setboard 2K2N2/2B5/p1p4p/2k5/2P5/7p/8/8 w - - +id "MES.0307" +solution Kb7 +go +setboard 8/8/B7/4p2N/5pp1/1kpK4/6P1/8 w - - +id "MES.0308" +solution Ng3 +go +setboard 8/8/8/4N3/8/B1k2p1p/4Pp1P/2K5 w - - +id "MES.0309" +solution Bb4+ +go +setboard 8/4B2p/8/3p3P/8/3Pk1K1/p7/6N1 w - - +id "MES.0310" +solution Bf6 +go +setboard 8/1kpB1p2/3p4/4pK2/N1P3p1/7p/5P2/8 w - - +id "MES.0311" +solution Nc5+ +go +setboard 8/4KBp1/1pp3p1/4k1P1/PP3p1N/P2p4/3P1pPP/8 w - - +id "MES.0312" +solution Nf3+ +go +setboard 7k/4p3/5p2/1p1p1p2/1PpP1PpB/1pP3P1/7P/6NK w - - +id "MES.0313" +solution Bxf6+ +go +setboard b7/7P/4P1kb/3PK3/8/n7/8/8 w - - +id "MES.0314" +solution h8=N+ +go +setboard 1k1K2n1/2p5/2PP1P2/bP6/P7/2n5/8/8 w - - +id "MES.0315" +solution b6 +go +setboard 4N3/2n5/1b6/8/k5p1/8/6P1/7K w - - +id "MES.0316" +solution Nf6 +go +setboard 5k2/1K4b1/5np1/P7/8/8/8/6N1 w - - +id "MES.0317" +solution a6 +go +setboard b6k/4n3/5P1K/3p4/5N2/8/8/8 w - - +id "MES.0318" +solution f7 +go +setboard 8/3b3p/pn2p3/6PP/PN3k1K/5P2/8/8 w - - +id "MES.0319" +solution g6 +go +setboard N7/P4n1P/p7/k4p2/1p2p1p1/7b/2P2K2/8 w - - +id "MES.0320" +solution Nb6 +go +setboard 3n4/8/4P3/7p/P3PP1p/3Pbk1P/2p4P/2N1K3 w - - +id "MES.0321" +solution e7 +go +setboard 8/8/8/7N/P5bb/K7/8/2k5 w - - +id "MES.0322" +solution Nf4 +go +setboard 8/8/1p6/k5P1/1p6/1p1N2b1/bK6/8 w - - +id "MES.0323" +solution Ka1 +go +setboard 8/4p3/P3p1NP/7p/K1kb4/7b/P4P2/8 w - - +id "MES.0324" +solution Nh4 +go +setboard 8/8/b5pn/4K3/8/5k2/B7/8 w - - +id "MES.0325" +solution Kf6 +go +setboard K6b/8/8/k3P3/7B/8/4n3/8 w - - +id "MES.0326" +solution e6 +go +setboard 5k2/3B2bK/6P1/8/2n5/8/6P1/8 w - - +id "MES.0327" +solution g3 +go +setboard 1kb5/3p4/P6p/1KB5/8/7P/8/n7 w - - +id "MES.0328" +solution Bd6+ +go +setboard 8/6p1/n4b1P/7P/p7/B3K3/8/4k3 w - - +id "MES.0329" +solution h7 +go +setboard 8/1B3pk1/3P4/6pP/n7/5K2/8/2b5 w - - +id "MES.0330" +solution d7 +go +setboard B5k1/6P1/7P/n3K2p/2b4P/8/8/8 w - - +id "MES.0331" +solution Kf6 +go +setboard 8/5P1K/3b4/8/6k1/1n4P1/1P4PB/8 w - - +id "MES.0332" +solution Kg8 +go +setboard 7b/B7/p2P4/7P/7k/8/P1n2KP1/8 w - - +id "MES.0333" +solution d7 +go +setboard 2b5/1pkp4/P1P1p3/1P3n2/8/6pp/6P1/6K1 w - - +id "MES.0334" +solution a7 +go +setboard 7B/1p3p1P/7n/7p/3K2p1/1P2P1Pp/1k2b3/8 w - - +id "MES.0335" +solution Kc5+ +go +setboard 8/pp5P/1p1p1P2/1K3b2/P2k4/8/p1pP4/1nB5 w - - +id "MES.0336" +solution f7 +go +setboard 2b5/P1n1Ppp1/P2p4/3P2PK/5k1P/8/4B2P/8 w - - +id "MES.0337" +solution g6 +go +setboard 8/2n2b1B/4p1pP/PP4p1/p5P1/3p2PK/3P4/7k w - - +id "MES.0338" +solution Bg8 +go +setboard 6k1/6pb/N5p1/K5N1/8/8/8/8 w - - +id "MES.0339" +solution Kb4 +go +setboard 8/8/N2b4/8/K2N4/pPk5/8/8 w - - +id "MES.0340" +solution Nb5+ +go +setboard K3b2N/8/2k3Np/7P/8/8/8/8 w - - +id "MES.0341" +solution Nf7 +go +setboard k4N2/8/1p3P2/pp6/8/K4b2/1N6/8 w - - +id "MES.0342" +solution Nc4 +go +setboard 1k6/2b5/p1Kpp3/P3PN2/8/2N5/8/8 w - - +id "MES.0343" +solution exd6 +go +setboard 8/7N/4p2P/p3p2P/P3P1k1/2p5/7p/2b1K2N w - - +id "MES.0344" +solution Nf6+ +go +setboard 1k4B1/8/8/n1K3N1/8/8/8/8 w - - +id "MES.0345" +solution Kb6 +go +setboard 8/8/8/8/1B2N3/8/k1K1n3/8 w - - +id "MES.0346" +solution Bc5 +go +setboard 8/8/4N1k1/8/5K2/8/B2n4/8 w - - +id "MES.0347" +solution Nd4 +go +setboard 8/8/7p/8/8/2N2K2/8/1B3nk1 w - - +id "MES.0348" +solution Ne2+ +go +setboard 8/8/8/NB6/8/5k2/2np3K/8 w - - +id "MES.0349" +solution Be8 +go +setboard n7/7k/4p3/B7/6N1/8/8/6K1 w - - +id "MES.0350" +solution Ne5 +go +setboard 8/8/8/8/8/p5pK/5B2/1Nn4k w - - +id "MES.0351" +solution Bd4 +go +setboard 8/4K2p/6kP/8/4N3/7B/8/n7 w - - +id "MES.0352" +solution Be6 +go +setboard 8/3N4/8/5K2/5B2/8/5Pp1/k3n3 w - - +id "MES.0353" +solution Bh2 +go +setboard 3N2n1/4p3/3P4/4k3/6K1/8/2B5/8 w - - +id "MES.0354" +solution Nf7+ +go +setboard 8/2N1k3/8/n7/B7/6p1/6Pp/7K w - - +id "MES.0355" +solution Ne8 +go +setboard 5B1k/7p/6P1/4NnP1/8/8/K4p2/8 w - - +id "MES.0356" +solution g7+ +go +setboard 8/8/p7/Pk6/p6p/3P1N2/8/K1n3B1 w - - +id "MES.0357" +solution Kb2 +go +setboard B7/1P1p2p1/k2n1P2/8/N5K1/8/6p1/8 w - - +id "MES.0358" +solution b8=N+ +go +setboard 8/3pB3/n4K1k/6N1/1p2P2p/1p6/1P4Pp/8 w - - +id "MES.0359" +solution Bf8+ +go +setboard 2n5/1P1p4/3P4/2B1P3/3P4/6p1/pp4P1/Nk5K w - - +id "MES.0360" +solution Ba3 +go +setboard nK6/2p3pk/1pp5/1P3NP1/5P2/1P4P1/p1B5/8 w - - +id "MES.0361" +solution Ne3+ +go +setboard 8/6B1/8/8/3N4/4k3/8/2b1K3 w - - +id "MES.0362" +solution Kd1 +go +setboard 1b5B/8/8/1N6/8/3k4/2p5/2K5 w - - +id "MES.0363" +solution Nc7 +go +setboard 3K4/8/8/4k3/8/N2bB3/p7/8 w - - +id "MES.0364" +solution Nb5 +go +setboard 1b6/8/1N4Pk/8/8/B6K/8/8 w - - +id "MES.0365" +solution Nd7 +go +setboard 7K/1b6/8/8/3P4/4k3/1B1N2p1/8 w - - +id "MES.0366" +solution d5 +go +setboard b6k/7p/2p5/8/8/2N5/3B4/1K6 w - - +id "MES.0367" +solution Bh6 +go +setboard 8/8/7k/8/7P/2p5/4KN2/3B2b1 w - - +id "MES.0368" +solution Nd3 +go +setboard 8/6P1/8/8/4k2K/8/2b4p/2N1B3 w - - +id "MES.0369" +solution g8=Q +go +setboard k7/8/B3P3/8/1K5b/8/4N2p/8 w - - +id "MES.0370" +solution Ng3 +go +setboard 8/5b2/8/6B1/3k4/K7/1P4p1/1N6 w - - +id "MES.0371" +solution Nd2 +go +setboard 1k6/2p5/B7/4Np2/8/8/6p1/6Kb w - - +id "MES.0372" +solution Nc6+ +go +setboard 8/4K1p1/3N4/5P2/4B3/1k6/3pb3/8 w - - +id "MES.0373" +solution f6 +go +setboard K7/2b5/3p1p2/4k3/4P3/4N3/8/2B5 w - - +id "MES.0374" +solution Kb7 +go +setboard 8/8/pp6/8/kb3Np1/7P/1K6/4B3 w - - +id "MES.0375" +solution Bxb4 +go +setboard 8/5N2/5pP1/7b/p7/8/1Pk5/4BK2 w - - +id "MES.0376" +solution Nh8 +go +setboard 8/8/6p1/7p/pb6/k6P/2P1pB2/NK6 w - - +id "MES.0377" +solution c3 +go +setboard 4K3/2k1Bp1N/6p1/5PP1/8/7p/b7/8 w - - +id "MES.0378" +solution Bf6 +go +setboard 4Bk2/1pp2p1K/3p4/P5Pb/4P3/5N2/8/8 w - - +id "MES.0379" +solution Bc6 +go +setboard 1b6/4P3/1P2PN2/8/2P5/P1k5/P1p2P2/K5B1 w - - +id "MES.0380" +solution Ne4+ +go +setboard 6b1/2p1B1P1/p1K5/k7/p6p/p1Np2p1/8/8 w - - +id "MES.0381" +solution Na2 +go +setboard 3k4/3p4/P2P2P1/p1p1P3/K3p3/3P3B/P3p2P/3N3b w - - +id "MES.0382" +solution Nc3 +go +setboard 8/1p1p4/1p1PPp2/1P1K1k1P/2PP4/4B2P/5pp1/6Nb w - - +id "MES.0383" +solution e7 +go +setboard 8/5BK1/8/8/p7/4B3/pn6/1k6 w - - +id "MES.0384" +solution Bg6+ +go +setboard 6K1/8/6B1/8/8/2B5/pP6/k2n4 w - - +id "MES.0385" +solution Bh8 +go +setboard 8/8/8/3kp3/3p4/P2B4/K1N3Np/8 w - - +id "MES.0386" +solution Nf4+ +go +setboard 8/B4p2/4Np2/8/3K1P2/7N/4p2k/8 w - - +id "MES.0387" +solution Ng1 +go +setboard 2N1k3/4p3/3pKp2/5p2/4NB2/pp6/8/8 w - - +id "MES.0388" +solution Nexd6+ +go +setboard 5N2/8/7B/8/2K5/1p1B4/p7/k7 w - - +id "MES.0389" +solution Bd2 +go +setboard 8/8/6bk/8/4nP2/4K3/4N3/4n3 w - - +id "MES.0390" +solution f5 +go +setboard 3kn1K1/1p6/P4b2/N2Pn3/8/6P1/8/8 w - - +id "MES.0391" +solution a7 +go +setboard 8/8/7N/1k5b/3P4/K3P3/2P5/n5b1 w - - +id "MES.0392" +solution Kb2 +go +setboard 8/8/P6P/5p2/8/1b6/nN4P1/k3b2K w - - +id "MES.0393" +solution Nd1 +go +setboard 2N2n2/8/1P4P1/1P3KP1/1b6/p7/8/k6b w - - +id "MES.0394" +solution g7 +go +setboard 2nn4/B7/KP1P4/8/3p3k/8/8/4b3 w - - +id "MES.0395" +solution b7 +go +setboard 6K1/8/Pp3p1k/1Pb4P/p2p3N/3P1PP1/4P3/3b4 w - - +id "MES.0396" +solution Nf5+ +go +setboard b7/7P/2p3np/2P3p1/1P4PP/2B3Pk/7p/6bK w - - +id "MES.0397" +solution h5 +go +setboard 3n2k1/3N4/7P/6N1/8/K7/7P/4b3 w - - +id "MES.0398" +solution Nf6+ +go +setboard 8/8/p5Pb/1kpbP3/5p2/1N6/1KPN4/8 w - - +id "MES.0399" +solution c4+ +go +setboard 2N5/5B2/8/4nk1K/6n1/4p3/8/8 w - - +id "MES.0400" +solution Ne7+ +go diff --git a/tests/newiq.ep_ b/tests/newiq.ep_ new file mode 100644 index 0000000..49cb4fe --- /dev/null +++ b/tests/newiq.ep_ @@ -0,0 +1,1440 @@ +setboard r3rnk1/4qpp1/p5np/4pQ2/Pb2N3/1B5P/1P3PP1/R1BR2K1 w - - +id "IQ.894" +solution Bxh6 +go +setboard r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - +id "IQ.895" +solution Bxh6 +go +setboard 6rk/1p1br2p/pqp5/3pNP2/1P1Pp3/P5PR/5PKR/Q7 w - - +id "IQ.915" +solution Rxh7+ +go +setboard r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/5PPP/2R3K1 w - - +id "IQ.916" +solution Bxh7+ +go +setboard 3rk1nr/1p3q2/p1n2P1p/P1ppp3/3b4/2N2QPB/1PP4P/R1B2R1K w k - +id "IQ.917" +solution Nxd5 +go +setboard 3rk1nr/1p3q2/p1n2P1p/P1ppp3/3b4/2N2QPB/1PP4P/R1B2R1K w k - +id "IQ.918" +solution Nxd5 +go +setboard 6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - +id "IQ.919" +solution Rxh7+ +go +setboard 6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - +id "IQ.920" +solution Rxh7+ +go +setboard 6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - +id "IQ.921" +solution Rxh7+ +go +setboard r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - +id "IQ.922" +solution Nf5+ +go +setboard r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - +id "IQ.923" +solution Nf5+ +go +setboard r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - +id "IQ.924" +solution Nf5+ +go +setboard 3r2k1/5pp1/R2B3q/2Q5/1p2rP2/6Pp/1bP2K1P/3R4 w - - +id "IQ.925" +solution Be5 +go +setboard 1rb2r2/1p1nppk1/2p1n1p1/p3P2p/2qP3R/2N3NP/PP1Q2B1/5RK1 w - - +id "IQ.926" +solution Bd5 +go +setboard 3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - +id "IQ.927" +solution g6 +go +setboard 2qrrb2/pb3ppk/1npp3p/5N2/1p2n3/1P3NPB/PBPQ1P1P/3RR1K1 w - - +id "IQ.928" +solution Rxe4 Qf4 +go +setboard 3r2k1/1p3pp1/1p6/7p/q2NP1P1/2Q2P1b/rP5P/2RR2K1 w - - +id "IQ.929" +solution Nf5 +go +setboard 3r2k1/1p3pp1/1p6/7p/q2NP1P1/2Q2P1b/rP5P/2RR2K1 w - - +id "IQ.930" +solution Nf5 +go +setboard 2q1r2k/5R1p/pp1B2pN/2p1P3/1n1b4/3P2Q1/1P4K1/8 w - - +id "IQ.931" +solution Qh4 +go +setboard 2rr2k1/pb3p1p/1pq3p1/4R1N1/2n5/P4P2/BP2Q1PP/4R2K w - - +id "IQ.932" +solution Nxf7 Re7 +go +setboard 2r1b1k1/p1q1brp1/1p2p1QB/4p3/4N3/2PBR3/P4PPP/6K1 w - - +id "IQ.933" +solution Qh7+ +go +setboard 2r1b1k1/p1q1brp1/1p2p1QB/4p3/4N3/2PBR3/P4PPP/6K1 w - - +id "IQ.934" +solution Qh7+ +go +setboard r1b1rnk1/pp3ppp/3qp3/2pnNPB1/2BP4/2P5/P1P1Q1PP/3R1RK1 w - - +id "IQ.935" +solution Nxf7 +go +setboard 2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - +id "IQ.936" +solution Qxc7+ +go +setboard 2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - +id "IQ.937" +solution Qxc7+ +go +setboard 2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - +id "IQ.938" +solution Qxc7+ +go +setboard r1bq1rk1/pp1n1pp1/5n1p/2b1pN2/2B4B/2N1P3/PPQ2PPP/2KR3R w - - +id "IQ.939" +solution Nxh6+ +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +id "IQ.940" +solution Re6 +go +setboard 5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - +id "IQ.941" +solution Re6 +go +setboard 5rk1/q5pp/4p3/r1bp1p2/1p1B1P2/1P1QP3/P4RPP/2R3K1 w - - +id "IQ.943" +solution Rxc5 +go +setboard 5rk1/q5pp/4p3/r1bp1p2/1p1B1P2/1P1QP3/P4RPP/2R3K1 w - - +id "IQ.944" +solution Rxc5 +go +setboard 2R4Q/pp1bkp2/4p1r1/qN1p4/Pb6/4B3/1P3PPP/6K1 w - - +id "IQ.945" +solution Bb6 +go +setboard 2R4Q/pp1bkp2/4p1r1/qN1p4/Pb6/4B3/1P3PPP/6K1 w - - +id "IQ.946" +solution Bb6 +go +setboard 6k1/6p1/p3br2/1p2Q3/5r2/1P1B2R1/1P3qPP/2R4K w - - +id "IQ.947" +solution Rc8+ +go +setboard 6k1/6p1/p3br2/1p2Q3/5r2/1P1B2R1/1P3qPP/2R4K w - - +id "IQ.948" +solution Rc8+ +go +setboard 5r1k/1b1P3p/4Q1pb/8/P7/4N1PP/1P2r3/R2R2K1 w - - +id "IQ.949" +solution Qf6+ +go +setboard 5r1k/1b1P3p/4Q1pb/8/P7/4N1PP/1P2r3/R2R2K1 w - - +id "IQ.950" +solution Qf6+ +go +setboard 4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - +id "IQ.951" +solution Bd3 +go +setboard 4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - +id "IQ.952" +solution Bd3 +go +setboard 4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - +id "IQ.953" +solution Bd3 +go +setboard 2rq1r2/pp1b1pkp/8/P2Q2P1/n1nN4/2P5/2P3BP/R1B2RK1 w - - +id "IQ.954" +solution Rxa4 +go +setboard 2rq1r2/pp1b1pkp/8/P2Q2P1/n1nN4/2P5/2P3BP/R1B2RK1 w - - +id "IQ.955" +solution Rxa4 +go +setboard 2qr1r2/p2n1ppk/1p2p2p/5b2/2PP2NQ/1B4R1/P4PPP/R5K1 w - - +id "IQ.956" +solution Bc2 +go +setboard 2qr1r2/p2n1ppk/1p2p2p/5b2/2PP2NQ/1B4R1/P4PPP/R5K1 w - - +id "IQ.957" +solution Bc2 +go +setboard 1r2q1k1/1p6/pN2p1p1/P3p3/2PbQ3/1P5P/6P1/5R1K w - - +id "IQ.958" +solution Nd7 +go +setboard 1r2q1k1/1p6/pN2p1p1/P3p3/2PbQ3/1P5P/6P1/5R1K w - - +id "IQ.959" +solution Nd7 +go +setboard 6k1/pp2q2r/2r1p3/1RPpPpp1/3P4/P5P1/3Q1PK1/7R w - - +id "IQ.960" +solution Rxb7 +go +setboard k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - +id "IQ.961" +solution Qxc3 +go +setboard k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - +id "IQ.962" +solution Qxc3 +go +setboard k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - +id "IQ.963" +solution Qxc3 +go +setboard 2r1k1nr/3bbpp1/p2p2P1/4pP2/1pqNP3/2N1B3/PPP3Q1/1K1R2R1 w k - +id "IQ.964" +solution b3 Nd5 +go +setboard r6r/p1kn4/2p1b3/q3p1Qp/4P3/2PBB2P/P5P1/3R1RK1 w - - +id "IQ.965" +solution Bc4 +go +setboard 1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - +id "IQ.966" +solution Bf4 +go +setboard 4rk2/1p3r2/3q1nQp/1R1P2p1/P2pp3/3B2PP/1P3P2/2R3K1 w - - +id "IQ.967" +solution Qxh6+ Rxb7 +go +setboard r5k1/1p3pbp/2q1p1p1/p1p1P3/n1P5/P1B2N1P/1P2QPP1/3R2K1 w - - +id "IQ.968" +solution Bxa5 +go +setboard 1rb1r2k/3nq1b1/2p2pp1/p3p2p/P1B1P3/1P1RB1N1/2P2QPP/3R3K w - - +id "IQ.969" +solution Nf5 Rd6 +go +setboard 1rb1r2k/3nq1b1/2p2pp1/p3p2p/P1B1P3/1P1RB1N1/2P2QPP/3R3K w - - +id "IQ.970" +solution Nf5 Rd6 +go +setboard 4q1k1/p6p/1p2n2B/2p2rp1/2P5/2P2P2/P2Q2PP/4R1K1 w - - +id "IQ.971" +solution Rxe6 +go +setboard 4q1k1/p6p/1p2n2B/2p2rp1/2P5/2P2P2/P2Q2PP/4R1K1 w - - +id "IQ.972" +solution Rxe6 +go +setboard 4rbk1/1q3ppp/2Rr4/1p1P1B2/2b1PR2/p5P1/5P1P/B1Q3K1 w - - +id "IQ.973" +solution Bxh7+ Rxd6 Rh4 Bxg7 +go +setboard 6k1/p1p2pp1/2p1n1q1/1r2P3/4N1PQ/5P2/P6P/3R3K w - - +id "IQ.974" +solution Rd8+ +go +setboard r1b2r2/4ppkp/p2p1np1/qpn5/2PNP1P1/2N2P2/PP1QB2P/R3K2R w KQ - +id "IQ.975" +solution g5 cxb5 +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.976" +solution Qh6+ +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.977" +solution Qh6+ +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.978" +solution Qh6+ +go +setboard 2r3k1/pR5p/2ppNb2/1Q1P1ppP/4q3/4P1P1/5P2/6K1 w - - +id "IQ.979" +solution Rg7+ Qa6 +go +setboard 7R/5Q2/6pp/4rp1k/P3P3/5Pb1/4KPq1/3R4 w - - +id "IQ.980" +solution Rxh6+ +go +setboard rnb4r/p1pq1Pkp/1pn1p1p1/3p2N1/3P4/P1PB3Q/2P2PPP/R1B1K2R w KQ - +id "IQ.981" +solution Qh6+ +go +setboard r1r5/p2qnkbp/bp2ppp1/3p4/3P1P2/1Q1N1N1B/PP2PP1P/2R2RK1 w - - +id "IQ.982" +solution Nde5+ +go +setboard r1b2rk1/1p3pbn/p2p2p1/q1nPp2p/P3P3/2NBBPN1/1P1Q2PP/R4RK1 w - - +id "IQ.983" +solution b4 +go +setboard b3k3/2q1b1p1/p3p2r/1pPpP2p/1P1N3P/6P1/P3Q3/1BR3K1 w - - +id "IQ.984" +solution Bg6+ +go +setboard 8/2bP1Q1p/6pk/p3p3/P1Bp4/1P1R2KP/5PP1/2q4r w - - +id "IQ.985" +solution Re3 +go +setboard 8/2bP1Q1p/6pk/p3p3/P1Bp4/1P1R2KP/5PP1/2q4r w - - +id "IQ.987" +solution Re3 +go +setboard 2b1rqk1/2R2ppp/1p1P4/p3Q3/7P/P7/B4PP1/6K1 w - - +id "IQ.989" +solution Qxe8 +go +setboard r3k2r/pppqnpbp/4p1p1/3nP1B1/Q2PN2P/5P2/PP2BP2/2R1K1R1 w - - +id "IQ.990" +solution Nd6+ +go +setboard r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - +id "IQ.991" +solution Rxe5 +go +setboard 1q1rr1k1/pn5p/1p3pp1/1Q2b1B1/1P6/5B1P/P4PP1/2R1R1K1 w - - +id "IQ.992" +solution Rxe5 Bxf6 +go +setboard r2qrbk1/p2b2pp/1pn1pn2/3p4/2pP1P2/2P2NN1/PPQ3PP/RBB2RK1 w - - +id "IQ.993" +solution Ng5 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.994" +solution Bxa6 Bxf6 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.995" +solution Bxa6 Bxf6 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.996" +solution Bxa6 Bxf6 +go +setboard r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - +id "IQ.997" +solution Bxa6 Bxf6 +go +setboard r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - +id "IQ.998" +solution Rxd6 +go +setboard r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - +id "IQ.999" +solution Rxd6 +go +setboard r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - +id "IQ.1000" +solution Rxd6 +go +setboard r4rk1/5pp1/p2R1Bb1/1pq1Pp1p/7Q/1Bn5/P5PP/5R1K w - - +id "IQ.1001" +solution Bxg7 +go +setboard r4rk1/5pp1/p2R1Bb1/1pq1Pp1p/7Q/1Bn5/P5PP/5R1K w - - +id "IQ.1002" +solution Bxg7 +go +setboard 5r2/p4pkp/3bpNp1/q3n3/1r3B1Q/3p4/PPP2PPP/R4K1R w - - +id "IQ.1003" +solution Qh6+ +go +setboard r3r3/pp2bBkp/6p1/q3p2Q/4n3/2N2R2/PPP3PP/2KR4 w - - +id "IQ.1005" +solution Bxg6 +go +setboard r3r3/pp2bBkp/6p1/q3p2Q/4n3/2N2R2/PPP3PP/2KR4 w - - +id "IQ.1006" +solution Bxg6 +go +setboard 5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - +id "IQ.1007" +solution Nf7+ +go +setboard r2q1rk1/1p1bbppp/p1n1p3/2p1P2Q/4N3/6P1/PPPB1PBP/3RR1K1 w - - +id "IQ.1008" +solution Nf6+ +go +setboard r2q1rk1/1p1bbppp/p1n1p3/2p1P2Q/4N3/6P1/PPPB1PBP/3RR1K1 w - - +id "IQ.1009" +solution Nf6+ +go +setboard r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - +id "IQ.1010" +solution Rxh6 Nd3 +go +setboard r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - +id "IQ.1011" +solution Rxh6 Nd3 +go +setboard r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - +id "IQ.1012" +solution Rxh6 Nd3 +go +setboard r1b1rb2/1p3kpQ/p1p1p3/q1P1P3/3P4/4P1R1/PP4PP/R1B3K1 w - - +id "IQ.1013" +solution Bd2 +go +setboard 3r1r2/p4pk1/bp2p1P1/4P2p/Pq1N1P2/2p4Q/2P3P1/3RK2R w - - +id "IQ.1014" +solution Qxh5 +go +setboard 4Q2r/1b4pk/p1n1pr1p/1p2P2B/1qn5/5N2/PPP2PP1/2KRR3 w - - +id "IQ.1015" +solution Ng5+ +go +setboard 3q1rk1/p1r2pp1/1p2p2p/6bn/3PNn2/1B2BP2/PP1Q1P1R/6RK w - - +id "IQ.1016" +solution Rxh5 +go +setboard rr4k1/2q2ppp/p1b1p3/2b1pPPN/1p2P1R1/3B3Q/PPP4P/1K1R4 w - - +id "IQ.1017" +solution Nf6+ +go +setboard 4r3/1r2ppk1/p2p1np1/2qP4/PpP5/1P1Q4/2B1R1PP/5R1K w - - +id "IQ.1018" +solution Rxf6 +go +setboard 4r3/1r2ppk1/p2p1np1/2qP4/PpP5/1P1Q4/2B1R1PP/5R1K w - - +id "IQ.1019" +solution Rxf6 +go +setboard r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - +id "IQ.1020" +solution Nxh5 +go +setboard 2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - +id "IQ.1021" +solution Qxh7+ +go +setboard r1r2k2/1q1n1p2/3PpPp1/4P2p/pbpN3R/2N3K1/1P2Q2P/3R4 w - - +id "IQ.1022" +solution Rxh5 +go +setboard 6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - +id "IQ.1023" +solution Rf5 +go +setboard 6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - +id "IQ.1024" +solution Rf5 +go +setboard 6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - +id "IQ.1025" +solution Rf5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1026" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1027" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1028" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1029" +solution Rxh5 +go +setboard 4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - +id "IQ.1030" +solution Rxh5 +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "IQ.1031" +solution Nxh7 +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "IQ.1032" +solution Nxh7 +go +setboard 2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - +id "IQ.1033" +solution Nxh7 +go +setboard r2qrnk1/1b2bppp/2p5/1p1pN1Pn/p2P1B2/3BP2P/PPQ2P2/2K3RR w - - +id "IQ.1034" +solution Bxh7+ +go +setboard 3r2k1/2nqprb1/1p2p1Np/p2nP3/3pBP2/PP4RQ/1B5P/6RK w - - +id "IQ.1035" +solution Nf8 Nh8 +go +setboard r4rk1/pppq2pp/1nbpp3/6B1/2PP2P1/3B3P/P1P2P2/1R1QR1K1 w - - +id "IQ.1036" +solution d5 +go +setboard r4rk1/pppq2pp/1nbpp3/6B1/2PP2P1/3B3P/P1P2P2/1R1QR1K1 w - - +id "IQ.1037" +solution d5 +go +setboard r1r1q2k/pp3pbp/4p3/2npPp1Q/3P1P1N/2P2RR1/P1P3PP/6K1 w - - +id "IQ.1038" +solution Rxg7 +go +setboard r1r1q2k/pp3pbp/4p3/2npPp1Q/3P1P1N/2P2RR1/P1P3PP/6K1 w - - +id "IQ.1039" +solution Rxg7 +go +setboard r4r1k/pbpq1p1B/1p2pp2/8/1b1P2Q1/8/PPP2PPP/2KR3R w - - +id "IQ.1040" +solution d5 +go +setboard r4r1k/pbpq1p1B/1p2pp2/8/1b1P2Q1/8/PPP2PPP/2KR3R w - - +id "IQ.1041" +solution d5 +go +setboard 2R5/r3b1k1/p2p4/P1pPp2p/6q1/2P2N1r/4Q1P1/5RK1 w - - +id "IQ.1042" +solution Nxe5 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1043" +solution f4 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1044" +solution f4 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1045" +solution f4 +go +setboard rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - +id "IQ.1046" +solution f4 +go +setboard 2q3k1/1p3pp1/4rbn1/r1pp1Np1/p2P4/4PN1R/PPQ2PP1/2K4R w - - +id "IQ.1047" +solution Ne7+ +go +setboard 2q3k1/1p3pp1/4rbn1/r1pp1Np1/p2P4/4PN1R/PPQ2PP1/2K4R w - - +id "IQ.1048" +solution Ne7+ +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "IQ.1049" +solution Rxh7+ e6 +go +setboard r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - +id "IQ.1050" +solution Rxh7+ e6 +go +setboard 4r3/pbrq1p1k/1p3Bpp/3pPn2/5PQ1/P6R/1P4PP/1B3RK1 w - - +id "IQ.1051" +solution Rh5 Qg5 +go +setboard r1bn1r2/1pp3k1/p2p3p/6p1/2qNB3/2P2PP1/P1Q2KP1/1R5R w - - +id "IQ.1052" +solution Rxh6 +go +setboard r1bn1r2/1pp3k1/p2p3p/6p1/2qNB3/2P2PP1/P1Q2KP1/1R5R w - - +id "IQ.1053" +solution Rxh6 +go +setboard r4rk1/3bpp1p/pqp3p1/4P2n/2B5/1P6/PBPbQ1PP/4RR1K w - - +id "IQ.1054" +solution e6 +go +setboard r4rk1/3bpp1p/pqp3p1/4P2n/2B5/1P6/PBPbQ1PP/4RR1K w - - +id "IQ.1055" +solution e6 +go +setboard 2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - +id "IQ.1056" +solution Rxd3 +go +setboard r3qrk1/1b3p2/1p1npnp1/2b1N1N1/p1P5/P1B5/1PB1QP1P/R2R2K1 w - - +id "IQ.1057" +solution Nd7 +go +setboard r3nrk1/pp1q2pp/4R3/6p1/2PP4/1B3Q2/P4P1P/3R2K1 w - - +id "IQ.1058" +solution c5 +go +setboard r5k1/4p2p/pp1qNnp1/2pPb3/2P1p1P1/4B3/PP1Q2P1/5R1K w - - +id "IQ.1059" +solution Bxc5 +go +setboard r7/pp2pkbp/2pq2p1/8/2P2N2/1P2R1PP/P3QPK1/8 w - - +id "IQ.1060" +solution c5 +go +setboard 2krb2r/p1q5/np2pPpp/n2pP3/2pP2P1/2P1N1B1/2P1Q1BK/RR6 w - - +id "IQ.1061" +solution Nxd5 +go +setboard 2krb2r/p1q5/np2pPpp/n2pP3/2pP2P1/2P1N1B1/2P1Q1BK/RR6 w - - +id "IQ.1062" +solution Nxd5 +go +setboard r7/1pqbr1pk/p1n4p/5p1P/2P1p3/2B3R1/PP1Q1PP1/1B2R1K1 w - - +id "IQ.1063" +solution Rxe4 +go +setboard 2rq1r2/pb4k1/1p1p1p1p/n1pP1RpQ/2P1P2B/P1PB4/6PP/R5K1 w - - +id "IQ.1064" +solution e5 +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +id "IQ.1065" +solution Nd6 +go +setboard r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - +id "IQ.1066" +solution Nd6 +go +setboard 5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - +id "IQ.1067" +solution Bg7 +go +setboard 5qk1/2p2r1p/p1p4P/1p6/3P4/1Q6/P1P3P1/5RK1 w - - +id "IQ.1068" +solution Qg3+ +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +id "IQ.1069" +solution Ng6+ +go +setboard r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - +id "IQ.1070" +solution Ng6+ +go +setboard r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - +id "IQ.1071" +solution Bf6 +go +setboard r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - +id "IQ.1072" +solution Bf6 +go +setboard r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - +id "IQ.1073" +solution Bf6 +go +setboard 2b2rk1/pp2R1bp/1qpp2p1/6N1/2P2PP1/3Q1B2/PP4PK/8 w - - +id "IQ.1074" +solution Bd5+ +go +setboard 1q3rnk/5p2/3p1P1p/p3n3/Np1r2P1/1P1B4/1PP4Q/1K1R3R w - - +id "IQ.1075" +solution Qxh6+ +go +setboard 2r3k1/1rq2p1p/pp1p1bp1/2pP2N1/2P1R3/1Q6/PP3PP1/4R1K1 w - - +id "IQ.1076" +solution Nxh7 +go +setboard 3r3k/p5qp/bp2B1p1/n2P1p2/5N2/Q1R5/P4PPP/6K1 w - - +id "IQ.1077" +solution Qb2 +go +setboard 3r3k/p5qp/bp2B1p1/n2P1p2/5N2/Q1R5/P4PPP/6K1 w - - +id "IQ.1078" +solution Qb2 +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +id "IQ.1079" +solution Rc1 +go +setboard 4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - +id "IQ.1080" +solution Rc1 +go +setboard 4k3/pp2pp2/4n1p1/3RP1P1/2r1N3/P1P5/1P2q3/1K5Q w - - +id "IQ.1081" +solution Nc5 +go +setboard 5rk1/1b3p1p/4pb2/2p1N2Q/1pP2p2/1P1R3P/qB3PP1/6K1 w - - +id "IQ.1082" +solution Rd8 +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +id "IQ.1083" +solution Rd4 +go +setboard 5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - +id "IQ.1084" +solution Rd4 +go +setboard k1n1r3/p2R2bb/2p2qpp/4pp2/2P5/2B1Q1P1/PP3PBP/6K1 w - - +id "IQ.1085" +solution Qc5 Bxe5 +go +setboard rr4k1/3nbp1p/p3p1p1/q2pPPP1/bp1B3R/1B2Q3/PPP4P/2K3R1 w - - +id "IQ.1086" +solution fxe6 +go +setboard 7k/p2rq2p/1p3R1P/2p5/2P2P1Q/8/6PK/8 w - - +id "IQ.1087" +solution Qe1 +go +setboard 7k/p2rq2p/1p3R1P/2p5/2P2P1Q/8/6PK/8 w - - +id "IQ.1088" +solution Qe1 +go +setboard b1R2nk1/5ppp/1p3n2/5N2/1b2p3/1P2BP2/q3BQPP/6K1 w - - +id "IQ.1089" +solution Bc5 +go +setboard 6k1/1p3ppp/1PbNp3/3rP1q1/2Q5/8/5PPP/1R4K1 w - - +id "IQ.1090" +solution Qxc6 +go +setboard 6k1/1p3ppp/1PbNp3/3rP1q1/2Q5/8/5PPP/1R4K1 w - - +id "IQ.1091" +solution Qxc6 +go +setboard 3r2k1/pqrP1p1p/6p1/1p6/n2Qp3/B1P1P3/P5PP/3R1RK1 w - - +id "IQ.1092" +solution Qf6 Bf8 +go +setboard 4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - +id "IQ.1093" +solution Bxf7+ +go +setboard 4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - +id "IQ.1094" +solution Bxf7+ +go +setboard 4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - +id "IQ.1095" +solution Bxf7+ +go +setboard 2b1r1k1/1r1n1pp1/q2p3p/1p1P4/1P1N1RPP/2Q1P3/5PBK/2R5 w - - +id "IQ.1096" +solution Qxc8 +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +id "IQ.1097" +solution Qh6 Kg2 +go +setboard b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - +id "IQ.1098" +solution Qh6 Kg2 +go +setboard 4r1k1/p4ppp/1p2q3/n2R4/2r1p3/Pn2B1P1/1Q2PPBP/3R2K1 w - - +id "IQ.1099" +solution Re5 +go +setboard rnb3k1/6pp/p4q2/3p1N2/1p3Q2/1P6/1PP3PP/5R1K w - - +id "IQ.1100" +solution Nh6+ +go +setboard r1b2r1k/2q2pp1/2pb3p/p1n1NB2/1pP5/1P5P/PBQ2PP1/3RR1K1 w - - +id "IQ.1101" +solution Rxd6 +go +setboard r1b2r1k/2q2pp1/2pb3p/p1n1NB2/1pP5/1P5P/PBQ2PP1/3RR1K1 w - - +id "IQ.1102" +solution Rxd6 +go +setboard 2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - +id "IQ.1103" +solution Ra8+ +go +setboard 2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - +id "IQ.1104" +solution Ra8+ +go +setboard 2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - +id "IQ.1105" +solution Ra8+ +go +setboard 1q4r1/3Q1Npk/p6p/1p5N/8/7P/Pn3PP1/6K1 w - - +id "IQ.1106" +solution Qf5+ +go +setboard 1q4r1/3Q1Npk/p6p/1p5N/8/7P/Pn3PP1/6K1 w - - +id "IQ.1107" +solution Qf5+ +go +setboard r1q1r1k1/p1n1R1bp/1pp2pp1/5b2/2P2P1Q/P4NN1/1P1B2PP/2KR4 w - - +id "IQ.1108" +solution Nxf5 +go +setboard r1q1r1k1/p1n1R1bp/1pp2pp1/5b2/2P2P1Q/P4NN1/1P1B2PP/2KR4 w - - +id "IQ.1109" +solution Nxf5 +go +setboard 2r1k2r/1p2pp1p/2bp1p1b/p1qN4/4P3/6Q1/PPPR1PPP/1K3B1R w k - +id "IQ.1110" +solution Qh3 +go +setboard 2r1k2r/1p2pp1p/2bp1p1b/p1qN4/4P3/6Q1/PPPR1PPP/1K3B1R w k - +id "IQ.1111" +solution Qh3 +go +setboard r1br2k1/1pq2ppp/p3pP2/8/1n3PP1/1NpB4/PPP2Q1P/2KR2R1 w - - +id "IQ.1112" +solution Bxh7+ +go +setboard 5k2/1pp2b1p/2p5/r3PPR1/pr6/2N5/1PP4P/2KR4 w - - +id "IQ.1113" +solution f6 +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +id "IQ.1114" +solution Bxg6 +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +id "IQ.1115" +solution Bxg6 +go +setboard r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - +id "IQ.1116" +solution Bxg6 +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1117" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1118" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1119" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1120" +solution g5+ +go +setboard 8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - +id "IQ.1121" +solution g5+ +go +setboard 6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - +id "IQ.1122" +solution cxb6 +go +setboard 5b2/pr4pk/4P1Rp/1pppBPP1/8/1P2P3/P6K/8 w - - +id "IQ.1123" +solution Rxh6+ gxh6 +go +setboard 5b2/pr4pk/4P1Rp/1pppBPP1/8/1P2P3/P6K/8 w - - +id "IQ.1124" +solution Rxh6+ gxh6 +go +setboard 8/kp6/4R3/1P2K3/8/3pp3/8/8 w - - +id "IQ.1125" +solution Kd6 +go +setboard 5rk1/2rnqp1p/b3p1pP/2ppP3/1p3QN1/pP1P1BP1/P1P2P2/R3R1K1 w - - +id "IQ.1126" +solution Bxd5 +go +setboard 5r1k/p5bp/1p6/4P3/P2B4/3n2PB/1PR4K/8 w - - +id "IQ.1127" +solution e6 +go +setboard 4R3/5Bq1/7p/5p2/1n3k1B/7P/6PK/8 w - - +id "IQ.1128" +solution g3+ +go +setboard 8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - +id "IQ.1129" +solution a6 +go +setboard 1r1q1rk1/Nb1n1pbp/p5p1/3P4/PPB2p2/4B3/6PP/2RQ1RK1 w - - +id "IQ.1130" +solution Nc6 +go +setboard b2rr1k1/P3pp2/3p2p1/1Q1Pb2p/2P4P/1R2B1P1/4qPBK/1R6 w - - +id "IQ.1131" +solution Qxe8+ +go +setboard 8/5pk1/3P2p1/pQ6/P2p4/5pP1/3rqP1P/5RK1 w - - +id "IQ.1132" +solution d7 +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1133" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1134" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1135" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1136" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1137" +solution Bxd4+ +go +setboard 3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - +id "IQ.1138" +solution Bxd4+ +go +setboard 8/5p1p/1n2p2P/1k1pPpP1/3K4/4N3/2P5/8 w - - +id "IQ.1139" +solution Nxf5 +go +setboard 8/1p1b4/4p1k1/1PPp4/P4P1p/4n1p1/8/4BBK1 w - - +id "IQ.1140" +solution a5 +go +setboard 8/1p1b4/4p1k1/1PPp4/P4P1p/4n1p1/8/4BBK1 w - - +id "IQ.1141" +solution a5 +go +setboard 2q1n1kr/6b1/1r1p2B1/2p2pP1/2P1bP1N/1P1QB2P/6RK/1R6 w - - +id "IQ.1142" +solution Qxe4 +go +setboard 5brk/2q2p1p/p3pP1B/4Pp2/8/1P1R1Q1K/P6P/8 w - - +id "IQ.1143" +solution Bxf8 +go +setboard 1q4rk/6r1/2RP3p/1NR3p1/p3Qn2/P6P/6P1/6K1 w - - +id "IQ.1144" +solution d7 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1145" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1146" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1147" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1148" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1149" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1150" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1151" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1152" +solution Nxd5 +go +setboard r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - +id "IQ.1153" +solution Nxd5 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1154" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1155" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1156" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1157" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1158" +solution Bc8 +go +setboard 8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - +id "IQ.1159" +solution Bc8 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1160" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1163" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1164" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1165" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1166" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1168" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1169" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1170" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1171" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1172" +solution Rb5 +go +setboard k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - +id "IQ.1173" +solution Rb5 +go +setboard 3r2k1/pp2qppp/4bn2/4p3/4P3/P1Nr4/1PQN1PPP/R4RK1 w - - +id "IQ.1175" +avoid Nd5 +go +setboard 3r2k1/pp2qppp/4bn2/4p3/4P3/P1Nr4/1PQN1PPP/R4RK1 w - - +id "IQ.1178" +avoid Nd5 +go +setboard r2q1rk1/3nbppp/p1bpp3/6PQ/1p1BP3/1BN5/PPP2P1P/2KR2R1 w - - +id "IQ.1179" +solution Rd3 +go +setboard r3r1k1/1pq2pp1/p2pbb1p/P3n3/3NP3/2N5/1PP1B1PP/R2Q1R1K w - - +id "IQ.1180" +solution Rxf6 +go +setboard r3r1k1/1pq2pp1/p2pbb1p/P3n3/3NP3/2N5/1PP1B1PP/R2Q1R1K w - - +id "IQ.1181" +solution Rxf6 +go +setboard 1rb1r1k1/3n1ppp/p1p1p3/q3P3/7P/2N1Q1R1/PPP3P1/2KR1B2 w - - +id "IQ.1182" +solution Rxd7 +go +setboard r2q1rk1/pp1n1p1p/2p2np1/4bQB1/3pNP2/1B5P/PP4P1/R3R1K1 w - - +id "IQ.1183" +solution Qxe5 +go +setboard 2rnr2k/2qbp3/pp1p2p1/3P1p1p/1PPN1P2/5B1P/P2Q2P1/2R1R1K1 w - - +id "IQ.1184" +solution Bxh5 +go +setboard 2r1r3/3qppkp/pp1p2p1/3PnP2/2PN4/1P5P/P2Q2P1/4RRK1 w - - +id "IQ.1185" +solution Rxe5 +go +setboard 1n2rk2/1qr1pp2/pp1p1npp/3P4/1PPN1P2/P2QR1P1/7P/4RBK1 w - - +id "IQ.1186" +solution Ne6+ +go +setboard 1r1r1n2/5pkp/4pNp1/2PpP1P1/p1bP1PP1/1qB1K3/p2Q4/3R3R w - - +id "IQ.1187" +solution f5 +go +setboard 1r1r1n2/5pkp/4pNp1/2PpP1P1/p1bP1PP1/1qB1K3/p2Q4/3R3R w - - +id "IQ.1188" +solution f5 +go +setboard 3r2k1/3rppb1/p1R1b1p1/qp1NP3/8/1P2QB2/P5PP/5RK1 w - - +id "IQ.1190" +solution Rxe6 +go +setboard r2qnrk1/pp2ppb1/3p3B/2p5/7Q/1PNP3b/1PP3PP/R4RK1 w - - +id "IQ.1191" +solution Ne4 +go +setboard r4bk1/pbq2pp1/1pn1p2p/8/4N3/1P2P1P1/PB2QPBP/3R2K1 w - - +id "IQ.1192" +solution Nf6+ +go +setboard r4bk1/pbq2pp1/1pn1p2p/8/4N3/1P2P1P1/PB2QPBP/3R2K1 w - - +id "IQ.1194" +solution Nf6+ +go +setboard rq2r1k1/pp2RNp1/1bp2n1p/8/1Q6/7P/PPB2PP1/5RK1 w - - +id "IQ.1195" +solution Nxh6+ +go +setboard r4rk1/p1p2pp1/1bp1b2p/3q2B1/Pn1PN3/5N2/1P1Q1PPP/R3R1K1 w - - +id "IQ.1196" +solution Bxh6 Be7 +go +setboard r4rk1/p1p2pp1/1bp1b2p/3q2B1/Pn1PN3/5N2/1P1Q1PPP/R3R1K1 w - - +id "IQ.1197" +solution Bxh6 Be7 +go +setboard r1b2rk1/2q1bppp/p2pp3/2n3PQ/1p1BP3/1BN5/PPP2P1P/2KR2R1 w - - +id "IQ.1198" +solution Bf6 +go +setboard r3k2r/1bqnBppp/p3p3/1p2P3/3N2Q1/3B4/PPP3PP/2KnR3 w kq - +id "IQ.1199" +solution Nxe6 +go +setboard r1bqkn1r/p3bpp1/1p2pn1p/2pPN1B1/2P5/3B2N1/PP3PPP/R2QR1K1 w kq - +id "IQ.1200" +solution Nf5 Nh5 dxe6 +go +setboard r3kb1r/2q2ppp/pn2p3/4P3/pPPN4/P3BQ2/6PP/R4RK1 w kq - +id "IQ.1201" +solution Nxe6 Rf2 Rad1 +go +setboard r4k1r/pp3pb1/2p3p1/3nNb1q/7p/1BB1Q2P/PP3PP1/3RR1K1 w - - +id "IQ.1202" +solution Rxd5 Bxd5 Qc5+ +go +setboard 4k1r1/1q1r1p2/4pQp1/3pP1B1/2p3P1/1nP2BP1/1P5K/3R4 w - - +id "IQ.1203" +solution Bxd5 +go +setboard 4k1r1/1q1r1p2/4pQp1/3pP1B1/2p3P1/1nP2BP1/1P5K/3R4 w - - +id "IQ.1204" +solution Bxd5 +go +setboard 2b2k1r/5ppp/1b6/q1p1PP2/3Np1Q1/1PP5/6PP/1N3RK1 w - - +id "IQ.1205" +solution Ne6+ +go +setboard 1r5r/p2bbk1p/4pnp1/q1ppQ1B1/7P/2N3P1/PPP2PB1/1K1R3R w - - +id "IQ.1206" +solution Nxd5 +go +setboard r2qk2r/1b1n1p2/p6n/1pp1p1Np/4P2P/2QBNP2/PPP5/2KR2R1 w kq - +id "IQ.1210" +solution Bxb5 Bc4 Bf1 +go +setboard rn1qk2r/pbp2p2/1p3ppb/7p/2BP1N1P/2N1P3/PP3PP1/R2QK2R w KQkq - +id "IQ.1211" +solution Bxf7+ +go +setboard r1b2k1r/p2n1pp1/1q2p3/2ppP1B1/1b1N1Q1P/2N5/PPP2P2/R3K1R1 w Q - +id "IQ.1212" +solution Bd8 +go +setboard r4b1r/pp3kpp/1qp1Rn2/8/8/5Q1P/PPPB1PP1/2KR4 w - - +id "IQ.1213" +solution Rxf6+ +go +setboard 7r/1Qrk1pbp/p2pp1p1/6P1/5PB1/1P6/q1P4P/2KR2BR w - - +id "IQ.1214" +solution Rxd6+ +go +setboard r3k2r/2pb1npp/ppp5/2q1p3/2N1P3/1QP2N1P/PP3PP1/R2R2K1 w kq - +id "IQ.1215" +solution Rxd7 Qb4 +go +setboard r3kb1r/pp3p1p/4pp2/q2pN3/2P5/8/PP3PPP/R2QR1K1 w kq - +id "IQ.1216" +solution Nxf7 +go +setboard r3kbnr/p4p2/1p2p2p/3qP1p1/3Nn1QB/8/PP2NPPP/R4RK1 w kq - +id "IQ.1217" +solution Nxe6 +go +setboard r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - +id "IQ.1218" +solution b3 Nd6+ +go +setboard r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - +id "IQ.1219" +solution b3 Nd6+ +go +setboard r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - +id "IQ.1221" +solution b3 Nd6+ +go +setboard r1bqr1k1/1p1nbppp/p1n1p3/3pP2Q/3N1P2/1BN1B3/PPP3PP/R4RK1 w - - +id "IQ.1222" +solution Nxd5 +go +setboard 2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - +id "IQ.1223" +solution Bxf7+ +go +setboard rn1q1rk1/1b2bppp/p3p3/1pn1P2Q/3N4/1BN1B3/PPP3PP/R4RK1 w - - +id "IQ.1224" +solution Rxf7 +go +setboard 2r1r3/pbq1bpk1/1pn3p1/6Bp/4Q3/PB3N2/1P3PPP/R3R1K1 w - - +id "IQ.1225" +solution Bxf7 +go +setboard 2rq1rk1/1b3pb1/5np1/1pn1p1Np/4P2Q/2N1B3/BPP3PP/R4R1K w - - +id "IQ.1226" +solution Nxf7 +go +setboard 4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - +id "IQ.1227" +solution Rxg6+ +go +setboard 4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - +id "IQ.1228" +solution Rxg6+ +go +setboard 4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - +id "IQ.1229" +solution Rxg6+ +go +setboard r5k1/1p3p1p/p1pqrPp1/3bN3/8/P1P3Q1/1P4PP/4RRK1 w - - +id "IQ.1231" +solution Nxf7 +go +setboard rnb2rk1/pp3p1p/3q2pQ/3pN3/2pP4/2PB4/P1P2PPP/4RRK1 w - - +id "IQ.1232" +solution Nxf7 +go +setboard r2r1bk1/1ppq2pp/2p2B2/p1n2N1b/P3P1R1/3PN3/2P3PP/R2Q2K1 w - - +id "IQ.1233" +solution Ne7+ +go +setboard r2r1bk1/1ppq2pp/2p2B2/p1n2N1b/P3P1R1/3PN3/2P3PP/R2Q2K1 w - - +id "IQ.1234" +solution Ne7+ +go +setboard r4rk1/pp2bpp1/1qp1b2p/4B2Q/n7/3B4/PPP2PPP/3RR1K1 w - - +id "IQ.1236" +solution Bxg7 +go +setboard r4rk1/pp2bpp1/1qp1b2p/4B2Q/n7/3B4/PPP2PPP/3RR1K1 w - - +id "IQ.1237" +solution Bxg7 +go +setboard 5Q2/pp1b2pk/1n1p2rp/2pP1p2/2P2P2/q1BB4/6PP/4R1K1 w - - +id "IQ.1238" +solution Bxg7 +go +setboard 5Q2/pp1b2pk/1n1p2rp/2pP1p2/2P2P2/q1BB4/6PP/4R1K1 w - - +id "IQ.1239" +solution Bxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1240" +solution Rxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1241" +solution Rxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1242" +solution Rxg7 +go +setboard 1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - +id "IQ.1243" +solution Rxg7 +go +setboard r1b2k1r/1p4pp/p4B2/2bpN3/8/q2n4/P1P2PPP/1R1QR1K1 w - - +id "IQ.1244" +solution Bxg7+ Qh5 +go +setboard 1r3r1k/1b2bppp/p1qp4/5PP1/1p1B3Q/1PN2R2/1PP4P/5RK1 w - - +id "IQ.1245" +solution Bxg7+ +go +setboard r2b1rk1/2q2ppp/p3b3/1pn1pNB1/4Pn1Q/P1NB4/1PP3PP/R4R1K w - - +id "IQ.1246" +solution Nxg7 +go +setboard 6k1/5rpp/8/2Np4/1Pn3R1/4Q2P/q2r1PP1/5RK1 w - - +id "IQ.1247" +solution Qe8+ +go +setboard r4rk1/1bpq1ppp/3p1b2/2nP1N2/8/1p3Q1P/PPB2PP1/R1B1R1K1 w - - +id "IQ.1248" +solution Nxg7 +go +setboard r2q1rk1/pp1b1Rp1/4p2p/4PnNQ/2pP4/2P1B3/P5PP/5RK1 w - - +id "IQ.1249" +solution R1xf5 +go +setboard r4r1k/pbq2pp1/1p2p2p/4P3/2pP3Q/P1P3RP/R4P1P/1B4K1 w - - +id "IQ.1250" +solution Rxg7 +go +setboard 2r2bk1/1bq1rppp/pp1p4/4n1P1/Pn1BP1N1/2N3Q1/1PP2RBP/5RK1 w - - +id "IQ.1251" +solution Bxe5 +go +setboard r1b2rk1/pppn2bp/3p1qp1/3p2N1/3P4/3BB3/PPP2PPP/R2QR1K1 w - - +id "IQ.1252" +solution Nxh7 +go +setboard rnb3kr/1p1nqppp/p3p3/2ppP3/3P1N2/2NB1Q2/PPP2PP1/R3K2R w KQ - +id "IQ.1253" +solution Bxh7+ +go +setboard r1qr2k1/p3bppp/b1p5/3nN3/NP1P4/P3B3/5PPP/1B1QR1K1 w - - +id "IQ.1254" +solution Bxh7+ +go +setboard 3r1rk1/1bq1bp1p/p3p1p1/3pP3/3N1P2/2PBB2R/n1P1Q1PP/5RK1 w - - +id "IQ.1255" +solution Rxh7 +go +setboard r1qb1rk1/5ppp/p1n5/1ppNP1P1/2p2P1P/P4Q2/1P6/1B1R1RK1 w - - +id "IQ.1256" +solution Bxh7+ +go +setboard 2r1r1k1/pbq2ppp/1p2pn2/2b1N3/2P5/2B5/PPB1QPPP/3RR1K1 w - - +id "IQ.1257" +solution Bxh7+ +go +setboard 1q1r2k1/pb2b1pp/1p3p2/3P4/1n1QB3/5N2/PB3PPP/2R4K w - - +id "IQ.1258" +solution Bxh7+ +go +setboard 1q1r2k1/pb2b1pp/1p3p2/3P4/1n1QB3/5N2/PB3PPP/2R4K w - - +id "IQ.1259" +solution Bxh7+ +go +setboard 2r5/3nr1pk/p2qpp1p/1p5Q/3P1PN1/2P3RP/P5PK/4R3 w - - +id "IQ.1260" +solution Nxh6 +go +setboard r1q2r1k/p1ppb1p1/1p2p1Qp/3n3P/3PN3/2P1B3/PP3PP1/3R1RK1 w - - +id "IQ.1261" +solution Bxh6 +go +setboard r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - +id "IQ.1262" +solution Qh6+ +go +setboard r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - +id "IQ.1263" +solution Bxh6 +go +setboard 2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - +id "IQ.1264" +solution Rxh6+ +go +setboard 2r2rk1/1bq1bpp1/pn2p2p/1pn3P1/3NNP1Q/P6R/1PP3BP/R1B4K w - - +id "IQ.1265" +solution Nf6+ +go +setboard 4rb2/1p1q1ppk/p1n1p2p/2p1Pn2/3PNR2/2P2K2/P2QBP2/6R1 w - - +id "IQ.1266" +solution Rxf5 +go +setboard r6r/pb1R1pk1/1p2p1pp/3nP3/4N2Q/4B3/P3qPPP/3R2K1 w - - +id "IQ.1267" +solution Bxh6+ +go +setboard rq1n1bk1/3b1pp1/3p3p/pppP3N/8/1P4PP/PBPQ1PB1/4R1K1 w - - +id "IQ.1268" +solution Qxh6 +go +setboard 2rq1rk1/pp3pp1/4pb1p/3bN3/3P4/PnPB3R/2Q2PPP/R1B3K1 w - - +id "IQ.1269" +solution Bh7+ +go +setboard 2r2rk1/p1n3pp/1p2p3/1q1pQP2/3Pn3/6N1/PP4PP/R1B2RK1 w - - +id "IQ.1270" +solution Bh6 +go +setboard 4rr1k/pp4b1/4P2p/5p1R/3q4/3B2P1/PP1R4/1K5Q w - - +id "IQ.1271" +solution Rxh6+ +go +setboard 1r2b3/pp1rqppk/3b3p/3Bp2Q/4P1N1/5R1P/PP3PP1/3R2K1 w - - +id "IQ.1272" +solution Rf6 +go +setboard r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - +id "IQ.1273" +solution Bxh6 +go +setboard r2q1rk1/3nbpp1/4p2p/p1p1P3/1p1P3P/3B1b1R/PPQB1PP1/R3K3 w - - +id "IQ.1274" +solution Bxh6 +go +setboard r1r1n3/5p1k/1n1P2pp/ppq1pN2/2p1P3/1PP1R2P/P1B2QPK/5R2 w - - +id "IQ.1275" +solution Nxh6 +go +setboard r1n1nrk1/p4p1p/1q4pQ/2p1pN2/1pB1P1P1/5P2/PPP4P/1K1R3R w - - +id "IQ.1276" +solution Rd6 Rhg1 +go +setboard r3r3/2qn1Qbk/b2p2pp/1npP4/1p6/3NB1NP/1P1R2P1/1B2R1K1 w - - +id "IQ.1277" +solution Qxg6+ +go +setboard 1b4k1/1pnq1r1p/4p1p1/1pPpP2Q/1P5B/3BPP2/7P/6RK w - - +id "IQ.1278" +solution Bxg6 +go +setboard 2r2rn1/p3q1bk/n2p2pp/1b1PPp2/1pp2P1N/1P2N1P1/P1QB2BP/4RRK1 w - - +id "IQ.1279" +solution Nxg6 +go +setboard r2q1r1k/p3pn1p/3p2pQ/1ppP1p1n/4P3/2N2P2/PPP1BP2/2K3RR w - - +id "IQ.1280" +solution Qxg6 +go +setboard 4Q3/p4pk1/2p3p1/8/3P1N2/4PBR1/q4P1K/r3r3 w - - +id "IQ.1281" +solution Rxg6+ Qe5+ +go +setboard 2r1r1k1/4qpb1/p2p2p1/1p1Pn1P1/3BB3/P1P5/1P4Q1/1K2R2R w - - +id "IQ.1282" +solution Bxg6 Qh2 Qh3 +go +setboard 2r1r1k1/4qpb1/p2p2p1/1p1Pn1P1/3BB3/P1P5/1P4Q1/1K2R2R w - - +id "IQ.1283" +solution Bxg6 Qh2 Qh3 +go +setboard 5r2/1pr1ppk1/1n1q2p1/p2P3p/5R2/1BP1RQ2/5PP1/6K1 w - - +id "IQ.1284" +solution Re6 +go +setboard 4rbk1/n2n3p/b1q1p1p1/1p1pP1B1/1PrP1N2/1R3NP1/3Q1PB1/R5K1 w - - +id "IQ.1285" +solution Nxg6 Bf1 +go +setboard 4rbk1/n2n3p/b1q1p1p1/1p1pP1B1/1PrP1N2/1R3NP1/3Q1PB1/R5K1 w - - +id "IQ.1286" +solution Nxg6 Bf1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1287" +solution Nxf6+ Rg1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1288" +solution Nxf6+ Rg1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1289" +solution Nxf6+ Rg1 +go +setboard r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - +id "IQ.1290" +solution Nxf6+ Rg1 +go diff --git a/tests/orig/LCT2.epd b/tests/orig/LCT2.epd new file mode 100644 index 0000000..fa8b61b --- /dev/null +++ b/tests/orig/LCT2.epd @@ -0,0 +1,36 @@ +r3kb1r/3n1pp1/p6p/2pPp2q/Pp2N3/3B2PP/1PQ2P2/R3K2R w KQkq - bm d6; id "POS-01";c0 "Chernin - Miles, Tunis 1985, 1.d6!"; +1k1r3r/pp2qpp1/3b1n1p/3pNQ2/2pP1P2/2N1P3/PP4PP/1K1RR3 b - - bm Bb4; id "POS-02";c0 "Lilienthal - Botvinnik, Moskau 1945, 1...Bb4!"; +r6k/pp4p1/2p1b3/3pP3/7q/P2B3r/1PP2Q1P/2K1R1R1 w - - bm Qc5; id "POS-03";c0 "Boissel - Boulard, corr. 1994, 1.Qc5!"; +1nr5/2rbkppp/p3p3/Np6/2PRPP2/8/PKP1B1PP/3R4 b - - bm e5; id "POS-04";c0 "Kaplan - Kopec, USA 1975, 1...e5!"; +2r2rk1/1p1bq3/p3p2p/3pPpp1/1P1Q4/P7/2P2PPP/2R1RBK1 b - - bm Bb5; id "POS-05";c0 "Estrin - Pytel, Albena 1973, 1...Bb5!"; +3r1bk1/p4ppp/Qp2p3/8/1P1B4/Pq2P1P1/2r2P1P/R3R1K1 b - - bm e5; id "POS-06"; c0 "Nimzowitsch - Capablanca, New York 1927, 1...e5!"; +r1b2r1k/pp2q1pp/2p2p2/2p1n2N/4P3/1PNP2QP/1PP2RP1/5RK1 w - - bm Nd1; id "POS-07";c0 "Tartakower - Rubinstein, Moskau 1925, 1.Nd1!"; +r2qrnk1/pp3ppb/3b1n1p/1Pp1p3/2P1P2N/P5P1/1B1NQPBP/R4RK1 w - - bm Bh3; id "POS-08";c0 "Polugaevsky - Unzicker, Kislovodsk 1972, 1.Bh3!"; +5nk1/Q4bpp/5p2/8/P1n1PN2/q4P2/6PP/1R4K1 w - - bm Qd4; id "POS-09";c0 "Boissel - Del Gobbo, corr. 1994, 1.Qd4!"; +r3k2r/3bbp1p/p1nppp2/5P2/1p1NP3/5NP1/PPPK3P/3R1B1R b kq - bm Bf8; id "POS-10";c0 "Cucka - Jansa, Brno 1960, 1...Bf8!"; +bn6/1q4n1/1p1p1kp1/2pPp1pp/1PP1P1P1/3N1P1P/4B1K1/2Q2N2 w - - bm h4; id "POS-11";c0 "Landau - Schmidt, Noordwijk 1938, 1.h4!"; +3r2k1/pp2npp1/2rqp2p/8/3PQ3/1BR3P1/PP3P1P/3R2K1 b - - bm Rb6; id "POS-12";c0 "Korchnoi - Karpov, Meran 1981, 1...Rb6!"; +1r2r1k1/4ppbp/B5p1/3P4/pp1qPB2/2n2Q1P/P4PP1/4RRK1 b - - bm Na2; id "POS-13";c0 "Barbero - Kouatly, Budapest 1987, 1...Na2:!"; +r2qkb1r/1b3ppp/p3pn2/1p6/1n1P4/1BN2N2/PP2QPPP/R1BR2K1 w kq - bm d5; id "POS-14";c0 "Spasski - Aftonomov, Leningrad 1949, 1.d5!"; +8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - bm f6; id "FIN-01";c0 "NN - Lasker,Ed, 1.f6!"; +8/pp2r1k1/2p1p3/3pP2p/1P1P1P1P/P5KR/8/8 w - - bm f5; id "FIN-02";c0 "Capablanca - Eliskases, Moskau 1936, 1.f5!"; +8/3p4/p1bk3p/Pp6/1Kp1PpPp/2P2P1P/2P5/5B2 b - - bm Be4; id "FIN-03";c0 "Studie 1994, 1...Be4:!"; +5k2/7R/4P2p/5K2/p1r2P1p/8/8/8 b - - bm h3; id "FIN-04";c0 "Karpov - Deep Thought, Analyse 1990, 1...h3!"; +6k1/6p1/7p/P1N5/1r3p2/7P/1b3PP1/3bR1K1 w - - bm a6; id "FIN-05";c0 "Karpov - Kasparov, Moskau 1985 [Analyse], 1.a6!"; +8/3b4/5k2/2pPnp2/1pP4N/pP1B2P1/P3K3/8 b - - bm f4; id "FIN-06";c0 "Minev - Portisch, Halle 1967, 1...f4!"; +6k1/4pp1p/3p2p1/P1pPb3/R7/1r2P1PP/3B1P2/6K1 w - - bm Bb4; id "FIN-07";c0 "Lengyel - Kaufman, Los Angeles 1974, 1.Bb4!"; +2k5/p7/Pp1p1b2/1P1P1p2/2P2P1p/3K3P/5B2/8 w - - bm c5; id "FIN-08";c0 "Spassky - Byrne, 1974, 1.c5!"; +8/5Bp1/4P3/6pP/1b1k1P2/5K2/8/8 w - - bm Kg4; id "FIN-09";c0 "Klimenok - Kabanov, UdSSR 1969, 1.Kg4!"; +1r4k1/1q2bp2/3p2p1/2pP4/p1N4R/2P2QP1/1P3PK1/8 w - - bm Nd6; id "CMB-01";c0 "Romanishin - Gdansky, Polonica Zdroj 1992, 1.Nd6:!"; +rn3rk1/pbppq1pp/1p2pb2/4N2Q/3PN3/3B4/PPP2PPP/R3K2R w KQ - bm Qh7; id "CMB-02";c0 "Lasker,Ed - Thomas, London 1911, 1.Qh7:+!"; +4r1k1/3b1p2/5qp1/1BPpn2p/7n/r3P1N1/2Q1RPPP/1R3NK1 b - - bm Qf3; id "CMB-03";c0 "Andruet - Spassky, BL 1988, 1...Qf3!"; +2k2b1r/1pq3p1/2p1pp2/p1n1PnNp/2P2B2/2N4P/PP2QPP1/3R2K1 w - - bm ef6; id "CMB-04";c0 "Vanka - Jansa, Prag 1957, 1.ef6:!"; +2r2r2/3qbpkp/p3n1p1/2ppP3/6Q1/1P1B3R/PBP3PP/5R1K w - - bm Rh7; id "CMB-05";c0 "Boros - Szabo, Budapest 1937, 1.Rh7:+!"; +2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - bm ef6; id "CMB-06";c0 "Lilienthal - Capablanca, Hastings 1934, 1.ef6:!"; +2rr2k1/1b3ppp/pb2p3/1p2P3/1P2BPnq/P1N3P1/1B2Q2P/R4R1K b - - bm Rc3; id "CMB-07";c0 "Rotlewi - Rubinstein, Lodz 1907, 1...Rc3:!"; +2b1r1k1/r4ppp/p7/2pNP3/4Q3/q6P/2P2PP1/3RR1K1 w - - bm Nf6; id "CMB-08";c0 "Zarkov - Mephisto, Albuquerque 1991, 1.Nf6+!"; +6k1/5p2/3P2p1/7n/3QPP2/7q/r2N3P/6RK b - - bm Rd2; id "CMB-09";c0 "Portisch - Kasparov, Moskau 1981, 1...Rd2:!"; +rq2rbk1/6p1/p2p2Pp/1p1Rn3/4PB2/6Q1/PPP1B3/2K3R1 w - - bm Bh6; id "CMB-10";c0 "Tchoudinovskikh - Merchiev, UdSSR 1987, 1.Bh6:!"; +rnbq2k1/p1r2p1p/1p1p1Pp1/1BpPn1N1/P7/2P5/6PP/R1B1QRK1 w - - bm Nh7; id "CMB-11";c0 "Vaisser - Genius 2, Aubervilliers, 1994, 1.Nh7:!"; +r2qrb1k/1p1b2p1/p2ppn1p/8/3NP3/1BN5/PPP3QP/1K3RR1 w - - bm e5; id "CMB-12"; c0 "Spassky - Petrosian, Moskau 1969, 1.e5!"; + diff --git a/tests/orig/arasan.epd b/tests/orig/arasan.epd new file mode 100644 index 0000000..8acc27f --- /dev/null +++ b/tests/orig/arasan.epd @@ -0,0 +1,143 @@ +2r3k1/4Bppp/p7/1p1bP3/8/2n5/P1PR2PP/R5K1 b - - am Bxa2; id "arasan4.1"; +8/1p2r1kp/1p1R2p1/4qp2/1P6/P1p1P1P1/5P1P/3Q2K1 w - - am Rxb6; id "arasan4.2"; +qr3k2/4Rp1p/1prp2p1/1Q1N2P1/1PPbRP2/6KP/8/8 b - - bm Qa1; id "arasan4.3"; +R7/5Qpk/2p1p2p/1bqp4/8/7P/5PP1/6K1 b - - bm Bd3; id "arasan4.4"; +2r3k1/1b1nqppp/p3p3/8/1pQPn3/4PNP1/PP3PBP/RN4K1 w - - bm Qf1; id "arasan4.5"; +r3r1k1/6p1/1pqp2Np/2p1nP1P/N1PbPQ2/1P3PR1/P2K4/7R w - - bm f6; id "arasan4.6"; +rn2kb1r/pp2pppp/2p2n2/q2p4/2PP4/4PN2/PP1BBPPP/1R1QK2R b Kkq - am Qxa2; id "arasan4.7"; +1B4k1/5p2/K5p1/7p/P4P2/5P2/8/6n1 b - - bm f5; id "arasan4.8"; +4k3/5ppQ/1n3b2/3bp3/1B6/1P1R2NP/5PPK/1qr5 w - - bm Ba5; id "arasan4.9"; +r3r1k1/pb1n1p2/1p1p1n1p/q1pPpN2/2P4p/2PBPP2/P1Q3PP/1R3RK1 w - - bm Qf2; id "arasan4.10"; +6k1/6pp/pRp5/r7/2P5/1P6/PK6/8 b - - am c5; id "arasan4.11"; +q2r2k1/1bpn1ppp/1p1bp3/8/r2PP3/P4NP1/1BQ2PBP/3RR1K1 w - - bm e5; id "arasan4.12"; +q2r2k1/1bpn1ppp/1p2p3/4P1N1/r2P4/b5P1/1BQ2PBP/3RR1K1 b - - bm Nf8; id "arasan4.13"; +rnbq1rk1/p3nppp/1p2p3/2ppP3/3P4/P1PB1N2/2P2PPP/R1BQK2R w KQ - bm Bxh7+; id "arasan4.14"; +4nr1k/r4p1p/2bq4/pp1pNP2/3P3Q/2P5/4PPB1/RR4K1 w - - bm c4; id "arasan4.15"; +3r3k/p1b3p1/2R1pr1p/3q4/3PQ3/5p2/P4PPP/B3R1K1 b - - bm Bxh2+; id "arasan4.16"; +1r1n3k/3qbppp/pr1p4/2pPpP2/2P1N1Q1/R6P/1P3PP1/2B1R1K1 w - - bm Bh6; id "arasan4.17"; +2r2rk1/p2R1ppp/2p1p3/q3N1b1/8/1P4P1/P3QP1P/3R2K1 b - - am Bf6; id "arasan4.18"; +1r2r1k1/p4ppp/2n1pq2/2P5/Q1Ppb3/8/P2NPPPP/3RKB1R b K - bm Qf5 Qg6; id "arasan4.19"; +q2r2k1/rbpn1ppp/1p1bp3/8/P2PP3/P4NP1/1BQ2PBP/3RR1K1 b - - am Rxa4; id "arasan4.20"; +2rqr1k1/1b1n1ppp/pp2p3/4N3/PbPPpB2/1PN3P1/R2Q1P1P/2R3K1 b - - bm Nf8; id "arasan4.21"; +2q2k1r/1pbb1ppp/2n2n2/1B2p3/Q3P3/4BP1P/PP4P1/1KRR4 w - - bm Rxd7; id "arasan4.22"; +2q1r3/3n2pk/p4r1p/3Q4/R1P1pN2/4BnP1/5P1P/R6K b - - bm Rxf4; id "arasan4.23"; +q3kb1r/5p2/2b3p1/r3pn1p/8/1PP1B1P1/P1R1Q2P/2NN1RK1 b - - bm h4; id "arasan4.24"; +5q2/3Q1N1p/r4kp1/4p3/3nb3/1B5P/5PP1/1R4K1 w - - bm f4; id "arasan4.25"; +5rk1/1p1P1ppp/pBn1p1r1/3p4/6P1/RPP4K/7P/4R3 w - - bm Ra5; id "arasan4.26"; +2rr2k1/1Q3ppp/2Rp4/p2Pp3/P1P1q3/8/5PPP/1R4K1 b - - am Rxc6; id "arasan4.27"; +3r2k1/2qn1ppp/8/1pbrp3/pP1N4/P2P2P1/RB2RP1P/4QK2 w - - bm Nxb5; id "arasan4.28"; +r2qr3/2pn1pbk/2n3pp/1p1bp3/p7/2PPB1NP/PPBN1PPK/R2QR3 b - - bm f5; id "arasan4.29"; +2Q5/8/8/8/3kbP1N/2pq3P/6PK/8 w - - bm f5; id "arasan4.30"; +rn2rnk1/5ppp/2p4P/ppb5/5P2/2N1P2R/PP1BB1P1/R2K4 b - - bm g6; id "arasan4.31"; +r1b2rk1/pp3pp1/4p2p/2ppP1b1/3Pq3/2P1PNP1/PP2Q2P/R3KB1R w KQ - bm Nxg5; id "arasan4.32"; +Qn3rk1/p5p1/1pnqp3/6p1/6P1/2P5/P4P1P/R1B2RK1 w - - bm Qb7; id "arasan4.33"; +2r3k1/ppr2p1p/b5nP/3NPpN1/P2P3R/1P6/5PP1/1RqQ2K1 b - - bm Qxg5; id "arasan4.34"; +r1b2r2/pp3p1p/1q1p3k/2p1n2N/3N4/4P1P1/P1PP2BP/R4QK1 w - - bm Qf6+; id "arasan4.35"; +r1bq2k1/1p1n1r1p/3Qppp1/pP5N/2P1B3/8/P4P1P/2KR2R1 w - - bm Bxg6; id "arasan4.36"; +8/1P6/n6p/p5k1/5p2/5K1P/2B5/8 b - - bm Kf6; id "arasan4.37"; +r4rk1/2qbbpp1/7p/2pPp3/ppN1P3/4Q1P1/PPPN4/2K3RR w - - bm Rxh6; id "arasan4.38"; +r2q1r1k/1p2bppp/pnb1p3/4P3/6R1/2N5/PPB1QPPP/R1B3K1 w - - bm Rxg7; id "arasan4.39"; +1r3k2/4q3/2Pp3b/3Bp3/2Q2p2/1p1P2P1/1P2KP2/3N4 w - - bm Be6; id "arasan4.40"; +r4rk1/pp1nqppp/2b1p3/6N1/4N3/6Q1/PPP2PPP/1K1RR3 w - - bm Rxd7; id "arasan4.41"; +r3k1nr/pp1b1ppp/4p3/3p4/q4B2/3B1Q2/PP3PPP/2R1R1K1 w kq - bm Qg3; id "arasan4.42"; +2b3k1/5pp1/r6p/3p4/p1qP1Q2/R1B2P2/1P2r1PP/R6K b - - bm Rxg2; id "arasan4.43"; +8/p7/1p6/k2n2PP/8/1q3QK1/8/8 b - - am Qxf3; id "arasan4.44"; +r1bk2nr/ppp2ppp/2np1b2/1N6/N4P1q/P3B3/1PP1B1PP/R2QR1K1 w - - bm Nxd6; id "arasan4.45"; +r5nr/ppp2kpp/3pbp2/1B6/PP5q/8/1BPQ1PPP/1R2R1K1 w - - bm Rxe6; id "arasan4.46"; +r2qkb1r/pB1n1ppp/4p3/3p4/8/1P2Pb2/P1QP1PPP/RNB2RK1 b kq - bm Qg5; id "arasan4.47"; +r1b1r1k1/ppq2p1p/3b2pQ/3pn3/8/2P4P/PPBN1PP1/R1B1R1K1 b - - bm Bf5; id "arasan4.48"; +2r1k1nr/p1Pq4/1p3p2/4pn1p/1B1p4/1N3Q2/PP2P1RP/2R4K w - - bm Nd2; id "arasan4.49"; +r2qr1k1/pp1b2pp/2nBpp1n/6NQ/2B1N3/P3b3/1PP3PP/R4R1K w - - bm Nxf6+; id "arasan4.50"; +1n3rn1/3b4/rq1P1pkp/1p4p1/p1p1N1N1/2Q2B1P/1P3PP1/R3R1K1 w - - bm Nexf6 Ngxf6; id "arasan4.51"; +r1bq1rk1/ppp1bpp1/2np3p/3N3n/2P1PB2/3BQN2/PP3PPP/R3K2R w KQ - bm Bxh6; id "arasan4.52"; +2r3k1/5pp1/1p5p/p1n1P3/2B2P2/P3Q3/1PP4q/1K4R1 w - - bm Qd4; id "arasan4.53"; +1q4k1/5p1p/5npR/1p1rp3/6P1/2P2N1P/1P3P2/2Q3K1 b - - bm Qd8; id "arasan4.54"; +2r1r1k1/1p3pb1/q2Pb1p1/p7/P5PP/1PNR4/2Q3BP/2BR1K2 b - - bm Bxg4; id "arasan4.55"; +4r3/3R4/6pk/2p3b1/3pp1P1/P7/1P5P/4R2K b - - bm Bh4; id "arasan4.56"; +r2r2k1/pbpq1ppp/1pn1pn2/8/P2PP3/B1R2NP1/P1Q2PBP/3R2K1 w - - bm d5; id "arasan4.57"; +8/r4p2/4qp2/kp6/3b4/1P2pQ2/2R4P/1R5K b - - bm Kb4; id "arasan4.58"; +1b6/4kPp1/Pp6/2p2K1B/2P5/3p4/8/8 w - - bm Ke4; id "arasan4.59"; +4r1k1/pppb3p/1n4p1/3P4/1bP2p2/qN3PPP/P1Q3B1/2R3KR w - - bm g4; id "arasan4.60"; +2r3k1/2r1b1p1/p1q3Pp/3pP3/1p6/1P2B2Q/2PR4/1K4R1 w - - bm Bxh6; id "arasan4.61"; +4R3/1k4p1/8/pp4P1/8/3K4/1b5P/8 w - - bm Re2; id "arasan4.62"; +r3k2r/pb3ppp/1p2pn2/1Nb1q3/4P3/P2B4/1PQ2PPP/R1B2RK1 w kq - bm b4; id "arasan4.63"; +2r1r1k1/1pn3qp/2pbn1p1/p2pN3/3P1P2/3BP1BP/PPQ3K1/2R2R2 w - - bm f5; id "arasan4.64"; +5Nk1/1p2n3/p2q1rp1/3p1pQP/5P2/2P2B2/b1PK2P1/4R3 w - - bm Nd7; id "arasan4.65"; +1R6/4qpbk/8/p2r2p1/P7/1PNp1PP1/3Q3P/7K b - - bm g4; id "arasan4.66"; +8/1B1r1b1k/3N2pp/p3Qp2/3P1P2/7P/1P1b1K2/2r5 w - - bm Nxf5; id "arasan4.67"; +r1b1r1k1/pp3ppp/2p2n2/q1n5/2P5/2N3PB/PP1Q1P1P/2KR2NR b - - bm Ng4; id "arasan4.68"; +2kb4/r7/4p1r1/1RNn2p1/8/6P1/pB3PK1/7R w - - bm Be5; id "arasan4.69"; +4r1k1/1p3p1p/1q3npP/p2p4/P2N1bP1/1NP1rP2/1PQ5/R4R1K b - - bm Nxg4; id "arasan4.70"; +4rrk1/1bpn1qp1/1p1b3p/pP1Ppn2/4N3/P2Q1N1P/1BB2PP1/2R1R1K1 w - - bm g4; id "arasan4.71"; +6k1/p4pp1/P1rbpn2/3q4/3P3R/2p1B3/r1R2PPP/3QN1K1 b - - bm Rxc2; id "arasan4.72"; +1r5k/pp5p/3Nn1p1/3R4/3b4/BP3rPP/P4P2/1R4K1 w - - bm Rxd4; id "arasan4.73"; +rn1r2k1/p4p2/1pp1pqp1/6Rp/3PB2P/8/PPPQ1P2/2KR4 w - - bm Bxg6; id "arasan4.74"; +r4rk1/1pp3q1/2np3p/p2Npb1B/2PbN1p1/3P2P1/PP4PP/R2Q1R1K w - - bm Ndf6+ Nef6+; id "arasan4.75"; +r5k1/p6r/1n2p2p/2BbPpp1/8/P2B4/5PPP/2RR2K1 w - - bm Bxf5; id "arasan4.76"; +5rk1/q4ppp/pp1bp1n1/6N1/4QP2/P3P3/1P1B2PP/2R3K1 w - - bm Nxe6; id "arasan4.77"; +r3kb1r/2R2bpp/p2p1p2/1p2pPP1/3qP3/5Q2/1PPB3P/2K2B1R w kq - bm Bc4; id "arasan4.78"; +5k2/p1q1ppbp/6p1/5b2/2P5/4BP2/PP4PP/2KR1B1R b - - bm Qa5; id "arasan4.79"; +6k1/3p2p1/1p1Npq2/3n3r/1P6/5PQ1/P4KP1/RNBR3r w - - bm Ne4; id "arasan4.80"; +7r/5R2/5p2/8/2kp4/5PKP/8/8 b - - bm d3; id "arasan4.81"; +2k4r/1q1bBQ2/2p1p3/1p2P2p/6r1/8/5PP1/R1R3K1 w - - bm Bf8; id "arasan4.82"; +2r2k1r/p1q3pp/1p3p2/3Bp3/2Pb2b1/P1Q5/1B1R1PPP/4R1K1 w - - bm Rxd4; id "arasan4.83"; +r1bq1rk1/b1p2p2/2n2n2/1B2p1B1/5P2/3p4/PP4PP/RN1Q1R1K b - - bm Qd6; id "arasan4.84"; +3q1k2/8/1p1b1r1p/p2R2p1/P1BQ2P1/1P3P2/8/3K4 w - - bm f4; id "arasan4.85"; +2r2rk1/5qp1/1pN2p1p/pPnRp3/P1P5/5PP1/2Q1R1KP/8 w - - bm Rxc5; id "arasan4.86"; +3r1r2/pb3pkp/1pn1qNp1/2p1P3/5P2/P2BQ3/1P4PP/3R1R1K w - - bm f5; id "arasan4.87"; +r3rb1k/1b3pp1/3p2qp/p2P1N2/Pp1Qn3/4RN1P/1P3PP1/R1B3K1 w - - bm N3h4; id "arasan4.88"; +3qr3/5pk1/2Qp3p/p2P2n1/1p1P2B1/4pPP1/PP5P/5R1K b - - bm h5; id "arasan4.89"; +8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - bm Rxb2; id "4.90"; +r3rk2/ppq2pbQ/2p1b1p1/4p1B1/2P3P1/3P1B2/P3PPK1/1R5R w - - bm Qxg7+ Qh8+; id "4.91"; +r1b2rk1/1pqp1p1p/p3nBpQ/4p3/4P3/1N4P1/PbP2PBP/R4RK1 w - - bm Nd2; id "4.92"; +4r1k1/2P3pp/1n2q3/2pn1p2/8/6B1/1P1QBP1P/4R1K1 w - - bm Rd1; id "arasan4.93"; +r2q1rk1/p4p2/1p2pn1p/n2b2p1/3P3B/2R2N2/PP3PPP/1B1QR1K1 w - - bm Nxg5; id "arasan4.94"; +n5qk/4pr1p/1p1p2p1/pP1N1P2/2P1n1PQ/P6K/8/1R1R4 b - - am gxf5; id "arasan4.95"; +1r2r1k1/3q1pb1/p2P3p/3P2p1/5n2/2N1BP2/PP1Q1P1P/R4RK1 b - - bm Be5; id "arasan4.96"; +5rk1/3R1p2/ppp3r1/b1p1P2p/2P2B1q/2P2Q2/P5PP/3R3K w - - bm h3; id "arasan4.97"; +2r1r1k1/5p1p/p3qBp1/1ppbP3/2n5/2PB3P/P3QPP1/3RR1K1 w - - bm Bxc4; id "arasan4.98"; +r1br3k/pp2qn1p/4p2P/4Ppp1/2B5/P4NQ1/1P3PP1/3R1RK1 w - - bm Nxg5; id "arasan4.99"; +2r2rk1/3bq1p1/4p1Pp/3pP3/1p1N1PQ1/pP5R/P1P4R/4K3 w - - bm Rxh6; id "arasan4.100"; +2b2rk1/r3bp2/p3pp2/q2p4/5PPp/1RNB4/P1PQ3P/1R5K w - - bm Qf2; id "arasan4.101"; +8/k7/P4p2/8/3pP3/3Br3/2P5/6K1 b - - bm Rxd3; id "arasan4.102"; +8/5p1k/5Pp1/1pQ2q1p/pP6/P7/2P4P/1K6 b - b3 am axb3; id "arasan4.103"; +3r4/6pp/p3kn2/2r5/1pp1P3/P3R3/1PB3PP/4R1K1 b - - bm b3; id "arasan4.104"; +8/1B3k2/4Rbp1/3Pp1p1/5p2/5P1P/3r2PK/8 b - - bm g4; id "arasan4.105"; +4r1k1/p5qp/Pp1Rbb2/4pp1r/2P1p1p1/1PB1P3/1Q2BPPP/3R2K1 w - - bm c5; id "arasan4.106"; +8/4k1p1/8/5P1p/b1N4P/5PP1/1p1K4/1B1n4 w - - bm g4; id "arasan4.107"; +3q1r1k/1P1n2p1/4R2p/2QBp2P/3pPb2/R1p2P2/5P2/5K2 w - - bm Qxf8+; id "arasan4.108"; +1r1q2k1/p5b1/2pNr1p1/2Bb1p1p/2B1pn1P/QP3PP1/P1PR4/2K4R b - - bm e3; id "arasan4.109"; +2rbk1r1/7R/p1n3p1/1p3q2/2n2N2/4pQ2/PP2B1PP/3R2K1 w - - bm g4; id "arasan4.110"; +8/8/3k4/1p1npP1p/pP2B2P/P7/5K2/8 w - - bm Bxd5; id "arasan4.111"; +5nk1/p2r1pp1/1p4bp/3B4/4PPP1/P6P/1B6/2R3K1 w - - bm f5; id "arasan4.112"; +5r1k/2P4p/2P3p1/1P2pb2/4Nb1q/2N2r2/2R4P/1Q3R1K b - - bm Rh3; id "arasan4.113"; +8/5q1k/2Q3p1/2P4p/7P/2B3P1/6K1/5r2 b - - bm Rc1; id "arasan4.114"; +2kr3r/Rbpnq3/1p1pp3/2P3p1/3P4/2P1P1p1/Q2N1PP1/4KB2 w - - bm Rxb7; id "arasan4.115"; +2R2b1r/3nkp2/B2pp1p1/1N4Pn/P3P3/4BP2/1r5q/3QK1R1 w - - bm Nd4 Na7; id "arasan4.116"; +r3r1k1/1p1b2pp/p2qpp2/3n4/Pn1P4/1BN2Q2/1P1B1PPP/R2R2K1 w - - bm Ne4; id "arasan5.1"; +r6r/1pbq2k1/p1p1bn2/2Pp1pp1/PP1Pp3/2N1P1P1/1Q1BBPK1/R6R b - - bm f4; id "arasan5.2"; +8/6p1/1b4k1/1p1KP3/1p3PP1/pB6/8/8 w - - bm e6; id "arasan5.3"; +r4rk1/1bq2p2/p3p1p1/n3P2p/3NpP2/2P1B2R/2P3PP/R3Q1K1 w - - bm g4; id "arasan5.4"; +2rq1rk1/pb1n1p2/1p2pn1p/6p1/2BP3B/1QR2N2/PP3PPP/4R1K1 w - - bm Nxg5; id "arasan5.5"; +2r1qrk1/1b1nbppp/4p3/pB1nP1B1/Pp2N3/5N1P/1P1Q1PP1/R2R2K1 w - - bm Nf6+; id "arasan5.6"; +1q4k1/r4p1p/6p1/1p1Q3n/p3N3/P7/1P3PPP/4R1K1 w - - bm g4; id "arasan5.7"; +3rr1k1/1pq2p1p/p1n3p1/3Bb3/P7/2P1BQ2/1P3PKP/3RR3 w - - bm Bb6; id "arasan5.8"; +r1q1r1k1/1p2b2p/2bp2p1/p6B/P1PBP3/1nN3QP/7K/4RR2 b - - bm Qe6; id "arasan5.9"; +r2qr1k1/pb4b1/1pnP2pp/5p2/5PB1/B4NQ1/P5PP/2R1R1K1 w - - bm Bxf5; id "arasan5.10"; +r1b2rk1/p1q4p/1p4p1/2NP1p2/1PPB4/6P1/P6P/Q3R1K1 w - - bm Qc1; id "arasan5.11"; +8/3k4/1p4b1/3p1p1p/K2P1PpP/3B2P1/1P6/8 w - - bm Kb5; id "arasan5.12"; +r1bn1rk1/2q2ppN/7p/p2p4/R7/2PB4/3B1PPb/3QRK2 w - - bm Nf6+; id "arasan5.13"; +4qrk1/1p1nb1p1/2p1pn1p/r2p4/3P1BPP/P1NBP3/5P2/R2QK1R1 w - - bm g5; id "arasan5.14"; +q5k1/3bp2p/3p2p1/4b3/1PP5/r3BPrP/4BQP1/1R1R1K2 b - - bm Bxh3; id "arasan5.15"; +8/4N1pk/2p4p/1r1p3P/2p1p1P1/2P1Nq2/5P2/2Q3K1 b - - bm d4; id "arasan5.16"; +r1bq1rk1/4ppbp/p2p1n1B/2p5/1p2p2Q/3P1N2/PPP1N1PP/R4RK1 w - - bm Ng5; id "arasan5.17"; +4rrk1/p2n2pp/npbp4/2p1p3/2P2P1q/PNB1P3/1P2B1PP/1R1Q1RK1 w - - am Qxd6; id "arasan5.18"; +r1b2rk1/5p1p/pP1p2p1/3Pb3/3np2q/N3B2P/PP3PP1/RQR2BK1 b - - bm Bxh3; id "arasan5.19"; +8/B3r1p1/8/P4k1p/1P6/5P2/5K2/8 w - - bm Bc5; id "arasan5.21"; +b2rn1k1/3r1ppp/3N2n1/1pB1P3/p5P1/P3KP2/B6P/1RR5 w - - bm e6; id "arasan5.24"; +8/4rq2/2Q1N1pk/p3R2p/3p1P2/2n4P/6P1/7K w - - bm g4; id "arasan5.25"; +4kb1r/3n1p1p/p1q1p1p1/1p1nP3/1prPN3/4BB2/P2Q1PPP/3R1RK1 w - - bm Bh6; id "arasan5.26"; +3q2k1/rbp2r1p/1p1p1pp1/p1nN4/2P1PP2/1P2QBPP/1P5K/3RR3 w - - bm e5; id "arasan5.27"; +r5k1/b1pr1pp1/2p4p/4p2q/Q1P5/2B1P1P1/P2NbP1P/1R2R1K1 b - - bm Rxd2; id "arasan5.28"; + + diff --git a/tests/orig/ecm-gcp.epd b/tests/orig/ecm-gcp.epd new file mode 100644 index 0000000..0c1ee9b --- /dev/null +++ b/tests/orig/ecm-gcp.epd @@ -0,0 +1,184 @@ +r1b1r1k1/p1p3pp/2p2n2/2bp4/5P2/3BBQPq/PPPK3P/R4N1R b - - bm Bg4; id "ECM.946"; +1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - bm Nxg4; id "ECM.949"; +2k4r/1pp2ppp/p1p1bn2/4N3/1q1rP3/2N1Q3/PPP2PPP/R4RK1 w - - bm Nd5; id "ECM.952"; +rn3rk1/4bppp/1q2p3/p2pP3/8/1PN2B1P/P4PP1/2RQ1RK1 w - - bm Bxd5; id "ECM.961"; +2r2bk1/4qp2/3n2p1/2R1p1Np/2p1N3/r6P/1Q3PP1/3R2K1 w - - bm Rxc8; id "ECM.973"; +r1b1rnk1/1p3pb1/1qpp2p1/2n5/2PNP2p/1PN3PP/3R1PBK/BR1Q4 b - - bm Rxa1; id "ECM.977"; +r1b2rk1/pp2b3/2pn1n1p/3pNppq/3P4/BP1N2P1/P3PPBP/R1Q2RK1 w - - bm Nxc6; id "ECM.978"; +3rkb1r/1p3p2/p1n1p3/q5pp/2PpP3/1P4P1/P1Q1BPKP/R2N3R b k - bm d3; id "ECM.986"; +5rk1/1r1qbnnp/R2p2p1/1p1Pp3/1Pp1P1N1/2P1B1NP/5QP1/5R1K w - - bm Qxf7+; id "ECM.987"; +5r2/1b2k2p/3bp3/5PP1/Bn1Q3P/1N6/1Pr5/1K3R2 b - - bm Rxb2+; id "ECM.993"; +r4rk1/1b3ppp/p2q1n2/1p2N3/3P4/1B6/P1Q2PPP/2R1R1K1 w - - bm Nxf7; id "ECM.999"; +3r1rk1/1b2bppp/2q1pn2/pp4Q1/3B1P2/PBN5/1PP3PP/R2R3K b - - bm Rxd4; id "ECM.1004"; +3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - bm g6; id "ECM.1007"; +b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - bm Kg2; id "ECM.1009"; +r1bqnrk1/pp2ppb1/1np3pp/4P1N1/5P2/2NBB3/PPP3PP/R2Q1RK1 w - - bm Nh7; id "ECM.1011"; +4rrk1/1bp2ppp/p1q2b1B/1pn2B2/4N1Q1/2P4P/PP3PP1/3RR1K1 w - - bm Nxc5; id "ECM.1016"; +5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - bm Rd4; id "ECM.1018"; +1r3rk1/5pp1/1n2qn1p/1p1pPNb1/2pP2QP/2P5/1PB3P1/R1B1R1K1 w - - bm exf6; id "ECM.1020"; +2r1rbk1/1b3ppp/pp6/2q1pNP1/Pn1RP3/2N5/1PP2QBP/5R1K w - - bm Nh6+; id "ECM.1025"; +r4k2/q4npp/P2P4/2p1R3/2N5/6PP/Q5K1/8 w - - bm Re7; id "ECM.1028"; +rr4k1/2p1ppb1/3pbnpp/q1pP4/4P3/1PNNBP1P/P1KR2P1/2Q4R b - - bm Qxc3+; id "ECM.1038"; +5rk1/p1pb2pp/2p5/3p3q/2P3n1/1Q4BN/PP1Np1KP/R3R3 b - - bm Qxh3+; id "ECM.1041"; +r1k4r/ppp1b3/5Npp/4pb1Q/8/1B2B3/PqP2PPP/2RR2K1 w - - bm Qxf5+; id "ECM.1045"; +r1bn1rk1/pp3p1p/6p1/2bR2N1/2B2B2/q1P1P3/2Q2PPP/4K2R w K - bm Nxh7; id "ECM.1053"; +2b2r2/1p2q1k1/r3pppp/4n2P/p3N3/1B4Q1/PPP3P1/3R1R1K w - - bm Rxf6; id "ECM.1057"; +rbbq1rk1/p3nppp/1p2p3/8/1B1pN3/P2B4/1P3PPP/2RQ1RK1 w - - bm Nf6+; id "ECM.1065"; +rn2qbr1/2p4k/p2p1nb1/1p1Pp2p/2P4P/2NBBPN1/PP1Q4/2KR2R1 w - - bm Nxh5; id "ECM.1066"; +r1bq1rk1/pp2bp1p/2p2np1/3p2B1/3P4/2NQ2N1/PPP2PPP/4RRK1 w - - bm Rxe7; id "ECM.1068"; +2rr1bk1/5p1p/pPN2np1/3Bp3/2Q1n3/1P2B1Pq/P3PP2/R2R2K1 b - - bm Rxd5; id "ECM.1076"; +b3r3/q2B2k1/3Q2p1/1p5p/3pP3/5P2/1p4PP/5RK1 b - - bm d3+; id "ECM.1080"; +2r3k1/pp2n3/6pQ/4q3/8/2P1p1P1/P5BP/3R2K1 w - - bm Bd5+; id "ECM.1082"; +8/p3q1kp/1p2Pnp1/3pQ3/2pP4/1nP3N1/1B4PP/6K1 w - - bm Ba3; id "ECM.1084"; +r2b1rk1/5qp1/2p2P2/2p3Pp/p6P/2Q5/PPP5/2KR2R1 w - - bm g6; id "ECM.1085"; +4r3/Q2bppkp/3p2p1/3Nn3/4P3/6PP/1qr2PB1/R3R1K1 b - - bm Ra8; id "ECM.1093"; +8/p5Q1/2ppq2p/3n1ppk/3B4/2P2P1P/P5P1/6K1 w - - bm g4+; id "ECM.1096"; +1r2k2r/3q2pp/p3pp2/P7/2P1Q3/8/1nB3PP/1R3R1K w k - bm Ba4; id "ECM.1098"; +1q6/2rk1p2/p1n1b1rN/3p2p1/8/3Q4/PP1B1PPP/2R1R1K1 w - - bm Nxf7; id "ECM.1114"; +3r3k/p1Q3bp/2p3p1/8/2P1BRn1/1P4Pb/P1N1q2P/6BK b - - bm Nf2+; id "ECM.1122"; +5rk1/Q2nqppp/5n2/2p5/8/1B2PP1P/Pr1B1P2/R3K2R b KQ - bm Ne4; id "ECM.1127"; +r2r1bk1/3qp2p/3pp1p1/p2n2N1/2N3Q1/BP4P1/P4PP1/2R3K1 w - - bm Nb6; id "ECM.1131"; +1r3rk1/p4pbp/q1p2pp1/3p1b2/1n1P1P1B/PB3N2/1PPQR1PP/2KR4 b - - bm Bxc2; id "ECM.1132"; +1rbr2k1/4qp2/p1n2bpp/1pp1p1N1/4P3/2P1BQ1P/PPB2PP1/3RR1K1 w - - bm Bxc5; id "ECM.1133"; +2r2rk1/1p1q1ppp/1p3n2/3p1N2/4n3/1N3Q2/PPP2PPP/R2R2K1 w - - bm Rxd5; id "ECM.1134"; +2r1r1k1/pp3pp1/3p3B/P2P1P2/2nb4/7R/1q3PQP/1B3R1K w - - bm Rb3; id "ECM.1147"; +1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - bm Bf4; id "ECM.1150"; +k3r3/pR5p/PppR1p1p/4nP2/1PP5/8/4B1rP/2K5 w - - bm Re7; id "ECM.1151"; +1q3rk1/r5b1/pNp1bn1p/2Pp1n2/1P2p3/1N2P2P/PBQKB3/3R3R b - - bm Nxe3; id "ECM.1152"; +r5k1/5p1p/bq1p2p1/r2Pp3/1p2N1P1/1P3P2/1KPQ3P/3R3R b - - bm Ra2+; id "ECM.1160"; +5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - bm Bg7; id "ECM.1161"; +6k1/p4pq1/2n1p1p1/1p1pP1N1/3P1QPP/8/P3K3/8 w - - bm Qc1; id "ECM.1176"; +3r1rk1/1pq1nppp/p7/2pB3Q/P4P2/1P2P3/6PP/2RR2K1 w - - bm Rxc5; id "ECM.1177"; +8/p1r2q1k/1p1p3p/1Pp1nP2/P1P5/3R2PP/1Q4BK/8 w - - bm Rxd6; id "ECM.1178"; +6k1/1pp2p2/p2p2q1/2PPb3/4r3/Pr4PK/2R5/2Q2NR1 b - - bm Rh4+; id "ECM.1179"; +r2qr1k1/1pnb1pp1/p1n1p2p/8/P2P3P/B2B1NP1/6P1/R2Q1RK1 w - - bm Bh7+; id "ECM.1185"; +2r1rbk1/5pp1/bq5p/1pnBPN2/6Q1/N7/5PPP/R2R2K1 w - - bm Bxf7+; id "ECM.1188"; +1k1r1r2/2b2R2/Bppp2p1/2q4p/Q2pP3/P2P4/2P3PP/1R4K1 w - - bm Bb7; id "ECM.1189"; +5r1r/1pkb4/5pB1/2P5/p3R2P/Pq6/1PQ2Pn1/K2R4 w - - bm Rxd7; id "ECM.1193"; +2rq4/5rbk/3p1n1p/p2Pp2P/1p2b3/4BNR1/PP1Q1P2/3BK1R1 w - - bm Bxh6; id "ECM.1199"; +r2q1rkb/pp2p3/2p2pp1/3pPb2/3P3R/2N3P1/PPPQBPK1/3R4 w - - bm Rxh8+; id "ECM.1200"; +r1bqrnk1/p4p2/1p5p/3pB1p1/P2P2n1/1P1B2N1/2Q3PP/R4RK1 w - - bm Bh7+; id "ECM.1202"; +r2r2k1/1bqpbpp1/ppn1p2p/2p1P1N1/P1B2B2/2P5/1PPRQPPP/3R2K1 w - - bm Nxf7; id "ECM.1204"; +6k1/1p3p2/4r1p1/1PPrbq1p/2QN4/P2R1P1P/R4KP1/8 b - - bm Bg3+; id "ECM.1208"; +6kb/B1p2p2/5r2/1r1p2pR/6q1/3P2P1/P1P2PP1/2KR3Q b - - bm Rb1+; id "ECM.1214"; +2r2rk1/pp3qpp/8/3P1b2/3Q4/P1N1B3/5PKP/R2R4 b - - bm Rxc3; id "ECM.1217"; +r1b2rk1/1pqp1ppp/p1n1pn2/5N2/8/2PBB3/P1P2PPP/R2QR1K1 w - - bm Nxg7; id "ECM.1218"; +b6r/2q2k2/4pPp1/1p1n2Bp/2pPB1PP/2P2Q2/8/4R1K1 w - - bm Bxg6+; id "ECM.1223"; +r1b2r2/3pNpkp/3pn1p1/2pN3P/2PnP3/q3QP2/4BKP1/1R5R w - - bm Qh6+; id "ECM.1224"; +2r1r1k1/pp1nbpp1/4pn1p/q3NN1P/P1pP1B2/2P5/1PQ2PP1/R3R1K1 w - - bm Nxg7; id "ECM.1227"; +1r3rk1/6p1/p1pb1qPp/3p4/4nPR1/2N4Q/PPP4P/2K1BR2 b - - bm Rxb2; id "ECM.1229"; +r2qnr2/pp3kbQ/2npb1p1/2pN1pP1/4P3/8/PPP1BP2/R1B1K1NR w KQ - bm Qxg6+; id "ECM.1232"; +2r2r2/2N2pkp/2Q5/1N2p1b1/1p6/3P1qPb/PPR2P1P/4R1K1 b - - bm e4; id "ECM.1234"; +r3rk2/p2q1b1p/1pnP1Qp1/5pN1/2p2P2/P1P5/7P/4RRK1 w - - bm Re7; id "ECM.1249"; +r1rbb3/1R3pkp/2pBp1p1/p3P3/q6P/6P1/P2Q1P2/1R3BK1 w - - bm R1b4; id "ECM.1254"; +8/5k1p/5PpB/3PR3/2r4P/1p3K2/2b5/8 b - - bm Re4; id "ECM.1257"; +rnb2rk1/pp2bppp/2p5/q7/4NN2/4B1QP/PPP3P1/2KR3R w - - bm Nd5; id "ECM.1259"; +5k1r/ppqnnp2/3b2p1/2pB2Qp/3p3N/1P1P2P1/P1P2P2/2B1R1K1 w - - bm Rxe7; id "ECM.1262"; +3r1rk1/pbqn1pp1/1pp2n1p/2b1p1B1/P1B1P2N/2N4P/1PP1QPP1/3R1RK1 w - - bm Rxd7; id "ECM.1265"; +1rr3k1/4ppb1/2q1bnp1/1p2B1Q1/6P1/2p2P2/2P1B2R/2K4R w - - bm Qh6; id "ECM.1267"; +3rqb2/1pR3pk/p3n1pp/3p4/3B4/PP6/1P4PP/4RQK1 w - - bm Rxe6; id "ECM.1269"; +rkb2qr1/1p5p/pQ1bp3/3p2B1/5n2/3B1N2/PP3PPP/2R2RK1 w - - bm Rxc8+; id "ECM.1270"; +2r2rk1/1bq2ppp/p7/1p1pNN2/1b1PnB2/3Q3P/PP3PP1/R3R1K1 w - - bm Rxe4; id "ECM.1271"; +8/5p2/4p1k1/4P1p1/2rBRbK1/5P2/r4P2/7R b - - bm Rxd4; id "ECM.1273"; +r1bqr1k1/pp3pp1/2p4p/3PN1n1/3P1b2/2NB4/PPQ2PPP/3R1RK1 b - - bm Rxe5; id "ECM.1274"; +r1b1r1k1/pp3p1p/1q2p1pQ/2b1P1B1/8/P2B3P/1P3PP1/2R1R1K1 w - - bm Rxc5; id "ECM.1277"; +1k2r2r/1bpQN2p/1p6/P3p2q/4np2/2P2N2/2P2PPP/R3R1K1 b - - bm Rxe7; id "ECM.1278"; +rnb2rk1/3n1ppp/p3p3/1p2P1q1/3N4/1BN5/PPP3PP/R2Q1RK1 w - - bm Nxe6; id "ECM.1281"; +4rrk1/ppn3pp/2pb1n1q/3p4/1P1P4/P3BNP1/2P1BPKP/R2Q1R2 b - - bm Rxe3; id "ECM.1285"; +r1b3rk/pp1n3p/2p2b1n/4pp1q/2P5/1P3NPP/PBQ1NPB1/3RR1K1 w - - bm Rxd7; id "ECM.1293"; +2r2rk1/p3p1bp/3qP1p1/1Q1p4/P4P2/3R4/1P4PP/2B2RK1 b - - bm Rxc1; id "ECM.1294"; +r3r1k1/4pp1p/b5pB/q1pP4/3b4/2N4P/PP4P1/R2RQ2K w - - bm Rxd4; id "ECM.1295"; +2rbr2k/1pq2ppp/p3bn2/4p1B1/P3P3/2N3Q1/1PP1B1PP/3R1R1K w - - bm Rxd8; id "ECM.1304"; +3nr1k1/p6p/2n1pRpB/3pP3/2pP2P1/q1P4P/6BK/5Q2 w - - bm Rxg6+; id "ECM.1306"; +1r2r1k1/1pqb2pp/p2bp1n1/2p3BQ/3pN3/1P1P2P1/P1P3BP/4RRK1 w - - bm Bd8; id "ECM.1308"; +r3k2N/pppbq1pp/5n2/3Ppn2/2BP4/2P3bP/PP2Q1P1/RNB2K1R b q - bm Bh2; id "ECM.1314"; +r3bb2/P1q3k1/Q2p3p/2pPp1pP/2B1P3/2B5/6P1/R5K1 w - - bm Bxe5+; id "ECM.1317"; +r1b1qbk1/7p/4p1p1/1p2Bp2/p1B2Q2/P3P3/1P3PPP/3R2K1 w - - bm Bc3; id "ECM.1318"; +q1r3k1/2r4p/2p3pP/2Qp1p2/PRn5/4P1P1/5PB1/1R4K1 w - - bm Rxc4; id "ECM.1321"; +r4r1k/1bq4p/p4bp1/3pn3/NP6/Q1PBB2P/6P1/3R1RK1 b - - bm d4; id "ECM.1325"; +r3rbk1/p1q2pp1/1n5p/2pp4/4N3/1PQ3P1/PB2PP1P/3R1RK1 w - - bm Nf6+; id "ECM.1327"; +r3r1k1/1pp2p1b/7p/2Q5/2PP2p1/2P1NpPq/P2R1P1P/6RK b - - bm Rxe3; id "ECM.1329"; +2k2r1r/1pp1nqbp/p2p1p2/5P2/2PBN3/1P3Q2/1P4PP/R4RK1 w - - bm Rxa6; id "ECM.1332"; +2kr3r/pp3p1p/2b1p3/q3Q3/5P2/2P1B3/P1P3PP/1R3RK1 b - - bm Rhg8; id "ECM.1335"; +2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - bm Rxd3; id "ECM.1336"; +r3nrk1/p1pb1qpp/3p1p2/2pP1N2/2P1PR2/P1PB4/4Q1PP/5RK1 w - - bm e5; id "ECM.1340"; +r1b2rk1/pp2qp2/2nRp1p1/6Pn/1Pp5/P1N1P3/1BQ2PP1/2K2B1R w - - bm Rxh5; id "ECM.1341"; +R2b2k1/2rq1n1p/3p2p1/1p1Ppp1n/1P6/1B1PQN1P/1B3PP1/6K1 w - - bm Nxe5; id "ECM.1344"; +6k1/5rb1/6pp/1p2p3/2b5/4B1P1/r4PBP/1RR3K1 w - - bm Rxc4; id "ECM.1346"; +4r1k1/1p5p/5ppP/1qnP4/r4R2/P6P/1B1Q2K1/5R2 w - - bm Rxf6; id "ECM.1347"; +r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - bm e6; id "ECM.1348"; +6k1/pbq2pp1/4r2p/8/3prb2/1P1Q3P/PN2BPP1/3RRK2 b - - bm Bd2; id "ECM.1350"; +r1b2rk1/pp2ppbp/2np1np1/q7/4P3/2N1BN2/PPPQBPPP/2KR3R b - - bm Nxe4; id "ECM.1352"; +r2q1rk1/p5pp/bn1p1p2/2pP4/1bP1NP2/3B1R2/PBQ3PP/R5K1 w - - bm Ng5; id "ECM.1354"; +1r1q2k1/7p/2p3p1/1P1n1b1r/2BQ4/4B3/P6P/1R3RK1 w - - bm bxc6; id "ECM.1355"; +r1b1qbk1/pp3r1p/2pR1np1/5p2/2P1pP2/1PN1Q1PP/PB2P1B1/5RK1 w - - bm Rxf6; id "ECM.1357"; +1n2n1r1/r3qppk/p2p3p/3PpP1P/1P2P3/3B2RQ/3B1P1K/6R1 w - - bm Bxh6; id "ECM.1371"; +3r1r2/1b4bk/p1n3pp/1p2p3/4P3/q1P1QNB1/B4RPP/5RK1 w - - bm Bh4; id "ECM.1376"; +r1r3kb/1pqbpp2/p2p1npB/n7/3NP3/1BN2P2/PPPQ2P1/2KR3R w - - bm Bf8; id "ECM.1377"; +4qn1k/1b3rpp/pb2pB2/1pp1P2P/3p1NQ1/P2P2PB/1PP4K/5R2 w - - bm Ng6+; id "ECM.1380"; +2b5/2qrrpk1/5Rp1/2p4p/1pB1PR1P/1P1P2P1/5Q1K/8 w - - bm Qb2; id "ECM.1381"; +7r/2p1q1k1/1p3r1p/p1pPpPp1/2P1P1P1/PP6/3Q2KR/7R w - - bm Qxg5+; id "ECM.1383"; +r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - bm Rxh2+; id "ECM.1387"; +2kr3r/p5b1/Pp2R1p1/2q2p1p/2p2Pn1/2P2BP1/1PQB2P1/5R1K b - - bm h4; id "ECM.1394"; +3qrbk1/1r3p2/p1bp1Pp1/1p2p1Pp/4P2R/1P2BB1Q/P1P4P/R6K w - - bm Bxh5; id "ECM.1398"; +r1b3k1/3nqp1p/p1n1p1pP/3pP1N1/Pp3QN1/1Pr3P1/2PR1P2/4RBK1 w - - bm Rxd5; id "ECM.1403"; +r6k/ppr1qpp1/4n2p/3pP3/3P2R1/3BQ2P/P5PK/5R2 w - - bm Rf6; id "ECM.1405"; +2r4r/1q1kb1p1/4p2p/3pP3/np6/3RBP2/NPP2Q1P/1K2R3 b - - bm Nc3+; id "ECM.1408"; +2r4r/3bk1b1/1q2pp2/3pPp1p/1p1N1P1P/1P1R1BP1/P2Q4/1K1R4 w - - bm Nxf5+; id "ECM.1409"; +1rb3k1/2r2pbp/p2q1npn/P1pPp1N1/2B1P3/2P1B1NP/5QP1/3R1RK1 w - - bm Ne6; id "ECM.1410"; +r1bqn1r1/p2k1pp1/1p5p/n1pPpN2/2P1P3/P1PBB2P/4Q1P1/R4RK1 w - - bm Nxh6; id "ECM.1421"; +r4rk1/p1p2pp1/bp1p1q1p/n1nPpN2/2P1P2P/2PB4/P2BQPP1/R3K2R w KQ - bm Bg5; id "ECM.1423"; +2kr2r1/2pqbp1p/p1n1b3/1P1pP3/4n3/1BP1BN2/1P4PP/RN1Q1RK1 b - - bm Bh3; id "ECM.1426"; +3Rq1k1/1pp1Ppbp/r1b3p1/p7/P1N5/1P4P1/1B2PP1P/2R3K1 w - - bm Nd6; id "ECM.1433"; +r2q1rk1/pp1n2pp/2pb4/1P1p3n/P1PPpP2/4P2b/1BNNBP1P/R2QR1K1 b - - bm Nxf4; id "ECM.1434"; +r1b2rk1/pp4bp/2p3p1/4q2n/NQPN1p1P/1P5n/P3PPB1/2BRRK2 b - - bm f3; id "ECM.1438"; +4rqk1/p5b1/3p3p/3Pn1p1/1pP1NrP1/4NP2/P3Q1P1/1K1RR3 b - - bm Nxf3; id "ECM.1439"; +3r1qk1/5p1p/4b1pP/1pRp4/1P1Q4/r5P1/5P2/4RBK1 w - - bm Rxe6; id "ECM.1448"; +2rr1nk1/pp2q1b1/4p1p1/5p2/1nB5/2B1N1QP/PP4P1/4RRK1 w - - bm Nxf5; id "ECM.1450"; +6rk/1b2bp1p/ppq1p3/2p1Pp2/P1Br1P2/1PNR2P1/2P1QK1P/6R1 b - - bm Rxf4+; id "ECM.1452"; +4qrk1/pp1bbppp/4pn2/2r1Q1B1/7P/2N3R1/PPP2PP1/2KR1B2 w - - bm Bxf6; id "ECM.1454"; +1k1r2r1/p1p3q1/2p2p2/3pn3/1P1b2bB/1QN5/P4PPP/1R2RBK1 b - - bm Nf3+; id "ECM.1457"; +5r1n/r2q1pkp/3p1npN/NppPp2P/1P2P3/2P1Q1P1/5P2/R3K2R w KQ - bm Nf5+; id "ECM.1478"; +5rk1/p1p1br2/1p1p2qp/4p3/2PPn1pP/3Q2P1/PPN1P1K1/2RR2B1 b - - bm Bxh4; id "ECM.1495"; +1r2r1k1/1bn2pbp/pp1q1np1/2pPN1B1/P1B5/2N4P/1P1Q1PP1/R3R1K1 w - - bm Nxf7; id "ECM.1503"; +1rb2bk1/2n2qp1/p2p3p/R1pP1p2/2B5/1PBQ1N1P/2P2PP1/6K1 w - - bm Rxc5; id "ECM.1504"; +2q1rk2/QR3ppp/1pPpb3/1P2p1b1/4P3/6P1/3N1PBP/6K1 w - - bm Bh3; id "ECM.1516"; +r2q1rk1/pb1nbpp1/1pp1pn1p/3pN3/2PPP3/2N1B1P1/PP3PBP/R2Q1RK1 w - - bm Nxc6; id "ECM.1525"; +2r2rk1/pp2pp1p/2np2p1/q4P2/2PBP1b1/2N5/PP1Q2PP/R4RK1 w - - bm h3; id "ECM.1527"; +r1b2rk1/1p3pbp/2p3p1/p1q5/1P6/1Q4P1/1P2PPBP/R1B1R1K1 b - - bm Be6; id "ECM.1529"; +1rb1r1k1/p1p1qppp/2pb4/8/2P3n1/4P1P1/PB2BP1P/R1QN1RK1 b - - bm Nxh2; id "ECM.1533"; +8/8/1p1k4/5ppp/PPK1p3/6P1/5PP1/8 b - - bm f4; id "ECM.1536"; +6r1/1p3k2/pPp4R/K1P1p1p1/1P2Pp1p/5P1P/6P1/8 w - - bm Rxc6; id "ECM.1546"; +1k2b3/4bpp1/p2pp1P1/1p3P2/2q1P3/4B3/PPPQN2r/1K1R4 w - - bm f6; id "ECM.1547"; +6k1/2q3p1/1n2Pp1p/pBp2P2/Pp2P3/1P1Q1KP1/8/8 w - - bm e5; id "ECM.1551"; +6k1/1q2rpp1/p6p/P7/1PB1n3/5Q2/6PP/5R1K w - - bm b5; id "ECM.1553"; +r5r1/8/bRP1pk1p/3pNp2/5P2/7P/PR4P1/6K1 w - - bm Rxa6; id "ECM.1554"; +6k1/p3b1pp/4p3/4Pp2/Pp1r1P1P/1P4P1/2p2R2/5RK1 b - - bm Rc4; id "ECM.1561"; +2r2rk1/p1N2p1p/2P1p1p1/1Pp3q1/3b4/5Q2/P1P3PP/4RR1K w - - bm Nxe6; id "ECM.1563"; +3r1r2/pp1P3k/4Rbp1/1BP2p1p/8/7P/P4KP1/3R4 w - - bm Ba6; id "ECM.1564"; +2r1rbk1/p1Bq1ppp/Ppn1b3/1Npp4/B7/3P2Q1/1PP2PPP/R4RK1 w - - bm Nxa7; id "ECM.1573"; +8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - bm Rxb2; id "ECM.1578"; +6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - bm cxb6; id "ECM.1579"; +4r2k/pppb2pp/2np2q1/3B4/2P2P2/1PB1R1P1/PQ5P/6K1 w - - bm f5; id "ECM.1582"; +8/2k5/2p5/2pb2K1/pp4P1/1P1R4/P7/8 b - - bm Bxb3; id "ECM.1584"; +r1b2rk1/1p2qppp/p3p3/2n5/3N4/3B1R2/PPP1Q1PP/R5K1 w - - bm Bxh7+; id "ECM.1590"; +r2qrbk1/5ppp/pn1p4/np2P1P1/3p4/5N2/PPB2PP1/R1BQR1K1 w - - bm Bxh7+; id "ECM.1592"; +1rb2rk1/3nqppp/p1n1p3/1p1pP3/5P2/2NBQN2/PPP3PP/2KR3R w - - bm Bxh7+; id "ECM.1594"; +r4rk1/1bq2ppp/p1p1p3/2b1P1B1/3p2Q1/3B4/PPP2PPP/R3R1K1 w - - bm Bxh7+; id "ECM.1597"; +2r2r2/p2qppkp/3p2p1/3P1P2/2n2R2/7R/P5PP/1B1Q2K1 w - - bm Rxh7+; id "ECM.1600"; +1r1qr1k1/5p1p/1n2p1p1/pp1pP1P1/2pP1BB1/PnP3P1/1P3PK1/1R1Q3R w - - bm Rxh7; id "ECM.1601"; +4rrk1/2q1bppp/p2p4/1p1Pn3/3B1R2/P2B2Q1/1PP3PP/5R1K w - - bm Bxh7+; id "ECM.1602"; +5r1k/ppp2qnp/1n1p1N1Q/3Ppb2/2P4P/7B/PP6/2KR2R1 w - - bm Nxh7; id "ECM.1604"; +r4rk1/pp2q1p1/4b2p/2ppb3/6n1/2P3N1/PPQBBPPP/R4RK1 b - - bm Nxh2; id "ECM.1605"; +b3r1k1/2rN1ppp/2n1p3/p7/P3BP2/1R6/q1P2QPP/3R2K1 w - - bm Bxh7+; id "ECM.1606"; +2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - bm Qxh7+; id "ECM.1607"; +5rk1/pbrn1ppp/1ppN1q2/2P1p3/3P4/1PRB4/P3QPPP/5RK1 w - - bm Bxh7+; id "ECM.1610"; +r1b2r1k/ppppq1pp/2n1n3/6N1/2B2P2/4B3/PPP3PP/R2Q1RK1 w - - bm Nxh7; id "ECM.1612"; +r2r2k1/p1p2p1p/4pPp1/1Pqb4/8/7R/1PB2PPP/3QR1K1 w - - bm Rxh7; id "ECM.1614"; +rn3rk1/pp1bppbp/1qp3p1/4P1N1/PP1PB3/2P1B3/4Q1PP/R4RK1 w - - bm Nxh7; id "ECM.1617"; +3rr1k1/1pq1nppp/p1p2b2/4pB2/2QPP3/P1P1B3/1P4PP/3R1RK1 w - - bm Bxh7+; id "ECM.1618"; +2rrn1k1/2q2ppp/p2pp3/1p2P1P1/4B3/P5Q1/1PP3PP/R4R1K w - - bm Bxh7+; id "ECM.1620"; +r2q3r/2pkb1p1/p2p1n2/4p1p1/Pp2P1P1/1QP5/1P1P2PP/RNB2RK1 b - - bm Rxh2; id "ECM.1621"; +2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - bm Nxh7; id "ECM.1622"; +2rq1bk1/1br2p1p/p2p2p1/1p1P4/4Q3/PP3N2/1BP5/1K1R3R w - - bm Rxh7; id "ECM.1623"; + diff --git a/tests/orig/gmg3.epd b/tests/orig/gmg3.epd new file mode 100644 index 0000000..5df1ca5 --- /dev/null +++ b/tests/orig/gmg3.epd @@ -0,0 +1,64 @@ +8/ppp3k1/8/PPP5/8/8/6K1/8 w - - bm b6; id "Larsen/Endings GMG 3.1"; +8/8/4pppp/8/4PPPP/k7/8/K7 w - - bm h5; id "Larsen/Endings GMG 3.2"; +8/5k2/1p2PP1p/p1p3p1/P1P3P1/1P1K3P/8/8 b - - bm Kxf6; id "Larsen/Endings GMG 3.3"; +8/2k5/p2p3p/2pPp1p1/P5P1/3K4/2P4P/8 w - - bm a5; id "Larsen/Endings GMG 3.4"; +8/p7/4k1P1/1p1p3P/1P2pK2/2P5/P7/8 w - - bm h6; id "Larsen/Endings GMG 3.5"; +4k3/5p2/3K2p1/4P2p/7P/8/6P1/8 w - - bm g3; id "Larsen/Endings GMG 3.6"; +8/7p/p5p1/3k2P1/3p1P1P/3K4/P7/8 w - - bm a3; id "Larsen/Endings GMG 3.7"; +8/1p3pp1/8/3k3P/5PP1/8/3K4/8 w - - bm g5; id "Larsen/Endings GMG 3.8"; +8/1p3pp1/7p/5P1P/2k3P1/8/2K2P2/8 w - - bm f6; id "Larsen/Endings GMG 3.9"; +8/8/3K1k2/5p1p/4p1p1/4P1P1/5PP1/8 b - - bm f4; id "Larsen/Endings GMG 3.10"; +8/5p2/2k5/K7/8/1P6/8/8 b - - bm Kd5; id "Larsen/Endings GMG 3.11"; +8/8/4k1p1/6Q1/K7/3q4/8/8 b - - bm Qd7+; id "Larsen/Endings GMG 3.12"; +5q2/6pk/p7/1p3PPK/1P2Q3/8/8/8 w - - bm g6+ f6; id "Larsen/Endings GMG 3.13"; +6Q1/8/3p4/2pPk1p1/1p5P/1P4PK/2q5/8 b - - bm g4+; id "Larsen/Endings GMG 3.14"; +8/6pk/4QP1p/7K/5qPP/8/8/8 w - - bm f7; id "Larsen/Endings GMG 3.15"; +4Q3/Pq4pk/5p1p/5P1K/6PP/8/8/8 w - - bm a8=B; id "Larsen/Endings GMG 3.16"; +2K5/3r4/5k2/4R3/1P4p1/3P4/8/8 w - - bm Kxd7 Rg5; id "Larsen/Endings GMG 3.17"; +8/8/3P4/2p5/3r4/1PK5/1P6/4k3 w - - bm b4; id "Larsen/Endings GMG 3.18"; +8/6KP/2r1k3/8/p7/P7/1P5P/8 b - - bm Rc7+; id "Larsen/Endings GMG 3.19"; +K1k5/2r3pp/P4p2/1P6/8/5P1P/8/8 b - - bm Rc6; id "Larsen/Endings GMG 3.20"; +3k4/3P3p/P2R2p1/6p1/8/6PP/1r6/5K2 w - - bm a7; id "Larsen/Endings GMG 3.21"; +8/8/5R1P/8/2K5/7r/4p3/4k3 b - - bm Kd2 Rh1; id "Larsen/Endings GMG 3.22"; +8/2p5/5pK1/5R2/4k2P/p4P2/1r6/8 b - - bm Kd3; id "Larsen/Endings GMG 3.23"; +8/8/4r3/1PP2k2/2R5/5p1p/P6K/8 w - - bm Kg3; id "Larsen/Endings GMG 3.24"; +4k3/1p3p2/p1pRr1pp/P1P1P3/5PK1/2P5/7P/8 w - - bm h4; id "Larsen/Endings GMG 3.25"; +8/8/R7/pp5p/2bK3k/2P5/6P1/8 w - - bm Rg6; id "Larsen/Endings GMG 3.26"; +3K2k1/2R3p1/1p2p2p/3bPp2/5P2/1p4P1/7P/8 w - - bm Ke7; id "Larsen/Endings GMG 3.27"; +R7/1P2p1k1/8/5p2/6p1/7p/7b/5K2 w - - bm Ra2; id "Larsen/Endings GMG 3.28"; +5k2/3R4/6pp/4bp2/8/5K2/8/8 w - - bm Rd5; id "Larsen/Endings GMG 3.29"; +7k/8/pP1N4/3P1p2/5PpP/3r4/7P/6K1 w - - bm Nf7+; id "Larsen/Endings GMG 3.30"; +8/4p3/8/3P3p/P2pK3/6P1/7b/3k4 w - - bm d6; id "Larsen/Endings GMG 3.31"; +8/8/3P1k2/2p1pB1p/2P3pP/4K1P1/6b1/8 w - - bm Bxg4; id "Larsen/Endings GMG 3.32"; +8/8/B4p1p/3k4/p2p1pP1/P2P3P/bP2KP2/8 w - - bm b4; id "Larsen/Endings GMG 3.33"; +4B3/8/p7/P3k1p1/1Pb3P1/6K1/5P2/8 w - - bm f3; id "Larsen/Endings GMG 3.34"; +6k1/5p1p/6p1/ppp5/4b3/P1P1P3/5PPP/3B2K1 b - - bm a4; id "Larsen/Endings GMG 3.35"; +8/8/1bk3p1/p4pP1/P1P5/2BK4/6P1/8 w - - bm Bd2 c5; id "Larsen/Endings GMG 3.36"; +8/1p3B2/p2k2p1/P2p3p/1P1KbP1P/4P3/8/8 w - - bm f5; id "Larsen/Endings GMG 3.37"; +8/5Bp1/4P3/6pP/1b1k1P2/5K2/8/8 w - - bm Kg4; id "Larsen/Endings GMG 3.38"; +8/1Pb5/K7/P5p1/1k4B1/8/3p4/8 w - - bm Bd1; id "Larsen/Endings GMG 3.39"; +8/2b5/8/2Np4/P2K4/7k/8/8 b - - bm Ba5; id "Larsen/Endings GMG 3.40"; +8/1N1b4/1P6/8/7p/4K3/8/6k1 w - - bm Nd8; id "Larsen/Endings GMG 3.41"; +3n4/1p3pk1/p4p1p/P4P1K/1P2B3/5P2/7P/8 w - - bm b5; id "Larsen/Endings GMG 3.42"; +8/7k/7P/7P/p1n1p3/2P5/2K5/2B5 b - - bm Kg8; id "Larsen/Endings GMG 3.43"; +8/7k/4B3/8/3p1K2/p1n2P2/8/8 w - - bm Bb3; id "Larsen/Endings GMG 3.44"; +8/8/6p1/5n1p/4Bp1P/5P1K/5kP1/8 b - - bm Kg1; id "Larsen/Endings GMG 3.45"; +8/k5p1/p2P1nBp/2p1p2P/2P5/P3K3/6P1/8 w - - bm d7; id "Larsen/Endings GMG 3.46"; +7k/6p1/6K1/p5P1/5N2/8/8/8 w - - bm Kf7; id "Larsen/Endings GMG 3.47"; +8/8/8/6N1/5pKp/8/5kn1/8 b - - bm Ke3; id "Larsen/Endings GMG 3.48"; +8/3b1p2/4p1k1/1pn1P1Pp/2pNPKp1/P1P3P1/2B5/8 b - - bm Be8; id "Larsen/Endings GMG 3.49"; +6k1/6p1/7p/8/pb5N/2B1p2P/PP4P1/3K1b2 b - - bm e2+; id "Larsen/Endings GMG 3.50"; +8/8/3k2p1/1p2p2p/pNp1P2P/P1Pn4/1P2K1P1/2bN4 b - - bm Nc5; id "Larsen/Endings GMG 3.51"; +1R2b3/5kp1/1p2rp1p/1P1p4/3P1PP1/3B3P/5K2/8 w - - bm Bg6+; id "Larsen/Endings GMG 3.52"; +6k1/4pp1p/3p2p1/P1pPb3/R7/1r2P1PP/3B1P2/6K1 w - - bm Bb4; id "Larsen/Endings GMG 3.53"; +6k1/4pp1p/3p2p1/R2P4/2P5/1r3P2/1b1B2PP/5K2 w - - bm Rb5; id "Larsen/Endings GMG 3.54"; +5k2/4bp2/2B3p1/1P4p1/3R4/3P2PP/2r2PK1/8 b - - bm Rxf2+; id "Larsen/Endings GMG 3.55"; +7R/8/6pp/4p1k1/3b2P1/5KNP/8/4r3 b - - bm Re3+; id "Larsen/Endings GMG 3.56"; +8/pp1k3p/2pr1p2/3n4/P1B2P1P/2P2KP1/8/4R3 w - - bm Bd3; id "Larsen/Endings GMG 3.57"; +8/7R/1pkpp1r1/p1n1p3/P1K1P3/2P1NP2/1P4P1/8 w - - bm Nd5; id "Larsen/Endings GMG 3.58"; +2r3k1/pR6/4r1p1/6Pp/3p3P/3P4/PP1Kp3/6R1 b - - bm Rec6; id "Larsen/Endings GMG 3.59"; +4nk2/5pp1/2B1p2p/4q3/8/7P/5PP1/5QK1 w - - bm Bxe8; id "Larsen/Endings GMG 3.60"; +7K/8/k1P5/7p/8/8/8/8 w - - bm Kg7; id "Larsen/Endings GMG 3.61"; +2b5/2P5/8/1k5p/5K1P/6B1/6P1/8 b - - bm Ka6; id "Larsen/Endings GMG 3.62"; +8/4k3/4P3/3K4/8/8/8/8 b - - bm Ke8; id "Larsen/Endings GMG 3.63"; + diff --git a/tests/orig/mes400.epd b/tests/orig/mes400.epd new file mode 100644 index 0000000..2ea5865 --- /dev/null +++ b/tests/orig/mes400.epd @@ -0,0 +1,401 @@ +8/6p1/7k/8/1K6/8/1P6/8 w - - bm Kc5; id "MES.0001"; +8/8/8/2p5/8/8/1kP5/3K4 w - - bm c4; id "MES.0002"; +7K/8/k1P5/7p/8/8/8/8 w - - bm Kg7; id "MES.0003"; +8/8/1p6/8/8/P7/8/5k1K w - - bm Kh2; id "MES.0004"; +8/8/8/8/8/P4p2/k6K/8 w - - bm a4; id "MES.0005"; +8/8/6p1/1k6/4K3/8/5P2/8 w - - bm Kd4; id "MES.0006"; +5k2/6p1/7p/8/7P/7K/8/8 w - - bm Kg3; id "MES.0007"; +8/8/1kpp4/8/2P5/2K5/8/8 w - - bm Kc2; id "MES.0008"; +8/5p2/1p6/1P2K2k/8/8/8/8 w - - bm Kf5; id "MES.0009"; +8/8/8/4p1p1/8/5P2/6K1/3k4 w - - bm Kh1; id "MES.0010"; +8/2p4K/8/7k/8/8/6PP/8 w - - bm g4+; id "MES.0011"; +4k3/4p3/4P3/4P3/8/8/2K5/8 w - - bm Kd3; id "MES.0012"; +K7/8/1k6/1p6/8/2P5/1P6/8 w - - bm b3; id "MES.0013"; +7k/5K2/7P/6pP/8/8/8/8 w - - bm Kf6; id "MES.0014"; +8/p7/P7/8/8/4k3/4P3/4K3 w - - bm Kf1; id "MES.0015"; +8/k7/3p4/6K1/2P1P3/8/8/8 w - - bm Kg6; id "MES.0016"; +K1k5/7p/8/2P5/8/8/P7/8 w - - bm c6; id "MES.0017"; +8/5p2/5p2/5p2/8/4K3/7P/7k w - - bm h4; id "MES.0018"; +8/6p1/k1P2p1p/7K/8/8/8/8 w - - bm Kg6; id "MES.0019"; +2k5/3p4/P7/Pp6/8/4K3/8/8 w - - bm Kd4; id "MES.0020"; +8/1p2pk2/1P6/8/4P3/8/6K1/8 w - - bm Kg3; id "MES.0021"; +8/3Pk1p1/8/1K3Pp1/8/8/8/8 w - - bm Kc6; id "MES.0022"; +8/5p2/7k/6p1/5P1P/8/8/7K w - - bm hxg5+; id "MES.0023"; +4k3/8/3p4/p6K/P5P1/8/8/8 w - - bm Kg5; id "MES.0024"; +8/2p1Pk2/5P2/8/3p1K2/8/8/8 w - - bm Kf3; id "MES.0025"; +1k1K4/1p5P/1P6/8/8/8/p7/8 w - - bm h8=Q; id "MES.0026"; +k7/5K2/8/8/7p/p6P/P7/8 w - - bm Ke6; id "MES.0027"; +8/p2p4/8/8/8/k7/5P1P/7K w - - bm f4; id "MES.0028"; +8/8/1k1p4/8/P1P5/p7/8/3K4 w - - bm Kc2; id "MES.0029"; +8/K3p3/5p2/5P2/8/8/2k1P3/8 w - - bm Kb6; id "MES.0030"; +8/2K5/1p6/1P4k1/5p2/8/6P1/8 w - - bm Kc6; id "MES.0031"; +8/5p2/5p2/8/5KP1/8/6P1/3k4 w - - bm Kf5; id "MES.0032"; +8/8/4k1P1/4p1p1/4K3/3P4/8/8 w - - bm g7; id "MES.0033"; +8/8/7p/p7/k1P2K2/8/P7/8 w - - bm a3; id "MES.0034"; +8/8/1p1K4/Pp6/2k1p3/8/1P6/8 w - - bm a6; id "MES.0035"; +3k4/3p3p/3p4/PK6/4P3/8/8/8 w - - bm Kb6; id "MES.0036"; +7k/3p2p1/2p5/5P2/2P5/K7/8/8 w - - bm Kb4; id "MES.0037"; +8/7p/3p4/8/6pP/8/4PK2/7k w - - bm Kg3; id "MES.0038"; +8/8/K7/2p1k3/8/1p1p4/1P1P4/8 w - - bm Kb5; id "MES.0039"; +8/8/2p5/k1p1K3/p1P5/P7/8/8 w - - bm Kf5; id "MES.0040"; +8/8/1p1p3p/3P4/4K3/8/4P2k/8 w - - bm Kf3; id "MES.0041"; +6K1/8/pp5p/8/7k/3PP3/8/8 w - - bm d4; id "MES.0042"; +K7/8/k7/6p1/6Pp/7p/7P/8 w - - bm Kb8; id "MES.0043"; +2k5/3p2p1/2p5/2K5/5P2/8/2P5/8 w - - bm Kd6; id "MES.0044"; +6k1/p7/3K2p1/1P5p/7P/8/8/8 w - - bm Kd5; id "MES.0045"; +8/1K6/8/k4p2/4pp2/8/4PP2/8 w - - bm Kc6; id "MES.0046"; +8/6p1/4K3/6k1/6P1/6pP/6P1/8 w - - bm Ke5; id "MES.0047"; +8/K7/3pk3/8/p3P3/P7/1P6/8 w - - bm Kb8; id "MES.0048"; +1k6/1p6/3p4/1P6/1P6/1P6/8/7K w - - bm Kg2; id "MES.0049"; +8/6p1/8/5p1P/5P2/6P1/8/5K1k w - - bm Ke1; id "MES.0050"; +8/2p5/3k4/1p1p1K2/8/1P1P4/2P5/8 w - - bm b4; id "MES.0051"; +4K3/pk6/2p5/2P5/1pP4P/1P6/8/8 w - - bm Kd7; id "MES.0052"; +8/2p5/3k3P/5pp1/5p2/1p5K/8/8 w - - bm h7; id "MES.0053"; +8/8/6K1/k2p4/2p5/2P4p/3P3P/8 w - - bm Kf7; id "MES.0054"; +8/8/1p3P1k/4P3/8/1p6/pK2P3/8 w - - bm e6; id "MES.0055"; +8/4Pk2/5p2/8/K7/3p2p1/3P2P1/8 w - - bm Kb5; id "MES.0056"; +8/1p6/8/5k1p/P1P3p1/8/5PK1/8 w - - bm a5; id "MES.0057"; +4k3/5p1p/1p5P/6P1/P7/8/8/4K3 w - - bm Kd2; id "MES.0058"; +5k2/5p1p/7P/6P1/p7/P7/8/1K6 w - - bm Kc2; id "MES.0059"; +K7/3p3p/3k4/8/6pP/8/P5P1/8 w - - bm Kb7; id "MES.0060"; +1k6/1P6/2P5/P7/5ppp/8/6K1/8 w - - bm Kg1; id "MES.0061"; +8/6p1/6pp/8/k4P2/6K1/6PP/8 w - - bm f5; id "MES.0062"; +1k6/p3pp2/p7/P2KP3/P7/8/8/8 w - - bm e6; id "MES.0063"; +8/1p6/8/P7/7p/1P2p2P/4P1k1/4K3 w - - bm b4; id "MES.0064"; +k7/P2K4/p7/1p4p1/1P4P1/6P1/8/8 w - - bm Kd6; id "MES.0065"; +8/2p2p2/1p6/3P1k1K/P1P2P2/8/8/8 w - - bm c5; id "MES.0066"; +2k2K2/2p5/P7/Pp1P4/8/7p/7P/8 w - - bm Ke7; id "MES.0067"; +8/2pp4/8/2PP3k/4pPp1/4P1K1/8/8 w - - bm d6; id "MES.0068"; +8/3p4/3P4/3p2pp/3P4/k4K1P/7P/8 w - - bm h4; id "MES.0069"; +8/2p5/pp6/kP1P4/p3K3/P1P5/8/8 w - - bm d6; id "MES.0070"; +8/5pp1/8/k2p1Pp1/P5P1/3P4/8/3K4 w - - bm Kc2; id "MES.0071"; +8/2pp1k2/2p1pP2/4P3/5P2/6K1/5P2/8 w - - bm f5; id "MES.0072"; +8/8/7p/2p2PP1/p1P5/p1K5/k2P4/8 w - - bm Kc2; id "MES.0073"; +8/1p6/1p6/1k2K3/2p1p3/PpP1P3/1P6/8 w - - bm a4+; id "MES.0074"; +7k/8/5PpK/Pp1P2pp/3P4/8/5p2/8 w - - bm a6; id "MES.0075"; +8/1p5k/1P1p4/3p4/3Pp2p/2K1P2p/7P/8 w - - bm Kb2; id "MES.0076"; +8/2pp2pp/8/2PP1P2/1p5k/8/PP4p1/6K1 w - - bm f6; id "MES.0077"; +8/5k2/2p5/1pPp4/p2P2p1/P2P2P1/P5K1/8 w - - bm Kf1; id "MES.0078"; +8/4p1p1/1k2p1p1/p3P1P1/P1p2P2/2P5/5P2/4K3 w - - bm Kd1; id "MES.0079"; +3k4/1pp5/p4P1p/P1p1KP1P/2P4p/7P/2P5/8 w - - bm Ke6; id "MES.0080"; +8/pp1pppp1/3p2p1/PP2P1P1/K1P4P/8/k7/8 w - - bm h5; id "MES.0081"; +K7/8/8/7p/N2k4/8/8/8 w - - bm Nb2; id "MES.0082"; +7N/2K5/8/8/7p/2k5/8/8 w - - bm Nf7; id "MES.0083"; +8/4k2N/7p/8/1p6/8/4K3/8 w - - bm Kd3; id "MES.0084"; +7K/3k4/8/pN6/8/8/1P6/8 w - - bm Nd4; id "MES.0085"; +8/8/8/8/5p2/4k1p1/4N1P1/5K2 w - - bm Ng1; id "MES.0086"; +8/8/8/8/3p4/2k1p3/2N1P3/3K4 w - - bm Ne1; id "MES.0087"; +5K2/5P2/8/8/kp3n2/8/P7/8 w - - bm Ke7; id "MES.0088"; +8/8/8/4P3/3pp1K1/N2k4/8/8 w - - bm e6; id "MES.0089"; +8/7K/6p1/7P/p7/8/3kN3/8 w - - bm h6; id "MES.0090"; +8/8/5N2/6P1/5k2/5pp1/8/4K3 w - - bm g6; id "MES.0091"; +8/3p4/3k1Np1/P4p2/5K2/8/8/8 w - - bm a6; id "MES.0092"; +8/2p5/1p6/1K6/7k/7P/7P/6N1 w - - bm Kc6; id "MES.0093"; +8/2kp1K2/6N1/3P4/p6P/8/8/8 w - - bm d6+; id "MES.0094"; +4k3/7N/4P3/6P1/8/4p1p1/8/6K1 w - - bm Kf1; id "MES.0095"; +8/8/p6k/8/3N4/PP1K4/7p/8 w - - bm Nf5+; id "MES.0096"; +8/8/8/4N3/5p2/p4p2/5P1p/5K1k w - - bm Nd3; id "MES.0097"; +1k6/p7/8/1p5P/8/2pK4/1P5n/8 w - - bm h6; id "MES.0098"; +2k5/2P4K/1P3p2/6p1/6n1/8/5P2/8 w - - bm f3; id "MES.0099"; +2n5/1k6/4pP2/4P3/2K5/7p/6P1/8 w - - bm f7; id "MES.0100"; +2n5/8/1PkP4/P4p2/1K6/7P/8/8 w - - bm d7; id "MES.0101"; +4k3/4Pp1p/3P1K2/6P1/8/p2n4/8/8 w - - bm g6; id "MES.0102"; +8/6p1/6Pp/5p2/5P1K/2p5/3k3P/7N w - - bm Ng3; id "MES.0103"; +4n2k/7P/5P1p/6p1/2K3P1/5P2/8/8 w - - bm Kd5; id "MES.0104"; +6K1/p7/4ppkp/7p/2PP1P1p/7P/P2P4/4n3 w - - bm d5; id "MES.0105"; +8/7K/7P/1P6/2n4k/4n3/1P6/8 w - - bm Kg6; id "MES.0106"; +8/p2P4/k7/P4P2/nKPn4/8/8/8 w - - bm d8=N; id "MES.0107"; +8/5N1N/8/8/1P6/2K4k/6p1/8 w - - bm Nhg5+; id "MES.0108"; +1K6/N7/k7/8/6N1/1pp5/1P6/8 w - - bm Ne5; id "MES.0109"; +5K2/7k/8/6P1/8/pp1N3N/8/8 w - - bm Ndf4; id "MES.0110"; +8/3N4/5p2/8/4PK2/8/5Pp1/1N2k3 w - - bm Nd2; id "MES.0111"; +8/8/7p/3KNN1k/2p4p/8/3P2p1/8 w - - bm Kc6; id "MES.0112"; +8/6p1/7p/6PN/3NK1k1/6Pp/6p1/8 w - - bm gxh6; id "MES.0113"; +8/1p3p2/8/1KP1P3/3NkpP1/7p/2N2P2/8 w - - bm e6; id "MES.0114"; +8/8/8/6K1/8/4N2p/5n1k/8 w - - bm Kh4; id "MES.0115"; +K2n4/8/P7/8/2k5/8/2N5/8 w - - bm Ka7; id "MES.0116"; +8/1K6/P7/kn6/4N3/8/8/8 w - - bm Nc5; id "MES.0117"; +8/K7/8/2P1N3/n3k3/2p5/8/8 w - - bm c6; id "MES.0118"; +7k/4np2/8/4K2p/8/4N3/P7/8 w - - bm Kd6; id "MES.0119"; +8/N1k1n3/6P1/1P2K3/8/1p6/8/8 w - - bm b6+; id "MES.0120"; +8/2Pp4/1n1N4/8/8/K4Pk1/8/8 w - - bm Kb2; id "MES.0121"; +K7/8/1Np5/8/6k1/n7/P5P1/8 w - - bm Kb7; id "MES.0122"; +3n4/8/2P5/8/5p2/p2N3k/7p/5K2 w - - bm Nf2+; id "MES.0123"; +8/6N1/p5k1/3K4/1p1p4/1P6/8/2n5 w - - bm Ne6; id "MES.0124"; +2n5/8/Pp5p/5N2/8/5k2/3P4/7K w - - bm d4; id "MES.0125"; +7n/8/6pP/6P1/k1K5/p7/8/1N6 w - - bm Kd5; id "MES.0126"; +3n4/3K4/8/1p6/pkN5/1P6/PP6/8 w - - bm Ne5; id "MES.0127"; +4Nn2/8/3P4/kP2P3/5p2/5p2/8/2K5 w - - bm Kd1; id "MES.0128"; +4k3/2p2nKP/3p4/3Ppp1N/8/8/8/8 w - - bm Nf6+; id "MES.0129"; +1n4N1/8/4p1P1/kp2p3/p3P3/8/K7/8 w - - bm Ne7; id "MES.0130"; +n7/K5PP/2k5/8/8/1P1p2Np/6p1/8 w - - bm Ne2; id "MES.0131"; +6N1/8/3P4/3n1P2/5p2/3K1k2/6n1/8 w - - bm f6; id "MES.0132"; +4NN2/8/8/6Pk/8/5nK1/8/8 w - - bm g6; id "MES.0133"; +8/8/2n1n3/8/6N1/5N2/K3p3/5k2 w - - bm Nf6; id "MES.0134"; +7k/3NN3/8/4K3/8/nP1p4/1n4P1/8 w - - bm Kf6; id "MES.0135"; +6K1/3p4/7k/3N4/4N2P/5nP1/8/4n3 w - - bm Nf4; id "MES.0136"; +4k1N1/5n2/1P1p2P1/2n5/3N4/p7/8/3K4 w - - bm b7; id "MES.0137"; +8/8/8/2k5/p1b5/8/1P1K4/8 w - - bm Kc2; id "MES.0138"; +5K2/k7/4P1p1/8/8/8/4b3/8 w - - bm Ke7; id "MES.0139"; +8/6b1/5k2/8/P3K1P1/8/8/8 w - - bm a5; id "MES.0140"; +5K2/8/7P/5p2/1P6/8/3b4/k7 w - - bm h7; id "MES.0141"; +3b4/5k2/3P1p1P/3K4/8/8/8/8 w - - bm Kc6; id "MES.0142"; +8/8/1b5P/kP6/8/5K2/1P6/8 w - - bm Ke4; id "MES.0143"; +1b6/5K2/7P/1kp5/1p6/8/3P4/8 w - - bm Ke6; id "MES.0144"; +K7/1P6/1kP5/3P4/8/8/1p5b/8 w - - bm d6; id "MES.0145"; +8/1p6/8/P1K5/1P6/5b1P/4k3/8 w - - bm Kd4; id "MES.0146"; +8/p7/8/1P2K3/P6P/5b2/5k2/8 w - - bm Kf5; id "MES.0147"; +K7/2P5/b4k1p/3P4/6P1/8/8/8 w - - bm d6; id "MES.0148"; +8/p3p3/K2PkP2/1P6/5b2/8/8/8 w - - bm f7; id "MES.0149"; +8/3k2K1/2p1p3/b5P1/3P1P2/8/8/8 w - - bm Kf7; id "MES.0150"; +8/3Pb1p1/8/3P2P1/5P2/7k/4K3/8 w - - bm Kd3; id "MES.0151"; +8/2p1p3/4Pb2/1P1P3k/4K2P/8/8/8 w - - bm d6; id "MES.0152"; +8/b7/3K1p2/7P/1p5k/1P6/1PP4P/8 w - - bm h6; id "MES.0153"; +5k2/8/5PP1/8/1p3p2/6P1/P4PpK/7b w - - bm Kg1; id "MES.0154"; +4k1K1/3p2pP/p2P3P/P7/8/1p6/1p6/b7 w - - bm h8=R; id "MES.0155"; +8/8/2PK2p1/7p/p1b2P2/P5P1/2P2kP1/8 w - - bm g4; id "MES.0156"; +7k/3K2pP/pb4P1/8/P6p/2p1p3/2P1P1P1/8 w - - bm Kd6; id "MES.0157"; +8/5p1b/4pPkp/3pP2p/1p1P3P/1p2K2P/1P6/8 w - - bm Ke2; id "MES.0158"; +6k1/3p4/8/8/8/B7/P7/7K w - - bm Bb4; id "MES.0159"; +5k2/4p2p/6P1/3K4/8/4B3/8/8 w - - bm Bh6+; id "MES.0160"; +8/5p1B/7P/1K6/1p6/p7/1k6/8 w - - bm Bc2; id "MES.0161"; +5B2/p7/3p4/PPk5/8/8/4K3/8 w - - bm b6; id "MES.0162"; +8/2p2B2/5PK1/3Pk3/8/7p/8/8 w - - bm d6; id "MES.0163"; +8/B1p2p1P/8/4p3/8/k7/p2K4/8 w - - bm Bd4; id "MES.0164"; +8/8/3p4/8/3B4/p7/p1P4p/5K1k w - - bm Ba1; id "MES.0165"; +8/8/5p2/3P4/p1PK4/p7/k7/3B4 w - - bm Kc3; id "MES.0166"; +8/8/5p2/5p2/5P2/3p3B/5k1P/3K4 w - - bm Bg2; id "MES.0167"; +8/8/2pp4/2p2kp1/2K5/6P1/6P1/2B5 w - - bm Be3; id "MES.0168"; +8/7p/6pP/1B4P1/pp6/1k1K4/8/8 w - - bm Be8; id "MES.0169"; +k7/pp1K4/P2B4/p7/P7/P7/8/8 w - - bm Kc8; id "MES.0170"; +8/1p6/1P1p4/1K1p2B1/P2P4/6pp/1P6/5k2 w - - bm Bd2; id "MES.0171"; +1k6/1p1p4/PK2p3/5p1p/6pP/8/8/5B2 w - - bm a7+; id "MES.0172"; +5kB1/3p1P2/7K/2Pp1P1P/p6p/4P3/7P/8 w - - bm Kg6; id "MES.0173"; +3k4/3p4/3P1P2/P6B/1p1p4/1KPP3p/1P3p2/8 w - - bm a6; id "MES.0174"; +8/1p6/1P6/3p1p1p/p2PpPpk/2p1P2P/2P1B1P1/6K1 w - - bm Kf2; id "MES.0175"; +8/8/8/2P4B/8/5K2/3k4/5b2 w - - bm c6; id "MES.0176"; +8/8/2B5/7b/7k/2K5/1P6/8 w - - bm b4; id "MES.0177"; +8/8/8/1P6/7b/7k/7B/7K w - - bm b6; id "MES.0178"; +B3K3/8/8/P1p5/8/8/2b4k/8 w - - bm a6; id "MES.0179"; +8/8/B3P3/3k4/5K2/2P4b/8/8 w - - bm Bc8; id "MES.0180"; +1K6/3p4/3P4/8/k7/1p6/8/1b5B w - - bm Bc6+; id "MES.0181"; +8/8/7B/2P5/1p4p1/3k4/7K/4b3 w - - bm c6; id "MES.0182"; +k7/8/8/1p2P1p1/bK6/8/B7/8 w - - bm Bf7; id "MES.0183"; +3B4/6b1/6P1/2p5/P1k5/8/8/5K2 w - - bm Ba5; id "MES.0184"; +8/pB4Pb/4k3/8/K2P4/8/8/8 w - - bm Be4; id "MES.0185"; +8/8/p7/p3b1B1/8/p7/1p2k3/1K6 w - - bm Be7; id "MES.0186"; +k2K4/8/6P1/2B5/5P2/p7/4p2b/8 w - - bm g7; id "MES.0187"; +B6k/6p1/2K3PP/8/4p3/8/6b1/8 w - - bm Kd6; id "MES.0188"; +8/4k3/6b1/2p5/2BP4/p4K2/4P3/8 w - - bm Kf4; id "MES.0189"; +8/8/2p2K2/5B1p/k7/8/2P1P3/1b6 w - - bm e4; id "MES.0190"; +8/p7/P7/P7/P4B2/8/5k2/6bK w - - bm Bc7; id "MES.0191"; +8/KPb5/8/P5p1/5p2/3k4/7P/2B5 w - - bm Ba3; id "MES.0192"; +8/1k6/1b6/p3p2P/1B5p/P7/5P2/2K5 w - - bm h6; id "MES.0193"; +5k2/P4P1K/1Pb2PB1/8/3p3p/8/8/8 w - - bm Bf5; id "MES.0194"; +8/3p4/pp1B4/k7/p1P5/P1bp4/8/3K4 w - - bm Kc1; id "MES.0195"; +1B6/3k4/3p4/1P6/p4b2/Pp6/1P1pK3/8 w - - bm b6; id "MES.0196"; +1b6/3k3p/P1p5/2Pp3p/K2P3P/8/8/6B1 w - - bm a7; id "MES.0197"; +8/8/8/3pk1K1/1p1p4/1PpP3b/2P1B2P/8 w - - bm Bg4; id "MES.0198"; +7k/2b5/6P1/2p2P1K/2Pp4/p2P4/2p5/2B5 w - - bm f6; id "MES.0199"; +6k1/4b2p/7B/6p1/3p2P1/3Pp1p1/2K1P1P1/8 w - - bm Kb3; id "MES.0200"; +8/2p2b2/Pp1p4/4pp2/k7/2P5/1P2BPK1/8 w - - bm b3+; id "MES.0201"; +B4k1K/4pP1p/PP2P2P/8/8/p7/1p6/3b4 w - - bm Be4; id "MES.0202"; +5k1K/7p/1Pb2P2/5P1B/p2Pp3/4P3/4P3/8 w - - bm Be8; id "MES.0203"; +8/6p1/4ppb1/P1p1p3/1k6/3PP3/1PK3P1/5B2 w - - bm a6; id "MES.0204"; +8/p1p2pp1/1pP3p1/7k/3PPb2/5P1P/8/3K2B1 w - - bm d5; id "MES.0205"; +8/5b1P/8/4K1B1/1k6/8/p7/8 w - - bm Bd2+; id "MES.0206"; +5b2/1B6/1P4k1/4P3/8/8/8/K7 w - - bm Be4+; id "MES.0207"; +7B/7k/3p1Kp1/6P1/8/8/8/1b6 w - - bm Bg7; id "MES.0208"; +8/1p6/8/8/4p3/1k1P4/5b2/KB6 w - - bm Ba2+; id "MES.0209"; +3k4/1K6/1P6/5p2/B1p5/8/3b4/8 w - - bm Ka6; id "MES.0210"; +b7/8/3p4/P7/6p1/8/4KBk1/8 w - - bm Be3; id "MES.0211"; +8/pkP3P1/3B4/8/3K4/1b6/8/8 w - - bm Kc3; id "MES.0212"; +3k4/8/1p1P4/1B6/7b/5K2/7P/8 w - - bm Kf4; id "MES.0213"; +4B3/8/4k3/P5p1/1PK5/8/8/4b3 w - - bm Kc5; id "MES.0214"; +3K1k2/8/2P5/2p5/5P2/8/1B4p1/3b4 w - - bm c7; id "MES.0215"; +8/2B3k1/2P5/6P1/4b2p/7K/7P/8 w - - bm Be5+; id "MES.0216"; +8/1K6/1P6/8/4P3/1p1k4/5P2/6bB w - - bm Ka8; id "MES.0217"; +3K4/3P1p1B/4k1p1/7p/5P2/b7/8/8 w - - bm f5+; id "MES.0218"; +8/K3p3/8/1k1P1b2/1P6/BP6/1P6/8 w - - bm Kb8; id "MES.0219"; +8/3pk3/6P1/P5Pp/5B2/1p5b/pP6/K7 w - - bm a6; id "MES.0220"; +8/B4p2/2p5/P2p4/5P2/1K1k1P2/3P4/5b2 w - - bm a6; id "MES.0221"; +8/2KB4/5pp1/1Pk1p1p1/4p3/7P/4P3/2b5 w - - bm b6; id "MES.0222"; +8/3p3p/3B3k/P1Pp1p1P/8/8/5P2/1b5K w - - bm c6; id "MES.0223"; +8/3p2p1/3P4/p1PkpP1P/K7/6B1/8/5b2 w - - bm h6; id "MES.0224"; +8/5pp1/3k2p1/1p6/pPB5/P4Kb1/5PP1/8 w - - bm fxg3; id "MES.0225"; +7b/1K2p3/7P/p4P2/1pk5/4P2p/1PP5/3B4 w - - bm Kc6; id "MES.0226"; +8/pp3pb1/P1p5/2K1k2B/5p1p/3P4/3P2P1/8 w - - bm d4+; id "MES.0227"; +1b6/5p1p/3k4/8/2Bp1pP1/1p1P4/1KPP3P/8 w - - bm Ba6; id "MES.0228"; +8/p2p1Bp1/P2p4/1Pp3pP/4K1kp/8/6P1/6b1 w - - bm h6; id "MES.0229"; +8/4B1pp/8/pp1PppP1/b3p3/P7/P3KP1P/2k5 w - - bm g6; id "MES.0230"; +4B2K/6B1/8/8/8/8/2p5/3k4 w - - bm Bh5+; id "MES.0231"; +3k2B1/p7/1p2K3/8/6P1/2P1p2p/1B6/8 w - - bm c4; id "MES.0232"; +8/2B5/1p2p1B1/1P6/2K5/8/2p1pP2/2k5 w - - bm Kb3; id "MES.0233"; +Bk6/1Pp5/1p2p3/4P3/P7/1pK4p/8/B7 w - - bm a5; id "MES.0234"; +1K6/2Pb4/1B5k/7P/5b2/2p5/8/8 w - - bm Bd4; id "MES.0235"; +8/8/P2K1k2/7b/8/5B2/4P2p/2b5 w - - bm a7; id "MES.0236"; +b7/2k5/P5P1/8/8/b2B1p1K/7P/8 w - - bm g7; id "MES.0237"; +8/3PP1P1/2b3P1/8/8/5kPp/5p1p/5BbK w - - bm d8=N; id "MES.0238"; +8/8/7k/5K1P/8/B1b5/B7/8 w - - bm Bc1+; id "MES.0239"; +2b5/K7/4p1p1/1p6/1B2B3/8/8/3k4 w - - bm Kb8; id "MES.0240"; +8/2B5/7k/3p4/8/1p2P3/6K1/b6B w - - bm Bf4+; id "MES.0241"; +8/6p1/6p1/5k1P/3Bp3/4PPP1/3p1PBK/4b3 w - - bm h6; id "MES.0242"; +8/6k1/1B6/4n3/8/7p/8/3K4 w - - bm Bg1; id "MES.0243"; +n6k/8/8/6P1/3K4/3B4/8/8 w - - bm Kc5; id "MES.0244"; +6B1/5P2/5Knk/8/7P/8/8/8 w - - bm Ke6; id "MES.0245"; +4k1B1/8/4P2p/3K4/7P/6np/8/8 w - - bm e7; id "MES.0246"; +8/8/4p3/3k1P2/3p4/8/2P5/Bn3K2 w - - bm f6; id "MES.0247"; +8/b7/k7/2P3pP/4p3/3N4/2K5/8 w - - bm h6; id "MES.0248"; +K6k/1p5B/6P1/1p6/8/4n3/2P5/8 w - - bm c3; id "MES.0249"; +8/2P2n1B/8/5K2/8/3p4/3Pkp2/8 w - - bm Ke6; id "MES.0250"; +8/B1p4p/2p5/8/P6k/8/2n2pK1/8 w - - bm Bc5; id "MES.0251"; +6nk/2p4p/3B1P1P/5KpP/8/8/8/8 w - g6 bm hxg6; id "MES.0252"; +B1k5/5n1P/3P3P/4p2K/4p3/4p3/8/8 w - - bm Bb7+; id "MES.0253"; +3B4/pp6/5p2/1P5n/k1K1pp2/7p/1P6/8 w - - bm Be7; id "MES.0254"; +4nk2/2p2p2/7P/4B2p/2K2P1p/7p/5P2/8 w - - bm h7; id "MES.0255"; +8/2p1p1pp/2P1P2k/6pP/p7/P4Bp1/1P4P1/n5K1 w - - bm Bd1; id "MES.0256"; +3N4/8/8/3b3K/5p2/8/8/7k w - - bm Kg4; id "MES.0257"; +8/2K5/bP4k1/3p4/3N4/8/8/8 w - - bm Nc6; id "MES.0258"; +2b5/4N3/5P2/8/2k1K3/8/3p4/8 w - - bm Nd5; id "MES.0259"; +b7/2K5/8/N2P4/pk6/8/8/8 w - - bm d6; id "MES.0260"; +N2k4/p7/8/8/4K3/8/P7/6b1 w - - bm Kd5; id "MES.0261"; +5b1N/8/5k2/8/K1P1nP2/8/8/8 w - - bm f5; id "MES.0262"; +8/1p6/1Pb5/8/8/N5pk/8/6K1 w - - bm Nc2; id "MES.0263"; +8/8/4p3/2bP4/8/8/p7/k2KN3 w - - bm Kc1; id "MES.0264"; +8/8/2k4b/P7/8/8/2N2PKp/8 w - - bm Nd4+; id "MES.0265"; +4k3/3p1N2/8/P1P4b/8/8/7K/8 w - - bm c6; id "MES.0266"; +8/2k5/8/2P5/6N1/2K2p2/5P2/6b1 w - - bm Kd3; id "MES.0267"; +8/pk6/pp6/5b2/2P5/8/3N1K2/8 w - - bm Nb3; id "MES.0268"; +8/N4k2/2P2p1P/8/7p/5K2/2b5/8 w - - bm c7; id "MES.0269"; +K2b4/3P2pp/8/5PN1/8/6k1/8/8 w - - bm f6; id "MES.0270"; +8/1pN2p2/1P6/8/2P5/5k2/b7/6K1 w - - bm c5; id "MES.0271"; +8/8/8/P5PN/8/8/2bPK2p/6k1 w - - bm Ng3; id "MES.0272"; +7k/7b/1P5N/6P1/7p/6pp/8/6K1 w - - bm Nf7+; id "MES.0273"; +8/3k1p2/P1p4P/1p6/8/N1b5/5K2/8 w - - bm Nxb5; id "MES.0274"; +7N/1pp5/8/P1P1k3/1p6/4K3/8/1b6 w - - bm c6; id "MES.0275"; +8/2p3Kp/1p2P3/8/k7/8/1PN3b1/8 w - - bm b3+; id "MES.0276"; +8/3pk3/5p2/P1P1P3/8/1b6/N7/6K1 w - - bm c6; id "MES.0277"; +7k/7P/1p1P4/1p4pp/8/5P2/3N4/b1K5 w - - bm f4; id "MES.0278"; +5b1k/4p1pP/4P1P1/1p6/8/1N6/2pP4/2K5 w - - bm d4; id "MES.0279"; +8/5p2/p3p1P1/7b/Pk6/1p6/8/1KN5 w - - bm g7; id "MES.0280"; +8/3pPp2/3p1k1K/5p2/1b1P3N/2P5/5p2/8 w - - bm Ng6; id "MES.0281"; +8/8/P1p3N1/2Pb4/6p1/1P3pPp/8/2k2K2 w - - bm Ne5; id "MES.0282"; +8/8/5b1P/1p1Pk3/1Pp1P3/6p1/3N2p1/6K1 w - - bm h7; id "MES.0283"; +1k6/2p1NbP1/PpP5/1K6/2p3p1/3P4/8/8 w - - bm Nc8; id "MES.0284"; +8/2k4N/p6p/5p1P/5p2/2p1pP1b/2P1P2P/6K1 w - - bm Ng5; id "MES.0285"; +8/3k4/1K6/PP6/2b5/8/8/5n2 w - - bm Kb7; id "MES.0286"; +1b2K3/1P6/6n1/1P2k3/8/8/8/8 w - - bm Kd8; id "MES.0287"; +3n4/6k1/6P1/1KP5/8/8/8/3b4 w - - bm c6; id "MES.0288"; +1n6/2k4K/5P2/3P1P2/8/8/8/4b3 w - - bm d6+; id "MES.0289"; +8/P1n1kP2/4P3/2K5/8/8/8/3b4 w - - bm Kb6; id "MES.0290"; +8/3n4/P4P2/4p3/K1p5/8/2k4b/8 w - - bm a7; id "MES.0291"; +8/7P/2n1P1KP/3k4/8/3P4/1b6/8 w - - bm d4; id "MES.0292"; +8/4K3/8/3k4/8/1N1B4/6p1/8 w - - bm Bc4+; id "MES.0293"; +1NBk4/p2p4/8/3K4/8/8/8/8 w - - bm Bb7; id "MES.0294"; +8/6B1/8/8/8/2N1p3/p7/k5K1 w - - bm Kf1; id "MES.0295"; +8/6B1/8/1N6/8/4p3/p1k3K1/8 w - - bm Kf3; id "MES.0296"; +N7/1K6/8/8/2p5/5k1p/3B3P/8 w - - bm Kc6; id "MES.0297"; +8/8/5N2/B1pK4/1p6/k7/8/8 w - - bm Ke4; id "MES.0298"; +8/1p6/8/5N2/p1K4B/p7/2k5/8 w - - bm Nd4+; id "MES.0299"; +8/1B6/8/8/6pp/7p/4K2k/1N6 w - - bm Ke1; id "MES.0300"; +8/8/4k3/8/1p6/3BP3/2K3Np/8 w - - bm Nf4+; id "MES.0301"; +8/8/8/1p6/2k3N1/4B3/p2PK3/8 w - - bm d3+; id "MES.0302"; +8/8/8/3N4/8/p4K2/1pP5/3B2k1 w - - bm Nc3; id "MES.0303"; +8/8/2P5/p7/K2p4/3k2N1/B1p5/8 w - - bm Bc4+; id "MES.0304"; +8/1p1K4/1P4NB/6p1/8/4k3/6p1/8 w - - bm Bf8; id "MES.0305"; +1N6/8/K7/3k4/3p3B/p7/2PP4/8 w - - bm Nc6; id "MES.0306"; +2K2N2/2B5/p1p4p/2k5/2P5/7p/8/8 w - - bm Kb7; id "MES.0307"; +8/8/B7/4p2N/5pp1/1kpK4/6P1/8 w - - bm Ng3; id "MES.0308"; +8/8/8/4N3/8/B1k2p1p/4Pp1P/2K5 w - - bm Bb4+; id "MES.0309"; +8/4B2p/8/3p3P/8/3Pk1K1/p7/6N1 w - - bm Bf6; id "MES.0310"; +8/1kpB1p2/3p4/4pK2/N1P3p1/7p/5P2/8 w - - bm Nc5+; id "MES.0311"; +8/4KBp1/1pp3p1/4k1P1/PP3p1N/P2p4/3P1pPP/8 w - - bm Nf3+; id "MES.0312"; +7k/4p3/5p2/1p1p1p2/1PpP1PpB/1pP3P1/7P/6NK w - - bm Bxf6+; id "MES.0313"; +b7/7P/4P1kb/3PK3/8/n7/8/8 w - - bm h8=N+; id "MES.0314"; +1k1K2n1/2p5/2PP1P2/bP6/P7/2n5/8/8 w - - bm b6; id "MES.0315"; +4N3/2n5/1b6/8/k5p1/8/6P1/7K w - - bm Nf6; id "MES.0316"; +5k2/1K4b1/5np1/P7/8/8/8/6N1 w - - bm a6; id "MES.0317"; +b6k/4n3/5P1K/3p4/5N2/8/8/8 w - - bm f7; id "MES.0318"; +8/3b3p/pn2p3/6PP/PN3k1K/5P2/8/8 w - - bm g6; id "MES.0319"; +N7/P4n1P/p7/k4p2/1p2p1p1/7b/2P2K2/8 w - - bm Nb6; id "MES.0320"; +3n4/8/4P3/7p/P3PP1p/3Pbk1P/2p4P/2N1K3 w - - bm e7; id "MES.0321"; +8/8/8/7N/P5bb/K7/8/2k5 w - - bm Nf4; id "MES.0322"; +8/8/1p6/k5P1/1p6/1p1N2b1/bK6/8 w - - bm Ka1; id "MES.0323"; +8/4p3/P3p1NP/7p/K1kb4/7b/P4P2/8 w - - bm Nh4; id "MES.0324"; +8/8/b5pn/4K3/8/5k2/B7/8 w - - bm Kf6; id "MES.0325"; +K6b/8/8/k3P3/7B/8/4n3/8 w - - bm e6; id "MES.0326"; +5k2/3B2bK/6P1/8/2n5/8/6P1/8 w - - bm g3; id "MES.0327"; +1kb5/3p4/P6p/1KB5/8/7P/8/n7 w - - bm Bd6+; id "MES.0328"; +8/6p1/n4b1P/7P/p7/B3K3/8/4k3 w - - bm h7; id "MES.0329"; +8/1B3pk1/3P4/6pP/n7/5K2/8/2b5 w - - bm d7; id "MES.0330"; +B5k1/6P1/7P/n3K2p/2b4P/8/8/8 w - - bm Kf6; id "MES.0331"; +8/5P1K/3b4/8/6k1/1n4P1/1P4PB/8 w - - bm Kg8; id "MES.0332"; +7b/B7/p2P4/7P/7k/8/P1n2KP1/8 w - - bm d7; id "MES.0333"; +2b5/1pkp4/P1P1p3/1P3n2/8/6pp/6P1/6K1 w - - bm a7; id "MES.0334"; +7B/1p3p1P/7n/7p/3K2p1/1P2P1Pp/1k2b3/8 w - - bm Kc5+; id "MES.0335"; +8/pp5P/1p1p1P2/1K3b2/P2k4/8/p1pP4/1nB5 w - - bm f7; id "MES.0336"; +2b5/P1n1Ppp1/P2p4/3P2PK/5k1P/8/4B2P/8 w - - bm g6; id "MES.0337"; +8/2n2b1B/4p1pP/PP4p1/p5P1/3p2PK/3P4/7k w - - bm Bg8; id "MES.0338"; +6k1/6pb/N5p1/K5N1/8/8/8/8 w - - bm Kb4; id "MES.0339"; +8/8/N2b4/8/K2N4/pPk5/8/8 w - - bm Nb5+; id "MES.0340"; +K3b2N/8/2k3Np/7P/8/8/8/8 w - - bm Nf7; id "MES.0341"; +k4N2/8/1p3P2/pp6/8/K4b2/1N6/8 w - - bm Nc4; id "MES.0342"; +1k6/2b5/p1Kpp3/P3PN2/8/2N5/8/8 w - - bm exd6; id "MES.0343"; +8/7N/4p2P/p3p2P/P3P1k1/2p5/7p/2b1K2N w - - bm Nf6+; id "MES.0344"; +1k4B1/8/8/n1K3N1/8/8/8/8 w - - bm Kb6; id "MES.0345"; +8/8/8/8/1B2N3/8/k1K1n3/8 w - - bm Bc5; id "MES.0346"; +8/8/4N1k1/8/5K2/8/B2n4/8 w - - bm Nd4; id "MES.0347"; +8/8/7p/8/8/2N2K2/8/1B3nk1 w - - bm Ne2+; id "MES.0348"; +8/8/8/NB6/8/5k2/2np3K/8 w - - bm Be8; id "MES.0349"; +n7/7k/4p3/B7/6N1/8/8/6K1 w - - bm Ne5; id "MES.0350"; +8/8/8/8/8/p5pK/5B2/1Nn4k w - - bm Bd4; id "MES.0351"; +8/4K2p/6kP/8/4N3/7B/8/n7 w - - bm Be6; id "MES.0352"; +8/3N4/8/5K2/5B2/8/5Pp1/k3n3 w - - bm Bh2; id "MES.0353"; +3N2n1/4p3/3P4/4k3/6K1/8/2B5/8 w - - bm Nf7+; id "MES.0354"; +8/2N1k3/8/n7/B7/6p1/6Pp/7K w - - bm Ne8; id "MES.0355"; +5B1k/7p/6P1/4NnP1/8/8/K4p2/8 w - - bm g7+; id "MES.0356"; +8/8/p7/Pk6/p6p/3P1N2/8/K1n3B1 w - - bm Kb2; id "MES.0357"; +B7/1P1p2p1/k2n1P2/8/N5K1/8/6p1/8 w - - bm b8=N+; id "MES.0358"; +8/3pB3/n4K1k/6N1/1p2P2p/1p6/1P4Pp/8 w - - bm Bf8+; id "MES.0359"; +2n5/1P1p4/3P4/2B1P3/3P4/6p1/pp4P1/Nk5K w - - bm Ba3; id "MES.0360"; +nK6/2p3pk/1pp5/1P3NP1/5P2/1P4P1/p1B5/8 w - - bm Ne3+; id "MES.0361"; +8/6B1/8/8/3N4/4k3/8/2b1K3 w - - bm Kd1; id "MES.0362"; +1b5B/8/8/1N6/8/3k4/2p5/2K5 w - - bm Nc7; id "MES.0363"; +3K4/8/8/4k3/8/N2bB3/p7/8 w - - bm Nb5; id "MES.0364"; +1b6/8/1N4Pk/8/8/B6K/8/8 w - - bm Nd7; id "MES.0365"; +7K/1b6/8/8/3P4/4k3/1B1N2p1/8 w - - bm d5; id "MES.0366"; +b6k/7p/2p5/8/8/2N5/3B4/1K6 w - - bm Bh6; id "MES.0367"; +8/8/7k/8/7P/2p5/4KN2/3B2b1 w - - bm Nd3; id "MES.0368"; +8/6P1/8/8/4k2K/8/2b4p/2N1B3 w - - bm g8=Q; id "MES.0369"; +k7/8/B3P3/8/1K5b/8/4N2p/8 w - - bm Ng3; id "MES.0370"; +8/5b2/8/6B1/3k4/K7/1P4p1/1N6 w - - bm Nd2; id "MES.0371"; +1k6/2p5/B7/4Np2/8/8/6p1/6Kb w - - bm Nc6+; id "MES.0372"; +8/4K1p1/3N4/5P2/4B3/1k6/3pb3/8 w - - bm f6; id "MES.0373"; +K7/2b5/3p1p2/4k3/4P3/4N3/8/2B5 w - - bm Kb7; id "MES.0374"; +8/8/pp6/8/kb3Np1/7P/1K6/4B3 w - - bm Bxb4; id "MES.0375"; +8/5N2/5pP1/7b/p7/8/1Pk5/4BK2 w - - bm Nh8; id "MES.0376"; +8/8/6p1/7p/pb6/k6P/2P1pB2/NK6 w - - bm c3; id "MES.0377"; +4K3/2k1Bp1N/6p1/5PP1/8/7p/b7/8 w - - bm Bf6; id "MES.0378"; +4Bk2/1pp2p1K/3p4/P5Pb/4P3/5N2/8/8 w - - bm Bc6; id "MES.0379"; +1b6/4P3/1P2PN2/8/2P5/P1k5/P1p2P2/K5B1 w - - bm Ne4+; id "MES.0380"; +6b1/2p1B1P1/p1K5/k7/p6p/p1Np2p1/8/8 w - - bm Na2; id "MES.0381"; +3k4/3p4/P2P2P1/p1p1P3/K3p3/3P3B/P3p2P/3N3b w - - bm Nc3; id "MES.0382"; +8/1p1p4/1p1PPp2/1P1K1k1P/2PP4/4B2P/5pp1/6Nb w - - bm e7; id "MES.0383"; +8/5BK1/8/8/p7/4B3/pn6/1k6 w - - bm Bg6+; id "MES.0384"; +6K1/8/6B1/8/8/2B5/pP6/k2n4 w - - bm Bh8; id "MES.0385"; +8/8/8/3kp3/3p4/P2B4/K1N3Np/8 w - - bm Nf4+; id "MES.0386"; +8/B4p2/4Np2/8/3K1P2/7N/4p2k/8 w - - bm Ng1; id "MES.0387"; +2N1k3/4p3/3pKp2/5p2/4NB2/pp6/8/8 w - - bm Nexd6+; id "MES.0388"; +5N2/8/7B/8/2K5/1p1B4/p7/k7 w - - bm Bd2; id "MES.0389"; +8/8/6bk/8/4nP2/4K3/4N3/4n3 w - - bm f5; id "MES.0390"; +3kn1K1/1p6/P4b2/N2Pn3/8/6P1/8/8 w - - bm a7; id "MES.0391"; +8/8/7N/1k5b/3P4/K3P3/2P5/n5b1 w - - bm Kb2; id "MES.0392"; +8/8/P6P/5p2/8/1b6/nN4P1/k3b2K w - - bm Nd1; id "MES.0393"; +2N2n2/8/1P4P1/1P3KP1/1b6/p7/8/k6b w - - bm g7; id "MES.0394"; +2nn4/B7/KP1P4/8/3p3k/8/8/4b3 w - - bm b7; id "MES.0395"; +6K1/8/Pp3p1k/1Pb4P/p2p3N/3P1PP1/4P3/3b4 w - - bm Nf5+; id "MES.0396"; +b7/7P/2p3np/2P3p1/1P4PP/2B3Pk/7p/6bK w - - bm h5; id "MES.0397"; +3n2k1/3N4/7P/6N1/8/K7/7P/4b3 w - - bm Nf6+; id "MES.0398"; +8/8/p5Pb/1kpbP3/5p2/1N6/1KPN4/8 w - - bm c4+; id "MES.0399"; +2N5/5B2/8/4nk1K/6n1/4p3/8/8 w - - bm Ne7+; id "MES.0400"; + diff --git a/tests/orig/newiq.epd b/tests/orig/newiq.epd new file mode 100644 index 0000000..fe65d28 --- /dev/null +++ b/tests/orig/newiq.epd @@ -0,0 +1,360 @@ +r3rnk1/4qpp1/p5np/4pQ2/Pb2N3/1B5P/1P3PP1/R1BR2K1 w - - bm Bxh6; id "IQ.894"; +r1br2k1/p1q2pp1/4p1np/2ppP2Q/2n5/2PB1N2/2P2PPP/R1B1R1K1 w - - bm Bxh6; id "IQ.895"; +6rk/1p1br2p/pqp5/3pNP2/1P1Pp3/P5PR/5PKR/Q7 w - - bm Rxh7+; id "IQ.915"; +r4rk1/pb1q1ppp/2N1p3/2Rn4/3P4/3BPQ2/5PPP/2R3K1 w - - bm Bxh7+; id "IQ.916"; +3rk1nr/1p3q2/p1n2P1p/P1ppp3/3b4/2N2QPB/1PP4P/R1B2R1K w k - bm Nxd5; id "IQ.917"; +5rk1/1p6/q2P3p/2p2rp1/p1nbQ3/P1N3BP/1PR1B1P1/4K3 b - - bm Rf1+; id "IQ.918"; +6rk/2nbNq1p/3p1PpR/2pPp1P1/1nBbP3/2N3K1/1P6/2B4Q w - - bm Rxh7+; id "IQ.919"; +2b2rk1/1p2p1b1/1q5p/3P2p1/1n1PQ1P1/pP6/P3N2P/1K1RB2R b - - bm Bxg4; id "IQ.920"; +4r1k1/1pq2p1p/2p2npb/2N5/1PPQn1P1/7P/6B1/B2R2K1 b - - bm Ng3; id "IQ.921"; +r4r2/2q2pkp/p3pnp1/1p1b2Q1/2nN1N2/P4P2/BPP3PP/R4R1K w - - bm Nf5+; id "IQ.922"; +3r2k1/p2r1p1p/1p2p1p1/q4n2/3P4/PQ1R3P/1P2NPP1/3R2K1 b - - bm Nxd4; id "IQ.923"; +5r1k/ppp2Bbp/6p1/1bq1N3/3r1P2/PQ6/1P4PP/2R2R1K b - - bm Rxf4; id "IQ.924"; +3r2k1/5pp1/R2B3q/2Q5/1p2rP2/6Pp/1bP2K1P/3R4 w - - bm Be5; id "IQ.925"; +1rb2r2/1p1nppk1/2p1n1p1/p3P2p/2qP3R/2N3NP/PP1Q2B1/5RK1 w - - bm Bd5; id "IQ.926"; +3r4/p2nrpkp/2B1p3/2P2pP1/3R3Q/q7/6PP/6RK w - - bm g6; id "IQ.927"; +2qrrb2/pb3ppk/1npp3p/5N2/1p2n3/1P3NPB/PBPQ1P1P/3RR1K1 w - - bm Rxe4 Qf4; id "IQ.928"; +3r2k1/1p3pp1/1p6/7p/q2NP1P1/2Q2P1b/rP5P/2RR2K1 w - - bm Nf5; id "IQ.929"; +1k1r4/1bp4Q/p7/8/1pP2p2/1P2bNrP/1P4P1/5R1K b - - bm Bxf3; id "IQ.930"; +2q1r2k/5R1p/pp1B2pN/2p1P3/1n1b4/3P2Q1/1P4K1/8 w - - bm Qh4; id "IQ.931"; +2rr2k1/pb3p1p/1pq3p1/4R1N1/2n5/P4P2/BP2Q1PP/4R2K w - - bm Nxf7 Re7; id "IQ.932"; +2r1b1k1/p1q1brp1/1p2p1QB/4p3/4N3/2PBR3/P4PPP/6K1 w - - bm Qh7+; id "IQ.933"; +6rk/7p/Q2R1p2/1p2n3/4b3/1P4NP/P1P2PPK/2q5 b - - bm Qf1; id "IQ.934"; +r1b1rnk1/pp3ppp/3qp3/2pnNPB1/2BP4/2P5/P1P1Q1PP/3R1RK1 w - - bm Nxf7; id "IQ.935"; +2k1r2r/ppn3pq/b7/5p2/5Qn1/2N1B1P1/1P3PB1/2RR2K1 w - - bm Qxc7+; id "IQ.936"; +2k5/1p2b3/2p1p3/3pP1p1/nP1P2P1/NKP5/3B4/q3Q3 b - - bm Qb2+; id "IQ.937"; +r6r/2p1kp1n/2pp4/p1b2P1p/P1B1P2P/1Q4Bq/5P2/3R1RK1 b - - bm Rhg8; id "IQ.938"; +r1bq1rk1/pp1n1pp1/5n1p/2b1pN2/2B4B/2N1P3/PPQ2PPP/2KR3R w - - bm Nxh6+; id "IQ.939"; +5r1k/1p2qp1p/p4R1Q/P1p5/2Prp3/7P/1P4P1/5R1K w - - bm Re6; id "IQ.940"; +6k1/1b2Bp1p/p1q2b2/1p1r1p2/8/5N1P/PP2QPP1/4R1K1 b - - bm Re5; id "IQ.941"; +5rk1/q5pp/4p3/r1bp1p2/1p1B1P2/1P1QP3/P4RPP/2R3K1 w - - bm Rxc5; id "IQ.943"; +4rnk1/1b3p2/1p1q2p1/pPb1p2p/2P1P1n1/3r1NPB/1B1NRP1P/1Q1R2K1 b - - bm Nxf2; id "IQ.944"; +2R4Q/pp1bkp2/4p1r1/qN1p4/Pb6/4B3/1P3PPP/6K1 w - - bm Bb6; id "IQ.945"; +r1r3k1/1p1bnp1p/p5pQ/q5P1/3Bp3/1P4R1/1PP1KP1P/3R4 b - - bm Bg4+; id "IQ.946"; +6k1/6p1/p3br2/1p2Q3/5r2/1P1B2R1/1P3qPP/2R4K w - - bm Rc8+; id "IQ.947"; +4r1k1/1p3p2/p1q2p1p/2b2Pr1/6PR/1P1P3Q/1P1B2RP/7K b - - bm Bf2; id "IQ.948"; +5r1k/1b1P3p/4Q1pb/8/P7/4N1PP/1P2r3/R2R2K1 w - - bm Qf6+; id "IQ.949"; +1r5r/3b1pk1/3p1np1/p1qPp3/p1N1PbP1/2P2PN1/1PB1Q1K1/R3R3 b - - bm Nxg4; id "IQ.950"; +4k3/1bQ3p1/pp2P3/2nP1qp1/8/2P3P1/P6P/5BK1 w - - bm Bd3; id "IQ.951"; +6r1/ppp4k/3p2rp/3Pb3/PPP1Np1q/5P1b/3QRRBP/6K1 b - - bm Bd4; id "IQ.952"; +r2qk2r/1bp2pQp/p7/1p1pP3/4n3/1B2b3/PPP2PPP/RN3RK1 b kq - bm Qg5; id "IQ.953"; +2rq1r2/pp1b1pkp/8/P2Q2P1/n1nN4/2P5/2P3BP/R1B2RK1 w - - bm Rxa4; id "IQ.954"; +r5k1/5pbp/2rp2p1/8/3N1PP1/Pp6/1P1Q2qP/K2R3R b - - bm Rc1+; id "IQ.955"; +2qr1r2/p2n1ppk/1p2p2p/5b2/2PP2NQ/1B4R1/P4PPP/R5K1 w - - bm Bc2; id "IQ.956"; +1k1r4/ppq2p2/8/2pPb1r1/2P1Q1B1/6P1/PP3PK1/R4R2 b - - bm f5; id "IQ.957"; +1r2q1k1/1p6/pN2p1p1/P3p3/2PbQ3/1P5P/6P1/5R1K w - - bm Nd7; id "IQ.958"; +5r1k/p5b1/1qp4p/1r2p3/4N1P1/2Pn2B1/QP2R1PP/R6K b - - bm Ra5; id "IQ.959"; +6k1/pp2q2r/2r1p3/1RPpPpp1/3P4/P5P1/3Q1PK1/7R w - - bm Rxb7; id "IQ.960"; +k7/p1r4p/1pP1bq2/1P4p1/1Qn1B3/2b1P2P/P1P2PP1/3R2K1 w - - bm Qxc3; id "IQ.961"; +8/5p1k/4p1b1/4P3/2Pq4/2Q2KP1/r3P3/2R2B2 b - - bm Ra3; id "IQ.962"; +r1b2rk1/p1q2ppp/1p2p3/4n3/3bP3/1B3N1P/PP2QPP1/R1B2RK1 b - - bm Ba6; id "IQ.963"; +2r1k1nr/3bbpp1/p2p2P1/4pP2/1pqNP3/2N1B3/PPP3Q1/1K1R2R1 w k - bm b3 Nd5; id "IQ.964"; +r6r/p1kn4/2p1b3/q3p1Qp/4P3/2PBB2P/P5P1/3R1RK1 w - - bm Bc4; id "IQ.965"; +1k1r2r1/pp3p1p/B2q1n2/8/3Pb1p1/2Q5/PR3PPP/2B1R1K1 w - - bm Bf4; id "IQ.966"; +4rk2/1p3r2/3q1nQp/1R1P2p1/P2pp3/3B2PP/1P3P2/2R3K1 w - - bm Qxh6+ Rxb7; id "IQ.967"; +r5k1/1p3pbp/2q1p1p1/p1p1P3/n1P5/P1B2N1P/1P2QPP1/3R2K1 w - - bm Bxa5; id "IQ.968"; +1rb1r2k/3nq1b1/2p2pp1/p3p2p/P1B1P3/1P1RB1N1/2P2QPP/3R3K w - - bm Nf5 Rd6; id "IQ.969"; +r1b1q1k1/p1p3b1/2pp2pp/N3r1n1/3N2PB/1P3P2/P1PQ3P/3R1RK1 b - - bm Rxa5; id "IQ.970"; +4q1k1/p6p/1p2n2B/2p2rp1/2P5/2P2P2/P2Q2PP/4R1K1 w - - bm Rxe6; id "IQ.971"; +6rk/5p1p/p4P2/1pbn2r1/3P3R/1PB4Q/PKP2R1P/6q1 b - - bm Ba3+; id "IQ.972"; +4rbk1/1q3ppp/2Rr4/1p1P1B2/2b1PR2/p5P1/5P1P/B1Q3K1 w - - bm Bxh7+ Rxd6 Rh4 Bxg7; id "IQ.973"; +6k1/p1p2pp1/2p1n1q1/1r2P3/4N1PQ/5P2/P6P/3R3K w - - bm Rd8+; id "IQ.974"; +r1b2r2/4ppkp/p2p1np1/qpn5/2PNP1P1/2N2P2/PP1QB2P/R3K2R w KQ - bm g5 cxb5; id "IQ.975"; +r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - bm Qh6+; id "IQ.976"; +4r2r/pp3k2/2p1pq2/3nR3/2PP1pp1/1B1Q2P1/PP3PK1/6R1 b - - bm Ne3+ Nb4; id "IQ.977"; +r2qk2r/1pp2ppp/p3pnn1/6N1/1B1P2P1/1Q2P2P/PP3PK1/R6R b kq - bm Nh4+; id "IQ.978"; +2r3k1/pR5p/2ppNb2/1Q1P1ppP/4q3/4P1P1/5P2/6K1 w - - bm Rg7+ Qa6; id "IQ.979"; +7R/5Q2/6pp/4rp1k/P3P3/5Pb1/4KPq1/3R4 w - - bm Rxh6+; id "IQ.980"; +rnb4r/p1pq1Pkp/1pn1p1p1/3p2N1/3P4/P1PB3Q/2P2PPP/R1B1K2R w KQ - bm Qh6+; id "IQ.981"; +r1r5/p2qnkbp/bp2ppp1/3p4/3P1P2/1Q1N1N1B/PP2PP1P/2R2RK1 w - - bm Nde5+; id "IQ.982"; +r1b2rk1/1p3pbn/p2p2p1/q1nPp2p/P3P3/2NBBPN1/1P1Q2PP/R4RK1 w - - bm b4; id "IQ.983"; +b3k3/2q1b1p1/p3p2r/1pPpP2p/1P1N3P/6P1/P3Q3/1BR3K1 w - - bm Bg6+; id "IQ.984"; +8/2bP1Q1p/6pk/p3p3/P1Bp4/1P1R2KP/5PP1/2q4r w - - bm Re3; id "IQ.985"; +7r/p5k1/4pr2/4Np2/1p1Pn1p1/4P3/PP3PP1/2R2RK1 b - - bm Nc3; id "IQ.987"; +2b1rqk1/2R2ppp/1p1P4/p3Q3/7P/P7/B4PP1/6K1 w - - bm Qxe8; id "IQ.989"; +r3k2r/pppqnpbp/4p1p1/3nP1B1/Q2PN2P/5P2/PP2BP2/2R1K1R1 w - - bm Nd6+; id "IQ.990"; +r3r1k1/1p3pPp/p1p5/3bb2N/7q/1P1Q4/2PB2PP/4RRK1 w - - bm Rxe5; id "IQ.991"; +1q1rr1k1/pn5p/1p3pp1/1Q2b1B1/1P6/5B1P/P4PP1/2R1R1K1 w - - bm Rxe5 Bxf6; id "IQ.992"; +r2qrbk1/p2b2pp/1pn1pn2/3p4/2pP1P2/2P2NN1/PPQ3PP/RBB2RK1 w - - bm Ng5; id "IQ.993"; +r3r1k1/2qb1pbp/n1p2np1/N3p1B1/1P2P3/P1N5/2Q1BPPP/3R1RK1 w - - bm Bxa6 Bxf6; id "IQ.994"; +2k4r/1b3p2/p3pP2/2p1n1P1/Ppprq2P/6P1/1P2BR1K/R2N1Q2 b - - bm Rxd1; id "IQ.995"; +1q2r1k1/p4ppp/1p3B2/2Nb4/5R2/1PQ1p1P1/P2r1P1P/2R3K1 b - - bm Qxf4; id "IQ.996"; +r1b2r1k/1pq3bp/8/3Qp2n/1P1n1pp1/2NP2P1/3BPPBP/1R2NRK1 b - - bm Qxc3; id "IQ.997"; +r1b2rk1/1p2qppp/2pb1n2/p3n1N1/2BR4/1PN1P3/PBQ2PPP/2K4R w - - bm Rxd6; id "IQ.998"; +4rr1k/pQ4pp/8/7q/2B2BbP/P1P2nP1/5PK1/R6R b - - bm Rxf4; id "IQ.999"; +r1b2Q2/1p4pk/pB3pq1/4p3/3p4/6P1/PP2PP1P/2R3K1 b - - bm Bh3; id "IQ.1000"; +r4rk1/5pp1/p2R1Bb1/1pq1Pp1p/7Q/1Bn5/P5PP/5R1K w - - bm Bxg7; id "IQ.1001"; +1k6/p1p3Q1/2qp1P2/2p5/rp6/3P3P/1BP1rP2/2KR3R b - - bm Ra1+; id "IQ.1002"; +5r2/p4pkp/3bpNp1/q3n3/1r3B1Q/3p4/PPP2PPP/R4K1R w - - bm Qh6+; id "IQ.1003"; +r3r3/pp2bBkp/6p1/q3p2Q/4n3/2N2R2/PPP3PP/2KR4 w - - bm Bxg6; id "IQ.1005"; +1k5r/1b5r/1b1qn3/1P2p1pP/3pPpP1/1N1Q4/6B1/1R2BRK1 b - - bm f3; id "IQ.1006"; +5n2/3bp1r1/1r1p3k/p1p2pNp/1nP2P1P/1PN1PB1K/P5R1/6R1 w - - bm Nf7+; id "IQ.1007"; +r2q1rk1/1p1bbppp/p1n1p3/2p1P2Q/4N3/6P1/PPPB1PBP/3RR1K1 w - - bm Nf6+; id "IQ.1008"; +2k4r/pp3ppp/2p2n2/5PBb/P3P3/2Nr3P/1PB2bP1/R3R2K b - - bm Rxh3+; id "IQ.1009"; +r5k1/pq2pn2/3pN1pp/n2P4/1rp1PQ2/1P3PP1/PN4K1/2R4R w - - bm Rxh6 Nd3; id "IQ.1010"; +1kqr2r1/ppp5/2nb1p2/1Q1N2pb/P2P4/1RN1P3/3B1PP1/5R1K b - - bm Be2 Rh8; id "IQ.1011"; +3r2k1/pb1r2pp/1p6/2p1pPqP/2P1P3/1P1BR2P/P4K2/R4Q2 b - - bm Bxe4; id "IQ.1012"; +r1b1rb2/1p3kpQ/p1p1p3/q1P1P3/3P4/4P1R1/PP4PP/R1B3K1 w - - bm Bd2; id "IQ.1013"; +3r1r2/p4pk1/bp2p1P1/4P2p/Pq1N1P2/2p4Q/2P3P1/3RK2R w - - bm Qxh5; id "IQ.1014"; +4Q2r/1b4pk/p1n1pr1p/1p2P2B/1qn5/5N2/PPP2PP1/2KRR3 w - - bm Ng5+; id "IQ.1015"; +3q1rk1/p1r2pp1/1p2p2p/6bn/3PNn2/1B2BP2/PP1Q1P1R/6RK w - - bm Rxh5; id "IQ.1016"; +rr4k1/2q2ppp/p1b1p3/2b1pPPN/1p2P1R1/3B3Q/PPP4P/1K1R4 w - - bm Nf6+; id "IQ.1017"; +4r3/1r2ppk1/p2p1np1/2qP4/PpP5/1P1Q4/2B1R1PP/5R1K w - - bm Rxf6; id "IQ.1018"; +r1b3k1/1pp1q1p1/1r5p/2nPpp2/p1P1p2P/2N1P3/PPQRBPP1/2K4R b - - bm Nb3+; id "IQ.1019"; +r4rk1/1nqb1pbn/6pB/pppPp2p/8/1PP2NNP/P1BQ2P1/R4RK1 w - - bm Nxh5; id "IQ.1020"; +2r1qrk1/3n3p/b3pPp1/4P3/1pp1nBN1/pP4PQ/P1P2PK1/3RR3 w - - bm Qxh7+; id "IQ.1021"; +r1r2k2/1q1n1p2/3PpPp1/4P2p/pbpN3R/2N3K1/1P2Q2P/3R4 w - - bm Rxh5; id "IQ.1022"; +6k1/1p3r1p/r2q1Pp1/2p1n1P1/p1PpP3/P2P2Q1/1P4B1/4RRK1 w - - bm Rf5; id "IQ.1023"; +6k1/r1qn2np/3pp3/2pB2P1/2P3PN/1PQ1R1KP/r7/4R3 b - - am exd5; id "IQ.1024"; +4r3/5pk1/2Q2n2/3B2pp/2b2q2/P6P/6P1/R2R2K1 b - - bm Ng4; id "IQ.1025"; +4rrk1/1b3p1p/pp2p1p1/2qnN1Pn/3N1P2/2P4R/PPB1Q2P/5RK1 w - - bm Rxh5; id "IQ.1026"; +5rk1/p1q1ppb1/3p2p1/3P1bBp/1pr4P/5PN1/PPPQ2P1/1KR4R b - - bm Bc3; id "IQ.1027"; +2kq4/ppp2p2/2np1Ppb/3Np3/1PPNP1n1/3P2P1/P6r/R2Q1RK1 b - - bm Be3+; id "IQ.1028"; +6rk/6bp/p3p1r1/3p4/4p3/2P1N1Pq/PP2QP1P/4RRK1 b - - bm Bxc3 Bf8; id "IQ.1029"; +6k1/pp3p1p/3b3r/3p3q/P2n2p1/1P1Pp1P1/1N2P1QP/2R2RK1 b - - bm Bxg3; id "IQ.1030"; +2rq1rk1/pp1bnpbp/4p1p1/3pP1N1/3P2Q1/2PB4/P4PPP/R1B1R1K1 w - - bm Nxh7; id "IQ.1031"; +3qr1k1/4r1pp/2pp1p2/p1p2P2/2PnPNPP/1P1Q4/P5R1/4R1K1 b - - bm d5; id "IQ.1032"; +7r/4q1k1/1p1p1ppr/p1nRp3/P1P1P1BP/1P4P1/2Q3K1/3R4 b - - bm f5; id "IQ.1033"; +r2qrnk1/1b2bppp/2p5/1p1pN1Pn/p2P1B2/3BP2P/PPQ2P2/2K3RR w - - bm Bxh7+; id "IQ.1034"; +3r2k1/2nqprb1/1p2p1Np/p2nP3/3pBP2/PP4RQ/1B5P/6RK w - - bm Nf8 Nh8; id "IQ.1035"; +r4rk1/pppq2pp/1nbpp3/6B1/2PP2P1/3B3P/P1P2P2/1R1QR1K1 w - - bm d5; id "IQ.1036"; +1k1r3r/1pp2p2/3b4/4n1p1/N3q1P1/1B2B3/PPP2RP1/4RQK1 b - - bm Rh1+; id "IQ.1037"; +r1r1q2k/pp3pbp/4p3/2npPp1Q/3P1P1N/2P2RR1/P1P3PP/6K1 w - - bm Rxg7; id "IQ.1038"; +r3r1k1/pp1q1p2/6pp/3N4/3b4/1Q3PPb/PP3R1P/1B1R2K1 b - - bm Re2; id "IQ.1039"; +r4r1k/pbpq1p1B/1p2pp2/8/1b1P2Q1/8/PPP2PPP/2KR3R w - - bm d5; id "IQ.1040"; +4rrk1/1p3p1p/p5pb/3P4/2Pp3q/N6P/PPQ1BP1P/R3K2R b KQ - bm d3; id "IQ.1041"; +2R5/r3b1k1/p2p4/P1pPp2p/6q1/2P2N1r/4Q1P1/5RK1 w - - bm Nxe5; id "IQ.1042"; +rq6/1r1k4/1pRp1p1p/1P1Pp1pP/p1R1P1P1/PpQ2P2/1K6/8 w - - bm f4; id "IQ.1043"; +2rq4/p2n1pk1/4b1r1/2pNp1p1/BpP1Pn2/3PQPP1/PR6/1R2B1K1 b - - bm Qh8; id "IQ.1044"; +5r1k/Rb4r1/3Q4/1p1q3p/1B1b3P/P4P2/1P4P1/3R3K b - - bm Rxf3; id "IQ.1045"; +r3k2r/pp1b1p1p/1q5b/3np3/3P3N/2PB4/PPQ1NKPP/R3R3 b kq - bm Qf6+ Ne3; id "IQ.1046"; +2q3k1/1p3pp1/4rbn1/r1pp1Np1/p2P4/4PN1R/PPQ2PP1/2K4R w - - bm Ne7+; id "IQ.1047"; +5bk1/5p1p/Q5p1/1B4n1/8/2q1p3/6PP/3R2K1 b - - bm e2; id "IQ.1048"; +r2q1rnk/1p1bb1pp/p2p4/3NP1P1/P2Bp3/3Q3R/1PP1B2P/6RK w - - bm Rxh7+ e6; id "IQ.1049"; +5rk1/pb1rqp1p/1p4p1/2p1P1n1/5P2/1P2Q1P1/PB4BP/2R2RK1 b - - bm Bxg2; id "IQ.1050"; +4r3/pbrq1p1k/1p3Bpp/3pPn2/5PQ1/P6R/1P4PP/1B3RK1 w - - bm Rh5 Qg5; id "IQ.1051"; +r1bn1r2/1pp3k1/p2p3p/6p1/2qNB3/2P2PP1/P1Q2KP1/1R5R w - - bm Rxh6; id "IQ.1052"; +r4rk1/pp3pbp/3Qbnp1/q1p5/4P1P1/2N1BP2/PPP4P/2KR1B1R b - - bm Nxe4; id "IQ.1053"; +r4rk1/3bpp1p/pqp3p1/4P2n/2B5/1P6/PBPbQ1PP/4RR1K w - - bm e6; id "IQ.1054"; +7r/pQ6/2R1bk2/3q4/3P1n2/5N2/P4PrP/4RK2 b - - bm Rg1+; id "IQ.1055"; +2br1rk1/2qnQ2p/p4pp1/4p3/P1p1P1N1/2Pn1N1P/2B2PP1/1R1R1K2 w - - bm Rxd3; id "IQ.1056"; +r3qrk1/1b3p2/1p1npnp1/2b1N1N1/p1P5/P1B5/1PB1QP1P/R2R2K1 w - - bm Nd7; id "IQ.1057"; +r3nrk1/pp1q2pp/4R3/6p1/2PP4/1B3Q2/P4P1P/3R2K1 w - - bm c5; id "IQ.1058"; +r5k1/4p2p/pp1qNnp1/2pPb3/2P1p1P1/4B3/PP1Q2P1/5R1K w - - bm Bxc5; id "IQ.1059"; +r7/pp2pkbp/2pq2p1/8/2P2N2/1P2R1PP/P3QPK1/8 w - - bm c5; id "IQ.1060"; +2krb2r/p1q5/np2pPpp/n2pP3/2pP2P1/2P1N1B1/2P1Q1BK/RR6 w - - bm Nxd5; id "IQ.1061"; +r3r1k1/pbp3pp/1p1pNn2/3P1p2/2P2PqP/B1PQP1P1/P6K/4RR2 b - - bm Rxe6 Ne4; id "IQ.1062"; +r7/1pqbr1pk/p1n4p/5p1P/2P1p3/2B3R1/PP1Q1PP1/1B2R1K1 w - - bm Rxe4; id "IQ.1063"; +2rq1r2/pb4k1/1p1p1p1p/n1pP1RpQ/2P1P2B/P1PB4/6PP/R5K1 w - - bm e5; id "IQ.1064"; +r1r3k1/1p1b1nq1/6p1/pN1p4/P2Np2R/1P2P3/1Q3PP1/1K5R w - - bm Nd6; id "IQ.1065"; +r2b2k1/1p3ppp/4b3/2B1p3/1n2P1n1/pPNB4/P1PN2PP/R5K1 b - - bm Nxd3 Ba5; id "IQ.1066"; +5Bk1/pr2pp1p/2b3pQ/2p1q3/8/2P4P/PP4P1/1B1Rb1K1 w - - bm Bg7; id "IQ.1067"; +5qk1/2p2r1p/p1p4P/1p6/3P4/1Q6/P1P3P1/5RK1 w - - bm Qg3+; id "IQ.1068"; +r2r3k/ppq3pp/2p1n3/4NQ2/3P4/1B6/PP3PPP/6K1 w - - bm Ng6+; id "IQ.1069"; +4rr1k/ppp3pp/3bBqb1/3P4/3Pn1PP/4BN2/PP3PK1/R2Q1R2 b - - bm Rxe6; id "IQ.1070"; +r3b1rk/1p1qn1p1/p3p1np/3pPpBQ/3P4/3B1N1P/PP3PP1/2R2RK1 w - - bm Bf6; id "IQ.1071"; +r2q1rk1/pb2Bppp/4p3/1p6/2pnP1n1/6N1/PPPN2PP/R1Q1RBK1 b - - bm Qb6; id "IQ.1072"; +6k1/5qp1/pN5p/3pRp2/3QnP2/2r4P/r5P1/6RK b - - bm Qh5 Nf2+; id "IQ.1073"; +2b2rk1/pp2R1bp/1qpp2p1/6N1/2P2PP1/3Q1B2/PP4PK/8 w - - bm Bd5+; id "IQ.1074"; +1q3rnk/5p2/3p1P1p/p3n3/Np1r2P1/1P1B4/1PP4Q/1K1R3R w - - bm Qxh6+; id "IQ.1075"; +2r3k1/1rq2p1p/pp1p1bp1/2pP2N1/2P1R3/1Q6/PP3PP1/4R1K1 w - - bm Nxh7; id "IQ.1076"; +3r3k/p5qp/bp2B1p1/n2P1p2/5N2/Q1R5/P4PPP/6K1 w - - bm Qb2; id "IQ.1077"; +r4qk1/1b3rpp/1pn1p3/p1b5/2P5/2NQ1N2/PP2BPPP/3R1RK1 b - - bm Ne5; id "IQ.1078"; +4r1kb/5p1p/6pB/3Np3/4n3/P3Q1PP/2q2P2/R5K1 w - - bm Rc1; id "IQ.1079"; +2r1r1k1/pp1b1ppp/1q6/3P4/7N/Pn1Q4/1P3PPP/1RB2RK1 b - - bm Nxc1; id "IQ.1080"; +4k3/pp2pp2/4n1p1/3RP1P1/2r1N3/P1P5/1P2q3/1K5Q w - - bm Nc5; id "IQ.1081"; +5rk1/1b3p1p/4pb2/2p1N2Q/1pP2p2/1P1R3P/qB3PP1/6K1 w - - bm Rd8; id "IQ.1082"; +5r1k/pb2r1bp/1p2B1p1/n7/4qNQ1/4B3/P4PPP/2RR2K1 w - - bm Rd4; id "IQ.1083"; +4r1k1/pb4p1/1pq2nQp/8/2PB1P1R/3Br3/P5PP/3R2K1 b - - bm Rxd3; id "IQ.1084"; +k1n1r3/p2R2bb/2p2qpp/4pp2/2P5/2B1Q1P1/PP3PBP/6K1 w - - bm Qc5 Bxe5; id "IQ.1085"; +rr4k1/3nbp1p/p3p1p1/q2pPPP1/bp1B3R/1B2Q3/PPP4P/2K3R1 w - - bm fxe6; id "IQ.1086"; +7k/p2rq2p/1p3R1P/2p5/2P2P1Q/8/6PK/8 w - - bm Qe1; id "IQ.1087"; +5rk1/6b1/1Q5p/2pNp1p1/2P1P2n/P6q/4nPRP/B5RK b - - bm Qf3; id "IQ.1088"; +b1R2nk1/5ppp/1p3n2/5N2/1b2p3/1P2BP2/q3BQPP/6K1 w - - bm Bc5; id "IQ.1089"; +6k1/1p3ppp/1PbNp3/3rP1q1/2Q5/8/5PPP/1R4K1 w - - bm Qxc6; id "IQ.1090"; +5rk1/5pp1/3b4/1pp2qB1/4R2Q/1BPn4/1P3PPP/6K1 b - - bm Bf4 Ra8; id "IQ.1091"; +3r2k1/pqrP1p1p/6p1/1p6/n2Qp3/B1P1P3/P5PP/3R1RK1 w - - bm Qf6 Bf8; id "IQ.1092"; +4rrk1/4Qppp/p2P1n2/1p6/3p4/PB6/1PP3Pq/1K1RR3 w - - bm Bxf7+; id "IQ.1093"; +5rk1/p1Q2p1p/6p1/1P3q2/P2PNn2/R4P2/4rP1P/5R1K b - - bm Rc8; id "IQ.1094"; +3r2k1/p1rq1pp1/1pR1p2p/8/Q2P4/4P3/P4PPP/2R3K1 b - - bm Rdc8; id "IQ.1095"; +2b1r1k1/1r1n1pp1/q2p3p/1p1P4/1P1N1RPP/2Q1P3/5PBK/2R5 w - - bm Qxc8; id "IQ.1096"; +b1n1r1k1/2q2p1p/p4Pp1/1pBP4/4B1P1/2P1Q3/P4K1P/4R3 w - - bm Qh6 Kg2; id "IQ.1097"; +3r1rk1/1p1bbp1p/pq1Npp2/2P5/8/1N2P3/nP1QBPPP/2RR2K1 b - - bm Qxb3; id "IQ.1098"; +4r1k1/p4ppp/1p2q3/n2R4/2r1p3/Pn2B1P1/1Q2PPBP/3R2K1 w - - bm Re5; id "IQ.1099"; +rnb3k1/6pp/p4q2/3p1N2/1p3Q2/1P6/1PP3PP/5R1K w - - bm Nh6+; id "IQ.1100"; +r1b2r1k/2q2pp1/2pb3p/p1n1NB2/1pP5/1P5P/PBQ2PP1/3RR1K1 w - - bm Rxd6; id "IQ.1101"; +6k1/1Q3p2/p4qp1/4p3/1P6/8/P3n1RP/5rRK b - - bm Nxg1 Qf2; id "IQ.1102"; +2k1r2r/2p2pb1/1pN4p/1P2P1p1/R1N5/2n5/5PPP/3R2K1 w - - bm Ra8+; id "IQ.1103"; +3r4/5pkp/B5p1/PPn1p3/2P1P3/4qP1P/1Q4P1/4NK2 b - - bm Rd2; id "IQ.1104"; +8/6kp/8/5r2/1QP1q3/1P3pP1/P3rP1P/5RKB b - - bm Rxf2; id "IQ.1105"; +1q4r1/3Q1Npk/p6p/1p5N/8/7P/Pn3PP1/6K1 w - - bm Qf5+; id "IQ.1106"; +r3r1k1/p1p3pp/2p3q1/8/2P2Rb1/1N6/PP4PP/1Q2R1K1 b - - bm Re2; id "IQ.1107"; +r1q1r1k1/p1n1R1bp/1pp2pp1/5b2/2P2P1Q/P4NN1/1P1B2PP/2KR4 w - - bm Nxf5; id "IQ.1108"; +r1b1k2r/pp1pppbp/2n2np1/8/1q1NP3/1BN1B3/PPP2PPP/R2Q1RK1 b kq - am Nxe4; id "IQ.1109"; +2r1k2r/1p2pp1p/2bp1p1b/p1qN4/4P3/6Q1/PPPR1PPP/1K3B1R w k - bm Qh3; id "IQ.1110"; +r3k2r/2pn1pp1/p1p2qb1/Np2P1b1/6P1/3P2B1/PPP2P2/RN1Q1RK1 b kq - bm Nxe5; id "IQ.1111"; +r1br2k1/1pq2ppp/p3pP2/8/1n3PP1/1NpB4/PPP2Q1P/2KR2R1 w - - bm Bxh7+; id "IQ.1112"; +5k2/1pp2b1p/2p5/r3PPR1/pr6/2N5/1PP4P/2KR4 w - - bm f6; id "IQ.1113"; +r1b5/p2k1r1p/3P2pP/1ppR4/2P2p2/2P5/P1B4P/4R1K1 w - - bm Bxg6; id "IQ.1114"; +8/5p1p/6p1/3P4/1k3P2/pp1B2P1/7P/1K6 b - - bm Kc3; id "IQ.1115"; +4k2r/1q3p2/1pn1p1p1/p2pP1Bp/1p1P3P/3P4/P1R2PP1/2Q3K1 b - - bm Nxd4; id "IQ.1116"; +8/8/pp1pPkpp/3P4/2P1K1P1/8/P7/8 w - - bm g5+; id "IQ.1117"; +6k1/6p1/7p/8/pb5N/2B1p2P/PP4P1/3K1b2 b - - bm e2+; id "IQ.1118"; +8/1R6/3k2P1/4b3/8/P1pB4/2Kn1p2/8 b - - bm Nf3; id "IQ.1119"; +r1bq1rk1/5pbp/pB1p1np1/3Pp3/4P3/2p1QP2/PP4PP/1KNR1B1R b - - bm Rb8; id "IQ.1120"; +7r/8/3p1p1r/p1kP2p1/Pp2P1P1/1PpR3P/5R1K/8 b - - bm Re8; id "IQ.1121"; +6k1/p4pp1/Pp2r3/1QPq3p/8/6P1/2P2P1P/1R4K1 w - - bm cxb6; id "IQ.1122"; +5b2/pr4pk/4P1Rp/1pppBPP1/8/1P2P3/P6K/8 w - - bm Rxh6+ gxh6; id "IQ.1123"; +7r/1pR5/p5k1/3p4/4n1np/8/PPP3PP/5R1K b - - bm Ng3+; id "IQ.1124"; +8/kp6/4R3/1P2K3/8/3pp3/8/8 w - - bm Kd6; id "IQ.1125"; +5rk1/2rnqp1p/b3p1pP/2ppP3/1p3QN1/pP1P1BP1/P1P2P2/R3R1K1 w - - bm Bxd5; id "IQ.1126"; +5r1k/p5bp/1p6/4P3/P2B4/3n2PB/1PR4K/8 w - - bm e6; id "IQ.1127"; +4R3/5Bq1/7p/5p2/1n3k1B/7P/6PK/8 w - - bm g3+; id "IQ.1128"; +8/8/8/P2k1p2/2N5/1pb2P2/4P3/2K5 w - - bm a6; id "IQ.1129"; +1r1q1rk1/Nb1n1pbp/p5p1/3P4/PPB2p2/4B3/6PP/2RQ1RK1 w - - bm Nc6; id "IQ.1130"; +b2rr1k1/P3pp2/3p2p1/1Q1Pb2p/2P4P/1R2B1P1/4qPBK/1R6 w - - bm Qxe8+; id "IQ.1131"; +8/5pk1/3P2p1/pQ6/P2p4/5pP1/3rqP1P/5RK1 w - - bm d7; id "IQ.1132"; +3n4/8/1P6/4k2P/n2p4/4pB2/1B6/3K4 w - - bm Bxd4+; id "IQ.1133"; +2r3k1/4qpp1/4bn1p/1p6/2PpP3/1N5P/2Q1BPP1/3R2K1 b - - bm d3; id "IQ.1134"; +2r2rk1/4p2p/bq1P2p1/p4p2/3R1P1B/2N5/P2Qp1PP/6K1 b - - bm Rxc3; id "IQ.1135"; +8/1Rb2r1k/6p1/6qp/4QP2/3p3K/7P/3B4 b - - bm Rxf4; id "IQ.1136"; +8/1p3b2/8/p1b1pN2/P1P1P1p1/1P6/6Bk/5K2 b - - bm b5; id "IQ.1137"; +8/8/8/pPk3pp/2P1p3/1pK3P1/5PP1/8 b - - bm g4; id "IQ.1138"; +8/5p1p/1n2p2P/1k1pPpP1/3K4/4N3/2P5/8 w - - bm Nxf5; id "IQ.1139"; +8/1p1b4/4p1k1/1PPp4/P4P1p/4n1p1/8/4BBK1 w - - bm a5; id "IQ.1140"; +2r1rbk1/1b1n1ppp/4p3/qB1pP3/pp1N1PP1/8/PPPQ3P/3RR1BK b - - bm Qxb5; id "IQ.1141"; +2q1n1kr/6b1/1r1p2B1/2p2pP1/2P1bP1N/1P1QB2P/6RK/1R6 w - - bm Qxe4; id "IQ.1142"; +5brk/2q2p1p/p3pP1B/4Pp2/8/1P1R1Q1K/P6P/8 w - - bm Bxf8; id "IQ.1143"; +1q4rk/6r1/2RP3p/1NR3p1/p3Qn2/P6P/6P1/6K1 w - - bm d7; id "IQ.1144"; +r3k2r/1nqb1pp1/p3p3/1p1pP1P1/3R1P2/2N2Q2/PPP3B1/2KR4 w kq - bm Nxd5; id "IQ.1145"; +1r2r1k1/p1p2p1p/6p1/8/8/4NBPb/qBQ2K1P/1R6 b - - bm Rxe3; id "IQ.1146"; +2r3k1/pp2r1pp/8/2b1Bp2/5P2/1PPpP1R1/6PP/R5K1 b - - bm Rxe5; id "IQ.1147"; +r4r1k/6pp/3p3b/1p1Npb2/3nB2q/2N3P1/PP3P1P/R2Q1RK1 b - - bm Qxe4; id "IQ.1148"; +r2r4/pp3p2/4bkpp/8/7P/3B1P2/PP4P1/1K1R3R b - - bm Rxd3; id "IQ.1149"; +8/r4p2/6p1/1pknP2p/2p1b3/P1P2N2/2BK2PP/R7 b - - bm Nxc3 Bxc2; id "IQ.1150"; +6R1/5p1p/4pN1k/4P1p1/3qQ3/7P/3r2P1/7K b - - bm Rd1+; id "IQ.1151"; +8/3R3p/6rk/2PP4/7p/6P1/5QKP/1q6 b - - bm h3+; id "IQ.1152"; +1r6/R7/5p1k/5Qp1/4n1B1/4P2P/2q2PP1/6K1 b - - bm Rb1+; id "IQ.1153"; +8/1b6/p2k2P1/2Rp1B2/PKp5/2P5/6r1/8 w - - bm Bc8; id "IQ.1154"; +3k4/p1p5/8/2p1p3/4P3/PpPP2K1/1P6/8 b - - bm c4; id "IQ.1155"; +r7/1p3k1p/3RRp1P/1qr1p1p1/4P1P1/P3QP2/1P6/1K6 b - - bm Qf1+; id "IQ.1156"; +2r5/1p6/pq2p2p/3rN3/k2P2Q1/3R2P1/1P3PP1/1K6 b - - bm Qxb2+ Qd6; id "IQ.1157"; +3rr1k1/1p2bpp1/2ppq2p/p1n5/2P4P/1PN1P1P1/PBQR1PK1/2R5 b - - bm Bxh4 Bf6; id "IQ.1158"; +6k1/6p1/6Kp/3PR3/q7/6P1/4QP1P/3r4 b - - bm Re1; id "IQ.1159"; +k5r1/p5Qp/8/3q4/8/8/P4NPP/1R4K1 w - - bm Rb5; id "IQ.1160"; +1r4k1/2R2pp1/1P2r2p/q2pP3/4n3/1R1B3P/1Q4PK/8 b - - am Rexb6; id "IQ.1163"; +4n3/p3kppp/Rb6/P3p3/1P6/5P2/4K1PP/8 b - - am Nc7; id "IQ.1164"; +r1b1k1nr/ppq2ppp/2n1p3/3pP3/3P4/P2B1N2/2P2PPP/R1BQK2R b - - am Nxd4; id "IQ.1165"; +6r1/4kp2/p1bRpp1b/1pr1P3/5P1p/PBP1N3/1P4PP/1K1R4 b - - am Bxf4; id "IQ.1166"; +3k2r1/5p2/5R2/2pB1p2/2P1p3/2P1P1r1/4PK2/8 b - - am Rg1; id "IQ.1168"; +2rr2k1/1b4p1/2q4p/p4p2/5b2/2BB4/P1Q3PP/3RR1K1 b - - am Qxc3; id "IQ.1169"; +rnb2r1k/pp2ppbp/2pp1np1/q2P4/2P5/1PN2NP1/PB2PPBP/R2Q1RK1 b - - am Nxd5; id "IQ.1170"; +r7/p1pb2pp/kp1P4/4p3/PQN1q3/2P5/6PP/1R5K b - - am cxd6; id "IQ.1171"; +r1b1k2r/p1p1nppp/2p5/3q4/8/1P4P1/P1P1QK1P/RNB1R3 b kq - am O-O; id "IQ.1172"; +5r1k/1bp2ppp/1pNnp3/1P5q/R5n1/4PNP1/2QPBP1P/6K1 b - - am Nxh2; id "IQ.1173"; +3r2k1/pp2qppp/4bn2/4p3/4P3/P1Nr4/1PQN1PPP/R4RK1 w - - am Nd5; id "IQ.1175"; +4rb1k/1p4r1/2p5/p2q3p/3B1P2/P2Q2R1/5K2/6R1 b - - am Bc5; id "IQ.1178"; +r2q1rk1/3nbppp/p1bpp3/6PQ/1p1BP3/1BN5/PPP2P1P/2KR2R1 w - - bm Rd3; id "IQ.1179"; +r3r1k1/1pq2pp1/p2pbb1p/P3n3/3NP3/2N5/1PP1B1PP/R2Q1R1K w - - bm Rxf6; id "IQ.1180"; +2kr3r/pppqbpp1/2n3n1/4P2p/2Pp3P/PP3NPb/1B1NPPB1/2RQ1RK1 b - - bm Bxh4; id "IQ.1181"; +1rb1r1k1/3n1ppp/p1p1p3/q3P3/7P/2N1Q1R1/PPP3P1/2KR1B2 w - - bm Rxd7; id "IQ.1182"; +r2q1rk1/pp1n1p1p/2p2np1/4bQB1/3pNP2/1B5P/PP4P1/R3R1K1 w - - bm Qxe5; id "IQ.1183"; +2rnr2k/2qbp3/pp1p2p1/3P1p1p/1PPN1P2/5B1P/P2Q2P1/2R1R1K1 w - - bm Bxh5; id "IQ.1184"; +2r1r3/3qppkp/pp1p2p1/3PnP2/2PN4/1P5P/P2Q2P1/4RRK1 w - - bm Rxe5; id "IQ.1185"; +1n2rk2/1qr1pp2/pp1p1npp/3P4/1PPN1P2/P2QR1P1/7P/4RBK1 w - - bm Ne6+; id "IQ.1186"; +1r1r1n2/5pkp/4pNp1/2PpP1P1/p1bP1PP1/1qB1K3/p2Q4/3R3R w - - bm f5; id "IQ.1187"; +r4rk1/pp2qppp/2pb1nb1/4n3/2P1p3/1PN1P2P/PBQRBPP1/3R1NK1 b - - bm Nf3+; id "IQ.1188"; +3r2k1/3rppb1/p1R1b1p1/qp1NP3/8/1P2QB2/P5PP/5RK1 w - - bm Rxe6; id "IQ.1190"; +r2qnrk1/pp2ppb1/3p3B/2p5/7Q/1PNP3b/1PP3PP/R4RK1 w - - bm Ne4; id "IQ.1191"; +r4bk1/pbq2pp1/1pn1p2p/8/4N3/1P2P1P1/PB2QPBP/3R2K1 w - - bm Nf6+; id "IQ.1192"; +r2r2k1/pp3ppp/2p1bn2/7q/NbP3P1/1P2B2P/PQ3PB1/R4RK1 b - - bm Bxg4; id "IQ.1194"; +rq2r1k1/pp2RNp1/1bp2n1p/8/1Q6/7P/PPB2PP1/5RK1 w - - bm Nxh6+; id "IQ.1195"; +r4rk1/p1p2pp1/1bp1b2p/3q2B1/Pn1PN3/5N2/1P1Q1PPP/R3R1K1 w - - bm Bxh6 Be7; id "IQ.1196"; +Q1b1r3/1p3pbk/1p3npp/7q/1BPpp1P1/1P5P/P3PPB1/R3R1K1 b - - bm Bxg4; id "IQ.1197"; +r1b2rk1/2q1bppp/p2pp3/2n3PQ/1p1BP3/1BN5/PPP2P1P/2KR2R1 w - - bm Bf6; id "IQ.1198"; +r3k2r/1bqnBppp/p3p3/1p2P3/3N2Q1/3B4/PPP3PP/2KnR3 w kq - bm Nxe6; id "IQ.1199"; +r1bqkn1r/p3bpp1/1p2pn1p/2pPN1B1/2P5/3B2N1/PP3PPP/R2QR1K1 w kq - bm Nf5 Nh5 dxe6; id "IQ.1200"; +r3kb1r/2q2ppp/pn2p3/4P3/pPPN4/P3BQ2/6PP/R4RK1 w kq - bm Nxe6 Rf2 Rad1; id "IQ.1201"; +r4k1r/pp3pb1/2p3p1/3nNb1q/7p/1BB1Q2P/PP3PP1/3RR1K1 w - - bm Rxd5 Bxd5 Qc5+; id "IQ.1202"; +4k1r1/1q1r1p2/4pQp1/3pP1B1/2p3P1/1nP2BP1/1P5K/3R4 w - - bm Bxd5; id "IQ.1203"; +2kr2r1/Qpq2p1p/1n2p3/2b2p2/8/2B2PP1/PPPN3P/R3K2R b - - bm Rxd2 Rxg3; id "IQ.1204"; +2b2k1r/5ppp/1b6/q1p1PP2/3Np1Q1/1PP5/6PP/1N3RK1 w - - bm Ne6+; id "IQ.1205"; +1r5r/p2bbk1p/4pnp1/q1ppQ1B1/7P/2N3P1/PPP2PB1/1K1R3R w - - bm Nxd5; id "IQ.1206"; +r2qk2r/1b1n1p2/p6n/1pp1p1Np/4P2P/2QBNP2/PPP5/2KR2R1 w kq - bm Bxb5 Bc4 Bf1; id "IQ.1210"; +rn1qk2r/pbp2p2/1p3ppb/7p/2BP1N1P/2N1P3/PP3PP1/R2QK2R w KQkq - bm Bxf7+; id "IQ.1211"; +r1b2k1r/p2n1pp1/1q2p3/2ppP1B1/1b1N1Q1P/2N5/PPP2P2/R3K1R1 w Q - bm Bd8; id "IQ.1212"; +r4b1r/pp3kpp/1qp1Rn2/8/8/5Q1P/PPPB1PP1/2KR4 w - - bm Rxf6+; id "IQ.1213"; +7r/1Qrk1pbp/p2pp1p1/6P1/5PB1/1P6/q1P4P/2KR2BR w - - bm Rxd6+; id "IQ.1214"; +r3k2r/2pb1npp/ppp5/2q1p3/2N1P3/1QP2N1P/PP3PP1/R2R2K1 w kq - bm Rxd7 Qb4; id "IQ.1215"; +r3kb1r/pp3p1p/4pp2/q2pN3/2P5/8/PP3PPP/R2QR1K1 w kq - bm Nxf7; id "IQ.1216"; +r3kbnr/p4p2/1p2p2p/3qP1p1/3Nn1QB/8/PP2NPPP/R4RK1 w kq - bm Nxe6; id "IQ.1217"; +r1b1k1nr/2R1b1pp/1p2pp2/1N2p3/q3P3/3Q1N2/PP3PPP/3R2K1 w kq - bm b3 Nd6+; id "IQ.1218"; +r4r2/1b4pk/p5pp/1pb1N3/4P3/2P1N1Pq/PPB1QP2/3R2K1 b - - bm Rxf2 Rad8; id "IQ.1219"; +4r1k1/1p2qrpb/p1p4p/2Pp1p2/1Q1Rn3/PNN1P1P1/1P3PP1/3R2K1 b - - bm Nxf2; id "IQ.1221"; +r1bqr1k1/1p1nbppp/p1n1p3/3pP2Q/3N1P2/1BN1B3/PPP3PP/R4RK1 w - - bm Nxd5; id "IQ.1222"; +2r1r1k1/5ppp/pq3b2/2pB1P2/2p2B2/5Q1P/Pn3PP1/2R1R1K1 w - - bm Bxf7+; id "IQ.1223"; +rn1q1rk1/1b2bppp/p3p3/1pn1P2Q/3N4/1BN1B3/PPP3PP/R4RK1 w - - bm Rxf7; id "IQ.1224"; +2r1r3/pbq1bpk1/1pn3p1/6Bp/4Q3/PB3N2/1P3PPP/R3R1K1 w - - bm Bxf7; id "IQ.1225"; +2rq1rk1/1b3pb1/5np1/1pn1p1Np/4P2Q/2N1B3/BPP3PP/R4R1K w - - bm Nxf7; id "IQ.1226"; +4r3/p2qppkp/3p2b1/1p1N4/2r1P1RQ/2P4P/PP4P1/5RK1 w - - bm Rxg6+; id "IQ.1227"; +6k1/3q2pp/b3pp2/p3n3/2rbP3/2B3P1/P1Q1NPBP/2R3K1 b - - bm Bxf2+ Nd3; id "IQ.1228"; +r1bq1rk1/pp2ppbp/2p2np1/3p4/2PPn3/1PN3P1/PBQNPPBP/R3K2R b KQ - bm Nxf2; id "IQ.1229"; +r5k1/1p3p1p/p1pqrPp1/3bN3/8/P1P3Q1/1P4PP/4RRK1 w - - bm Nxf7; id "IQ.1231"; +rnb2rk1/pp3p1p/3q2pQ/3pN3/2pP4/2PB4/P1P2PPP/4RRK1 w - - bm Nxf7; id "IQ.1232"; +r2r1bk1/1ppq2pp/2p2B2/p1n2N1b/P3P1R1/3PN3/2P3PP/R2Q2K1 w - - bm Ne7+; id "IQ.1233"; +2q5/1b2Q3/1p3pkp/4p1p1/3n4/4N2P/5PP1/4R1K1 b - - bm Bxg2; id "IQ.1234"; +r4rk1/pp2bpp1/1qp1b2p/4B2Q/n7/3B4/PPP2PPP/3RR1K1 w - - bm Bxg7; id "IQ.1236"; +6rk/pp4rp/4pq2/1PPpNp1b/P2Pn3/2NQ4/2R3PP/4R1K1 b - - bm Rxg2+; id "IQ.1237"; +5Q2/pp1b2pk/1n1p2rp/2pP1p2/2P2P2/q1BB4/6PP/4R1K1 w - - bm Bxg7; id "IQ.1238"; +8/1p4pk/6rp/p1q1pr2/2P1b3/P1Q1P3/1B2R1PP/2R3K1 b - - bm Bxg2; id "IQ.1239"; +1nb2r1k/2r1qppp/p3p2n/1p1BP3/3N1Q2/2N5/PPP4P/2KR2R1 w - - bm Rxg7; id "IQ.1240"; +r3k3/2pb1p1p/p2p4/6rq/4P3/2P5/PP1Q1PP1/R3RNK1 b q - bm Rxg2+; id "IQ.1241"; +2q3k1/3b1p2/1b1p3p/1p1Pp1p1/1P2Pn2/QN3P2/2r3PP/1R2BB1K b - - bm Rxg2; id "IQ.1242"; +2q3k1/1p3pp1/6rp/p1BP4/5b2/P4P1b/BPQ1R1P1/7K b - - bm Bxg2+; id "IQ.1243"; +r1b2k1r/1p4pp/p4B2/2bpN3/8/q2n4/P1P2PPP/1R1QR1K1 w - - bm Bxg7+ Qh5; id "IQ.1244"; +1r3r1k/1b2bppp/p1qp4/5PP1/1p1B3Q/1PN2R2/1PP4P/5RK1 w - - bm Bxg7+; id "IQ.1245"; +r2b1rk1/2q2ppp/p3b3/1pn1pNB1/4Pn1Q/P1NB4/1PP3PP/R4R1K w - - bm Nxg7; id "IQ.1246"; +6k1/5rpp/8/2Np4/1Pn3R1/4Q2P/q2r1PP1/5RK1 w - - bm Qe8+; id "IQ.1247"; +r4rk1/1bpq1ppp/3p1b2/2nP1N2/8/1p3Q1P/PPB2PP1/R1B1R1K1 w - - bm Nxg7; id "IQ.1248"; +r2q1rk1/pp1b1Rp1/4p2p/4PnNQ/2pP4/2P1B3/P5PP/5RK1 w - - bm R1xf5; id "IQ.1249"; +r4r1k/pbq2pp1/1p2p2p/4P3/2pP3Q/P1P3RP/R4P1P/1B4K1 w - - bm Rxg7; id "IQ.1250"; +2r2bk1/1bq1rppp/pp1p4/4n1P1/Pn1BP1N1/2N3Q1/1PP2RBP/5RK1 w - - bm Bxe5; id "IQ.1251"; +r1b2rk1/pppn2bp/3p1qp1/3p2N1/3P4/3BB3/PPP2PPP/R2QR1K1 w - - bm Nxh7; id "IQ.1252"; +rnb3kr/1p1nqppp/p3p3/2ppP3/3P1N2/2NB1Q2/PPP2PP1/R3K2R w KQ - bm Bxh7+; id "IQ.1253"; +r1qr2k1/p3bppp/b1p5/3nN3/NP1P4/P3B3/5PPP/1B1QR1K1 w - - bm Bxh7+; id "IQ.1254"; +3r1rk1/1bq1bp1p/p3p1p1/3pP3/3N1P2/2PBB2R/n1P1Q1PP/5RK1 w - - bm Rxh7; id "IQ.1255"; +r1qb1rk1/5ppp/p1n5/1ppNP1P1/2p2P1P/P4Q2/1P6/1B1R1RK1 w - - bm Bxh7+; id "IQ.1256"; +2r1r1k1/pbq2ppp/1p2pn2/2b1N3/2P5/2B5/PPB1QPPP/3RR1K1 w - - bm Bxh7+; id "IQ.1257"; +1q1r2k1/pb2b1pp/1p3p2/3P4/1n1QB3/5N2/PB3PPP/2R4K w - - bm Bxh7+; id "IQ.1258"; +2kr3r/pp1b1p2/1qn1pb2/2p5/4Q3/5N1B/PPP2PPP/R1B2RK1 b - - bm Rxh3; id "IQ.1259"; +2r5/3nr1pk/p2qpp1p/1p5Q/3P1PN1/2P3RP/P5PK/4R3 w - - bm Nxh6; id "IQ.1260"; +r1q2r1k/p1ppb1p1/1p2p1Qp/3n3P/3PN3/2P1B3/PP3PP1/3R1RK1 w - - bm Bxh6; id "IQ.1261"; +r2qrn2/1p2nbkp/2p1pp2/p7/3PP1BN/2N4R/PP1Q1P2/2KR4 w - - bm Qh6+; id "IQ.1262"; +r4rk1/pp2qpp1/2p1bn1p/8/1bP4Q/5N1P/PPB2PP1/R1BR2K1 w - - bm Bxh6; id "IQ.1263"; +2r5/1p4bk/3p2rp/4pN2/1P2P1pR/2P2q2/QP6/1K5R w - - bm Rxh6+; id "IQ.1264"; +2r2rk1/1bq1bpp1/pn2p2p/1pn3P1/3NNP1Q/P6R/1PP3BP/R1B4K w - - bm Nf6+; id "IQ.1265"; +4rb2/1p1q1ppk/p1n1p2p/2p1Pn2/3PNR2/2P2K2/P2QBP2/6R1 w - - bm Rxf5; id "IQ.1266"; +r6r/pb1R1pk1/1p2p1pp/3nP3/4N2Q/4B3/P3qPPP/3R2K1 w - - bm Bxh6+; id "IQ.1267"; +rq1n1bk1/3b1pp1/3p3p/pppP3N/8/1P4PP/PBPQ1PB1/4R1K1 w - - bm Qxh6; id "IQ.1268"; +2rq1rk1/pp3pp1/4pb1p/3bN3/3P4/PnPB3R/2Q2PPP/R1B3K1 w - - bm Bh7+; id "IQ.1269"; +2r2rk1/p1n3pp/1p2p3/1q1pQP2/3Pn3/6N1/PP4PP/R1B2RK1 w - - bm Bh6; id "IQ.1270"; +4rr1k/pp4b1/4P2p/5p1R/3q4/3B2P1/PP1R4/1K5Q w - - bm Rxh6+; id "IQ.1271"; +1r2b3/pp1rqppk/3b3p/3Bp2Q/4P1N1/5R1P/PP3PP1/3R2K1 w - - bm Rf6; id "IQ.1272"; +r2qr3/2p1b1pk/p5pp/1p2p3/nP2P1P1/1BP2RP1/P3QPK1/R1B5 w - - bm Bxh6; id "IQ.1273"; +r2q1rk1/3nbpp1/4p2p/p1p1P3/1p1P3P/3B1b1R/PPQB1PP1/R3K3 w - - bm Bxh6; id "IQ.1274"; +r1r1n3/5p1k/1n1P2pp/ppq1pN2/2p1P3/1PP1R2P/P1B2QPK/5R2 w - - bm Nxh6; id "IQ.1275"; +r1n1nrk1/p4p1p/1q4pQ/2p1pN2/1pB1P1P1/5P2/PPP4P/1K1R3R w - - bm Rd6 Rhg1; id "IQ.1276"; +r3r3/2qn1Qbk/b2p2pp/1npP4/1p6/3NB1NP/1P1R2P1/1B2R1K1 w - - bm Qxg6+; id "IQ.1277"; +1b4k1/1pnq1r1p/4p1p1/1pPpP2Q/1P5B/3BPP2/7P/6RK w - - bm Bxg6; id "IQ.1278"; +2r2rn1/p3q1bk/n2p2pp/1b1PPp2/1pp2P1N/1P2N1P1/P1QB2BP/4RRK1 w - - bm Nxg6; id "IQ.1279"; +r2q1r1k/p3pn1p/3p2pQ/1ppP1p1n/4P3/2N2P2/PPP1BP2/2K3RR w - - bm Qxg6; id "IQ.1280"; +4Q3/p4pk1/2p3p1/8/3P1N2/4PBR1/q4P1K/r3r3 w - - bm Rxg6+ Qe5+; id "IQ.1281"; +2r1r1k1/4qpb1/p2p2p1/1p1Pn1P1/3BB3/P1P5/1P4Q1/1K2R2R w - - bm Bxg6 Qh2 Qh3; id "IQ.1282"; +3rr1k1/5p2/1p1q2pQ/p2Pb3/1pPp3P/6P1/P4P2/1R1R1BK1 b - - bm Bxg3; id "IQ.1283"; +5r2/1pr1ppk1/1n1q2p1/p2P3p/5R2/1BP1RQ2/5PP1/6K1 w - - bm Re6; id "IQ.1284"; +4rbk1/n2n3p/b1q1p1p1/1p1pP1B1/1PrP1N2/1R3NP1/3Q1PB1/R5K1 w - - bm Nxg6 Bf1; id "IQ.1285"; +2r2rk1/pp2Qp1p/3p2p1/7n/2P5/1PN3Pq/P3PP2/2R2RK1 b - - bm Nxg3; id "IQ.1286"; +r3r1k1/bpp1q1pp/p3bp2/2p4Q/4N3/1P2PP2/PB3P1P/R2R3K w - - bm Nxf6+ Rg1; id "IQ.1287"; +2r1k2r/3bbp1p/p3pp1Q/q2P4/1p3P1B/8/1PP3PP/1K1R1B1R b k - bm Rxc2; id "IQ.1288"; +2r1r1k1/5pbp/p5p1/3Pn3/3QP3/N1B5/PP4qP/1K1R3R b - - bm Rxc3; id "IQ.1289"; +r4rk1/4ppbp/1q2bnp1/n1p4P/4P1P1/2NBBP2/PP1Q4/1K1R2NR b - - bm Bxa2+ Rfb8; id "IQ.1290"; diff --git a/tests/orig/quick.epd b/tests/orig/quick.epd new file mode 100644 index 0000000..da42049 --- /dev/null +++ b/tests/orig/quick.epd @@ -0,0 +1,25 @@ +1n1r1rk1/ppq2ppp/3p2b1/3B1NP1/4PB1R/bP2P2P/P1P5/3KQ1R1 w - - bm Qc3; id Quick-01; +1q6/r4pbk/1r1p2pp/B2Pn3/Q2NP3/1p3P2/6PP/1R3RK1 b - - bm Rxa5; id Quick-02; +3Q4/3p4/P2p4/N2b4/8/4P3/5p1p/5Kbk w - - bm Qa8; id Quick-03; +4qrk1/3nppb1/R1Np2p1/3P2P1/1Pr5/4B3/5Q1P/5R1K w - - bm Ra8; id Quick-04; +r3r3/2R2pk1/p2p1bpp/3P4/q2pQ3/5N1P/5PP1/1R4K1 w - - bm Rxf7+; id Quick-05; +r1b1Rbk1/pp3p2/2npN2p/2qp2p1/8/1QPB3P/PP3PPB/6K1 b - - bm Bxe6; id Quick-06; +r5k1/Rb4p1/2q2pBp/1pp5/1b4QN/1P2P2P/5PP1/6K1 w - - bm Rxb7; id Quick-07; +3R4/5r1p/5ppk/8/1Q3PPq/5P2/6K1/8 w - - bm Rg8; id Quick-08; +2kr3r/ppp3pp/2pbbn2/4N3/3Pp3/2P3Pq/PP1NQP1P/R1B2RK1 w - - am Nxe4; id Quick-09; +2r3k1/pp1bpp1p/3p1npQ/q1r5/4P1P1/2NR1P2/PPP1N3/2K4R w - - bm g5; id Quick-10; +r1b2rk1/pp3p2/2p2bpQ/8/1q1P4/2N2N2/Pn3PPP/1B1RR1K1 w - - bm Bxg6; id Quick-11; +r2qk2r/1p1bbp2/1P2p3/p2pPp2/n2N1N1p/3PB3/5QPP/R4RK1 w kq - bm Rxa4; id Quick-12; +3r1n1r/1p2q1k1/p1p1P1p1/3n4/5Pp1/P5N1/1P3QP1/1BR1R1K1 w - - bm Bxg6;id Quick-13; +r2q1rk1/p1p3pp/b2bp3/2pp4/6p1/2NPPN2/PPP2PP1/R1BQR1K1 w - - bm Ne5; id Quick-14; +r2qr1k1/p2b1ppp/5n2/2pp4/5b2/NP6/PBP1NPPP/R3QRK1 b - - bm Bxh2+; id Quick-15; +3k4/p7/K3BP2/8/7p/8/2P4P/8 w - - bm Kb7; id Quick-16; +rq4k1/pp1nrppp/4bn2/6R1/3QP3/P4PN1/4B1PP/2B2RK1 w - - bm Rxg7+; id Quick-17; +2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - bm Qb4; id Quick-18; +5k2/6p1/2p2p2/P7/1Q6/2P1pqPP/7K/8 b - - bm c5; id Quick-19; +rnbq1b1r/ppp1p1pp/1n1p2k1/4P1N1/8/5Q2/PPPP1PPP/RNB1K2R b KQ - bm Qe8; id Quick-20; +r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - bm Bxb5+; id Quick-21; +4r2k/3n3p/2q3p1/2p1p1Q1/1pP1P3/1P6/5PP1/R2B2K1 b - - am Qxe4; id Quick-22; +r3r1k1/1Bp1qppp/3p1n2/pNb5/2P5/PQ6/1P3PPP/R2R2K1 b - - bm Ng4; id Quick-23; +3B4/1R3p1k/2p4p/2Pp3r/3P4/4Q1K1/6P1/3b1q2 w - - bm Bf6; id Quick-24; + diff --git a/tests/orig/swiss.epd b/tests/orig/swiss.epd new file mode 100644 index 0000000..19649cd --- /dev/null +++ b/tests/orig/swiss.epd @@ -0,0 +1,65 @@ +r2qkb1r/1b1n1ppp/p3pn2/1p6/3P4/1BN2N2/PP2QPPP/R1BR2K1 b kq - am b4; fmvc 11; id "ST3_01 - Entwicklung"; +rn4kr/pp2p1bp/1qpp2p1/8/3P1P2/4BN2/PPPQ2PP/R3K2R b KQ - am Qxb2; fmvc 12; id "ST3_02 - Entwicklung"; +r1bqkb1r/pppp1ppp/2n5/4P3/3pn3/2P2N2/PP2QPPP/RNB1KB1R b KQkq - am Nc5; fmvc 6; id "ST3_03 - Entwicklung"; +3r2k1/p1R1qp1p/1p2p1p1/nN6/1b3NQ1/4P1P1/P4P1P/6K1 b - - am Qf8; fmvc 26; id "ST3_04 - Koenigssicherheit"; +r2qr1k1/pp3pbp/2n3p1/1N1p4/2P2Pb1/5N2/PP1QBPPP/2KR3R w - - am cxd5; fmvc 14; id "ST3_05 - Koenigssicherheit"; +r4r1k/1pRb1p1p/p3pp1Q/8/3qP1BP/8/P4PP1/2R2K2 b - - am Kg8; fmvc 21; id "ST3_06 - Koenigssicherheit"; +2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - am O-O; fmvc 14; id "ST3_07 - Koenigssicherheit"; +rqb1k2r/1p3p1p/p1n2Pp1/3Qb3/4N3/4B3/PP2B1P1/R4R1K b kq - am O-O; fmvc 19; id "ST3_08 - Koenigssicherheit"; +r3k2r/p2n1p2/1p3n1p/q1pb2p1/8/P1PB1NB1/3Q1PPP/2R2RK1 b kq - am O-O; fmvc 18; id "ST3_09 - Koenigssicherheit"; +rnbq1rk1/ppp1bpp1/4pn1p/6B1/2pP3P/2N1P2N/PP3PP1/2RQKB1R b K - am hxg5; fmvc 8; id "ST3_10 - Trojaner"; +r1bq1rk1/pp1n1pp1/4pb1p/6B1/7P/5N2/PPPQ1PP1/2KR1B1R b - - am hxg5; fmvc 12; id "ST3_11 - Trojaner"; +2rr2k1/1b1nbppp/p1qnp3/8/Pp1BNP2/3B2N1/1PP1QRPP/3R3K b - - am Qxa4; fmvc 23; id "ST3_12 - Vergifteter Bauer"; +rnb1r1k1/pp1p1ppp/3P1n2/q7/8/2P2N2/P3BPPP/R1BQ1RK1 b - - am Qxc3; fmvc 12; id "ST3_13 - Vergifteter Bauer"; +3r1rk1/4bppp/p1pq1n2/3p1P2/4p2B/2N5/PPP1QPPP/R3R1K1 w - - am Qxa6; fmvc 16; id "ST3_14 - Vergifteter Bauer"; +r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - am Qxd4; fmvc 18; id "ST3_15 - Vergifteter Bauer"; +1r1qr1k1/4b1p1/p1np3p/2pN1Rp1/P3P2P/4B3/1PPQ4/5R1K b - h3 am Rxb2; fmvc 25; id "ST3_16 - Vergifteter Bauer"; +r3qrk1/1ppb3n/n2p4/p1bP1p1p/N1P1pP1B/PP6/3NB1PP/1RQ2R1K b - - am Bxa4; fmvc 20; id "ST3_17 - Vergifteter Bauer"; +rnb1kb1r/pp2pppp/1q1p1n2/2pP4/4PB2/2N2P2/PPP3PP/R2QKBNR b KQkq - am Qxb2; fmvc 7; id "ST3_18 - Vergifteter Bauer"; +r1bq1rk1/ppp1n1bp/3p4/3Ppnp1/2P1N3/1Q4BP/PP1NBPP1/R3K2R w KQ - am Nxg5; fmvc 16; id "ST3_19 - Vergifteter Bauer"; +rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 am Qxa8; fmvc 14; id "ST3_20 - Dame vs Tuerme"; +rnb2rk1/pp3pbp/3N2p1/q3p3/8/2P3P1/P3PPBP/R1BQ1RK1 b - - am Rd8; fmvc 12; id "ST3_21 - Dame vs Tuerme"; +2r2rk1/1b1qbppp/p2pp1P1/1pn4P/n2NP3/3BBP2/PPP1NQ2/1KR4R b - - am fxg6; fmvc 19; id "ST3_22 - Laeuferopfer"; +r1bqk2r/1p1n2bp/p1p2pp1/2PppP2/3P4/2NB1N1P/PP3PP1/R2Q1RK1 b kq - am e4; fmvc 12; id "ST3_23 - Laeuferopfer"; +rn1q1rk1/pb3pb1/2p1pn2/1p2N1p1/2pPP3/2N3B1/PPQ1BPP1/R3K2R b KQ - am b4; fmvc 13; id "ST3_24 - Springeropfer"; +rnbq1rk1/pp4pp/2pbp3/5p2/2BP2P1/2P1PN1P/P1Q2P2/R1B1K2R b KQ - am fxg4; fmvc 11; id "ST3_25 - Springeropfer"; +r5k1/1qr1bpp1/3pb1n1/4p1Pp/Np2P2P/1P1B1P2/P1P1Q3/BK1R3R w - - am Qe3; fmvc 28; id "ST3_26 - Qualitaetsopfer"; +rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - am Qxb7; fmvc 10; id "ST3_27 - Qualitaetsopfer"; +r1bq1rk1/7p/p2p4/nppPn3/2P2P2/1P6/PQ1NB2P/R2N1RK1 b - - am Bh3; fmvc 20; id "ST3_28 - Qualitaetsopfer"; +r1bqr1k1/ppnnppbp/3p2p1/P1pPP3/2B2P2/2N2N1P/1PP3P1/R1BQ1RK1 b - - am dxe5; fmvc 13; id "ST3_29 - Verteidigung"; +r4rk1/2q1ppb1/p5pp/nppPn3/4P3/2N1B3/PP2BPPP/2QR1RK1 b - - am Nac4; fmvc 19; id "ST3_30 - Verteidigung"; +r1bq1rk1/pp2bpp1/3pp3/6P1/4PPn1/2N5/PPPQ2P1/2KR1B1R b - - am Qb6; fmvc 13; id "ST3_31 - Verteidigung"; +r3r1k1/p1p2ppp/b1p1q3/4P3/1np2P1Q/1P6/P3B1PP/B1R2RK1 b - f3 am cxb3; fmvc 19; id "ST3_32 - Verteidigung"; +r1b2rk1/p2pbppp/2p1p3/3nP3/q3NP2/P2B4/2PBQ1PP/1R3R1K b - - am f5 Qd4; fmvc 16; id "ST3_33 - Verteidigung"; +2r1qrk1/p3b1pp/4b3/1pP5/PQpP1p2/4B3/4BPPP/R4RK1 w - - am Bd2; fmvc 22; id "ST3_34 - Verteidigung"; +1r5r/4qp1k/pn2p1b1/4P3/P4Q2/1R5P/1P2NPP1/3R2K1 w - - am Nd4 Qg4; fmvc 36; id "ST3_35 - Verteidigung"; +r1bqkb1r/ppp2p1p/2n3p1/3np1NQ/2B5/8/PPPP1PPP/RNB1K2R w KQkq - am Qf3; fmvc 7; id "ST3_36 - Verteidigung"; +N4bk1/5pp1/6qp/2n5/6b1/6P1/PP3KBP/2R1Q3 w - - am Qe3; fmvc 27; id "ST3_37 - Verteidigung"; +4rrk1/q6p/8/p2P1p2/2PbB3/8/PPQ2N1P/5RK1 w - - am Bd3; fmvc 31; id "ST3_38 - Verteidigung"; +2kr1b1r/pp1b3p/1qn1pp2/3p3n/2pPP1p1/2P2NB1/PPBN1PPP/RQ2K2R w KQ - am Nh4; fmvc 14; id "ST3_39 - Verteidigung"; +3r1rk1/2q3p1/8/1p1bp3/8/PP4P1/4Q2P/R1B1R1K1 w - - am Bg5; fmvc 26; id "ST3_40 - Verteidigung"; +1r2r1k1/Nb1n1ppp/4q3/8/2p1n3/P4Q2/BB3PPP/1R1R2K1 w - - am Nb5; fmvc 24; id "ST3_41 - Verteidigung"; +r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - am Qa3; fmvc 17; id "ST3_42 - Verteidigung"; +2r2r2/pb2qpp1/1p4k1/3pP1N1/3R1Q1P/8/Pn3PP1/4R1K1 b - - am Nc4; fmvc 22; id "ST3_43 - Verteidigung"; +8/7p/1p3pp1/p2K4/Pk3PPP/8/1P6/8 b - - am Kxa4; fmvc 34; id "ST3_44 - Endspiel B vs B"; +8/2p3k1/3p2p1/1P2p3/2P1P1K1/3P4/8/8 b - - am Kh6; fmvc 30; id "ST3_45 - Endspiel B vs B"; +4k3/8/3PP1p1/8/3K3p/8/3n2PP/8 b - - am Nf1; fmvc 57; id "ST3_46 - Endspiel B vs S"; +8/1p2q2p/p4k2/P3p1p1/1PP1Q2P/8/6P1/7K b - - am gxh4; fmvc 36; id "ST3_47 - Endspiel D vs D"; +6k1/5p2/P3p1p1/2Qp4/5q2/2K5/8/8 b - - am Qc1+; fmvc 50; id "ST3_48 - Endspiel D vs D"; +2r3k1/2Pr2p1/1QR4p/p2qp3/8/3pP3/P4PPP/2R3K1 b - - am d2; fmvc 28; id "ST3_49 - Endspiel D&T vs D&T"; +8/1p4k1/pK5p/2B5/P4pp1/8/7P/8 b - - am g3; fmvc 57; id "ST3_50 - Endspiel L vs B"; +8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - am Kd7; fmvc 26; id "ST3_51 - Endspiel L vs L"; +B7/p5p1/8/4p3/1P4bP/k1K3P1/8/8 b - - am Bf5; fmvc 57; id "ST3_52 - Endspiel L vs L"; +3k4/p4pp1/5b2/1p1P3p/2p1PB2/2P3P1/KP4P1/8 w - b6 am e5; fmvc 31; id "ST3_53 - Endspiel L vs L"; +6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - am Ng5; fmvc 34; id "ST3_54 - Endspiel S vs L"; +8/8/4b3/p1n5/N4k2/K1P5/2P5/8 b - - am Ne4; fmvc 37; id "ST3_55 - Endspiel S&B vs L&S"; +5k2/5ppp/8/1R2PP2/1P6/3K4/1r6/8 b - - am g5; fmvc 38; id "ST3_56 - Endspiel T vs T"; +8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - am Rh6; fmvc 41; id "ST3_57 - Endspiel T vs T"; +8/2R4p/4k3/1p2P3/pP3PK1/r7/8/8 b - - am Rb3; fmvc 52; id "ST3_58 - Endspiel T vs T"; +8/6p1/1p5p/1R2k3/4p3/1P2P3/1K4PP/3r4 b - - am Rd5; fmvc 47; id "ST3_59 - Endspiel T vs T"; +2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - am f8=Q; fmvc 58; id "ST3_60 - Endspiel T vs T"; +2r5/7P/p5K1/8/p7/6P1/P2kp3/1R6 b - - am e1=Q e1=R e1=B e1=N; fmvc 50; id "ST3_61 - Endspiel T vs T"; +3r4/pp6/4kp2/1BPbp1pp/1P6/P3KP2/6PP/3R4 b - - am f5; fmvc 26; id "ST3_62 - Endspiel T&L vs T&L"; +8/3b1p2/3Pk3/R1K4p/8/6r1/8/2B5 w - - am Ra3; fmvc 64; id "ST3_63 - Endspiel T&L vs T&L"; +8/1pp2pPk/p1n2B2/2R1p1Pp/4P2P/1P2KP2/8/3r4 b - - am Rb1; fmvc 39; id "ST3_64 - Endspiel T&L vs T&S"; + diff --git a/tests/pet.ep_ b/tests/pet.ep_ new file mode 100644 index 0000000..8ee0bb7 --- /dev/null +++ b/tests/pet.ep_ @@ -0,0 +1,196 @@ +setboard 8/7p/2k1Pp2/pp1p2p1/3P2P1/4P3/P3K2P/8 w - - +solution e4 +id "PET001: Pawn endgame" +go +setboard 8/1p4kP/5pP1/3p4/8/4P3/7K/8 w - - +solution e4 +id "PET002: Pawn endgame" +go +setboard 8/8/8/pPk3pp/2P1p3/1pK3P1/5PP1/8 w - - +solution g4 +id "PET003: Pawn endgame" +go +setboard 6k1/3p4/3p4/3P4/4P1p1/6P1/8/K7 w - - +solution Kb1 +id "PET004: Pawn endgame" +go +setboard 8/p7/1p2k1p1/8/1p2p1Pp/3pP2P/PP6/5K2 w - - +solution b3 +id "PET005: Pawn endgame" +go +setboard 8/p7/1p2k1p1/8/1p2p1Pp/3pP2P/PP6/5K2 b - - +solution b3 +id "PET006: Pawn endgame" +go +setboard 8/7p/p3pk2/1p5P/3K1P2/1P6/P7/8 w - - +solution a4 +id "PET007: Pawn endgame" +go +setboard 8/8/1p3p2/p3k1pp/4P2P/P3K1P1/1P6/8 w - - +solution g4 +id "PET008: Pawn endgame" +go +setboard 8/8/p3k1p1/1pp5/4KP2/1P6/P5P1/8 w - - +solution g4 +id "PET009: Pawn endgame" +go +setboard 8/1p3p2/p4kpp/1PPp4/P7/7P/5K1P/8 b - - +solution Ke6 +solution Ke7 +id "PET010: Pawn endgame" +go +setboard 8/6p1/7p/p1N5/6PP/2k5/8/3K4 b - - +solution a4 +id "PET011: pawns vs N" +go +setboard 8/8/8/5Bp1/7k/8/4pPKP/8 w - - +solution Bg4 +id "PET012: pawns vs B" +go +setboard 8/8/2p5/pkp3R1/7B/P7/2p3K1/8 w - - +solution a4+ +id "PET013: pawns vs R+B" +go +setboard 8/6k1/6p1/2n2PP1/3N3p/3pK3/8/8 b - - +solution d2 +id "PET014: Knight endgame" +go +setboard 8/1N6/1p1P1n2/p1p1p3/P1P5/1P2k3/2K5/8 w - - +solution Nxc5 +id "PET015: Knight endgame" +go +setboard 4k3/B1p4p/8/p2n1p2/5P2/5P2/1P2K2P/8 w - - +avoid Be3 +id "PET016: bishop vs knight" +go +setboard 8/8/p2k1p2/1p1p3p/1P1P3p/P3NPP1/5K2/1b6 w - - +solution Ng2 +id "PET017: bishop vs knight" +go +setboard 8/3k4/3b4/1K6/7p/5B1P/PP6/8 w - - +solution b4 +id "PET018: opposite bishops" +go +setboard 8/8/4kpp1/3p1b2/p6P/2B5/6P1/6K1 b - - +solution Bh3 +id "PET019: opposite bishops" +go +setboard 8/4k1p1/1p2B2p/4p3/8/4P2P/1PP1KbP1/8 b - - +avoid Bxe3 +id "PET020: opposite bishops" +go +setboard 5k2/8/4b3/1B5P/8/8/5pPP/5K2 b - - +solution Bh3 +id "PET021: bishop endgame" +go +setboard 8/2B5/1p1p4/1PkP1p2/P4P2/5P2/1p6/bK6 w - - +solution Bd8 +id "PET022: bishop endgame" +go +setboard 8/2p1bpp1/2Pp4/p2P1P1p/2K2B1P/k5P1/8/8 w - - +solution f6 +id "PET023: bishop endgame" +go +setboard 8/4ppbk/p5pp/3pP3/3B4/5P1P/PP3P2/6K1 b - - +avoid g5 +id "PET024: bishop endgame" +go +setboard 4K3/2k1Bp1N/6p1/5PP1/8/7p/b7/8 w - - +solution Bf6 +id "PET025: BN vs B" +go +setboard 8/5k2/4p3/4Pp1p/5P1P/3Rn2K/6p1/8 b - - +solution g1=B +id "PET026: rook vs knight" +go +setboard 5k2/8/8/3R4/6K1/8/3b2pP/8 w - - +solution Rf5+ +id "PET027: rook vs bishop" +go +setboard 8/4kp2/4p1p1/2p1r3/PpP5/3R4/1P1K1PP1/8 w - - +solution g4 +id "PET028: rook endgame" +go +setboard 1r3k2/5pp1/3p2p1/8/3P4/P6P/2R2P1K/8 b - - +solution Ra8 +id "PET029: rook endgame" +go +setboard 5k2/p1p4R/1pr5/3p1pP1/P2P1P2/2P2K2/8/8 w - - +solution Kg3 +id "PET030: rook endgame" +go +setboard 8/1r3pkp/8/5p2/8/5PP1/1P1R3P/6K1 b - - +solution f4 +id "PET031: rook endgame" +go +setboard 8/5pk1/r5pp/P7/3R3P/6P1/5PK1/8 w - - +solution Ra4 +id "PET032: rook endgame" +go +setboard 8/4k3/2P2p2/6p1/1P4R1/4K3/7r/8 w - - +solution Rd4 +id "PET033: rook endgame" +go +setboard 3r4/7p/Rp4k1/5p2/4p3/2P5/PP3P1P/5K2 b - - +solution Rd2 +id "PET034: rook endgame" +go +setboard 8/8/p2k3p/1P1p1pp1/P1r5/1R1K1PP1/7P/8 b - - +solution a5 +id "PET035: rook endgame" +go +setboard 8/1r3pkp/R7/6Pp/8/4P3/5PK1/8 b - - +solution Re7 +id "PET036: rook endgame" +go +setboard 8/pR4pk/1b6/2p5/N1p5/8/PP1r2PP/6K1 b - - +solution Rxb2 +id "PET037: RN vs RB" +go +setboard 4k3/2p1b3/4p1p1/1pp1P3/5PP1/1PBK4/r1P2R2/8 b - - +solution c4+ +id "PET038: RB vs RB" +go +setboard 1r6/1pb1k1p1/4p2p/1p1p4/3Pp2P/1R2P1PB/1P2PK2/8 b - - +solution b4 +id "PET039: RB vs RB" +go +setboard 8/8/5P1k/8/2K5/pr2r3/4R3/2R5 w - - +solution f7 +id "PET042: double rook endgame" +go +r5k1/5pp1/1P5p/3R4/2r5/P3P3/2p2PPP/2R3K1 b - - +solution Rxa3 +id "PET043: double rook endgame" +go +setboard 1r6/Rp2rp2/1Pp2kp1/N1Pp3p/3Pp1nP/4P1P1/R4P2/6K1 w - - +solution Nxb7 +solution Rxb7 +id "PET044: RRN vs RRN" +go +setboard 5k2/4p3/3p2Q1/3Pq1pP/5pP1/2P4K/8/8 w - - +solution Qf5+ +id "PET045: Queen endgame" +go +setboard 8/8/1P1k2p1/8/5P1p/4Qb2/1q4PK/8 w - - +solution Qe5+ +id "PET046: Q+B vs Q" +go +setboard 8/p4k2/1p1p1qp1/1P1P4/P5P1/7P/4Q1K1/2b5 b - - +avoid Qb2 +id "PET047: Q+B vs Q" +go +setboard 6qk/1p4pn/8/3p4/2P5/p3P1P1/P1Q3K1/1B6 w - - +avoid Qxh7+ +id "PET048: Q+B vs Q+N" +go +setboard 1Q6/Nn3pbp/2N2p2/1Pqk1P1P/8/8/6P1/7K w - - +avoid Qxb7 +id "PET049: QNN vs QBN" +go +setboard 7k/7p/1p4p1/n2p4/1K1p3R/2NB4/3Q1P2/q1r5 w - - +solution Rxh7+ +id "PET050: QNBR vs QNR" +go +version + diff --git a/tests/quick.ep_ b/tests/quick.ep_ new file mode 100644 index 0000000..65a6a19 --- /dev/null +++ b/tests/quick.ep_ @@ -0,0 +1,96 @@ +setboard 1n1r1rk1/ppq2ppp/3p2b1/3B1NP1/4PB1R/bP2P2P/P1P5/3KQ1R1 w - - +id Quick-01 +solution Qc3 +go +setboard 1n1r1rk1/ppq2ppp/3p2b1/3B1NP1/4PB1R/bP2P2P/P1P5/3KQ1R1 w - - +id Quick-02 +solution Qc3 +go +setboard 3Q4/3p4/P2p4/N2b4/8/4P3/5p1p/5Kbk w - - +id Quick-03 +solution Qa8 +go +setboard 4qrk1/3nppb1/R1Np2p1/3P2P1/1Pr5/4B3/5Q1P/5R1K w - - +id Quick-04 +solution Ra8 +go +setboard r3r3/2R2pk1/p2p1bpp/3P4/q2pQ3/5N1P/5PP1/1R4K1 w - - +id Quick-05 +solution Rxf7+ +go +setboard r3r3/2R2pk1/p2p1bpp/3P4/q2pQ3/5N1P/5PP1/1R4K1 w - - +id Quick-06 +solution Rxf7+ +go +setboard r5k1/Rb4p1/2q2pBp/1pp5/1b4QN/1P2P2P/5PP1/6K1 w - - +id Quick-07 +solution Rxb7 +go +setboard 3R4/5r1p/5ppk/8/1Q3PPq/5P2/6K1/8 w - - +id Quick-08 +solution Rg8 +go +setboard 2kr3r/ppp3pp/2pbbn2/4N3/3Pp3/2P3Pq/PP1NQP1P/R1B2RK1 w - - +id Quick-09 +avoid Nxe4 +go +setboard 2r3k1/pp1bpp1p/3p1npQ/q1r5/4P1P1/2NR1P2/PPP1N3/2K4R w - - +id Quick-10 +solution g5 +go +setboard r1b2rk1/pp3p2/2p2bpQ/8/1q1P4/2N2N2/Pn3PPP/1B1RR1K1 w - - +id Quick-11 +solution Bxg6 +go +setboard r2qk2r/1p1bbp2/1P2p3/p2pPp2/n2N1N1p/3PB3/5QPP/R4RK1 w kq - +id Quick-12 +solution Rxa4 +go +setboard 3r1n1r/1p2q1k1/p1p1P1p1/3n4/5Pp1/P5N1/1P3QP1/1BR1R1K1 w - - +id Quick-13 +solution Bxg6 +go +setboard r2q1rk1/p1p3pp/b2bp3/2pp4/6p1/2NPPN2/PPP2PP1/R1BQR1K1 w - - +id Quick-14 +solution Ne5 +go +setboard r2q1rk1/p1p3pp/b2bp3/2pp4/6p1/2NPPN2/PPP2PP1/R1BQR1K1 w - - +id Quick-15 +solution Ne5 +go +setboard 3k4/p7/K3BP2/8/7p/8/2P4P/8 w - - +id Quick-16 +solution Kb7 +go +setboard rq4k1/pp1nrppp/4bn2/6R1/3QP3/P4PN1/4B1PP/2B2RK1 w - - +id Quick-17 +solution Rxg7+ +go +setboard 2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - +id Quick-18 +solution Qb4 +go +setboard 2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - +id Quick-19 +solution Qb4 +go +setboard 2r4k/pb2q2P/1p6/3Pp3/4p3/1P2R3/PBrQ2PP/5RK1 w - - +id Quick-20 +solution Qb4 +go +setboard r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - +id Quick-21 +solution Bxb5+ +go +setboard r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - +id Quick-22 +solution Bxb5+ +go +setboard r1b1kb1r/2q2ppp/p2ppP2/1pn3P1/3NP3/2N2Q2/PPP4P/2KR1B1R w kq - +id Quick-23 +solution Bxb5+ +go +setboard 3B4/1R3p1k/2p4p/2Pp3r/3P4/4Q1K1/6P1/3b1q2 w - - +id Quick-24 +solution Bf6 +go diff --git a/tests/swiss.ep_ b/tests/swiss.ep_ new file mode 100644 index 0000000..2cdeef6 --- /dev/null +++ b/tests/swiss.ep_ @@ -0,0 +1,256 @@ +setboard +id "ST3_01 - Entwicklung" + +go +setboard +id "ST3_02 - Entwicklung" + +go +setboard +id "ST3_03 - Entwicklung" + +go +setboard +id "ST3_04 - Koenigssicherheit" + +go +setboard r2qr1k1/pp3pbp/2n3p1/1N1p4/2P2Pb1/5N2/PP1QBPPP/2KR3R w - - +id "ST3_05 - Koenigssicherheit" +avoid cxd5 +go +setboard r2qr1k1/pp3pbp/2n3p1/1N1p4/2P2Pb1/5N2/PP1QBPPP/2KR3R w - - +id "ST3_06 - Koenigssicherheit" +avoid cxd5 +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_07 - Koenigssicherheit" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_08 - Koenigssicherheit" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_09 - Koenigssicherheit" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_10 - Trojaner" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_11 - Trojaner" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_12 - Vergifteter Bauer" +avoid O-O +go +setboard 2kr1nr1/pbp1qp2/1p2pn1p/8/3Pp2Q/P1P3N1/2PBBPPP/R3K2R w KQ - +id "ST3_13 - Vergifteter Bauer" +avoid O-O +go +setboard 3r1rk1/4bppp/p1pq1n2/3p1P2/4p2B/2N5/PPP1QPPP/R3R1K1 w - - +id "ST3_14 - Vergifteter Bauer" +avoid Qxa6 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_15 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_16 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_17 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r2q1r1k/1p2b1pp/p3Bn2/3N4/P2pP3/4p3/1PP3PP/R2Q1RK1 w - - +id "ST3_18 - Vergifteter Bauer" +avoid Qxd4 +go +setboard r1bq1rk1/ppp1n1bp/3p4/3Ppnp1/2P1N3/1Q4BP/PP1NBPP1/R3K2R w KQ - +id "ST3_19 - Vergifteter Bauer" +avoid Nxg5 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_20 - Dame vs Tuerme" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_21 - Dame vs Tuerme" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_22 - Laeuferopfer" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_23 - Laeuferopfer" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_24 - Springeropfer" +avoid Qxa8 +go +setboard rn2r1k1/p1pq2pp/bp2p3/5p2/2PPQ3/B1PB4/P4PPP/R3K2R w KQ f6 +id "ST3_25 - Springeropfer" +avoid Qxa8 +go +setboard r5k1/1qr1bpp1/3pb1n1/4p1Pp/Np2P2P/1P1B1P2/P1P1Q3/BK1R3R w - - +id "ST3_26 - Qualitaetsopfer" +avoid Qe3 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_27 - Qualitaetsopfer" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_28 - Qualitaetsopfer" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_29 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_30 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_31 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_32 - Verteidigung" +avoid Qxb7 +go +setboard rn2kb1r/pp3p1p/2p2np1/3p1b2/3q1B2/1QN5/PP1NPPPP/R3KB1R w KQkq - +id "ST3_33 - Verteidigung" +avoid Qxb7 +go +setboard 2r1qrk1/p3b1pp/4b3/1pP5/PQpP1p2/4B3/4BPPP/R4RK1 w - - +id "ST3_34 - Verteidigung" +avoid Bd2 +go +setboard 1r5r/4qp1k/pn2p1b1/4P3/P4Q2/1R5P/1P2NPP1/3R2K1 w - - +id "ST3_35 - Verteidigung" +avoid Nd4 Qg4 +go +setboard r1bqkb1r/ppp2p1p/2n3p1/3np1NQ/2B5/8/PPPP1PPP/RNB1K2R w KQkq - +id "ST3_36 - Verteidigung" +avoid Qf3 +go +setboard N4bk1/5pp1/6qp/2n5/6b1/6P1/PP3KBP/2R1Q3 w - - +id "ST3_37 - Verteidigung" +avoid Qe3 +go +setboard 4rrk1/q6p/8/p2P1p2/2PbB3/8/PPQ2N1P/5RK1 w - - +id "ST3_38 - Verteidigung" +avoid Bd3 +go +setboard 2kr1b1r/pp1b3p/1qn1pp2/3p3n/2pPP1p1/2P2NB1/PPBN1PPP/RQ2K2R w KQ - +id "ST3_39 - Verteidigung" +avoid Nh4 +go +setboard 3r1rk1/2q3p1/8/1p1bp3/8/PP4P1/4Q2P/R1B1R1K1 w - - +id "ST3_40 - Verteidigung" +avoid Bg5 +go +setboard 1r2r1k1/Nb1n1ppp/4q3/8/2p1n3/P4Q2/BB3PPP/1R1R2K1 w - - +id "ST3_41 - Verteidigung" +avoid Nb5 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_42 - Verteidigung" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_43 - Verteidigung" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_44 - Endspiel B vs B" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_45 - Endspiel B vs B" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_46 - Endspiel B vs S" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_47 - Endspiel D vs D" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_48 - Endspiel D vs D" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_49 - Endspiel D&T vs D&T" +avoid Qa3 +go +setboard r2qr1k1/pp3pp1/5n1p/2pPn3/2b5/1QP1B1PP/P3NPB1/R3R1K1 w - - +id "ST3_50 - Endspiel L vs B" +avoid Qa3 +go +setboard 8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - +id "ST3_51 - Endspiel L vs L" +avoid Kd7 +go +setboard 8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - +id "ST3_52 - Endspiel L vs L" +avoid Kd7 +go +setboard 8/8/2p1K1p1/2k5/p7/P4BpP/1Pb3P1/8 w - - +id "ST3_53 - Endspiel L vs L" +avoid Kd7 +go +setboard 6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - +id "ST3_54 - Endspiel S vs L" +avoid Ng5 +go +setboard 6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - +id "ST3_55 - Endspiel S&B vs L&S" +avoid Ng5 +go +setboard 6k1/4b3/4p1p1/8/6pP/4PN2/5K2/8 w - - +id "ST3_56 - Endspiel T vs T" +avoid Ng5 +go +setboard 8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - +id "ST3_57 - Endspiel T vs T" +avoid Rh6 +go +setboard 8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - +id "ST3_58 - Endspiel T vs T" +avoid Rh6 +go +setboard 8/4k3/1R6/5p1p/3K1Pp1/P5r1/1P6/8 w - - +id "ST3_59 - Endspiel T vs T" +avoid Rh6 +go +setboard 2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - +id "ST3_60 - Endspiel T vs T" +avoid f8=Q +go +setboard 2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - +id "ST3_61 - Endspiel T vs T" +avoid f8=Q +go +setboard 2r5/1R3PK1/p7/7p/8/1pk4P/8/8 w - - +id "ST3_62 - Endspiel T&L vs T&L" +avoid f8=Q +go +setboard 8/3b1p2/3Pk3/R1K4p/8/6r1/8/2B5 w - - +id "ST3_63 - Endspiel T&L vs T&L" +avoid Ra3 +go +setboard 8/3b1p2/3Pk3/R1K4p/8/6r1/8/2B5 w - - +id "ST3_64 - Endspiel T&L vs T&S" +avoid Ra3 +go diff --git a/tests/wac.ep_ b/tests/wac.ep_ new file mode 100644 index 0000000..029bef9 --- /dev/null +++ b/tests/wac.ep_ @@ -0,0 +1,1227 @@ +setboard 2rr3k/pp3pp1/1nnqbN1p/3pN3/2pP4/2P3Q1/PPB4P/R4RK1 w - - +solution Qg6 +id "WAC.001" +go +setboard 8/7p/5k2/5p2/p1p2P2/Pr1pPK2/1P1R3P/8 b - - +solution Rxb2 +id "WAC.002" +go +setboard 5rk1/1ppb3p/p1pb4/6q1/3P1p1r/2P1R2P/PP1BQ1P1/5RKN w - - +solution Rg3 +id "WAC.003" +go +setboard r1bq2rk/pp3pbp/2p1p1pQ/7P/3P4/2PB1N2/PP3PPR/2KR4 w - - +solution Qxh7+ +id "WAC.004" +go +setboard 5k2/6pp/p1qN4/1p1p4/3P4/2PKP2Q/PP3r2/3R4 b - - +solution Qc4+ +id "WAC.005" +go +setboard 7k/p7/1R5K/6r1/6p1/6P1/8/8 w - - +solution Rb7 +id "WAC.006" +go +setboard rnbqkb1r/pppp1ppp/8/4P3/6n1/7P/PPPNPPP1/R1BQKBNR b KQkq - +solution Ne3 +id "WAC.007" +go +setboard r4q1k/p2bR1rp/2p2Q1N/5p2/5p2/2P5/PP3PPP/R5K1 w - - +solution Rf7 +id "WAC.008" +go +setboard 3q1rk1/p4pp1/2pb3p/3p4/6Pr/1PNQ4/P1PB1PP1/4RRK1 b - - +solution Bh2+ +id "WAC.009" +go +setboard 2br2k1/2q3rn/p2NppQ1/2p1P3/Pp5R/4P3/1P3PPP/3R2K1 w - - +solution Rxh7 +id "WAC.010" +go +setboard r1b1kb1r/3q1ppp/pBp1pn2/8/Np3P2/5B2/PPP3PP/R2Q1RK1 w kq - +solution Bxc6 +id "WAC.011" +go +setboard 4k1r1/2p3r1/1pR1p3/3pP2p/3P2qP/P4N2/1PQ4P/5R1K b - - +solution Qxf3+ +id "WAC.012" +go +setboard 5rk1/pp4p1/2n1p2p/2Npq3/2p5/6P1/P3P1BP/R4Q1K w - - +solution Qxf8+ +id "WAC.013" +go +setboard r2rb1k1/pp1q1p1p/2n1p1p1/2bp4/5P2/PP1BPR1Q/1BPN2PP/R5K1 w - - +solution Qxh7+ +id "WAC.014" +go +setboard 1R6/1brk2p1/4p2p/p1P1Pp2/P7/6P1/1P4P1/2R3K1 w - - +solution Rxb7 +id "WAC.015" +go +setboard r4rk1/ppp2ppp/2n5/2bqp3/8/P2PB3/1PP1NPPP/R2Q1RK1 w - - +solution Nc3 +id "WAC.016" +go +setboard 1k5r/pppbn1pp/4q1r1/1P3p2/2NPp3/1QP5/P4PPP/R1B1R1K1 w - - +solution Ne5 +id "WAC.017" +go +setboard R7/P4k2/8/8/8/8/r7/6K1 w - - +solution Rh8 +id "WAC.018" +go +setboard r1b2rk1/ppbn1ppp/4p3/1QP4q/3P4/N4N2/5PPP/R1B2RK1 w - - +solution c6 +id "WAC.019" +go +setboard r2qkb1r/1ppb1ppp/p7/4p3/P1Q1P3/2P5/5PPP/R1B2KNR b kq - +solution Bb5 +id "WAC.020" +go +setboard 5rk1/1b3p1p/pp3p2/3n1N2/1P6/P1qB1PP1/3Q3P/4R1K1 w - - +solution Qh6 +id "WAC.021" +go +setboard r1bqk2r/ppp1nppp/4p3/n5N1/2BPp3/P1P5/2P2PPP/R1BQK2R w KQkq - +solution Ba2 +solution Nxf7 +id "WAC.022" +go +setboard r3nrk1/2p2p1p/p1p1b1p1/2NpPq2/3R4/P1N1Q3/1PP2PPP/4R1K1 w - - +solution g4 +id "WAC.023" +go +setboard 6k1/1b1nqpbp/pp4p1/5P2/1PN5/4Q3/P5PP/1B2B1K1 b - - +solution Bd4 +id "WAC.024" +go +setboard 3R1rk1/8/5Qpp/2p5/2P1p1q1/P3P3/1P2PK2/8 b - - +solution Qh4+ +id "WAC.025" +go +setboard 3r2k1/1p1b1pp1/pq5p/8/3NR3/2PQ3P/PP3PP1/6K1 b - - +solution Bf5 +id "WAC.026" +go +setboard 7k/pp4np/2p3p1/3pN1q1/3P4/Q7/1r3rPP/2R2RK1 w - - +solution Qf8+ +id "WAC.027" +go +setboard 1r1r2k1/4pp1p/2p1b1p1/p3R3/RqBP4/4P3/1PQ2PPP/6K1 b - - +solution Qe1+ +id "WAC.028" +go +setboard r2q2k1/pp1rbppp/4pn2/2P5/1P3B2/6P1/P3QPBP/1R3RK1 w - - +solution c6 +id "WAC.029" +go +setboard 1r3r2/4q1kp/b1pp2p1/5p2/pPn1N3/6P1/P3PPBP/2QRR1K1 w - - +solution Nxd6 +id "WAC.030" +go +setboard rb3qk1/pQ3ppp/4p3/3P4/8/1P3N2/1P3PPP/3R2K1 w - - +solution Qxa8 +solution d6 +solution dxe6 +id "WAC.031" +go +setboard 6k1/p4p1p/1p3np1/2q5/4p3/4P1N1/PP3PPP/3Q2K1 w - - +solution Qd8+ +id "WAC.032" +go +setboard 8/p1q2pkp/2Pr2p1/8/P3Q3/6P1/5P1P/2R3K1 w - - +solution Qe5+ +solution Qf4 +id "WAC.033" +go +setboard 7k/1b1r2p1/p6p/1p2qN2/3bP3/3Q4/P5PP/1B1R3K b - - +solution Bg1 +id "WAC.034" +go +setboard r3r2k/2R3pp/pp1q1p2/8/3P3R/7P/PP3PP1/3Q2K1 w - - +solution Rxh7+ +id "WAC.035" +go +setboard 3r4/2p1rk2/1pQq1pp1/7p/1P1P4/P4P2/6PP/R1R3K1 b - - +solution Re1+ +id "WAC.036" +go +setboard 2r5/2rk2pp/1pn1pb2/pN1p4/P2P4/1N2B3/nPR1KPPP/3R4 b - - +solution Nxd4+ +id "WAC.037" +go +setboard 4k3/p4prp/1p6/2b5/8/2Q3P1/P2R1PKP/4q3 w - - +solution Rd8+ +id "WAC.038" +go +setboard r1br2k1/pp2bppp/2nppn2/8/2P1PB2/2N2P2/PqN1B1PP/R2Q1R1K w - - +solution Na4 +id "WAC.039" +go +setboard 3r1r1k/1p4pp/p4p2/8/1PQR4/6Pq/P3PP2/2R3K1 b - - +solution Rc8 +id "WAC.040" +go +setboard 1k6/5RP1/1P6/1K6/6r1/8/8/8 w - - +solution Ka5 +solution Kc5 +id "WAC.041" +go +setboard r1b1r1k1/pp1n1pbp/1qp3p1/3p4/1B1P4/Q3PN2/PP2BPPP/R4RK1 w - - +solution Ba5 +id "WAC.042" +go +setboard r2q3k/p2P3p/1p3p2/3QP1r1/8/B7/P5PP/2R3K1 w - - +solution Be7 +solution Qxa8 +id "WAC.043" +go +setboard 3rb1k1/pq3pbp/4n1p1/3p4/2N5/2P2QB1/PP3PPP/1B1R2K1 b - - +solution dxc4 +id "WAC.044" +go +setboard 7k/2p1b1pp/8/1p2P3/1P3r2/2P3Q1/1P5P/R4qBK b - - +solution Qxa1 +id "WAC.045" +go +setboard r1bqr1k1/pp1nb1p1/4p2p/3p1p2/3P4/P1N1PNP1/1PQ2PP1/3RKB1R w K - +solution Nb5 +id "WAC.046" +go +setboard r1b2rk1/pp2bppp/2n1pn2/q5B1/2BP4/2N2N2/PP2QPPP/2R2RK1 b - - +solution Nxd4 +id "WAC.047" +go +setboard 1rbq1rk1/p1p1bppp/2p2n2/8/Q1BP4/2N5/PP3PPP/R1B2RK1 b - - +solution Rb4 +id "WAC.048" +go +setboard 2b3k1/4rrpp/p2p4/2pP2RQ/1pP1Pp1N/1P3P1P/1q6/6RK w - - +solution Qxh7+ +id "WAC.049" +go +setboard k4r2/1R4pb/1pQp1n1p/3P4/5p1P/3P2P1/r1q1R2K/8 w - - +solution Rxb6+ +id "WAC.050" +go +setboard r1bq1r2/pp4k1/4p2p/3pPp1Q/3N1R1P/2PB4/6P1/6K1 w - - +solution Rg4+ +id "WAC.051" +go +setboard r1k5/1p3q2/1Qpb4/3N1p2/5Pp1/3P2Pp/PPPK3P/4R3 w - - +solution Re7 +id "WAC.052" +go +setboard 6k1/6p1/p7/3Pn3/5p2/4rBqP/P4RP1/5QK1 b - - +solution Re1 +id "WAC.053" +go +setboard r3kr2/1pp4p/1p1p4/7q/4P1n1/2PP2Q1/PP4P1/R1BB2K1 b q - +solution Qh1+ +id "WAC.054" +go +setboard r3r1k1/pp1q1pp1/4b1p1/3p2B1/3Q1R2/8/PPP3PP/4R1K1 w - - +solution Qxg7+ +id "WAC.055" +go +setboard r1bqk2r/pppp1ppp/5n2/2b1n3/4P3/1BP3Q1/PP3PPP/RNB1K1NR b KQkq - +solution Bxf2+ +id "WAC.056" +go +setboard r3q1kr/ppp5/3p2pQ/8/3PP1b1/5R2/PPP3P1/5RK1 w - - +solution Rf8+ +id "WAC.057" +go +setboard 8/8/2R5/1p2qp1k/1P2r3/2PQ2P1/5K2/8 w - - +solution Qd1+ +id "WAC.058" +go +setboard r1b2rk1/2p1qnbp/p1pp2p1/5p2/2PQP3/1PN2N1P/PB3PP1/3R1RK1 w - - +solution Nd5 +id "WAC.059" +go +setboard rn1qr1k1/1p2np2/2p3p1/8/1pPb4/7Q/PB1P1PP1/2KR1B1R w - - +solution Qh8+ +id "WAC.060" +go +setboard 3qrbk1/ppp1r2n/3pP2p/3P4/2P4P/1P3Q2/PB6/R4R1K w - - +solution Qf7+ +id "WAC.061" +go +setboard 6r1/3Pn1qk/p1p1P1rp/2Q2p2/2P5/1P4P1/P3R2P/5RK1 b - - +solution Rxg3+ +id "WAC.062" +go +setboard r1brnbk1/ppq2pp1/4p2p/4N3/3P4/P1PB1Q2/3B1PPP/R3R1K1 w - - +solution Nxf7 +id "WAC.063" +go +setboard 8/6pp/3q1p2/3n1k2/1P6/3NQ2P/5PP1/6K1 w - - +solution g4+ +id "WAC.064" +go +setboard 1r1r1qk1/p2n1p1p/bp1Pn1pQ/2pNp3/2P2P1N/1P5B/P6P/3R1RK1 w - - +solution Ne7+ +id "WAC.065" +go +setboard 1k1r2r1/ppq5/1bp4p/3pQ3/8/2P2N2/PP4P1/R4R1K b - - +solution Qxe5 +id "WAC.066" +go +setboard 3r2k1/p2q4/1p4p1/3rRp1p/5P1P/6PK/P3R3/3Q4 w - - +solution Rxd5 +id "WAC.067" +go +setboard 6k1/5ppp/1q6/2b5/8/2R1pPP1/1P2Q2P/7K w - - +solution Qxe3 +id "WAC.068" +go +setboard 2k5/pppr4/4R3/4Q3/2pp2q1/8/PPP2PPP/6K1 w - - +solution f3 +solution h3 +id "WAC.069" +go +setboard 2kr3r/pppq1ppp/3p1n2/bQ2p3/1n1PP3/1PN1BN1P/1PP2PP1/2KR3R b - - +solution Na2+ +id "WAC.070" +go +setboard 2kr3r/pp1q1ppp/5n2/1Nb5/2Pp1B2/7Q/P4PPP/1R3RK1 w - - +solution Nxa7+ +id "WAC.071" +go +setboard r3r1k1/pp1n1ppp/2p5/4Pb2/2B2P2/B1P5/P5PP/R2R2K1 w - - +solution e6 +id "WAC.072" +go +setboard r1q3rk/1ppbb1p1/4Np1p/p3pP2/P3P3/2N4R/1PP1Q1PP/3R2K1 w - - +solution Qd2 +id "WAC.073" +go +setboard 5r1k/pp4pp/2p5/2b1P3/4Pq2/1PB1p3/P3Q1PP/3N2K1 b - - +solution Qf1+ +id "WAC.074" +go +setboard r3r1k1/pppq1ppp/8/8/1Q4n1/7P/PPP2PP1/RNB1R1K1 b - - +solution Qd6 +id "WAC.075" +go +setboard r1b1qrk1/2p2ppp/pb1pnn2/1p2pNB1/3PP3/1BP5/PP2QPPP/RN1R2K1 w - - +solution Bxf6 +id "WAC.076" +go +setboard 3r2k1/ppp2ppp/6q1/b4n2/3nQB2/2p5/P4PPP/RN3RK1 b - - +solution Ng3 +id "WAC.077" +go +setboard r2q3r/ppp2k2/4nbp1/5Q1p/2P1NB2/8/PP3P1P/3RR1K1 w - - +solution Ng5+ +id "WAC.078" +go +setboard r3k2r/pbp2pp1/3b1n2/1p6/3P3p/1B2N1Pq/PP1PQP1P/R1B2RK1 b kq - +solution Qxh2+ +id "WAC.079" +go +setboard r4rk1/p1B1bpp1/1p2pn1p/8/2PP4/3B1P2/qP2QP1P/3R1RK1 w - - +solution Ra1 +id "WAC.080" +go +setboard r4rk1/1bR1bppp/4pn2/1p2N3/1P6/P3P3/4BPPP/3R2K1 b - - +solution Bd6 +id "WAC.081" +go +setboard 3rr1k1/pp3pp1/4b3/8/2P1B2R/6QP/P3q1P1/5R1K w - - +solution Bh7+ +id "WAC.082" +go +setboard 3rr1k1/ppqbRppp/2p5/8/3Q1n2/2P3N1/PPB2PPP/3R2K1 w - - +solution Qxd7 +id "WAC.083" +go +setboard r2q1r1k/2p1b1pp/p1n5/1p1Q1bN1/4n3/1BP1B3/PP3PPP/R4RK1 w - - +solution Qg8+ +id "WAC.084" +go +setboard kr2R3/p4r2/2pq4/2N2p1p/3P2p1/Q5P1/5P1P/5BK1 w - - +solution Na6 +id "WAC.085" +go +setboard 8/p7/1ppk1n2/5ppp/P1PP4/2P1K1P1/5N1P/8 b - - +solution Ng4+ +id "WAC.086" +go +setboard 8/p3k1p1/4r3/2ppNpp1/PP1P4/2P3KP/5P2/8 b - - +solution Rxe5 +id "WAC.087" +go +setboard r6k/p1Q4p/2p1b1rq/4p3/B3P3/4P3/PPP3P1/4RRK1 b - - +solution Rxg2+ +id "WAC.088" +go +setboard 1r3b1k/p4rpp/4pp2/3q4/2ppbPPQ/6RK/PP5P/2B1NR2 b - - +solution g5 +id "WAC.089" +go +setboard 3qrrk1/1pp2pp1/1p2bn1p/5N2/2P5/P1P3B1/1P4PP/2Q1RRK1 w - - +solution Nxg7 +id "WAC.090" +go +setboard 2qr2k1/4b1p1/2p2p1p/1pP1p3/p2nP3/PbQNB1PP/1P3PK1/4RB2 b - - +solution Be6 +id "WAC.091" +go +setboard r4rk1/1p2ppbp/p2pbnp1/q7/3BPPP1/2N2B2/PPP4P/R2Q1RK1 b - - +solution Bxg4 +id "WAC.092" +go +setboard r1b1k1nr/pp3pQp/4pq2/3pn3/8/P1P5/2P2PPP/R1B1KBNR w KQkq - +solution Bh6 +id "WAC.093" +go +setboard 8/k7/p7/3Qp2P/n1P5/3KP3/1q6/8 b - - +solution e4+ +id "WAC.094" +go +setboard 2r5/1r6/4pNpk/3pP1qp/8/2P1QP2/5PK1/R7 w - - +solution Ng4+ +id "WAC.095" +go +setboard r1b4k/ppp2Bb1/6Pp/3pP3/1qnP1p1Q/8/PPP3P1/1K1R3R w - - +solution Qd8+ +id "WAC.096" +go +setboard 6k1/5p2/p5np/4B3/3P4/1PP1q3/P3r1QP/6RK w - - +solution Qa8+ +id "WAC.097" +go +setboard 1r3rk1/5pb1/p2p2p1/Q1n1q2p/1NP1P3/3p1P1B/PP1R3P/1K2R3 b - - +solution Nxe4 +id "WAC.098" +go +setboard r1bq1r1k/1pp1Np1p/p2p2pQ/4R3/n7/8/PPPP1PPP/R1B3K1 w - - +solution Rh5 +id "WAC.099" +go +setboard 8/k1b5/P4p2/1Pp2p1p/K1P2P1P/8/3B4/8 w - - +solution b6+ +id "WAC.100" +go +setboard 5rk1/p5pp/8/8/2Pbp3/1P4P1/7P/4RN1K b - - +solution Bc3 +id "WAC.101" +go +setboard 2Q2n2/2R4p/1p1qpp1k/8/3P3P/3B2P1/5PK1/r7 w - - +solution Qxf8+ +id "WAC.102" +go +setboard 6k1/2pb1r1p/3p1PpQ/p1nPp3/1q2P3/2N2P2/PrB5/2K3RR w - - +solution Qxg6+ +id "WAC.103" +go +setboard b4r1k/pq2rp2/1p1bpn1p/3PN2n/2P2P2/P2B3K/1B2Q2N/3R2R1 w - - +solution Qxh5 +id "WAC.104" +go +setboard r2r2k1/pb3ppp/1p1bp3/7q/3n2nP/PP1B2P1/1B1N1P2/RQ2NRK1 b - - +solution Qxh4 +id "WAC.105" +go +setboard 4rrk1/pppb4/7p/3P2pq/3Qn3/P5P1/1PP4P/R3RNNK b - - +solution Nf2+ +id "WAC.106" +go +setboard 5n2/pRrk2p1/P4p1p/4p3/3N4/5P2/6PP/6K1 w - - +solution Nb5 +id "WAC.107" +go +setboard r5k1/1q4pp/2p5/p1Q5/2P5/5R2/4RKPP/r7 w - - +solution Qe5 +id "WAC.108" +go +setboard rn2k1nr/pbp2ppp/3q4/1p2N3/2p5/QP6/PB1PPPPP/R3KB1R b KQkq - +solution c3 +id "WAC.109" +go +setboard 2kr4/bp3p2/p2p2b1/P7/2q5/1N4B1/1PPQ2P1/2KR4 b - - +solution Be3 +id "WAC.110" +go +setboard 6k1/p5p1/5p2/2P2Q2/3pN2p/3PbK1P/7P/6q1 b - - +solution Qf1+ +id "WAC.111" +go +setboard r4kr1/ppp5/4bq1b/7B/2PR1Q1p/2N3P1/PP3P1P/2K1R3 w - - +solution Rxe6 +id "WAC.112" +go +setboard rnbqkb1r/1p3ppp/5N2/1p2p1B1/2P5/8/PP2PPPP/R2QKB1R b KQkq - +solution Qxf6 +id "WAC.113" +go +setboard r1b1rnk1/1p4pp/p1p2p2/3pN2n/3P1PPq/2NBPR1P/PPQ5/2R3K1 w - - +solution Bxh7+ +id "WAC.114" +go +setboard 4N2k/5rpp/1Q6/p3q3/8/P5P1/1P3P1P/5K2 w - - +solution Nd6 +id "WAC.115" +go +setboard r2r2k1/2p2ppp/p7/1p2P1n1/P6q/5P2/1PB1QP1P/R5RK b - - +solution Rd2 +id "WAC.116" +go +setboard 3r1rk1/q4ppp/p1Rnp3/8/1p6/1N3P2/PP3QPP/3R2K1 b - - +solution Ne4 +id "WAC.117" +go +setboard r5k1/pb2rpp1/1p6/2p4q/5R2/2PB2Q1/P1P3PP/5R1K w - - +solution Rh4 +id "WAC.118" +go +setboard r2qr1k1/p1p2ppp/2p5/2b5/4nPQ1/3B4/PPP3PP/R1B2R1K b - - +solution Qxd3 +id "WAC.119" +go +setboard r4rk1/1bn2qnp/3p1B1Q/p2P1pP1/1pp5/5N1P/PPB2P2/2KR3R w - - +solution g6 +id "WAC.120" +go +setboard 6k1/5p1p/2bP2pb/4p3/2P5/1p1pNPPP/1P1Q1BK1/1q6 b - - +solution Bxf3+ +id "WAC.121" +go +setboard 1k6/ppp4p/1n2pq2/1N2Rb2/2P2Q2/8/P4KPP/3r1B2 b - - +solution Rxf1+ +id "WAC.122" +go +setboard 6k1/1b2rp2/1p4p1/3P4/PQ4P1/2N2q2/5P2/3R2K1 b - - +solution Bxd5 +solution Rc7 +id "WAC.123" +go +setboard 6k1/3r4/2R5/P5P1/1P4p1/8/4rB2/6K1 b - - +solution g3 +id "WAC.124" +go +setboard r1bqr1k1/pp3ppp/1bp5/3n4/3B4/2N2P1P/PPP1B1P1/R2Q1RK1 b - - +solution Bxd4+ +id "WAC.125" +go +setboard r5r1/pQ5p/1qp2R2/2k1p3/4P3/2PP4/P1P3PP/6K1 w - - +solution Rxc6+ +id "WAC.126" +go +setboard 2k4r/1pr1n3/p1p1q2p/5pp1/3P1P2/P1P1P3/1R2Q1PP/1RB3K1 w - - +solution Rxb7 +id "WAC.127" +go +setboard 6rk/1pp2Qrp/3p1B2/1pb1p2R/3n1q2/3P4/PPP3PP/R6K w - - +solution Qg6 +id "WAC.128" +go +setboard 3r1r1k/1b2b1p1/1p5p/2p1Pp2/q1B2P2/4P2P/1BR1Q2K/6R1 b - - +solution Bf3 +id "WAC.129" +go +setboard 6k1/1pp3q1/5r2/1PPp4/3P1pP1/3Qn2P/3B4/4R1K1 b - - +solution Qh6 +solution Qh8 +id "WAC.130" +go +setboard 2rq1bk1/p4p1p/1p4p1/3b4/3B1Q2/8/P4PpP/3RR1K1 w - - +solution Re8 +id "WAC.131" +go +setboard 4r1k1/5bpp/2p5/3pr3/8/1B3pPq/PPR2P2/2R2QK1 b - - +solution Re1 +id "WAC.132" +go +setboard r1b1k2r/1pp1q2p/p1n3p1/3QPp2/8/1BP3B1/P5PP/3R1RK1 w kq - +solution Bh4 +id "WAC.133" +go +setboard 3r2k1/p6p/2Q3p1/4q3/2P1p3/P3Pb2/1P3P1P/2K2BR1 b - - +solution Rd1+ +id "WAC.134" +go +setboard 3r1r1k/N2qn1pp/1p2np2/2p5/2Q1P2N/3P4/PP4PP/3R1RK1 b - - +solution Nd4 +id "WAC.135" +go +setboard 6kr/1q2r1p1/1p2N1Q1/5p2/1P1p4/6R1/7P/2R3K1 w - - +solution Rc8+ +id "WAC.136" +go +setboard 3b1rk1/1bq3pp/5pn1/1p2rN2/2p1p3/2P1B2Q/1PB2PPP/R2R2K1 w - - +solution Rd7 +id "WAC.137" +go +setboard r1bq3r/ppppR1p1/5n1k/3P4/6pP/3Q4/PP1N1PP1/5K1R w - - +solution h5 +id "WAC.138" +go +setboard rnb3kr/ppp2ppp/1b6/3q4/3pN3/Q4N2/PPP2KPP/R1B1R3 w - - +solution Nf6+ +id "WAC.139" +go +setboard r2b1rk1/pq4p1/4ppQP/3pB1p1/3P4/2R5/PP3PP1/5RK1 w - - +solution Rc7 +id "WAC.140" +go +setboard 4r1k1/p1qr1p2/2pb1Bp1/1p5p/3P1n1R/1B3P2/PP3PK1/2Q4R w - - +solution Qxf4 +id "WAC.141" +go +setboard r2q3n/ppp2pk1/3p4/5Pr1/2NP1Qp1/2P2pP1/PP3K2/4R2R w - - +solution Re8 +solution f6+ +id "WAC.142" +go +setboard 5b2/pp2r1pk/2pp1pRp/4rP1N/2P1P3/1P4QP/P3q1P1/5R1K w - - +solution Rxh6+ +id "WAC.143" +go +setboard r2q1rk1/pp3ppp/2p2b2/8/B2pPPb1/7P/PPP1N1P1/R2Q1RK1 b - - +solution d3 +id "WAC.144" +go +setboard r1bq4/1p4kp/3p1n2/p4pB1/2pQ4/8/1P4PP/4RRK1 w - - +solution Re8 +id "WAC.145" +go +setboard 8/8/2Kp4/3P1B2/2P2k2/5p2/8/8 w - - +solution Bc8 +id "WAC.146" +go +setboard r2r2k1/ppqbppbp/2n2np1/2pp4/6P1/1P1PPNNP/PBP2PB1/R2QK2R b KQ - +solution Nxg4 +id "WAC.147" +go +setboard 2r1k3/6pr/p1nBP3/1p3p1p/2q5/2P5/P1R4P/K2Q2R1 w - - +solution Rxg7 +id "WAC.148" +go +setboard 6k1/6p1/2p4p/4Pp2/4b1qP/2Br4/1P2RQPK/8 b - - +solution Bxg2 +id "WAC.149" +go +setboard r3r1k1/5p2/pQ1b2pB/1p6/4p3/6P1/Pq2BP1P/2R3K1 b - - +solution Ba3 +solution Bf8 +solution e3 +id "WAC.150" +go +setboard 8/3b2kp/4p1p1/pr1n4/N1N4P/1P4P1/1K3P2/3R4 w - - +solution Nc3 +id "WAC.151" +go +setboard 1br2rk1/1pqb1ppp/p3pn2/8/1P6/P1N1PN1P/1B3PP1/1QRR2K1 w - - +solution Ne4 +id "WAC.152" +go +setboard 2r3k1/q4ppp/p3p3/pnNp4/2rP4/2P2P2/4R1PP/2R1Q1K1 b - - +solution Nxd4 +id "WAC.153" +go +setboard r1b2rk1/2p2ppp/p7/1p6/3P3q/1BP3bP/PP3QP1/RNB1R1K1 w - - +solution Qxf7+ +id "WAC.154" +go +setboard 5bk1/1rQ4p/5pp1/2pP4/3n1PP1/7P/1q3BB1/4R1K1 w - - +solution d6 +id "WAC.155" +go +setboard r1b1qN1k/1pp3p1/p2p3n/4p1B1/8/1BP4Q/PP3KPP/8 w - - +solution Qxh6+ +id "WAC.156" +go +setboard 5rk1/p4ppp/2p1b3/3Nq3/4P1n1/1p1B2QP/1PPr2P1/1K2R2R w - - +solution Ne7+ +id "WAC.157" +go +setboard 5rk1/n1p1R1bp/p2p4/1qpP1QB1/7P/2P3P1/PP3P2/6K1 w - - +solution Rxg7+ +id "WAC.158" +go +setboard r1b2r2/5P1p/ppn3pk/2p1p1Nq/1bP1PQ2/3P4/PB4BP/1R3RK1 w - - +solution Ne6+ +id "WAC.159" +go +setboard qn1kr2r/1pRbb3/pP5p/P2pP1pP/3N1pQ1/3B4/3B1PP1/R5K1 w - - +solution Qxd7+ +id "WAC.160" +go +setboard 3r3k/3r1P1p/pp1Nn3/2pp4/7Q/6R1/Pq4PP/5RK1 w - - +solution Qxd8+ +id "WAC.161" +go +setboard r3kbnr/p4ppp/2p1p3/8/Q1B3b1/2N1B3/PP3PqP/R3K2R w KQkq - +solution Bd5 +id "WAC.162" +go +setboard 5rk1/2p4p/2p4r/3P4/4p1b1/1Q2NqPp/PP3P1K/R4R2 b - - +solution Qg2+ +id "WAC.163" +go +setboard 8/6pp/4p3/1p1n4/1NbkN1P1/P4P1P/1PR3K1/r7 w - - +solution Rxc4+ +id "WAC.164" +go +setboard 1r5k/p1p3pp/8/8/4p3/P1P1R3/1P1Q1qr1/2KR4 w - - +solution Re2 +id "WAC.165" +go +setboard r3r1k1/5pp1/p1p4p/2Pp4/8/q1NQP1BP/5PP1/4K2R b K - +solution d4 +id "WAC.166" +go +setboard 7Q/ppp2q2/3p2k1/P2Ppr1N/1PP5/7R/5rP1/6K1 b - - +solution Rxg2+ +id "WAC.167" +go +setboard r3k2r/pb1q1p2/8/2p1pP2/4p1p1/B1P1Q1P1/P1P3K1/R4R2 b kq - +solution Qd2+ +id "WAC.168" +go +setboard 5rk1/1pp3bp/3p2p1/2PPp3/1P2P3/2Q1B3/4q1PP/R5K1 b - - +solution Bh6 +id "WAC.169" +go +setboard 5r1k/6Rp/1p2p3/p2pBp2/1qnP4/4P3/Q4PPP/6K1 w - - +solution Qxc4 +id "WAC.170" +go +setboard 2rq4/1b2b1kp/p3p1p1/1p1nNp2/7P/1B2B1Q1/PP3PP1/3R2K1 w - - +solution Bh6+ +id "WAC.171" +go +setboard 5r1k/p5pp/8/1P1pq3/P1p2nR1/Q7/5BPP/6K1 b - - +solution Qe1+ +id "WAC.172" +go +setboard 2r1b3/1pp1qrk1/p1n1P1p1/7R/2B1p3/4Q1P1/PP3PP1/3R2K1 w - - +solution Qh6+ +id "WAC.173" +go +setboard 2r2rk1/6p1/p3pq1p/1p1b1p2/3P1n2/PP3N2/3N1PPP/1Q2RR1K b - - +solution Nxg2 +id "WAC.174" +go +setboard r5k1/pppb3p/2np1n2/8/3PqNpP/3Q2P1/PPP5/R4RK1 w - - +solution Nh5 +id "WAC.175" +go +setboard r1bq3r/ppp2pk1/3p1pp1/8/2BbPQ2/2NP2P1/PPP4P/R4R1K b - - +solution Rxh2+ +id "WAC.176" +go +setboard r1b3r1/4qk2/1nn1p1p1/3pPp1P/p4P2/1p3BQN/PKPBN3/3R3R b - - +solution Qa3+ +id "WAC.177" +go +setboard 3r2k1/p1rn1p1p/1p2pp2/6q1/3PQNP1/5P2/P1P4R/R5K1 w - - +solution Nxe6 +id "WAC.178" +go +setboard r1b2r1k/pp4pp/3p4/3B4/8/1QN3Pn/PP3q1P/R3R2K b - - +solution Qg1+ +id "WAC.179" +go +setboard r1q2rk1/p3bppb/3p1n1p/2nPp3/1p2P1P1/6NP/PP2QPB1/R1BNK2R b KQ - +solution Nxd5 +id "WAC.180" +go +setboard r3k2r/2p2p2/p2p1n2/1p2p3/4P2p/1PPPPp1q/1P5P/R1N2QRK b kq - +solution Ng4 +id "WAC.181" +go +setboard r1b2rk1/ppqn1p1p/2n1p1p1/2b3N1/2N5/PP1BP3/1B3PPP/R2QK2R w KQ - +solution Qh5 +id "WAC.182" +go +setboard 1r2k1r1/5p2/b3p3/1p2b1B1/3p3P/3B4/PP2KP2/2R3R1 w - - +solution Bf6 +id "WAC.183" +go +setboard 4kn2/r4p1r/p3bQ2/q1nNP1Np/1p5P/8/PPP3P1/2KR3R w - - +solution Qe7+ +id "WAC.184" +go +setboard 1r1rb1k1/2p3pp/p2q1p2/3PpP1Q/Pp1bP2N/1B5R/1P4PP/2B4K w - - +solution Qxh7+ +id "WAC.185" +go +setboard r5r1/p1q2p1k/1p1R2pB/3pP3/6bQ/2p5/P1P1NPPP/6K1 w - - +solution Bf8+ +id "WAC.186" +go +setboard 6k1/5p2/p3p3/1p3qp1/2p1Qn2/2P1R3/PP1r1PPP/4R1K1 b - - +solution Nh3+ +id "WAC.187" +go +setboard 3RNbk1/pp3p2/4rQpp/8/1qr5/7P/P4P2/3R2K1 w - - +solution Qg7+ +id "WAC.188" +go +setboard 3r1k2/1ppPR1n1/p2p1rP1/3P3p/4Rp1N/5K2/P1P2P2/8 w - - +solution Re8+ +id "WAC.189" +go +setboard 8/p2b2kp/1q1p2p1/1P1Pp3/4P3/3B2P1/P2Q3P/2Nn3K b - - +solution Bh3 +id "WAC.190" +go +setboard 2r1Rn1k/1p1q2pp/p7/5p2/3P4/1B4P1/P1P1QP1P/6K1 w - - +solution Qc4 +id "WAC.191" +go +setboard r3k3/ppp2Npp/4Bn2/2b5/1n1pp3/N4P2/PPP3qP/R2QKR2 b Qq - +solution Nd3+ +id "WAC.192" +go +setboard 5bk1/p4ppp/Qp6/4B3/1P6/Pq2P1P1/2rr1P1P/R4RK1 b - - +solution Qxe3 +id "WAC.193" +go +setboard 5rk1/ppq2ppp/2p5/4bN2/4P3/6Q1/PPP2PPP/3R2K1 w - - +solution Nh6+ +id "WAC.194" +go +setboard 3r1rk1/1p3p2/p3pnnp/2p3p1/2P2q2/1P5P/PB2QPPN/3RR1K1 w - - +solution g3 +id "WAC.195" +go +setboard rr4k1/p1pq2pp/Q1n1pn2/2bpp3/4P3/2PP1NN1/PP3PPP/R1B1K2R b KQ - +solution Nb4 +id "WAC.196" +go +setboard 7k/1p4p1/7p/3P1n2/4Q3/2P2P2/PP3qRP/7K b - - +solution Qf1+ +id "WAC.197" +go +setboard 2br2k1/ppp2p1p/4p1p1/4P2q/2P1Bn2/2Q5/PP3P1P/4R1RK b - - +solution Rd3 +id "WAC.198" +go +setboard r1br2k1/pp2nppp/2n5/1B1q4/Q7/4BN2/PP3PPP/2R2RK1 w - - +solution Bxc6 +solution Rfd1 +id "WAC.199" +go +setboard 2rqrn1k/pb4pp/1p2pp2/n2P4/2P3N1/P2B2Q1/1B3PPP/2R1R1K1 w - - +solution Bxf6 +id "WAC.200" +go +setboard 2b2r1k/4q2p/3p2pQ/2pBp3/8/6P1/1PP2P1P/R5K1 w - - +solution Ra7 +id "WAC.201" +go +setboard QR2rq1k/2p3p1/3p1pPp/8/4P3/8/P1r3PP/1R4K1 b - - +solution Rxa2 +id "WAC.202" +go +setboard r4rk1/5ppp/p3q1n1/2p2NQ1/4n3/P3P3/1B3PPP/1R3RK1 w - - +solution Qh6 +id "WAC.203" +go +setboard r1b1qrk1/1p3ppp/p1p5/3Nb3/5N2/P7/1P4PQ/K1R1R3 w - - +solution Rxe5 +id "WAC.204" +go +setboard r3rnk1/1pq2bb1/p4p2/3p1Pp1/3B2P1/1NP4R/P1PQB3/2K4R w - - +solution Qxg5 +id "WAC.205" +go +setboard 1Qq5/2P1p1kp/3r1pp1/8/8/7P/p4PP1/2R3K1 b - - +solution Rc6 +id "WAC.206" +go +setboard r1bq2kr/p1pp1ppp/1pn1p3/4P3/2Pb2Q1/BR6/P4PPP/3K1BNR w - - +solution Qxg7+ +id "WAC.207" +go +setboard 3r1bk1/ppq3pp/2p5/2P2Q1B/8/1P4P1/P6P/5RK1 w - - +solution Bf7+ +id "WAC.208" +go +setboard 4kb1r/2q2p2/r2p4/pppBn1B1/P6P/6Q1/1PP5/2KRR3 w k - +solution Rxe5+ +id "WAC.209" +go +setboard 3r1rk1/pp1q1ppp/3pn3/2pN4/5PP1/P5PQ/1PP1B3/1K1R4 w - - +solution Rh1 +id "WAC.210" +go +setboard r1bqrk2/pp1n1n1p/3p1p2/P1pP1P1Q/2PpP1NP/6R1/2PB4/4RBK1 w - - +solution Qxf7+ +id "WAC.211" +go +setboard rn1qr2Q/pbppk1p1/1p2pb2/4N3/3P4/2N5/PPP3PP/R4RK1 w - - +solution Qxg7+ +id "WAC.212" +go +setboard 3r1r1k/1b4pp/ppn1p3/4Pp1R/Pn5P/3P4/4QP2/1qB1NKR1 w - - +solution Rxh7+ +id "WAC.213" +go +setboard r2r2k1/1p2qpp1/1np1p1p1/p3N3/2PPN3/bP5R/4QPPP/4R1K1 w - - +solution Ng5 +id "WAC.214" +go +setboard 3r2k1/pb1q1pp1/1p2pb1p/8/3N4/P2QB3/1P3PPP/1Br1R1K1 w - - +solution Qh7+ +id "WAC.215" +go +setboard r2qr1k1/1b1nbppp/p3pn2/1p1pN3/3P1B2/2PB1N2/PP2QPPP/R4RK1 w - - +solution Nxf7 +id "WAC.216" +go +setboard r3kb1r/1pp3p1/p3bp1p/5q2/3QN3/1P6/PBP3P1/3RR1K1 w kq - +solution Qd7+ +id "WAC.217" +go +setboard 6k1/pp5p/2p3q1/6BP/2nPr1Q1/8/PP3R1K/8 w - - +solution Bh6 +id "WAC.218" +go +setboard 7k/p4q1p/1pb5/2p5/4B2Q/2P1B3/P6P/7K b - - +solution Qf1+ +id "WAC.219" +go +setboard 3rr1k1/ppp2ppp/8/5Q2/4n3/1B5R/PPP1qPP1/5RK1 b - - +solution Qxf1+ +id "WAC.220" +go +setboard r3k3/P5bp/2N1bp2/4p3/2p5/6NP/1PP2PP1/3R2K1 w q - +solution Rd8+ +id "WAC.221" +go +setboard 2r1r2k/1q3ppp/p2Rp3/2p1P3/6QB/p3P3/bP3PPP/3R2K1 w - - +solution Bf6 +id "WAC.222" +go +setboard r1bqk2r/pp3ppp/5n2/8/1b1npB2/2N5/PP1Q2PP/1K2RBNR w kq - +solution Nxe4 +id "WAC.223" +go +setboard 5rk1/p1q3pp/1p1r4/2p1pp1Q/1PPn1P2/3B3P/P2R2P1/3R2K1 b - - +solution Rh6 +solution e4 +id "WAC.224" +go +setboard 4R3/4q1kp/6p1/1Q3b2/1P1b1P2/6KP/8/8 b - - +solution Qh4+ +id "WAC.225" +go +setboard 2b2rk1/p1p4p/2p1p1p1/br2N1Q1/1p2q3/8/PB3PPP/3R1RK1 w - - +solution Nf7 +id "WAC.226" +go +setboard 2k1rb1r/ppp3pp/2np1q2/5b2/2B2P2/2P1BQ2/PP1N1P1P/2KR3R b - - +solution d5 +id "WAC.227" +go +setboard r4rk1/1bq1bp1p/4p1p1/p2p4/3BnP2/1N1B3R/PPP3PP/R2Q2K1 w - - +solution Bxe4 +id "WAC.228" +go +setboard 8/8/8/1p5r/p1p1k1pN/P2pBpP1/1P1K1P2/8 b - - +solution Rxh4 +solution b4 +id "WAC.229" +go +setboard 2b5/1r6/2kBp1p1/p2pP1P1/2pP4/1pP3K1/1R3P2/8 b - - +solution Rb4 +id "WAC.230" +go +setboard r4rk1/1b1nqp1p/p5p1/1p2PQ2/2p5/5N2/PP3PPP/R1BR2K1 w - - +solution Bg5 +id "WAC.231" +go +setboard 1R2rq1k/2p3p1/Q2p1pPp/8/4P3/8/P1r3PP/1R4K1 w - - +solution Qb5 +solution Rxe8 +id "WAC.232" +go +setboard 5rk1/p1p2r1p/2pp2p1/4p3/PPPnP3/3Pq1P1/1Q1R1R1P/4NK2 b - - +solution Nb3 +id "WAC.233" +go +setboard 2kr1r2/p6p/5Pp1/2p5/1qp2Q1P/7R/PP6/1KR5 w - - +solution Rb3 +id "WAC.234" +go +setboard 5r2/1p1RRrk1/4Qq1p/1PP3p1/8/4B3/1b3P1P/6K1 w - - +solution Qxf7+ +solution Rxf7+ +id "WAC.235" +go +setboard 1R6/p5pk/4p2p/4P3/8/2r3qP/P3R1b1/4Q1K1 b - - +solution Rc1 +id "WAC.236" +go +setboard r5k1/pQp2qpp/8/4pbN1/3P4/6P1/PPr4P/1K1R3R b - - +solution Rc1+ +id "WAC.237" +go +setboard 1k1r4/pp1r1pp1/4n1p1/2R5/2Pp1qP1/3P2QP/P4PB1/1R4K1 w - - +solution Bxb7 +id "WAC.238" +go +setboard 8/6k1/5pp1/Q6p/5P2/6PK/P4q1P/8 b - - +solution Qf1+ +id "WAC.239" +go +setboard 2b4k/p1b2p2/2p2q2/3p1PNp/3P2R1/3B4/P1Q2PKP/4r3 w - - +solution Qxc6 +id "WAC.240" +go +setboard 2rq1rk1/pp3ppp/2n2b2/4NR2/3P4/PB5Q/1P4PP/3R2K1 w - - +solution Qxh7+ +id "WAC.241" +go +setboard r1b1r1k1/pp1nqp2/2p1p1pp/8/4N3/P1Q1P3/1P3PPP/1BRR2K1 w - - +solution Rxd7 +id "WAC.242" +go +setboard 1r3r1k/3p4/1p1Nn1R1/4Pp1q/pP3P1p/P7/5Q1P/6RK w - - +solution Qe2 +id "WAC.243" +go +setboard r6r/pp3ppp/3k1b2/2pb4/B4Pq1/2P1Q3/P5PP/1RBR2K1 w - - +solution Qxc5+ +id "WAC.244" +go +setboard 4rrn1/ppq3bk/3pPnpp/2p5/2PB4/2NQ1RPB/PP5P/5R1K w - - +solution Qxg6+ +id "WAC.245" +go +setboard 6R1/4qp1p/ppr1n1pk/8/1P2P1QP/6N1/P4PP1/6K1 w - - +solution Qh5+ +id "WAC.246" +go +setboard 2k1r3/1p2Bq2/p2Qp3/Pb1p1p1P/2pP1P2/2P5/2P2KP1/1R6 w - - +solution Rxb5 +id "WAC.247" +go +setboard 5r1k/1p4pp/3q4/3Pp1R1/8/8/PP4PP/4Q1K1 b - - +solution Qc5+ +id "WAC.248" +go +setboard r4rk1/pbq2pp1/1ppbpn1p/8/2PP4/1P1Q1N2/PBB2PPP/R3R1K1 w - - +solution c5 +solution d5 +id "WAC.249" +go +setboard 1b5k/7P/p1p2np1/2P2p2/PP3P2/4RQ1R/q2r3P/6K1 w - - +solution Re8+ +id "WAC.250" +go +setboard k7/p4p2/P1q1b1p1/3p3p/3Q4/7P/5PP1/1R4K1 w - - +solution Qe5 +solution Qf4 +id "WAC.251" +go +setboard 1rb1r1k1/p1p2ppp/5n2/2pP4/5P2/2QB4/qNP3PP/2KRB2R b - - +solution Re2 +id "WAC.252" +go +setboard k5r1/p4b2/2P5/5p2/3P1P2/4QBrq/P5P1/4R1K1 w - - +solution Qe8+ +id "WAC.253" +go +setboard r6k/pp3p1p/2p1bp1q/b3p3/4Pnr1/2PP2NP/PP1Q1PPN/R2B2RK b - - +solution Nxh3 +id "WAC.254" +go +setboard 3r3r/p4pk1/5Rp1/3q4/1p1P2RQ/5N2/P1P4P/2b4K w - - +solution Rfxg6+ +id "WAC.255" +go +setboard 3r1rk1/1pb1qp1p/2p3p1/p7/P2Np2R/1P5P/1BP2PP1/3Q1BK1 w - - +solution Nf5 +id "WAC.256" +go +setboard 4r1k1/pq3p1p/2p1r1p1/2Q1p3/3nN1P1/1P6/P1P2P1P/3RR1K1 w - - +solution Rxd4 +id "WAC.257" +go +setboard r3brkn/1p5p/2p2Ppq/2Pp3B/3Pp2Q/4P1R1/6PP/5R1K w - - +solution Bxg6 +id "WAC.258" +go +setboard r1bq1rk1/ppp2ppp/2np4/2bN1PN1/2B1P3/3p4/PPP2nPP/R1BQ1K1R w - - +solution Qh5 +id "WAC.259" +go +setboard 2r2b1r/p1Nk2pp/3p1p2/N2Qn3/4P3/q6P/P4PP1/1R3K1R w - - +solution Qe6+ +id "WAC.260" +go +setboard r5k1/1bp3pp/p2p4/1p6/5p2/1PBP1nqP/1PP3Q1/R4R1K b - - +solution Nd4 +id "WAC.261" +go +setboard 6k1/p1B1b2p/2b3r1/2p5/4p3/1PP1N1Pq/P2R1P2/3Q2K1 b - - +solution Rh6 +id "WAC.262" +go +setboard rnbqr2k/pppp1Qpp/8/b2NN3/2B1n3/8/PPPP1PPP/R1B1K2R w KQ - +solution Qg8+ +id "WAC.263" +go +setboard r2r2k1/1R2qp2/p5pp/2P5/b1PN1b2/P7/1Q3PPP/1B1R2K1 b - - +solution Rab8 +id "WAC.264" +go +setboard 2r1k2r/2pn1pp1/1p3n1p/p3PP2/4q2B/P1P5/2Q1N1PP/R4RK1 w k - +solution exf6 +id "WAC.265" +go +setboard r3q2r/2p1k1p1/p5p1/1p2Nb2/1P2nB2/P7/2PNQbPP/R2R3K b - - +solution Rxh2+ +id "WAC.266" +go +setboard 2r1kb1r/pp3ppp/2n1b3/1q1N2B1/1P2Q3/8/P4PPP/3RK1NR w Kk - +solution Nc7+ +id "WAC.267" +go +setboard 2r3kr/ppp2n1p/7B/5q1N/1bp5/2Pp4/PP2RPPP/R2Q2K1 w - - +solution Re8+ +id "WAC.268" +go +setboard 2kr2nr/pp1n1ppp/2p1p3/q7/1b1P1B2/P1N2Q1P/1PP1BPP1/R3K2R w KQ - +solution axb4 +id "WAC.269" +go +setboard 2r1r1k1/pp1q1ppp/3p1b2/3P4/3Q4/5N2/PP2RPPP/4R1K1 w - - +solution Qg4 +id "WAC.270" +go +setboard 2kr4/ppp3Pp/4RP1B/2r5/5P2/1P6/P2p4/3K4 w - - +solution Rd6 +id "WAC.271" +go +setboard nrq4r/2k1p3/1p1pPnp1/pRpP1p2/P1P2P2/2P1BB2/1R2Q1P1/6K1 w - - +solution Bxc5 +id "WAC.272" +go +setboard 2k4B/bpp1qp2/p1b5/7p/1PN1n1p1/2Pr4/P5PP/R3QR1K b - - +solution Ng3+ +id "WAC.273" +go +setboard 8/1p6/p5R1/k7/Prpp4/K7/1NP5/8 w - - +solution Rb6 +id "WAC.274" +go +setboard r1b2rk1/1p1n1ppp/p1p2q2/4p3/P1B1Pn2/1QN2N2/1P3PPP/3R1RK1 b - - +solution Nxg2 +solution b5 +id "WAC.275" +go +setboard r5k1/pp1RR1pp/1b6/6r1/2p5/B6P/P4qPK/3Q4 w - - +solution Qd5+ +id "WAC.276" +go +setboard 1r4r1/p2kb2p/bq2p3/3p1p2/5P2/2BB3Q/PP4PP/3RKR2 b - - +solution Rg3 +solution Rxg2 +id "WAC.277" +go +setboard r2qkb1r/pppb2pp/2np1n2/5pN1/2BQP3/2N5/PPP2PPP/R1B1K2R w KQkq - +solution Bf7+ +id "WAC.278" +go +setboard r7/4b3/2p1r1k1/1p1pPp1q/1P1P1P1p/PR2NRpP/2Q3K1/8 w - - +solution Nxf5 +id "WAC.279" +go +setboard r1r2bk1/5p1p/pn4p1/N2b4/3Pp3/B3P3/2q1BPPP/RQ3RK1 b - - +solution Bxa3 +id "WAC.280" +go +setboard 2R5/2R4p/5p1k/6n1/8/1P2QPPq/r7/6K1 w - - +solution Rxh7+ +id "WAC.281" +go +setboard 6k1/2p3p1/1p1p1nN1/1B1P4/4PK2/8/2r3b1/7R w - - +solution Rh8+ +id "WAC.282" +go +setboard 3q1rk1/4bp1p/1n2P2Q/3p1p2/6r1/Pp2R2N/1B4PP/7K w - - +solution Ng5 +id "WAC.283" +go +setboard 3r3k/pp4pp/8/1P6/3N4/Pn2P1qb/1B1Q2B1/2R3K1 w - - +solution Nf5 +id "WAC.284" +go +setboard 2rr3k/1b2bppP/p2p1n2/R7/3P4/1qB2P2/1P4Q1/1K5R w - - +solution Qxg7+ +id "WAC.285" +go +setboard 3r1k2/1p6/p4P2/2pP2Qb/8/1P1KB3/P6r/8 b - - +solution Rxd5+ +id "WAC.286" +go +setboard rn3k1r/pp2bBpp/2p2n2/q5N1/3P4/1P6/P1P3PP/R1BQ1RK1 w - - +solution Qh5 +id "WAC.287" +go +setboard r1b2rk1/p4ppp/1p1Qp3/4P2N/1P6/8/P3qPPP/3R1RK1 w - - +solution Nf6+ +id "WAC.288" +go +setboard 2r3k1/5p1p/p3q1p1/2n3P1/1p1QP2P/1P4N1/PK6/2R5 b - - +solution Qe5 +id "WAC.289" +go +setboard 2k2r2/2p5/1pq5/p1p1n3/P1P2n1B/1R4Pp/2QR4/6K1 b - - +solution Ne2+ +id "WAC.290" +go +setboard 5r1k/3b2p1/p6p/1pRpR3/1P1P2q1/P4pP1/5QnP/1B4K1 w - - +solution h3 +id "WAC.291" +go +setboard 4r3/1Q1qk2p/p4pp1/3Pb3/P7/6PP/5P2/4R1K1 w - - +solution d6+ +id "WAC.292" +go +setboard 1nbq1r1k/3rbp1p/p1p1pp1Q/1p6/P1pPN3/5NP1/1P2PPBP/R4RK1 w - - +solution Nfg5 +id "WAC.293" +go +setboard 3r3k/1r3p1p/p1pB1p2/8/p1qNP1Q1/P6P/1P4P1/3R3K w - - +solution Bf8 +solution Nf5 +solution Qf4 +id "WAC.294" +go +setboard 4r3/p4r1p/R1p2pp1/1p1bk3/4pNPP/2P1K3/2P2P2/3R4 w - - +solution Rxd5+ +id "WAC.295" +go +setboard 3r4/1p2k2p/p1b1p1p1/4Q1Pn/2B3KP/4pP2/PP2R1N1/6q1 b - - +solution Rd4+ +solution Rf8 +id "WAC.296" +go +setboard 3r1rk1/p3qp1p/2bb2p1/2p5/3P4/1P6/PBQN1PPP/2R2RK1 b - - +solution Bxg2 +solution Bxh2+ +id "WAC.297" +go +setboard 3Q4/p3b1k1/2p2rPp/2q5/4B3/P2P4/7P/6RK w - - +solution Qh8+ +id "WAC.298" +go +setboard 1n2rr2/1pk3pp/pNn2p2/2N1p3/8/6P1/PP2PPKP/2RR4 w - - +solution Nca4 +id "WAC.299" +go +setboard b2b1r1k/3R1ppp/4qP2/4p1PQ/4P3/5B2/4N1K1/8 w - - +solution g6 +id "WAC.300" +go +version +quit