commit - /dev/null
commit + 653509f98ce8c3581e61f6039c893eaf4973a6fc
blob - /dev/null
blob + 89f2c8c5fc370e57b51b11abc6b088d31e2b77af (mode 644)
Binary files /dev/null and FICS.1.6.2.tar.gz differ
blob - /dev/null
blob + 98ae35d7db1c5d2084629df2301b635e80174a79 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/.depend.old
+adminproc.o : adminproc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h network.h \
+ command.h variable.h adminproc.h playerdb.h lists.h gamedb.h board.h gameproc.h \
+ obsproc.h ratings.h utils.h multicol.h rmalloc.h talkproc.h comproc.h /usr/include/sys/param.h \
+ /usr/include/sys/syslimits.h /usr/include/machine/param.h /usr/include/machine/limits.h
+algcheck.o : algcheck.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h algcheck.h \
+ board.h movecheck.h utils.h multicol.h
+board.o : board.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h board.h \
+ playerdb.h command.h variable.h lists.h gamedb.h utils.h multicol.h
+channel.o : channel.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h channel.h \
+ network.h command.h variable.h rmalloc.h playerdb.h lists.h
+command.o : command.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h rmalloc.h \
+ command.h variable.h command_list.h comproc.h matchproc.h talkproc.h lists.h \
+ gameproc.h obsproc.h adminproc.h playerdb.h ratings.h eco.h rating_conv.h shutdown.h \
+ movecheck.h board.h ficsmain.h config.h utils.h multicol.h gamedb.h network.h \
+ /usr/include/sys/param.h /usr/include/sys/syslimits.h /usr/include/machine/param.h \
+ /usr/include/machine/limits.h
+talkproc.o : talkproc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h talkproc.h \
+ comproc.h command.h variable.h utils.h multicol.h ficsmain.h config.h playerdb.h \
+ lists.h network.h rmalloc.h gamedb.h board.h gameproc.h obsproc.h formula.h \
+ /usr/include/sys/resource.h
+comproc.o : comproc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h talkproc.h \
+ comproc.h command.h variable.h utils.h multicol.h ficsmain.h config.h playerdb.h \
+ lists.h network.h rmalloc.h gamedb.h board.h gameproc.h obsproc.h ratings.h \
+ formula.h eco.h /usr/include/sys/resource.h
+matchproc.o : matchproc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h talkproc.h \
+ comproc.h command.h variable.h utils.h multicol.h ficsmain.h config.h playerdb.h \
+ lists.h network.h rmalloc.h gamedb.h board.h gameproc.h obsproc.h ratings.h \
+ formula.h eco.h /usr/include/sys/resource.h
+fics_addplayer.o : fics_addplayer.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h utils.h \
+ multicol.h playerdb.h command.h variable.h lists.h
+ficsmain.o : ficsmain.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h ficsmain.h \
+ config.h network.h command.h variable.h playerdb.h lists.h ratings.h utils.h \
+ multicol.h board.h talkproc.h comproc.h shutdown.h eco.h /usr/include/sys/param.h \
+ /usr/include/sys/syslimits.h /usr/include/machine/param.h /usr/include/machine/limits.h
+formula.o : formula.c /usr/include/ctype.h /usr/include/sys/cdefs.h config.h \
+ formula.h playerdb.h command.h variable.h stdinclude.h /usr/include/sys/types.h \
+ /usr/include/machine/endian.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/sys/errno.h \
+ /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h lists.h gamedb.h board.h common.h \
+ vers.h legal.h utils.h multicol.h rmalloc.h network.h ratings.h
+gamedb.o : gamedb.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h ficsmain.h \
+ config.h gamedb.h board.h playerdb.h command.h variable.h lists.h gameproc.h \
+ utils.h multicol.h rmalloc.h eco.h network.h
+gameproc.o : gameproc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h command.h \
+ variable.h ficsmain.h config.h playerdb.h lists.h gamedb.h board.h gameproc.h \
+ obsproc.h movecheck.h utils.h multicol.h ratings.h rmalloc.h comproc.h matchproc.h \
+ eco.h network.h
+obsproc.o : obsproc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h command.h \
+ variable.h ficsmain.h config.h playerdb.h lists.h gamedb.h board.h gameproc.h \
+ obsproc.h movecheck.h utils.h multicol.h ratings.h rmalloc.h comproc.h matchproc.h \
+ formula.h eco.h network.h
+legal.o : legal.c
+lists.o : lists.c lists.h /usr/include/stdio.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ common.h vers.h legal.h multicol.h command.h variable.h stdinclude.h /usr/include/strings.h \
+ /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h /usr/include/sys/dirent.h \
+ /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h /usr/include/stdarg.h \
+ /usr/include/machine/stdarg.h /usr/include/stdlib.h /usr/include/sys/socket.h \
+ /usr/include/netinet/in.h /usr/include/arpa/inet.h /usr/include/netdb.h /usr/include/unistd.h \
+ /usr/include/sys/unistd.h /usr/include/ctype.h /usr/include/sys/errno.h /usr/include/signal.h \
+ /usr/include/sys/signal.h /usr/include/machine/signal.h /usr/include/math.h \
+ /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h /usr/include/sys/ttycom.h \
+ /usr/include/sys/ioccom.h /usr/include/sys/filio.h /usr/include/sys/sockio.h \
+ /usr/include/sys/wait.h utils.h playerdb.h ratings.h rmalloc.h talkproc.h gamedb.h \
+ board.h comproc.h
+makerank.o : makerank.c /usr/include/stdio.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/stdlib.h /usr/include/string.h /usr/include/ctype.h config.h
+movecheck.o : movecheck.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h movecheck.h \
+ board.h algcheck.h gamedb.h utils.h multicol.h network.h command.h variable.h \
+ playerdb.h lists.h
+multicol.o : multicol.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h multicol.h \
+ utils.h rmalloc.h
+network.o : network.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h /usr/include/arpa/telnet.h \
+ ficsmain.h common.h vers.h legal.h utils.h multicol.h playerdb.h command.h variable.h \
+ lists.h network.h rmalloc.h config.h
+playerdb.o : playerdb.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h command.h \
+ variable.h comproc.h playerdb.h lists.h rmalloc.h utils.h multicol.h network.h \
+ ficsmain.h config.h talkproc.h gamedb.h board.h ratings.h
+ratings.o : ratings.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h playerdb.h \
+ command.h variable.h lists.h ratings.h gamedb.h board.h comproc.h ficsmain.h \
+ config.h utils.h multicol.h
+rmalloc.o : rmalloc.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h
+utils.o : utils.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h utils.h \
+ multicol.h playerdb.h command.h variable.h lists.h network.h rmalloc.h config.h
+variable.o : variable.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h variable.h \
+ playerdb.h command.h lists.h utils.h multicol.h ficsmain.h config.h rmalloc.h \
+ board.h talkproc.h comproc.h
+vers.o : vers.c
+eco.o : eco.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h board.h gamedb.h command.h \
+ variable.h playerdb.h lists.h gameproc.h obsproc.h utils.h multicol.h common.h \
+ vers.h legal.h config.h
+rating_conv.o : rating_conv.c rating_conv.h common.h vers.h legal.h stdinclude.h \
+ /usr/include/sys/types.h /usr/include/machine/endian.h /usr/include/sys/cdefs.h \
+ /usr/include/machine/ansi.h /usr/include/machine/types.h /usr/include/strings.h \
+ /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h /usr/include/sys/dirent.h \
+ /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h /usr/include/stdio.h \
+ /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h /usr/include/sys/socket.h \
+ /usr/include/netinet/in.h /usr/include/arpa/inet.h /usr/include/netdb.h /usr/include/unistd.h \
+ /usr/include/sys/unistd.h /usr/include/ctype.h /usr/include/sys/errno.h /usr/include/signal.h \
+ /usr/include/sys/signal.h /usr/include/machine/signal.h /usr/include/math.h \
+ /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h /usr/include/sys/ttycom.h \
+ /usr/include/sys/ioccom.h /usr/include/sys/filio.h /usr/include/sys/sockio.h \
+ /usr/include/sys/wait.h command.h variable.h utils.h multicol.h
+shutdown.o : shutdown.c stdinclude.h /usr/include/sys/types.h /usr/include/machine/endian.h \
+ /usr/include/sys/cdefs.h /usr/include/machine/ansi.h /usr/include/machine/types.h \
+ /usr/include/strings.h /usr/include/string.h /usr/include/sys/dir.h /usr/include/dirent.h \
+ /usr/include/sys/dirent.h /usr/include/sys/stat.h /usr/include/sys/time.h /usr/include/time.h \
+ /usr/include/stdio.h /usr/include/stdarg.h /usr/include/machine/stdarg.h /usr/include/stdlib.h \
+ /usr/include/sys/socket.h /usr/include/netinet/in.h /usr/include/arpa/inet.h \
+ /usr/include/netdb.h /usr/include/unistd.h /usr/include/sys/unistd.h /usr/include/ctype.h \
+ /usr/include/sys/errno.h /usr/include/signal.h /usr/include/sys/signal.h /usr/include/machine/signal.h \
+ /usr/include/math.h /usr/include/sys/file.h /usr/include/sys/fcntl.h /usr/include/sys/ioctl.h \
+ /usr/include/sys/ttycom.h /usr/include/sys/ioccom.h /usr/include/sys/filio.h \
+ /usr/include/sys/sockio.h /usr/include/sys/wait.h common.h vers.h legal.h shutdown.h \
+ command.h variable.h ficsmain.h network.h playerdb.h lists.h utils.h multicol.h
blob - /dev/null
blob + a43ea2126fb6b114bff5f8e003ee118e045dacf1 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/GNU_LICENSE
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.
+ 675 Mass Ave, Cambridge, MA 02139, USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Library General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
+
+ END OF TERMS AND CONDITIONS
+
+ Appendix: How to Apply These Terms to Your New Programs
+
+ If you develop a new program, and you want it to be of the greatest
+possible use to the public, the best way to achieve this is to make it
+free software which everyone can redistribute and change under these terms.
+
+ To do so, attach the following notices to the program. It is safest
+to attach them to the start of each source file to most effectively
+convey the exclusion of warranty; and each file should have at least
+the "copyright" line and a pointer to where the full notice is found.
+
+ <one line to give the program's name and a brief idea of what it does.>
+ Copyright (C) 19yy <name of author>
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+Also add information on how to contact you by electronic and paper mail.
+
+If the program is interactive, make it output a short notice like this
+when it starts in an interactive mode:
+
+ Gnomovision version 69, Copyright (C) 19yy name of author
+ Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
+ This is free software, and you are welcome to redistribute it
+ under certain conditions; type `show c' for details.
+
+The hypothetical commands `show w' and `show c' should show the appropriate
+parts of the General Public License. Of course, the commands you use may
+be called something other than `show w' and `show c'; they could even be
+mouse-clicks or menu items--whatever suits your program.
+
+You should also get your employer (if you work as a programmer) or your
+school, if any, to sign a "copyright disclaimer" for the program, if
+necessary. Here is a sample; alter the names:
+
+ Yoyodyne, Inc., hereby disclaims all copyright interest in the program
+ `Gnomovision' (which makes passes at compilers) written by James Hacker.
+
+ <signature of Ty Coon>, 1 April 1989
+ Ty Coon, President of Vice
+
+This General Public License does not permit incorporating your program into
+proprietary programs. If your program is a subroutine library, you may
+consider it more useful to permit linking proprietary applications with the
+library. If this is what you want to do, use the GNU Library General
+Public License instead of this License.
blob - /dev/null
blob + f4ef7b4d3fe98f0a9369e3c658ec96b58a01d370 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makedist
+# Makefile for tar
+
+distrib:
+ tar cvf - GNU* Make* *.[c,h] READ* | compress > FICS.src_beta-1.2.17.tar.Z
+
+
blob - /dev/null
blob + 0df7ad4432d51c87dba32440415e9b9d89bd3a25 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=cc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+#LNFLAGS=-lm -lcompat -lcrypt
+LNFLAGS=-lm
+
+# dfree is temporary, for debugging only, and works only if you are using
+# the GNU C library --mann
+#MORESRCS=dfree.c
+#MOREOBJS=dfree.o
+#you may have to hash out the above two
+
+# This is just for versions distributed with timeseal.
+#MORESRCS=timeseal.c
+#MOREOBJS=timeseal.o
+
+# Define the system below that you are compiling on.
+# Set the flags for your system
+
+SYSFLAG=-DNETBSD
+
+# The following is needed when using gcc and glibc, as on caissa.
+#MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + 80c15842464df51e2442ef563bd99547b2b58cd6 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.alpha
+# Makefile for FICS
+# This version is for the Alpha under Digital OSF/1 Unix
+#
+# Define the system below that you are compiling on.
+#SYSFLAG= -DSYSV -DSYSTEM_AIX
+SYSFLAG=
+
+# Set the flags for your system
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+#OPTFLAGS=-O
+
+# Turn on debugging
+DEBUGFLAGS= -DDEBUG -g
+
+# Anything else you care to flag?
+#OTHERFLAGS= -qlanglvl=saa
+OTHERFLAGS= -DHAVE_STDARG
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+#CC=gcc -ansi -pedantic -O3 -pipe -fomit-frame-pointer
+#CC=xlc
+CC=cc
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+include ./Makefile.common
blob - /dev/null
blob + 0df7ad4432d51c87dba32440415e9b9d89bd3a25 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.bak
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=cc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+#LNFLAGS=-lm -lcompat -lcrypt
+LNFLAGS=-lm
+
+# dfree is temporary, for debugging only, and works only if you are using
+# the GNU C library --mann
+#MORESRCS=dfree.c
+#MOREOBJS=dfree.o
+#you may have to hash out the above two
+
+# This is just for versions distributed with timeseal.
+#MORESRCS=timeseal.c
+#MOREOBJS=timeseal.o
+
+# Define the system below that you are compiling on.
+# Set the flags for your system
+
+SYSFLAG=-DNETBSD
+
+# The following is needed when using gcc and glibc, as on caissa.
+#MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + 9fb6cb74d0c49722c0c8a8010df9ec8c2ca0d917 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.bsd
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=gcc
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm -lcompat -lcrypt
+
+# dfree is temporary, for debugging only, and works only if you are using
+# the GNU C library --mann
+#MORESRCS=dfree.c
+#MOREOBJS=dfree.o
+#you may have to hash out the above two
+
+# This is just for versions distributed with timeseal.
+MORESRCS=timeseal.c
+MOREOBJS=timeseal.o
+
+# Define the system below that you are compiling on.
+# Set the flags for your system
+
+SYSFLAG=-DNETBSD -DTIMESEAL
+
+# The following is needed when using gcc and glibc, as on caissa.
+#MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + 525f5796008af8261bb508bf262e63630473b428 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.clean
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=gcc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm -lcompat -lcrypt
+
+# dfree is temporary, for debugging only, and works only if you are using
+# the GNU C library --mann
+#MORESRCS=dfree.c
+#MOREOBJS=dfree.o
+#you may have to hash out the above two
+
+# This is just for versions distributed with timeseal.
+MORESRCS=timeseal.c
+MOREOBJS=timeseal.o
+
+# Define the system below that you are compiling on.
+# Set the flags for your system
+
+SYSFLAG=-DNETBSD -DTIMESEAL
+
+# The following is needed when using gcc and glibc, as on caissa.
+#MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + 36b28574d6a9d6c2ae688c914becbdfc399861be (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.common
+#this is the common part of the Makefile regardless of which system
+# you compile on.
+
+#need to sort out lame including of all objects in all programs - DAV
+
+
+SRCS= adminproc.c algcheck.c board.c channel.c command.c talkproc.c \
+ comproc.c matchproc.c fics_addplayer.c ficsmain.c formula.c \
+ gamedb.c gameproc.c obsproc.c legal.c lists.c makerank.c \
+ movecheck.c multicol.c network.c playerdb.c ratings.c \
+ rmalloc.c utils.c variable.c vers.c eco.c rating_conv.c \
+ shutdown.c ${MORESRCS}
+
+OBJS= network.o lists.o formula.o playerdb.o command.o talkproc.o \
+ comproc.o matchproc.o movecheck.o ratings.o gamedb.o channel.o \
+ utils.o rmalloc.o legal.o vers.o variable.o board.o gameproc.o \
+ algcheck.o adminproc.o multicol.o eco.o rating_conv.o shutdown.o \
+ obsproc.o
+
+VERSION=echo 'char SGS_VERS[]=""; char VERS_NUM[]="1.6.2"; char COMP_DATE[]="'`date`'";'
+
+PROGRAM=fics
+ADDPLAYER=fics_addplayer
+#DELPLAYER=fics_delplayer
+#MAILSERVER=fics_mailproc
+#MAILPROC=mailproc
+MAKERANK=makerank
+#MAKEDEPEND=makedepend
+MAKEDEPEND=mkdep
+#DEPFLAG=--
+DEPFLAG=
+
+#all: ${PROGRAM} ${MAILSERVER} ${ADDPLAYER} ${DELPLAYER} ${MAILPROC}
+all: ${PROGRAM} ${MAKERANK} ${ADDPLAYER}
+
+${PROGRAM}: ficsmain.o $(OBJS) $(MOREOBJS)
+ $(CC) ficsmain.o $(CFLAGS) $(OBJS) $(MOREOBJS) $(LNFLAGS) -o ${PROGRAM}
+
+#${MAILSERVER}: fics_mailproc.o $(OBJS)
+# $(CC) fics_mailproc.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${MAILSERVER}
+
+${ADDPLAYER}: fics_addplayer.o $(OBJS) $(MOREOBJS)
+ $(CC) fics_addplayer.o $(CFLAGS) $(OBJS) $(MOREOBJS) $(LNFLAGS) -o ${ADDPLAYER}
+
+#${DELPLAYER}: fics_delplayer.o $(OBJS)
+# $(CC) fics_delplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${DELPLAYER}
+
+#${MAILPROC}: mailproc.o lock.o network.o rmalloc.o
+# $(CC) mailproc.o lock.o network.o rmalloc.o $(CFLAGS) -o ${MAILPROC}
+# $(CC) mailproc.o lock.o network.o rmalloc.o memmove.o $(CFLAGS) -o ${MAILPROC}
+
+${MAKERANK}: makerank.o
+ $(CC) makerank.o $(CFLAGS) $(LNFLAGS) -o ${MAKERANK}
+
+vers.c:
+ ${VERSION} >vers.c
+
+depend:
+ $(MAKEDEPEND) ${DEPFLAG} ${CFLAGS} ${MAKEDEPMORECFLAGS} ${DEPFLAG} ${SRCS}
+
+clean:
+# rm -f *.o ${PROGRAM} ${MAILSERVER} ${ADDPLAYER} ${MAILPROC} ${DELPLAYER} *~ vers.c
+ rm -f *.o ${PROGRAM} ${ADDPLAYER} ${MAKERANK} *~ vers.c
+
+ @ echo "Project cleaned."
+
+
blob - /dev/null
blob + a5226900d8bf52077a327366ac5c6e5a99a1af2f (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.common.bak
+#this is the common part of the Makefile regardless of which system
+# you compile on.
+
+#need to sort out lame including of all objects in all programs - DAV
+
+
+SRCS=adminproc.c algcheck.c board.c channel.c command.c talkproc.c \
+ comproc.c matchproc.c fics_addplayer.c ficsmain.c formula.c \
+ gamedb.c gameproc.c legal.c lists.c makerank.c \
+ movecheck.c multicol.c network.c playerdb.c ratings.c \
+ rmalloc.c utils.c variable.c vers.c eco.c rating_conv.c ${MORESRCS}
+
+OBJS=network.o lists.o formula.o playerdb.o command.o talkproc.o \
+ comproc.o matchproc.o movecheck.o ratings.o gamedb.o channel.o \
+ utils.o rmalloc.o legal.o vers.o variable.o board.o gameproc.o \
+ algcheck.o adminproc.o multicol.o eco.o rating_conv.o
+
+VERSION=echo 'char SGS_VERS[]=""; char VERS_NUM[]="1.3.3"; char COMP_DATE[]="'`date`'";'
+
+PROGRAM=fics
+ADDPLAYER=fics_addplayer
+#DELPLAYER=fics_delplayer
+#MAILSERVER=fics_mailproc
+#MAILPROC=mailproc
+MAKERANK=makerank
+
+#all: ${PROGRAM} ${MAILSERVER} ${ADDPLAYER} ${DELPLAYER} ${MAILPROC}
+all: ${PROGRAM} ${MAKERANK} ${ADDPLAYER}
+
+${PROGRAM}: ficsmain.o $(OBJS) $(MOREOBJS)
+ $(CC) ficsmain.o $(CFLAGS) $(OBJS) $(MOREOBJS) $(LNFLAGS) -o ${PROGRAM}
+
+#${MAILSERVER}: fics_mailproc.o $(OBJS)
+# $(CC) fics_mailproc.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${MAILSERVER}
+
+${ADDPLAYER}: fics_addplayer.o $(OBJS) $(MOREOBJS)
+ $(CC) fics_addplayer.o $(CFLAGS) $(OBJS) $(MOREOBJS) $(LNFLAGS) -o ${ADDPLAYER}
+
+#${DELPLAYER}: fics_delplayer.o $(OBJS)
+# $(CC) fics_delplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${DELPLAYER}
+
+#${MAILPROC}: mailproc.o lock.o network.o rmalloc.o
+# $(CC) mailproc.o lock.o network.o rmalloc.o $(CFLAGS) -o ${MAILPROC}
+# $(CC) mailproc.o lock.o network.o rmalloc.o memmove.o $(CFLAGS) -o ${MAILPROC}
+
+${MAKERANK}: makerank.o
+ $(CC) makerank.o $(CFLAGS) $(LNFLAGS) -o ${MAKERANK}
+
+vers.c:
+ ${VERSION} >vers.c
+
+depend:
+ makedepend -- ${CFLAGS} ${MAKEDEPMORECFLAGS} -- ${SRCS}
+
+clean:
+# rm -f *.o ${PROGRAM} ${MAILSERVER} ${ADDPLAYER} ${MAILPROC} ${DELPLAYER} *~ vers.c
+ rm -f *.o ${PROGRAM} ${ADDPLAYER} ${MAKERANK} *~ vers.c
+
+ @ echo "Project cleaned."
+
+
blob - /dev/null
blob + 7b3bff12243f5cf4d35f6acc4124e7c9fa23d45f (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.in
+##
+## fics - An internet chess server.
+## Copyright (C) 1993 Richard V. Nash
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program 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 General Public License for more details.
+##
+##
+## This is the Makefile template; see machine dependant config.h for
+## more configuration options.
+
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+
+##
+## Where to install FICS
+##
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = ${exec_prefix}/bin
+
+
+##
+## Binaries and Options to use
+##
+CC = @CC@
+CFLAGS = @CFLAGS@ -DTIMESEAL -I${srcdir}
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+LIBS = @LIBS@
+LNFLAGS = @LDFLAGS@ ${LIBS}
+
+
+##
+## Version information
+##
+VERSION=echo 'char SGS_VERS[]=""; char VERS_NUM[]="1.2.3";'
+
+
+SRCS=adminproc.c algcheck.c board.c channel.c command.c talkproc.c comproc.c \
+ fics_addplayer.c ficsmain.c formula.c gamedb.c gameproc.c \
+ get_tcp_conn.c legal.c lists.c makerank.c \
+ movecheck.c multicol.c network.c playerdb.c ratings.c \
+ rmalloc.c utils.c variable.c vers.c eco.c matchproc.c \
+ timeseal.c ${MORESRCS}
+
+OBJS=network.o lists.o formula.o playerdb.o command.o talkproc.o comproc.o movecheck.o \
+ ratings.o gamedb.o channel.o utils.o rmalloc.o legal.o vers.o variable.o \
+ board.o gameproc.o algcheck.o adminproc.o \
+ get_tcp_conn.o multicol.o eco.o matchproc.o timeseal.o ${MOREOBJS}
+
+VERSION=echo 'char SGS_VERS[]=""; char VERS_NUM[]="1.2.18"; char COMP_DATE[]="'`date`'";'
+
+PROGRAM=fics
+ADDPLAYER=fics_addplayer
+#DELPLAYER=fics_delplayer
+#MAILSERVER=fics_mailproc
+#MAILPROC=mailproc
+MAKERANK=makerank
+
+ALL= ${PROGRAM} ${ADDPLAYER} ${MAKERANK}
+
+#all: ${PROGRAM} ${MAILSERVER} ${ADDPLAYER} ${DELPLAYER} ${MAILPROC}
+all: ${ALL}
+
+${PROGRAM}: ficsmain.o $(OBJS)
+ $(CC) ficsmain.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${PROGRAM}
+
+#${MAILSERVER}: fics_mailproc.o $(OBJS)
+# $(CC) fics_mailproc.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${MAILSERVER}
+
+${ADDPLAYER}: fics_addplayer.o $(OBJS)
+ $(CC) fics_addplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${ADDPLAYER}
+
+#${DELPLAYER}: fics_delplayer.o $(OBJS)
+# $(CC) fics_delplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${DELPLAYER}
+
+#${MAILPROC}: mailproc.o lock.o network.o rmalloc.o
+# $(CC) mailproc.o lock.o network.o rmalloc.o $(CFLAGS) -o ${MAILPROC}
+# $(CC) mailproc.o lock.o network.o rmalloc.o memmove.o $(CFLAGS) -o ${MAILPROC}
+
+${MAKERANK}: makerank.o
+ $(CC) makerank.o $(CFLAGS) $(LNFLAGS) -o ${MAKERANK}
+
+vers.c:
+ ${VERSION} >vers.c
+
+depend:
+ makedepend -- ${CFLAGS} ${MAKEDEPMORECFLAGS} -- ${SRCS}
+
+clean:
+ rm -f *.o ${ALL} *~ vers.c
+ @ echo "Project cleaned."
+
+distclean: clean
+ rm -rf Makefile autoconfig.h config.h config.status config.cache \
+ config.log
+
+install:
+ for f in ${ALL}; do ${INSTALL} $$f ${bindir}; done
blob - /dev/null
blob + 7b3bff12243f5cf4d35f6acc4124e7c9fa23d45f (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.in.orig
+##
+## fics - An internet chess server.
+## Copyright (C) 1993 Richard V. Nash
+##
+## This program is free software; you can redistribute it and/or modify
+## it under the terms of the GNU General Public License as published by
+## the Free Software Foundation; either version 2 of the License, or
+## (at your option) any later version.
+##
+## This program 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 General Public License for more details.
+##
+##
+## This is the Makefile template; see machine dependant config.h for
+## more configuration options.
+
+
+SHELL = /bin/sh
+srcdir = @srcdir@
+VPATH = @srcdir@
+
+
+##
+## Where to install FICS
+##
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+bindir = ${exec_prefix}/bin
+
+
+##
+## Binaries and Options to use
+##
+CC = @CC@
+CFLAGS = @CFLAGS@ -DTIMESEAL -I${srcdir}
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+LIBS = @LIBS@
+LNFLAGS = @LDFLAGS@ ${LIBS}
+
+
+##
+## Version information
+##
+VERSION=echo 'char SGS_VERS[]=""; char VERS_NUM[]="1.2.3";'
+
+
+SRCS=adminproc.c algcheck.c board.c channel.c command.c talkproc.c comproc.c \
+ fics_addplayer.c ficsmain.c formula.c gamedb.c gameproc.c \
+ get_tcp_conn.c legal.c lists.c makerank.c \
+ movecheck.c multicol.c network.c playerdb.c ratings.c \
+ rmalloc.c utils.c variable.c vers.c eco.c matchproc.c \
+ timeseal.c ${MORESRCS}
+
+OBJS=network.o lists.o formula.o playerdb.o command.o talkproc.o comproc.o movecheck.o \
+ ratings.o gamedb.o channel.o utils.o rmalloc.o legal.o vers.o variable.o \
+ board.o gameproc.o algcheck.o adminproc.o \
+ get_tcp_conn.o multicol.o eco.o matchproc.o timeseal.o ${MOREOBJS}
+
+VERSION=echo 'char SGS_VERS[]=""; char VERS_NUM[]="1.2.18"; char COMP_DATE[]="'`date`'";'
+
+PROGRAM=fics
+ADDPLAYER=fics_addplayer
+#DELPLAYER=fics_delplayer
+#MAILSERVER=fics_mailproc
+#MAILPROC=mailproc
+MAKERANK=makerank
+
+ALL= ${PROGRAM} ${ADDPLAYER} ${MAKERANK}
+
+#all: ${PROGRAM} ${MAILSERVER} ${ADDPLAYER} ${DELPLAYER} ${MAILPROC}
+all: ${ALL}
+
+${PROGRAM}: ficsmain.o $(OBJS)
+ $(CC) ficsmain.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${PROGRAM}
+
+#${MAILSERVER}: fics_mailproc.o $(OBJS)
+# $(CC) fics_mailproc.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${MAILSERVER}
+
+${ADDPLAYER}: fics_addplayer.o $(OBJS)
+ $(CC) fics_addplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${ADDPLAYER}
+
+#${DELPLAYER}: fics_delplayer.o $(OBJS)
+# $(CC) fics_delplayer.o $(CFLAGS) $(OBJS) $(LNFLAGS) -o ${DELPLAYER}
+
+#${MAILPROC}: mailproc.o lock.o network.o rmalloc.o
+# $(CC) mailproc.o lock.o network.o rmalloc.o $(CFLAGS) -o ${MAILPROC}
+# $(CC) mailproc.o lock.o network.o rmalloc.o memmove.o $(CFLAGS) -o ${MAILPROC}
+
+${MAKERANK}: makerank.o
+ $(CC) makerank.o $(CFLAGS) $(LNFLAGS) -o ${MAKERANK}
+
+vers.c:
+ ${VERSION} >vers.c
+
+depend:
+ makedepend -- ${CFLAGS} ${MAKEDEPMORECFLAGS} -- ${SRCS}
+
+clean:
+ rm -f *.o ${ALL} *~ vers.c
+ @ echo "Project cleaned."
+
+distclean: clean
+ rm -rf Makefile autoconfig.h config.h config.status config.cache \
+ config.log
+
+install:
+ for f in ${ALL}; do ${INSTALL} $$f ${bindir}; done
blob - /dev/null
blob + 90de8f03f71fc5089dcd949aa5060c1c681b430e (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.next
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+# Define the system below that you are compiling on.
+SYSFLAG=-DSYSTEM_NEXT
+
+# Set the flags for your system
+
+# Turn on optimization
+# OPTFLAGS=-O
+
+# Turn on debugging
+DEBUGFLAGS=-g -DDEBUG
+
+# Anything else you care to flag?
+OTHERFLAGS=-Wall
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=cc
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+include ./Makefile.common
blob - /dev/null
blob + 7b7b20211223e83c805f9b9fd05169bd047959b7 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.sgi
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+# Define the system below that you are compiling on.
+SYSFLAG=-DSGI
+# Set the flags for your system
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=gcc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+
+# The following is needed when using gcc and glibc, as on caissa.
+
+MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + a82e6b3ffbf7035f4523c80dc663340eaf5d5f1e (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.sun4
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+# Define the system below that you are compiling on.
+SYSFLAG=-DSYSTEM_SUN4
+# Set the flags for your system
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=gcc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+# dfree is temporary, for debugging only, and works only if you are using
+# the GNU C library --mann
+#MORESRCS=dfree.c
+#MOREOBJS=dfree.o
+#you may have to hash out the above two
+
+# The following is needed when using gcc and glibc, as on caissa.
+
+MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + a87dd9bae52902e1b8939b688ee612c45c64562d (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.sun5
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+# Define the system below that you are compiling on.
+SYSFLAG=-DSYSTEM_SUN5
+# Set the flags for your system
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+#DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=gcc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+
+# The following is needed when using gcc and glibc, as on caissa.
+
+MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + 48b70d5300cb3b8ea238da40041ec1c0356a2e7e (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.sunos-glibc
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+SYSFLAG=-DSYSTEM_SUN4 -DTIMESEAL
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+OPTFLAGS=
+
+# Turn on debugging
+DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-traditional-cpp -Wall -g
+OTHERFLAGS=-Wall -g
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=gcc
+#cc doesn't seem to be supported at present.
+
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS} -I/usr/local/glibc-include
+LNFLAGS=-lm -L/usr/local/lib/glibc
+
+# dfree is temporary, for debugging only, and works only if you are using
+# the GNU C library --mann
+#MORESRCS=dfree.c
+#MOREOBJS=dfree.o
+#you may have to hash out the above two
+
+# This is just for versions distributed with timeseal.
+MORESRCS=timeseal.c
+MOREOBJS=timeseal.o
+
+# Define the system below that you are compiling on.
+# Set the flags for your system
+
+SYSFLAG=-DSYSTEM_SUN4 -DTIMESEAL
+
+# The following is needed when using gcc and glibc, as on caissa.
+MAKEDEPMORECFLAGS= -I/usr/local/include -I/usr/local/lib/gcc-lib/sparc-sun-sunos4.1.3/2.6.3/include
+
+include ./Makefile.common
+# include ./Makedist
+
+#run makedepend to fill out the info below
+# DO NOT DELETE THIS LINE -- make depend depends on it.
blob - /dev/null
blob + 2b5f6881af6f94e21e606d88d14ab6414bc4d347 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.ultrix
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+# Define the system below that you are compiling on.
+# SYSFLAG=-DSYSTEM_NEXT
+SYSFLAG=-DSYSTEM_ULTRIX
+
+# Set the flags for your system
+
+# Turn on optimization
+# There seems to be an optimization bug which screws up
+# ratings calculation.
+# OPTFLAGS=-O
+
+# Turn on debugging
+DEBUGFLAGS=-DDEBUG
+
+# Anything else you care to flag?
+# OTHERFLAGS=-Wall
+
+# Which architectures are you compiling for? (NeXTSTEP)
+#ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=cc
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+include ./Makefile.common
blob - /dev/null
blob + 0af74180b71881d29690156fe504f758cafc41d3 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/Makefile.usl
+# Makefile for FICS
+# This was originally written under NeXTSTEP
+#
+# Define the system below that you are compiling on.
+SYSFLAG=-DSYSTEM_USL
+
+# Set the flags for your system
+
+# Turn on optimization
+# With optimization on you may get errors during compiling.
+# OPTFLAGS=-O
+
+# Turn on debugging
+#DEBUGFLAGS=-g -DDEBUG
+
+# Anything else you care to flag?
+#OTHERFLAGS=-Wall
+
+# Which architectures are you compiling for? (NeXTSTEP)
+# ARCHFLAGS=-arch m68k -arch i386
+
+PROGRAM=fics
+
+
+CC=cc
+CFLAGS=${SYSFLAG} ${OPTFLAGS} ${DEBUGFLAGS} ${OTHERFLAGS} ${ARCHFLAGS}
+LNFLAGS=-lm
+
+include ./Makefile.common
blob - /dev/null
blob + 5a76069161aff6e41f66c24b297187e5889de4db (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/README
+README file for FICS - Free Internet Chess Server
+
+Please report any changes back to chess@ics.onenet.net. The code is
+very volatile right now, so keep gratuitous changes to a minimum. DO NOT
+send mail about the code to Richard Nash. He is no longer working on the
+FICS project. (We thank him for all his past work!)
+
+HOW TO START YOUR CHESS SERVER
+
+A. INTRODUCTION
+ First off, you should be familiar with programming in C and with the
+nuances of the system on which you will be running the server. The
+documentation is sparse, so often the code is the best place to go to find
+the answers.
+
+B. Compiling the code
+ 1. cd FICS
+ 2. Edit the file config.h to set the directories where the program's
+ data can be found.
+ 3. Copy the Makefile for your system to Makefile. At the time of writing
+ this there are only a few machines represented, so you may have to edit.
+ If you create a new Makefile that works on your machine, please mail
+ it back to the above address so that we can include it in the distribution.
+ NB. You may have to # out dfree.c and dfree.o in the makefile - they are
+ for debug perposes only (sun4).
+ 4. type 'makedepend' type 'make'
+ 5. If it doesn't compile, well...do your best. If you modify the code to
+ get it to compile on your machine, use #ifdef's wisely and send the
+ changes back to us so that we can include them in the distribution.
+ Also check the code for already defined ifdefs.
+ 6. Once code is built, start the server with "fics", the default port
+ is 5000. To specify another, use "fics -p #". login as AdminGuy
+ with no password and set his password. :-) Good luck.
+
+
+C. Registering with the ratings server.
+*** THERE IS NO RATINGS SERVER IN OPERATION AT PRESENT ***
+** The procedures below were for FICS 1.0 and are now obsolete **
+** Distributed ratings may come in a later version **
+
+ If you want to be hooked in with the distributed ratings server, and I
+hope everyone does, send mail to XXXXXXXXXXX to get your password and to
+confirm to and from email addresses.
+
+D. Configuring for the ratings server.
+ Once you have your email address, the servers email address and your secret
+code, copy the file config/hostinfo.client.format to config/hostinfo.client.
+Then edit that file and replace the appropriate entry with the correct
+information. Here is what an example should look like.
+
+client fics_client@foobar.com
+fics_server@XXXXXXX.XXX MyPassword 0 0
+
+ The next part is a little tricky, and you may need root privileges on your
+machine to do it. The goal here is this... To get the contents of the mail
+sent to fics_client piped into the fics_mailproc program. If there is no way
+you are getting root privileges, go right to way #4.
+
+1. One way is to create a mail alias that does it.
+
+ Here is the pertanent line from my aliases file.
+
+fics_client: "|/Users/nash/Source/FICS/FICS-distrib/fics_mailproc client"
+
+The '|' character causes mail to fics_client to get sent to the program that
+follows. The 'client' parameter to the fics_mailproc program is important
+because the fics_mailproc program is two-faced. It can run as a client or as
+the server.
+
+ Once you are set up, the ratings server should send you accounts for all
+of the registered network players.
+
+2. Another way is to create a user called fics_client with the same UID as
+ the user you will be running FICS as. This is to allow fics and
+ fics_mailproc to have the same uid. Then, in /etc/crontab put an entry
+ that periodically calls the 'mailproc' program. Here is my entry:
+0,15,30,45 * * * * nash /Users/nash/Source/FICS/FICS-distrib/mailproc /usr/spool/mail/fics_client "/Users/nash/Source/FICS/FICS-distrib/fics_mailproc client"
+
+3. Yet another way is to simply run mailproc by hand when you want mail to
+ be picked up. In a C-shell this works:
+while (1)
+ /Users/nash/Source/FICS/FICS-distrib/mailproc /usr/spool/mail/fics_client "/Users/nash/Source/FICS/FICS-distrib/fics_mailproc client"
+ sleep 900
+end
+
+4. There is yet one more way to set up a connection to the rating's server
+ if there is no way to get the mail client set up. It may be lest reliable
+ than the mail way of doing things because it doesn't have store and
+ forward capability if network errors occur during transmission. But it
+ will probably work. The mailproc program can be a daemon wait for
+ connections on a port and then send what it gets to a program. For
+ example:
+mailproc 5001 "/Users/nash/Source/FICS/FICS-distrib/fics_mailproc client"
+ Will wait for the server to connect and send the mail directly. Of course
+ you will need to set this up with the server administrator so that he
+ knows to send directly rather than through mail.
+
+E. Adding local players.
+ Of course this is your server and you have the write to include or exclude
+players as you like. To add a player user the fics_addplayer function or
+use addplayer when logged in as an ADMIN. To remove a player, just put *
+in the password field of their file. They won't be able to log in.
+
blob - /dev/null
blob + 8a5d0449d5260eb923140acbce40dd0f421b03cd (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/README-UPGRADE_FROM_1.2.3
+If you are running 1.2.3, congratulations on 1) putting up with it until now
+and 2) getting a very fine upgrade! :-)
+
+BEWARE: You must remove all login logs from the data/stats/player-data
+directory. They have changed in format greatly. They will cause a crash. :-)
+
+ cd FICSDIR/data/stats/player_data
+ rm */*.logons
+ cd ..
+ rm logons
+
+Should do it.
+
blob - /dev/null
blob + 6b58291e4e18d336311124bc227b1aa95e1e4ec2 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/README.NEW
+
+Versions up to 1.2.16 and between 1.2.23 and 1.3.2 are approximate.
+Information on changes may not be exact or complete.
+
+1.6.2 News bug fixed (Marsalis), caused crash and corrupted index file.
+ ECO brought back (Sparky), bug fixed for use with scratch games
+ (uninitialized moveList caused crash). Examine can now
+ be used to load board positions (Sparky). Works with
+ scratch games also.
+
+1.6.1 News rewritten (Marsalis), Much faster code. Some crash
+ protection code (writing player files after every 'set'
+ command for example) has been supressed for speed.
+ Bug in new playerfile code fixed (sanity checks added to
+ avoid crashes).
+
+1.6 Playerfile formats completely recoded (DAV) new and old
+ formats recognized. New format is written always. The
+ new format has expanded functionallity, more compact form,
+ and much faster processing.
+
+1.5.2 Ghosts hopefully killed; no more timeseal sitting;
+ Oldmoves implementation changes; game structure shrunk.
+ fics_hostname now takes it's contents from SERVER_NAME,
+ which should nwo be a DNS resolvable hostname.
+ fics_addplayer new account message modernized to include
+ brief instructions on how to connect to the server and
+ and warn about the use of anauthorzied duplicate accounts.
+ both adminproc.c and fics_addplayer modified.
+
+1.5.1 Fixes in journal commands, some bughouse bugs.
+
+1.5.0 Journals allowed. Some fixes for NULL v. NULL games.
+
+1.4.0 Initial bughouse version.
+
+1.3.3 clearing and showing individual messages.
+
+1.3.2 fixes to open file bugs;
+ clearing and showing messages from a particular player.
+
+1.3.1 kibitz level; tell/whisper bugs and similar fixed;
+ noplay and gnotify lists.
+
+1.3.0 new admin structure for coordination, responding to suggestions, etc;
+ got rid of annoyingly large version numbers :-).
+
+1.2.23-1.2.24 ???
+
+1.2.22 Examining of history games supported.
+
+1.2.21 Language variable; can't refresh private games;
+ Got rid of "You are not observing" message when you are observing.
+ New news interface; cnewsi, cnewsf, and news show on startup.
+ Percent of life stats.
+
+1.2.20 New help interface; index command.
+
+1.2.19 Examine mode (without history game support)
+ ECO and NIC codes now supported for history games and for
+ interactive reporting on games in process.
+ PGN format now supported for email of game scores.
+ Direct sendmail support provided with the SENDMAILPROG
+ definition in config.h, which overrides any MAILPROGRAM
+ definition. Provides for more reliable and efficient operation
+ under heavy load.
+
+1.2.18 variable mailmess: mails messages to you.
+ messages give the user feedback on what was sent.
+ simul commands simallabort, simadjourn, simalladjourn
+ (aliases saa sadj saadj)
+ simabort given alias sa
+ cshout and it prompts fixed
+ it gives better feedback
+ can restart simuls (or untimed games in simul form) with simmatch
+ game format reduced in size
+1.2.17 asetpasswd now sends mail to the player telling him the new
+ password.
+ extra info in up for admins
+ annunreg seen by all admins
+ hostinfo and lock removed as was fics_delplayer, fics_mailproc
+ and mail_proc.
+ see messages from one person, clear messages from a person
+ More simul bug fixes.
+ simprev (alias sp), goboard (alias go, goto), gonum commands.
+ allow admin to reset RD; ratings may be set with 0 games played.
+1.2.16 Many simul bugs fixed, one fatal bug corrected which caused
+ a crash during a simul.
+ unobserve command.
+ MAILPROGRAM replaced by "sendmail -t" and appropriate "To:"
+ and subject headers. This should help with blank mail
+ message problem. mailhelp and mailsource still depend on MAILPROGRAM
+ stuff added for SUN5 compilation
+ best info shown in who
+1.2.15 Simul bug fixed - losing connection led to a crash
+ adjudicate written (forcedraw, forcewin, forceres commands removed)
+ hostinfo removed from addplayer
+1.2.14 Simul code made operational.
+ games list ordered.
+ tally code disabled
+1.2.13 forcedraw, forcewin, forceres commands
+ asetv command replaces pose
+1.2.12 bug fixes.
+ pose weakened.
+1.2.11 First stable version of FICS. unnotify and unalias had big problems
+ that led to crashes and corrupt player files.
+ siteinfo removed - caused infinite lag
+ mailmess
+1.2.10 bug fixes, max length enforced in alias to stop a crash.
+1.2.9 autoboot out code added.
+1.2.8 aliases fixed, @ added, can alias system commands
+ flagging without material claims a draw, not a win.
+1.2.7 filter list operational.
+ multicol.c used to drop 2048 bytes
+1.2.6 rank and best, makerank
+ time for next shout shown.
+ bug fix to timelog
+ login/logouts logged
+ addcomment and showcomment
+1.2.5 Summon written.
+ ban list
+ (TD) in who
+ board styles fixed
+ shout quotas, it and shout modified
+ admin command to toggle (*)
+ fixes to up
+ admins can observe anything
+1.2.4 td list
+ qtell, getpi, commands for TD
+ asetblitz, asetstd
+ news,anews
+ wild chess made rated, best shows wild, new file
+ asetwild
+ next
+ SGI compilation possible.
+1.2.3 lists
+ (FM) (GM) (IM) (C) shown in who
+ raisedead given a second argument to rename a player
+ ahelp, info written
+ help files split into help and info
+ shutdown fixed
+1.2.2 internal version
+1.2.1 bug fixes.
+ admin gods can only use pose.
+ siteinfo shown
+1.2 notifiedby flag
+ remplayer, asethandle, raisedead written
+ nuke improved
+ query disabled
+1.1 who bug fixed - caused a crash if more than 10 players on.
+ ++++ shown in who for unreg players
+ early version of nuke.
+ (*) shown if level 10 admin
+ level 60 given title Assistant superuser.
+ who A, who l, who U, who R
+ Look of announce and other stuff improved.
+1.0 Original Nash code.
+-----------------------------------------------------------------------------
+Here is a more stable, hopefully more portable release of the
+FICS source code with many features added.
+
+People who have helped improve this from previous releases
+(March 1st 1995 onward) include (FICS names):
+DAV, foxbat, grimm, Hawk, hersco, loon, mann, Shane, Sparky, vek
+SORRY if you feel you should have been on this list but were forgotten.
+
+And Most thanks to red (Richard Nash) for the original code!
+ And Micheal Moore for the original idea of an ICS.
+
+-- Uploaded by Shane Hudson (Shane on FICS).
+Thanks to everyone for their support of FICS.
+
blob - /dev/null
blob + 3696fdfb5b5dfd51e6270802662843469ef2b1bc (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/README.timeseal
+/*
+
+ The timeseal package must NEVER be distributed without
+ permission from Henrik Gram <u940456@daimi.aau.dk>
+
+ It's security is based SOLELY on keeping the crypt alg.
+ secret.
+
+ Both the timeseal server and client code was written
+ entirely by Henrik Gram.
+
+ Only the FICS sites at chess.onenet.net and *.daimi.aau.dk
+ are allowed to have it and use it - and NEVER charge for
+ its use nor for the distribution of the timeseal client.
+
+*/
blob - /dev/null
blob + 655d207ed592c7e801ff7bb0f0c8d549c29fce26 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/README_LEGAL
+fics - An internet chess server.
+
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ any later version.
+
+ This program 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 General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program; if not, write to the Free Software
+ Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+
+
+You may also contact the author(s) at
+ Richard Nash: email - nash@visus.com
+ phone - (412)-488-3600
+
blob - /dev/null
blob + 9f6fa1b45f39cb79bb6b12e5766f9ec0a4d0a4c1 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/README_Nash
+From nash@nomos.com Tue May 30 07:56:37 1995
+Content-Type: text/plain
+Mime-Version: 1.0 (NeXT Mail 3.3 v118.2)
+From: "Richard V. Nash" <nash@nomos.com>
+Date: Tue, 30 May 95 08:52:10 -0400
+To: danke%daimi.aau.dk.kris%dgate.org.chess%onenet.net.romeo@dcs.warwick.ac.uk
+Subject: Please remove nash@nomos.com and visus.com from help files
+Content-Length: 1130
+Status: RO
+X-Lines: 25
+
+Hello Chess Server Administrators,
+
+ I, nash@nomos.com, am getting dozens of emails everyday inquiring about
+chess servers. I would like to stop this. Could you please remove any
+reference to nash@nomos.com or nash@visus.com from the help files associated
+with FICS. This is in both your running systems and versions of the code that
+is being passed around or placed in ftp'able directories.
+
+ There are also references to ftp.visus.com in help files. These should also
+be removed.
+
+ Could you also pass this message along to anybody that you know who may
+have a copy of FICS but who I've missed on my search for FICS's.
+
+ That said, thanks to all of you for taking the FICS code and making it a
+success! I'm so happy that my work to keep chess servers available and free
+did not fail.
+
+Rich
+-----------------------+---------------------------+
+| Richard V. Nash | NOMOS Corporation |
+| nash@nomos.com | Suite 400 |
+| Tel. (412)-934-5477 | 2591 Wexford-Bayne Road |
+| Fax. (412)-934-5488 | Sewickley, PA 15143 |
++----------------------+---------------------------+
+
blob - /dev/null
blob + a7f3dd89fffac445378d9c514c1646987dddba7c (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/acconfig.h
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+
+ This file contains descriptive text for the C preprocessor macros
+ that are missing in the original acconfig.h of the autoconf
+ distribution, but used in the configure.in of the FICS distribution.
+
+ It is used *only* by the autoheader program contained in the
+ autoconf distribution.
+
+
+ Leave the following blank line there!! Autoheader needs it. */
+
+
+/* Define this to be the return value of the time() function. */
+#undef time_t
+
+/* Undefine, if your compiler doesn't support prototypes */
+#undef HAVE_PROTOTYPES
+
+/* Define, if you have a statfs() function which fills a struct
+ statfs, declared in sys/vfs.h. (NeXTStep) */
+#undef HAVE_STATFS_FILLING_STRUCT_STATFS
+
+/* Define, if you have a statfs() function which fills a struct
+ fs_data, declared in sys/mount.h. (Ultrix) */
+#undef HAVE_STATFS_FILLING_STRUCT_FS_DATA
+
+/* Define, if you have crypt() and it is declared in either
+ crypt.h or unistd.h. */
+#undef HAVE_CRYPT_DECLARED
+
+/* Define this to be tv_usec, if your struct rusage has
+ a member ru_utime.tv_usec.
+ Define this to be tv_nsec, if your struct rusage has
+ a member ru_utime.tv_nsec. */
+#undef TV_USEC
blob - /dev/null
blob + a7f3dd89fffac445378d9c514c1646987dddba7c (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/acconfig.h.orig
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+
+ This file contains descriptive text for the C preprocessor macros
+ that are missing in the original acconfig.h of the autoconf
+ distribution, but used in the configure.in of the FICS distribution.
+
+ It is used *only* by the autoheader program contained in the
+ autoconf distribution.
+
+
+ Leave the following blank line there!! Autoheader needs it. */
+
+
+/* Define this to be the return value of the time() function. */
+#undef time_t
+
+/* Undefine, if your compiler doesn't support prototypes */
+#undef HAVE_PROTOTYPES
+
+/* Define, if you have a statfs() function which fills a struct
+ statfs, declared in sys/vfs.h. (NeXTStep) */
+#undef HAVE_STATFS_FILLING_STRUCT_STATFS
+
+/* Define, if you have a statfs() function which fills a struct
+ fs_data, declared in sys/mount.h. (Ultrix) */
+#undef HAVE_STATFS_FILLING_STRUCT_FS_DATA
+
+/* Define, if you have crypt() and it is declared in either
+ crypt.h or unistd.h. */
+#undef HAVE_CRYPT_DECLARED
+
+/* Define this to be tv_usec, if your struct rusage has
+ a member ru_utime.tv_usec.
+ Define this to be tv_nsec, if your struct rusage has
+ a member ru_utime.tv_nsec. */
+#undef TV_USEC
blob - /dev/null
blob + ed96d4a6cba642d2ed4d3f1fd8d85ddac6332ab9 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/adminproc.c
+/*
+ fics - An internet chess server
+ Copyright (c) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+
+ Continued development of this software is done by the GNU ICS
+ development team. Contact <chess@caissa.onenet.net> with questions.
+
+
+ adminproc.c - All administrative commands and related functions */
+
+
+#include "stdinclude.h"
+#include "common.h"
+#include "network.h"
+#include "adminproc.h"
+#include "command.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "ratings.h"
+#include "utils.h"
+#include "rmalloc.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "multicol.h"
+#include <sys/param.h>
+
+#define PASSLEN 4
+
+PUBLIC int num_anews = -1;
+
+/*
+ * adjudicate
+ *
+ * Usage: adjudicate white_player black_player result
+ *
+ * Adjudicates a saved (stored) game between white_player and black_player.
+ * The result is one of: abort, draw, white, black. "Abort" cancels the game
+ * (no win, loss or draw), "white" gives white_player the win, "black" gives
+ * black_player the win, and "draw" gives a draw.
+ */
+PUBLIC int com_adjudicate(int p, param_list param)
+{
+ int wp, wconnected, bp, bconnected, g, inprogress, confused = 0;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &wp, &wconnected))
+ return COM_OK;
+ if (!FindPlayer(p, param[1].val.word, &bp, &bconnected)) {
+ if (!wconnected)
+ player_remove(wp);
+ return COM_OK;
+ }
+
+ inprogress = ((parray[wp].game >=0) &&(parray[wp].opponent == bp));
+
+ if (inprogress) {
+ g = parray[wp].game;
+ } else {
+ g = game_new();
+ if (game_read(g, wp, bp) < 0) {
+ confused = 1;
+ pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ } else {
+ garray[g].white = wp;
+ garray[g].black = bp;
+ }
+ }
+ if (!confused) {
+ if (strstr("abort", param[2].val.word) != NULL) {
+ game_ended(g, WHITE, END_ADJABORT);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been aborted.",
+ parray[wp].name, parray[wp].name, parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been aborted.",
+ parray[bp].name, parray[wp].name, parray[bp].name);
+ } else if (strstr("draw", param[2].val.word) != NULL) {
+ game_ended(g, WHITE, END_ADJDRAW);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a draw", parray[wp].name, parray[wp].name, parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a draw", parray[bp].name, parray[wp].name, parray[bp].name);
+ } else if (strstr("white", param[2].val.word) != NULL) {
+ game_ended(g, WHITE, END_ADJWIN);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a win", parray[wp].name, parray[wp].name, parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a loss", parray[bp].name, parray[wp].name, parray[bp].name);
+ } else if (strstr("black", param[2].val.word) != NULL) {
+ game_ended(g, BLACK, END_ADJWIN);
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a loss", parray[wp].name, parray[wp].name, parray[bp].name);
+
+ pcommand(p, "message %s Your game \"%s vs. %s\" has been adjudicated "
+ "as a win", parray[bp].name, parray[wp].name, parray[bp].name);
+ } else {
+ confused = 1;
+ pprintf(p, "Result must be one of: abort draw white black\n");
+ }
+ }
+ if (!confused) {
+ pprintf(p, "Game adjudicated.\n");
+ if (!inprogress) {
+ game_delete(wp, bp);
+ } else {
+ return (COM_OK);
+ }
+ }
+ game_remove(g);
+ if (!wconnected)
+ player_remove(wp);
+ if (!bconnected)
+ player_remove(bp);
+ return COM_OK;
+}
+
+/*
+ * create_news_file: Creates either a general or and admin news
+ * file, depending upon the admin switch.
+ */
+PRIVATE int create_news_file(int p, param_list param, int admin)
+{
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+
+ if (admin) {
+ if (param[0].val.integer > num_anews)
+ pprintf(p, "There must be an admin news index #%d before you can create the file.", param[0].val.integer);
+ else {
+ sprintf(filename, "%s/adminnews.%d", news_dir, param[0].val.integer);
+ fp = fopen(filename, "w");
+ fprintf(fp, "%s\n", param[1].val.string);
+ fclose(fp);
+ }
+ } else {
+ if (param[0].val.integer > num_news)
+ pprintf(p, "There must be a news index #%d before you can create the file.", param[0].val.integer);
+ else {
+ sprintf(filename, "%s/news.%d", news_dir, param[0].val.integer);
+ fp = fopen(filename, "w");
+ fprintf(fp, "%s\n", param[1].val.string);
+ fclose(fp);
+ }
+ }
+
+ return COM_OK;
+}
+
+PRIVATE int add_item(char *new_item, char *filename)
+{
+ FILE *new_fp, *old_fp;
+ char tmp_file[MAX_FILENAME_SIZE];
+ char junk[MAX_LINE_SIZE];
+
+ sprintf(tmp_file, "%s/.tmp.idx", news_dir);
+ new_fp = fopen(tmp_file, "w");
+ old_fp = fopen(filename, "r");
+
+ if (!new_fp || !old_fp)
+ return 0;
+
+ fprintf(new_fp, "%s", new_item);
+ while (1) {
+ fgets(junk, MAX_LINE_SIZE, old_fp);
+ if (feof(old_fp))
+ break;
+ fprintf(new_fp, "%s", junk);
+ }
+ fclose(new_fp);
+ fclose(old_fp);
+ remove(filename);
+ rename(tmp_file, filename);
+
+ return 1;
+}
+
+/*
+ * create_news_index: Adds a new item to either the general or admin news
+ * index file, depending upon the admin switch.
+ */
+PRIVATE int create_news_index(int p, param_list param, int admin)
+{
+ char filename[MAX_FILENAME_SIZE];
+ char new_item[MAX_LINE_SIZE];
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+
+ if (admin) {
+ if (strlen(param[0].val.string) > 50)
+ pprintf(p, "Sorry, you must limit an index to 50 charaters! Admin news index not created.\n");
+ else {
+ num_anews++;
+ sprintf(new_item, "%d %d %s\n", (int) time(0), num_anews, param[0].val.string);
+ sprintf(filename, "%s/newadminnews.index", news_dir);
+ if (add_item(new_item, filename)) {
+ pprintf(p, "Index for admin news item #%d created.\n", num_anews);
+ pprintf(p, "Please use 'canewsf' to include more info.\n");
+ } else
+ pprintf(p, "Something went wrong creating item.\nNotify Marsalis.\n");
+ }
+ } else {
+ if (strlen(param[0].val.string) > 50)
+ pprintf(p, "Sorry, you must limit an index to 50 charaters! News index not created.\n");
+ else {
+ num_news++;
+ sprintf(filename, "%s/newnews.index", news_dir);
+ sprintf(new_item, "%d %d %s\n", (int) time(0), num_news, param[0].val.string);
+ if (add_item(new_item, filename)) {
+ pprintf(p, "Index for news item #%d created.\n", num_news);
+ pprintf(p, "Please use 'cnewsf' to include more info.\n");
+ } else
+ pprintf(p, "Something went wrong creating item.\nNotify Marsalis.\n");
+ }
+ }
+
+ return COM_OK;
+}
+
+/* cnewsi
+ *
+ * Usage: cnewsi message
+ *
+ *
+ * This command adds a new item to the news index. The message is limited to
+ * 45 characters for formating purposes. In essence, the news index works
+ * like a newspaper headline, giving the user enough information to know
+ * whether they should read the entire news file for that item. After
+ * creating the news item, the command reports the news item number along
+ * with a reminder to create a news file if necessary.
+ */
+PUBLIC int com_cnewsi(int p, param_list param)
+{
+ return create_news_index(p, param, 0);
+}
+
+/* cnewsf
+ *
+ * Usage: cnewsf # message
+ *
+ * This command allows you to add additional information about a news item
+ * that had previously been created using 'cnewsi'. The '#' is the number
+ * of the news index and 'message' is the additional text. You can also
+ * modify a previous news item description and thus update the news item
+ * easily.
+ */
+PUBLIC int com_cnewsf(int p, param_list param)
+{
+ return create_news_file(p, param, 0);
+}
+
+PUBLIC int com_canewsi(int p, param_list param)
+{
+ return create_news_index(p, param, 1);
+}
+
+PUBLIC int com_canewsf(int p, param_list param)
+{
+ return create_news_file(p, param, 1);
+}
+
+/*
+ * anews
+ *
+ *
+ * Usage: anews [#, all]
+ *
+ * This command is used to display anews (admin news) entries. The
+ * entries are numbered. "Anews #" displays that anews item. "Anews
+ * all" will display all items.
+ *
+ */
+PUBLIC int com_anews(int p, param_list param)
+{
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+ char junk[MAX_LINE_SIZE];
+ char *junkp;
+ int crtime, found = 0;
+ char count[10];
+
+ sprintf(filename, "%s/newadminnews.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Cant find news index.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == 0) {
+
+ /* no params - then just display index over news */
+ sprintf(filename, "%s/newadminnews.index", news_dir);
+ pprintf(p, "Index of recent admin news items:\n");
+ fgets(junk, MAX_LINE_SIZE, fp);
+ sscanf(junk, "%d %s", &crtime, count);
+ rscan_news2(fp, p, 9);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ fclose(fp);
+
+ } else if ((param[0].type == TYPE_WORD) && !strcmp(param[0].val.word, "all")) {
+ /* param all - displays all news items */
+ pprintf(p, "Index of all admin news items:\n");
+ fgets(junk, MAX_LINE_SIZE, fp);
+ sscanf(junkp, "%d %s", &crtime, count);
+ rscan_news(fp, p, 0);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ fclose(fp);
+
+ } else {
+
+ while (!feof(fp) && !found) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (strlen(junk) > 1) {
+ sscanf(junkp, "%d %s", &crtime, count);
+ if (!strcmp(count, param[0].val.word)) {
+ found = 1;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "ANEWS %3s (%s) %s\n", count, fix_time(strltime(&crtime)),
+ junkp);
+ }
+ }
+ }
+ fclose(fp);
+ if (!found) {
+ pprintf(p, "Bad index number!\n");
+ return COM_OK;
+ }
+ /* file exists - show it */
+ sprintf(filename, "%s/adminnews.%s", news_dir, param[0].val.word);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pprintf(p, "No more info.\n");
+ return COM_OK;
+ }
+ fclose(fp);
+ sprintf(filename, "adminnews.%s", param[0].val.word);
+ if (psend_file(p, news_dir, filename) < 0) {
+ pprintf(p, "Internal error - couldn't send news file!\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int strcmpwild(char *mainstr, char *searchstr)
+{
+ int i;
+
+ if (strlen(mainstr) < strlen(searchstr))
+ return 1;
+ for (i = 0; i < strlen(mainstr); i++) {
+ if (searchstr[i] == '*')
+ return 0;
+ if (mainstr[i] != searchstr[i])
+ return 1;
+ }
+ return 0;
+}
+
+/*
+ * chkip
+ *
+ * Usage: chkip ip_address
+ *
+ * This command returns the names of all users currently logged on
+ * from a given IP address.
+ */
+PUBLIC int com_checkIP(int p, param_list param)
+{
+ char *ipstr = param[0].val.word;
+ int p1;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ pprintf(p, "Matches the following player(s): \n\n");
+ for (p1 = 0; p1 < p_num; p1++)
+ if (!strcmpwild(dotQuad(parray[p1].thisHost), ipstr) && (parray[p1].status != PLAYER_EMPTY))
+ pprintf(p, "%16.16s %s\n", parray[p1].name, dotQuad(parray[p1].thisHost));
+ return COM_OK;
+}
+
+PUBLIC int com_checkSOCKET(int p, param_list param)
+{
+ int fd = param[0].val.integer;
+ int p1, flag;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ flag = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].socket == fd) {
+ flag = 1;
+ pprintf(p, "Socket %d is used by %s\n", fd, parray[p1].name);
+ }
+ }
+ if (!flag)
+ pprintf(p, "Socket %d is unused!\n", fd);
+ return COM_OK;
+}
+
+/*
+ * chkpl
+ *
+ * Usage: chkpl handle
+ *
+ * This command displays server information about a given user. Items
+ * displayed are:
+ *
+ * number X in parray of size Y
+ * name
+ * login
+ * fullName
+ * emailAddress
+ * socket
+ * registered
+ * last_tell
+ * last_channel
+ * logon_time
+ * adminLevel
+ * thisHost
+ * lastHost
+ * num_comments
+ */
+PUBLIC int com_checkPLAYER(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ int p1;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ p1 = player_search(p, param[0].val.word);
+ if (!p1)
+ return COM_OK;
+ if (p1 < 0) {
+ p1 = (-p1) - 1;
+ pprintf(p, "%s is not logged in.\n", player);
+ stolower(player);
+ pprintf(p, "name = %s\n", parray[p1].name);
+ pprintf(p, "login = %s\n", parray[p1].login);
+ pprintf(p, "fullName = %s\n", (parray[p1].fullName ? parray[p1].fullName : "(none)"));
+ pprintf(p, "emailAddress = %s\n", (parray[p1].emailAddress ? parray[p1].emailAddress : "(none)"));
+ pprintf(p, "adminLevel = %d\n", parray[p1].adminLevel);
+/* pprintf(p, "network_player = %d\n", parray[p1].network_player); */
+ pprintf(p, "lastHost = %s\n", dotQuad(parray[p1].lastHost));
+ pprintf(p, "num_comments = %d\n", parray[p1].num_comments);
+
+ player_remove(p1);
+ return COM_OK;
+ } else {
+ p1 = p1 - 1;
+ pprintf(p, "%s is number %d in parray of size %d\n", player, p1, p_num + 1);
+ pprintf(p, "name = %s\n", parray[p1].name);
+ pprintf(p, "login = %s\n", parray[p1].login);
+ pprintf(p, "fullName = %s\n", parray[p1].fullName ? parray[p1].fullName : "(none)");
+ pprintf(p, "emailAddress = %s\n", parray[p1].emailAddress ? parray[p1].emailAddress : "(none)");
+ pprintf(p, "socket = %d\n", parray[p1].socket);
+ pprintf(p, "registered = %d\n", parray[p1].registered);
+ pprintf(p, "last_tell = %d\n", parray[p1].last_tell);
+ pprintf(p, "last_channel = %d\n", parray[p1].last_channel);
+ pprintf(p, "logon_time = %s", ctime((time_t *) &parray[p1].logon_time));
+ pprintf(p, "adminLevel = %d\n", parray[p1].adminLevel);
+/* pprintf(p, "network_player = %d\n", parray[p1].network_player); */
+ pprintf(p, "thisHost = %s\n", dotQuad(parray[p1].thisHost));
+ pprintf(p, "lastHost = %s\n", dotQuad(parray[p1].lastHost));
+ pprintf(p, "num_comments = %d\n", parray[p1].num_comments);
+
+ }
+ return COM_OK;
+}
+
+/*
+ * chkts
+ *
+ * Usage: chkts
+ *
+ * This command displays all current users who are using timeseal.
+ */
+PUBLIC int com_checkTIMESEAL(int p, param_list param)
+{
+ int p1, count = 0;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ pprintf(p, "The following player(s) are using timeseal:\n\n");
+
+#ifdef TIMESEAL
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_EMPTY
+ && con[parray[p1].socket].timeseal) {
+ pprintf(p, "%s\n", parray[p1].name);
+ count++;
+ }
+ }
+ pprintf(p, "\nNumber of people using timeseal: %d\n", count);
+#endif
+
+ return COM_OK;
+}
+
+PUBLIC int com_checkGAME (int p,param_list param)
+{
+ int p1,g,link;
+ char tmp[10 + 1 + 7]; /* enough to store number 'black: ' and \0 */
+ int startTime;
+ multicol *m;
+ int found = 0;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+
+ if (g_num == 0) {
+ pprintf (p,"No games are currently linked into the garray structure.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_WORD) { /* a player name */
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s doesn't appear to be logged in.\n", param[0].val.word);
+ pprintf(p,"Searching through garray to find matching game numbers.\n");
+ pprintf(p,"Use chkgame <number> to view the results.\n");
+ m = multicol_start(g_num*2); /* Obviously no more than that */
+ for (g = 0; g < g_num; g++) {
+ multicol_store(m,tmp);
+ if (!(strcasecmp (garray[g].white_name,param[0].val.word))) {
+ sprintf (tmp,"White: %d",g);
+ multicol_store(m,tmp);
+ found = 1;
+ }
+ if (!(strcasecmp (garray[g].black_name,param[0].val.word))) {
+ sprintf (tmp,"Black: %d",g);
+ multicol_store(m,tmp);
+ found = 1;
+ }
+ }
+ if (found)
+ multicol_pprint(m,p,parray[p].d_width,2);
+ else
+ pprintf(p,"No matching games were found.\n");
+ multicol_end(m);
+ return COM_OK;
+ }
+
+ if ((g = parray[p1].game) < 0) {
+ pprintf(p,"%s doesn't appear to be playing a game.\n",parray[p1].name);
+ pprintf(p,"Searching through garray to find matching game numbers.\n");
+ pprintf(p,"Use chkgame <number> to view the results.\n");
+ m = multicol_start(g_num*2); /* Obviously no more than that */
+ for (g = 0; g < g_num; g++) {
+ if ((garray[g].white) == p1) {
+ sprintf (tmp,"White: %d",g);
+ multicol_store(m,tmp);
+ found = 1;
+ }
+ if ((garray[g].black) == p1) {
+ sprintf (tmp,"Black: %d",g);
+ multicol_store(m,tmp);
+ found = 1;
+ }
+ }
+ if (found)
+ multicol_pprint(m,p,parray[p].d_width,2);
+ else
+ pprintf (p,"No matching games were found.\n");
+ multicol_end(m);
+ return COM_OK;
+ }
+ } else {
+ if (((g = param[0].val.integer - 1) < 0) || (g >= g_num)) {
+ pprintf (p, "The current range of game numbers is 1 to %d.\n",g_num);
+ return COM_OK;
+ }
+ }
+ startTime = untenths(garray[g].timeOfStart);
+ pprintf (p,"Current stored info for game %d (garray[%d]):\n",g+1,g);
+ pprintf (p,"Initial white time: %d Initial white increment %d\n",
+ garray[g].wInitTime/600,garray[g].wIncrement/10);
+ pprintf (p,"Initial black time: %d Initial black increment %d\n",
+ garray[g].bInitTime/600,garray[g].bIncrement/10);
+ pprintf (p,"Time of starting: %s\n",strltime (&startTime));
+ pprintf (p,"Game is: %s (%d) vs. %s (%d)\n",garray[g].white_name,garray[g].white_rating,
+ garray[g].black_name,garray[g].black_rating);
+ pprintf (p,"White parray entry: %d Black parray entry %d\n",garray[g].white,garray[g].black);
+ if ((link = garray[g].link) >= 0) {
+ pprintf (p,"Bughouse linked to game: %d\n",garray[g].link + 1);
+ pprintf (p,"Partner is playing game: %s (%d) vs. %s (%d)\n",garray[link].white_name,garray[link].white_rating,
+ garray[link].black_name,garray[link].black_rating);
+ } else
+ pprintf (p,"Game is not bughouse or link to partner's game not found.\n");
+ pprintf (p,"Game is %s\n",(garray[g].rated) ? "rated" : "unrated");
+ pprintf (p,"Game is %s\n",(garray[g].private) ? "private" : "not private");
+ pprintf (p,"Games is of type %s\n",
+ garray[g].type == TYPE_UNTIMED ? "untimed" :
+ garray[g].type == TYPE_BLITZ ? "blitz" :
+ garray[g].type == TYPE_STAND ? "standard" :
+ garray[g].type == TYPE_NONSTANDARD ? "non-standard" :
+ garray[g].type == TYPE_WILD ? "wild" :
+ garray[g].type == TYPE_LIGHT ? "lightning" :
+ garray[g].type == TYPE_BUGHOUSE ? "bughouse" :
+ "Unknown - Error!");
+ pprintf (p,"%d halfmove(s) have been made\n",garray[g].numHalfMoves);
+ if (garray[g].status == GAME_ACTIVE)
+ game_update_time(g);
+ pprintf (p,"White's time %s Black's time ",
+ tenth_str((garray[g].wTime > 0 ? garray[g].wTime : 0), 0));
+ pprintf (p,"%s\n",
+ tenth_str((garray[g].bTime > 0 ? garray[g].bTime : 0), 0));
+ pprintf (p,"The clock is%sticking\n",
+ (garray[g].clockStopped || (garray[g].status != GAME_ACTIVE)) ? " not " : " ");
+ pprintf (p,"Game status: %s\n",
+ garray[g].status == GAME_EMPTY ? "GAME_EMPTY" :
+ garray[g].status == GAME_NEW ? "GAME_NEW" :
+ garray[g].status == GAME_ACTIVE ? "GAME_ACTIVE" :
+ garray[g].status == GAME_EXAMINE ? "GAME_EXAMINE" :
+ "Unknown - Error!");
+ return COM_OK;
+}
+
+/*
+ * remplayer
+ *
+ * Usage: remplayer name
+ *
+ * Removes an account. A copy of its files are saved under .rem.* which can
+ * be found in the appropriate directory (useful in case of an accident).
+ *
+ * The account's details, messages, games and logons are all saved as
+ * 'zombie' files. These zombie accounts are not listed in handles or
+ * totals.
+ */
+PUBLIC int com_remplayer(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ char playerlower[MAX_LOGIN_NAME];
+ int p1, lookup;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ strcpy(playerlower, player);
+ stolower(playerlower);
+ p1 = player_new();
+ lookup = player_read(p1, playerlower);
+ if (!lookup) {
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can't remove an admin with a level higher than or equal to yourself.\n");
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ player_remove(p1);
+ if (lookup) {
+ pprintf(p, "No player by the name %s is registered.\n", player);
+ return COM_OK;
+ }
+ if (player_find_bylogin(playerlower) >= 0) {
+ pprintf(p, "A player by that name is logged in.\n");
+ return COM_OK;
+ }
+ if (!player_kill(playerlower)) {
+ pprintf(p, "Player %s removed.\n", player);
+ UpdateRank(TYPE_BLITZ, NULL, NULL, player);
+ UpdateRank(TYPE_STAND, NULL, NULL, player);
+ UpdateRank(TYPE_WILD, NULL, NULL, player);
+ } else {
+ pprintf(p, "Remplayer failed.\n");
+ }
+ return COM_OK;
+}
+
+/*
+ * raisedead
+ *
+ * Usage: raisedead oldname [newname]
+ *
+ * Restores an account that has been previously removed using "remplayer".
+ * The zombie files from which it came are removed. Under most
+ * circumstances, you restore the account to the same handle it had
+ * before (oldname). However, in some circumstances you may need to
+ * restore the account to a different handle, in which case you include
+ * "newname" as the new handle. After "raisedead", you may need to use the
+ * "asetpasswd" command to get the player started again as a registered
+ * user, especially if the account had been locked
+ * by setting the password to *.
+ */
+PUBLIC int com_raisedead(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ char playerlower[MAX_LOGIN_NAME], newplayerlower[MAX_LOGIN_NAME];
+
+ int p1, p2, lookup;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ strcpy(playerlower, player);
+ stolower(playerlower);
+ if (player_find_bylogin(playerlower) >= 0) {
+ pprintf(p, "A player by that name is logged in.\n");
+ pprintf(p, "Can't raise until they leave.\n");
+ return COM_OK;
+ }
+ p1 = player_new();
+ lookup = player_read(p1, playerlower);
+ player_remove(p1);
+ if (!lookup) {
+ pprintf(p, "A player by the name %s is already registered.\n", player);
+ pprintf(p, "Obtain a new handle for the dead person.\n");
+ pprintf(p, "Then use raisedead [oldname] [newname].\n");
+ return COM_OK;
+ }
+ if (param[1].type == TYPE_NULL) {
+ if (!player_raise(playerlower)) {
+ pprintf(p, "Player %s raised from dead.\n", player);
+
+ p1 = player_new();
+ if (!(lookup = player_read(p1, playerlower))) {
+ if (parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, player, &parray[p1].s_stats, player);
+ if (parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, player, &parray[p1].b_stats, player);
+ if (parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, player, &parray[p1].w_stats, player);
+ }
+ player_remove(p1);
+ } else {
+ pprintf(p, "Raisedead failed.\n");
+ }
+ return COM_OK;
+ } else {
+ char *newplayer = param[1].val.word;
+ strcpy(newplayerlower, newplayer);
+ stolower(newplayerlower);
+ if (player_find_bylogin(newplayerlower) >= 0) {
+ pprintf(p, "A player by the requested name is logged in.\n");
+ pprintf(p, "Can't reincarnate until they leave.\n");
+ return COM_OK;
+ }
+ p2 = player_new();
+ lookup = player_read(p2, newplayerlower);
+ player_remove(p2);
+ if (!lookup) {
+ pprintf(p, "A player by the name %s is already registered.\n", player);
+ pprintf(p, "Obtain another new handle for the dead person.\n");
+ return COM_OK;
+ }
+ if (!player_reincarn(playerlower, newplayerlower)) {
+ pprintf(p, "Player %s reincarnated to %s.\n", player, newplayer);
+ p2 = player_new();
+ if (!(lookup = player_read(p2, newplayerlower))) {
+ strfree(parray[p2].name);
+ parray[p2].name = strdup(newplayer);
+ player_save(p2);
+ if (parray[p2].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, newplayer, &parray[p2].s_stats, newplayer);
+ if (parray[p2].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, newplayer, &parray[p2].b_stats, newplayer);
+ if (parray[p2].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, newplayer, &parray[p2].w_stats, newplayer);
+ }
+ player_remove(p2);
+ } else {
+ pprintf(p, "Raisedead failed.\n");
+ }
+ }
+ return COM_OK;
+}
+
+/*
+ * addplayer
+ *
+ * Usage: addplayer playername emailaddress realname
+ *
+ * Adds a local player to the server with the handle of "playername". For
+ * example:
+ *
+ * addplayer Hawk u940456@daimi.aau.dk Henrik Gram
+ */
+PUBLIC int com_addplayer(int p, param_list param)
+{
+ char text[2048];
+ char *newplayer = param[0].val.word;
+ char *newname = param[2].val.string;
+ char *newemail = param[1].val.word;
+ char password[PASSLEN + 1];
+ char newplayerlower[MAX_LOGIN_NAME];
+ char salt[3];
+ int p1, lookup;
+ int i;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (strlen(newplayer) >= MAX_LOGIN_NAME) {
+ pprintf(p, "Player name is too long\n");
+ return COM_OK;
+ }
+ if (strlen(newplayer) < 3) {
+ pprintf(p, "Player name is too short\n");
+ return COM_OK;
+ }
+ if (!alphastring(newplayer)) {
+ pprintf(p, "Illegal characters in player name. Only A-Za-z allowed.\n");
+ return COM_OK;
+ }
+ strcpy(newplayerlower, newplayer);
+ stolower(newplayerlower);
+ p1 = player_new();
+ lookup = player_read(p1, newplayerlower);
+ if (!lookup) {
+ pprintf(p, "A player by the name %s is already registered.\n", newplayerlower);
+ player_remove(p1);
+ return COM_OK;
+ }
+ parray[p1].name = strdup(newplayer);
+ parray[p1].login = strdup(newplayerlower);
+ parray[p1].fullName = strdup(newname);
+ parray[p1].emailAddress = strdup(newemail);
+ if (strcmp(newemail, "none")) {
+ for (i = 0; i < PASSLEN; i++) {
+ password[i] = 'a' + rand() % 26;
+ }
+ password[i] = '\0';
+ salt[0] = 'a' + rand() % 26;
+ salt[1] = 'a' + rand() % 26;
+ salt[2] = '\0';
+ parray[p1].passwd = strdup(crypt(password, salt));
+ } else {
+ password[0] = '\0';
+ parray[p1].passwd = strdup(password);
+ }
+ parray[p1].registered = 1;
+/* parray[p1].network_player = 0; */
+ parray[p1].rated = 1;
+ player_add_comment(p, p1, "Player added by addplayer.");
+ player_save(p1);
+ player_remove(p1);
+ pprintf(p, "Added: >%s< >%s< >%s< >%s<\n", newplayer, newname, newemail, password);
+ if (strcmp(newemail, "none")) {
+/*
+ sprintf(text, "\nYou have been added as a local player.\n\nLogin Name: "
+ "%s\nFull Name: %s\nEmail Address: %s\nInitial Password: "
+ "%s\n\nIf any of this information is incorrect, please "
+ "contact the administrator\nto get it corrected.\n\n"
+ "Please write down your password.\n\nRegards,\n\nThe FICS admins\n",
+ newplayer, newname, newemail, password);
+*/
+
+ sprintf(text, "\nYour player account has been created.\n\n"
+ "Login Name: %s\nFull Name: %s\nEmail Address: %s\nInitial Password: %s\n\n"
+ "If any of this information is incorrect, please contact the administrator\n"
+ "to get it corrected.\n\n"
+ "You may change your password with the password command on the the server.\n"
+ "\nPlease be advised that if this is an unauthorized duplicate account for\n"
+ "you, by using it you take the risk of being banned from accessing this\n"
+ "chess server.\n\nTo connect to the server and use this account:\n\n"
+ " telnet %s 5000\n\nand enter your handle name and password.\n\n"
+ "Regards,\n\nThe FICS admins\n",
+ newplayer, newname, newemail, password, fics_hostname);
+
+ mail_string_to_address(newemail, "FICS Account Created", text);
+ if ((p1 = player_find_part_login(newplayer)) >= 0) {
+ pprintf_prompt(p1, "\n\nYou are now registered! Confirmation together with\npassword is sent to your email address.\n\n");
+ return COM_OK;
+ }
+ return COM_OK;
+ } else {
+ if ((p1 = player_find_part_login(newplayer)) >= 0) {
+ pprintf_prompt(p1, "\n\nYou are now registered! Your have NO password!\n\n");
+ return COM_OK;
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_pose(int p, param_list param)
+{
+ int p1;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s is not logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can only pose as players below your adminlevel.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Command issued as %s\n", parray[p1].name);
+ pcommand(p1, "%s\n", param[1].val.string);
+ return COM_OK;
+}
+
+/*
+ * asetv
+ *
+ * Usage: asetv user instructions
+ *
+ * This command executes "set" instructions as if they had been made by the
+ * user indicated. For example, "asetv DAV shout 0" would set DAV's shout
+ * variable to 0.
+ */
+PUBLIC int com_asetv(int p, param_list param)
+{
+ int p1;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s is not logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can only aset players below your adminlevel.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Command issued as %s\n", parray[p1].name);
+ pcommand(p1, "set %s\n", param[1].val.string);
+ return COM_OK;
+}
+
+/*
+ * announce
+ *
+ * Usage: announce message
+ *
+ * Broadcasts your message to all logged on users. Announcements reach all
+ * users and cannot be censored in any way (such as by "set shout 0").
+ */
+PUBLIC int com_announce(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n\n **ANNOUNCEMENT** from %s: %s\n\n", parray[p].name, param[0].val.string);
+ }
+ pprintf(p, "\n(%d) **ANNOUNCEMENT** from %s: %s\n\n", count, parray[p].name, param[0].val.string);
+ return COM_OK;
+}
+
+/*
+ * annunreg
+ *
+ * Usage: annunreg message
+ *
+ * Broadcasts your message to all logged on unregistered users, and admins,
+ * too. Announcements reach all unregistered users and admins and cannot be
+ * censored in any way (such as by "set shout 0").
+ */
+PUBLIC int com_annunreg(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if ((parray[p1].registered) && (parray[p1].adminLevel < ADMIN_ADMIN))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n\n **UNREG ANNOUNCEMENT** from %s: %s\n\n", parray[p].name, param[0].val.string);
+ }
+ pprintf(p, "\n(%d) **UNREG ANNOUNCEMENT** from %s: %s\n\n", count, parray[p].name, param[0].val.string);
+ return COM_OK;
+}
+
+PUBLIC int com_muzzle(int p, param_list param)
+{
+ pprintf(p, "Obsolete command: Please use +muzzle and -muzzle.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_cmuzzle(int p, param_list param)
+{
+ pprintf(p, "Obsolete command: Please use +cmuzzle and -cmuzzle.\n");
+ return COM_OK;
+}
+
+/*
+ * asetpasswd
+ *
+ * Usage: asetpasswd player {password,*}
+ *
+ * This command sets the password of the player to the password given.
+ * If '*' is specified then the player's account is locked, and no password
+ * will work until a new one is set by asetpasswd.
+ *
+ * If the player is connected, he is told of the new password and the name
+ * of the admin who changed it, or likewise of his account status. An
+ * email message is mailed to the player's email address as well.
+ */
+PUBLIC int com_asetpasswd(int p, param_list param)
+{
+ int p1, connected;
+ char subject[400], text[10100];
+ char salt[3];
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can only set password for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "You cannot set the password of an unregistered player!\n");
+ return COM_OK;
+ }
+ if (parray[p1].passwd)
+ rfree(parray[p1].passwd);
+ if (param[1].val.word[0] == '*') {
+ parray[p1].passwd = strdup(param[1].val.word);
+ pprintf(p, "Account %s locked!\n", parray[p1].name);
+ sprintf(text, "Password of %s is now useless. Your account at our FICS has been locked.\n", parray[p1].name);
+ } else {
+ salt[0] = 'a' + rand() % 26;
+ salt[1] = 'a' + rand() % 26;
+ salt[2] = '\0';
+ parray[p1].passwd = strdup(crypt(param[1].val.word, salt));
+ sprintf(text, "Password of %s changed to \"%s\".\n", parray[p1].name, param[1].val.word);
+ pprintf(p, "%s", text);
+ }
+ if (param[1].val.word[0] == '*') {
+ sprintf(subject, "FICS: %s has locked your account.", parray[p].name);
+ if (connected)
+ pprintf_prompt(p1, "\n%s\n", subject);
+ } else {
+ sprintf(subject, "FICS: %s has changed your password.", parray[p].name);
+ if (connected)
+ pprintf_prompt(p1, "\n%s\n", subject);
+ }
+ mail_string_to_address(parray[p1].emailAddress, subject, text);
+ player_save(p1);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetemail
+ *
+ * Usage: asetemail player [address]
+ *
+ * Sets the email address of the player to the address given. If the
+ * address is omited, then the player's email address is cleared. The
+ * person's email address is revealed to them when they use the "finger"
+ * command, but no other users -- except admins -- will have another
+ * player's email address displayed.
+ */
+PUBLIC int com_asetemail(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can only set email addr for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (parray[p1].emailAddress)
+ rfree(parray[p1].emailAddress);
+ if (param[1].type == TYPE_NULL) {
+ parray[p1].emailAddress = NULL;
+ pprintf(p, "Email address for %s removed\n", parray[p1].name);
+ } else {
+ parray[p1].emailAddress = strdup(param[1].val.word);
+ pprintf(p, "Email address of %s changed to \"%s\".\n", parray[p1].name, param[1].val.word);
+ }
+ player_save(p1);
+ if (connected) {
+ if (param[1].type == TYPE_NULL) {
+ pprintf_prompt(p1, "\n\n%s has removed your email address.\n\n", parray[p].name);
+ } else {
+ pprintf_prompt(p1, "\n\n%s has changed your email address.\n\n", parray[p].name);
+ }
+ } else {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+/*
+ * asetrealname
+ *
+ * Usage: asetrealname user newname
+ *
+ * This command sets the user's real name (as displayed to admins on finger
+ * notes) to "newname".
+ */
+PUBLIC int com_asetrealname(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can only set real names for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (parray[p1].fullName)
+ rfree(parray[p1].fullName);
+ if (param[1].type == TYPE_NULL) {
+ parray[p1].fullName = NULL;
+ pprintf(p, "Real name for %s removed\n", parray[p1].name);
+ } else {
+ parray[p1].fullName = strdup(param[1].val.word);
+ pprintf(p, "Real name of %s changed to \"%s\".\n", parray[p1].name, param[1].val.word);
+ }
+ player_save(p1);
+ if (connected) {
+ if (param[1].type == TYPE_NULL) {
+ pprintf_prompt(p1, "\n\n%s has removed your real name.\n\n", parray[p].name);
+ } else {
+ pprintf_prompt(p1, "\n\n%s has changed your real name.\n\n", parray[p].name);
+ }
+ } else {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+/*
+ * asethandle
+ *
+ * Usage: asethandle oldname newname
+ *
+ * This command changes the handle of the player from oldname to
+ * newname. The various player information, messages, logins, comments
+ * and games should be automatically transferred to the new account.
+ */
+PUBLIC int com_asethandle(int p, param_list param)
+{
+ char *player = param[0].val.word;
+ char *newplayer = param[1].val.word;
+ char playerlower[MAX_LOGIN_NAME], newplayerlower[MAX_LOGIN_NAME];
+ int p1;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ strcpy(playerlower, player);
+ stolower(playerlower);
+ strcpy(newplayerlower, newplayer);
+ stolower(newplayerlower);
+ if (player_find_bylogin(playerlower) >= 0) {
+ pprintf(p, "A player by that name is logged in.\n");
+ return COM_OK;
+ }
+ if (player_find_bylogin(newplayerlower) >= 0) {
+ pprintf(p, "A player by that new name is logged in.\n");
+ return COM_OK;
+ }
+ p1 = player_new();
+ if (player_read(p1, playerlower)) {
+ pprintf(p, "No player by the name %s is registered.\n", player);
+ player_remove(p1);
+ return COM_OK;
+ } else {
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can't set handles for an admin with a level higher than or equal to yourself.\n");
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ player_remove(p1);
+
+ p1 = player_new();
+ if ((!player_read(p1, newplayerlower)) && (strcmp(playerlower, newplayerlower))) {
+ pprintf(p, "Sorry that handle is already taken.\n");
+ player_remove(p1);
+ return COM_OK;
+ }
+ player_remove(p1);
+
+ if ((!player_rename(playerlower, newplayerlower)) && (!player_read(p1, newplayerlower))) {
+ pprintf(p, "Player %s renamed to %s.\n", player, newplayer);
+ strfree(parray[p1].name);
+ parray[p1].name = strdup(newplayer);
+ player_save(p1);
+ if (parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, newplayer, &parray[p1].s_stats, player);
+ if (parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, newplayer, &parray[p1].b_stats, player);
+ if (parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, newplayer, &parray[p1].w_stats, player);
+ } else {
+ pprintf(p, "Asethandle failed.\n");
+ }
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetadmin
+ *
+ * Usage: asetadmin player AdminLevel
+ *
+ * Sets the admin level of the player with the following restrictions.
+ * 1. You can only set the admin level of players lower than yourself.
+ * 2. You can only set the admin level to a level that is lower than
+ * yourself.
+ */
+PUBLIC int com_asetadmin(int p, param_list param)
+{
+ int p1, connected, oldlevel;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_GOD);
+ if (!FindPlayer(p, param[0].val.word,&p1, &connected))
+ return COM_OK;
+
+ if ((parray[p].adminLevel <= parray[p1].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can only set adminlevel for players below your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if ((parray[p1].login) == (parray[p].login)) {
+ pprintf(p, "You can't change your own adminlevel.\n");
+ return COM_OK;
+ }
+ if ((param[1].val.integer >= parray[p].adminLevel) && !player_ishead(p)) {
+ pprintf(p, "You can't promote someone to or above your adminlevel.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ oldlevel = parray[p1].adminLevel;
+ parray[p1].adminLevel = param[1].val.integer;
+ pprintf(p, "Admin level of %s set to %d.\n", parray[p1].name, parray[p1].adminLevel);
+ player_save(p1);
+ if (connected) {
+ pprintf_prompt(p1, "\n\n%s has set your admin level to %d.\n\n", parray[p].name, parray[p1].adminLevel);
+ } else {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+PRIVATE void SetRating(int p1, param_list param, statistics *s)
+{
+ s->rating = param[1].val.integer;
+ if (s->ltime == 0L)
+ s->sterr = 70.0;
+
+ if (param[2].type == TYPE_INT) {
+ s->win = param[2].val.integer;
+ if (param[3].type == TYPE_INT) {
+ s->los = param[3].val.integer;
+ if (param[4].type == TYPE_INT) {
+ s->dra = param[4].val.integer;
+ if (param[5].type == TYPE_INT) {
+ s->sterr = (double) param[5].val.integer;
+ }
+ }
+ }
+ }
+ s->num = s->win + s->los + s->dra;
+ if (s->num == 0) {
+ s->ltime = 0L;
+#if 0
+ s->dra = 1;
+ s->num = 1;
+#endif
+ } else {
+ s->ltime = time(0);
+ }
+}
+
+/*
+ * asetblitz
+ *
+ * Usage: asetblitz handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Blitz games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses,
+ * # of draws, and ratings deviation.
+ */
+PUBLIC int com_asetblitz(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ SetRating(p1, param, &parray[p1].b_stats);
+ player_save(p1);
+ UpdateRank(TYPE_BLITZ, parray[p1].name, &parray[p1].b_stats,
+ parray[p1].name);
+ pprintf(p, "Blitz rating for %s modified.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetwild
+ *
+ * Usage: asetwild handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Wild games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses,
+ * # of draws, and ratings deviation.
+ */
+PUBLIC int com_asetwild(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ SetRating(p1, param, &parray[p1].w_stats);
+ player_save(p1);
+ UpdateRank(TYPE_WILD, parray[p1].name, &parray[p1].w_stats,
+ parray[p1].name);
+ pprintf(p, "Wild rating for %s modified.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetstd
+ *
+ * Usage: asetstd handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Standard games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses, # of
+ * draws, and ratings deviation.
+ */
+PUBLIC int com_asetstd(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ SetRating(p1, param, &parray[p1].s_stats);
+ player_save(p1);
+ UpdateRank(TYPE_STAND, parray[p1].name, &parray[p1].s_stats,
+ parray[p1].name);
+ pprintf(p, "Standard rating for %s modified.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * asetlight
+ *
+ * Usage: asetlight handle rating won lost drew RD
+ *
+ * This command allows admins to set a user's statistics for Lightning games.
+ * The parameters are self-explanatory: rating, # of wins, # of losses, # of
+ * draws, and ratings deviation.
+ */
+PUBLIC int com_asetlight(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ SetRating(p1, param, &parray[p1].l_stats);
+ player_save(p1);
+ pprintf(p, "Lightning rating for %s modified.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * nuke
+ *
+ * Usage: nuke user
+ *
+ * This command disconnects the user from the server. The user is informed
+ * that she/he has been nuked by the admin named and a comment is
+ * automatically placed in the user's files (if she/he is a registered
+ * user, of course).
+ */
+PUBLIC int com_nuke(int p, param_list param)
+{
+ int p1, fd;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s isn't logged in.\n", param[0].val.word);
+ } else {
+ if ((parray[p].adminLevel > parray[p1].adminLevel) || player_ishead(p)) {
+ pprintf(p, "Nuking: %s\n", param[0].val.word);
+ pprintf(p, "Please leave a comment explaining why %s was nuked.\n", parray[p1].name);
+ pprintf(p1, "\n\n**** You have been kicked out by %s! ****\n\n", parray[p].name);
+ pcommand(p, "addcomment %s Nuked\n", parray[p1].name);
+ fd = parray[p1].socket;
+ process_disconnection(fd);
+ net_close_connection(fd);
+ return COM_OK;
+ } else {
+ pprintf(p, "You need a higher adminlevel to nuke %s!\n", param[0].val.word);
+ }
+ }
+ return COM_OK;
+}
+
+/*
+ * summon
+ *
+ * Usage: summon player
+ *
+ * This command gives a beep and a message to the player indicating that you
+ * want to talk with him/her. The command is useful for waking someone up,
+ * for example a sleepy admin or an ignorant player.
+ */
+PUBLIC int com_summon(int p, param_list param)
+{
+ int p1;
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "%s isn't logged in.\n", param[0].val.word);
+ return COM_OK;
+ } else {
+ pprintf(p1, "\a\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " needs to talk with you. Use tell %s <message> to reply.\a\n", parray[p].name);
+ pprintf(p, "Summoning sent to %s.\n", parray[p1].name);
+ return COM_OK;
+ }
+}
+
+/*
+ * addcomment
+ *
+ * Usage: addcomment user comment
+ *
+ * Places "comment" in the user's comments. If a user has comments, the
+ * number of comments is indicated to admins using the "finger" command.
+ * The comments themselves are displayed by the "showcomments" command.
+ */
+PUBLIC int com_addcomment(int p, param_list param)
+{
+ int p1, connected;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (player_add_comment(p, p1, param[1].val.string)) {
+ pprintf(p, "Error adding comment!\n");
+ } else {
+ pprintf(p, "Comment added for %s.\n", parray[p1].name);
+ player_save(p1);
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * showcomment
+ *
+ * Usage: showcomment user
+ *
+ * This command will display all of the comments added to the user's account.
+ */
+PUBLIC int com_showcomment(int p, param_list param)
+{
+ int p1, connected;
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ ASSERT(param[0].type == TYPE_WORD);
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ player_show_comments(p, p1);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+/*
+ * admin
+ *
+ * Usage: admin
+ *
+ * This command toggles your admin symbol (*) on/off. This symbol appears
+ * in who listings.
+ */
+PUBLIC int com_admin(int p, param_list param)
+{
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ parray[p].i_admin = !(parray[p].i_admin);
+ if (parray[p].i_admin) {
+ pprintf(p, "Admin mode (*) is now shown\n");
+ } else {
+ pprintf(p, "Admin mode (*) is now not shown\n");
+ }
+ return COM_OK;
+}
+
+/*
+ * quota
+ *
+ * Usage: quota [n]
+ *
+ * The command sets the number of seconds (n) for the shout quota, which
+ * affects only those persons on the shout quota list. If no parameter
+ * (n) is given, the current setting is displayed.
+ */
+PUBLIC int com_quota(int p, param_list param)
+{
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (param[0].type == TYPE_NULL) {
+ pprintf(p, "The current shout quota is 2 shouts per %d seconds.\n", quota_time);
+ return COM_OK;
+ }
+ quota_time = param[0].val.integer;
+ pprintf(p, "The shout quota is now 2 shouts per %d seconds.\n", quota_time);
+ return COM_OK;
+}
+
+
+/*
+ * asetmaxplayer
+ *
+ * Usage: asetmaxplayer [n]
+ *
+ * The command sets the maximum number of players (n) who can connect.
+ */
+PUBLIC int com_asetmaxplayer(int p, param_list param)
+{
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ if (param[0].type != TYPE_NULL) {
+ pprintf(p, "Previously %d total conenctions allowed...\n", max_connections);
+ max_connections = param[0].val.integer;
+ if ((max_connections > MAX_PLAYER) || (max_connections > getdtablesize()-4)) {
+ max_connections = MIN(MAX_PLAYER, getdtablesize()-4);
+ pprintf (p, "Value too high. System OS limits us to %d.\n",
+ max_connections);
+ pprintf (p, "For saftey's sake, it should not be higher than %d.\n",
+ max_connections-2);
+ }
+ }
+ pprintf(p,
+ "There are currently %d regular and %d admin connections available,\n",
+ max_connections-10, 10 );
+ pprintf(p,
+ "with %d maximum logins before unregistered login restrictions begin.\n",
+ MAX(max_connections-50, 200) );
+ pprintf(p, "Total allowed connections: %d.\n", max_connections );
+ return COM_OK;
+}
blob - /dev/null
blob + c6a21a7212fb7c97d5c67a08b2ac6060bc12875a (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/adminproc.h
+/* adminproc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _ADMINPROC_H
+#define _ADMINPROC_H
+
+extern int num_anews;
+
+extern int com_addplayer();
+extern int com_adjudicate(int, param_list);
+extern int com_nuke();
+extern int com_pose();
+extern int com_asetv();
+extern int com_announce();
+extern int com_annunreg();
+extern int com_muzzle();
+extern int com_cmuzzle();
+extern int com_asetrealname();
+extern int com_asetpasswd();
+extern int com_asetemail();
+extern int com_asethandle();
+extern int com_asetadmin();
+extern int server_shutdown();
+extern int com_asetblitz();
+extern int com_asetwild();
+extern int com_asetstd();
+extern int com_asetlight();
+extern int com_checkIP();
+extern int com_checkGAME();
+extern int com_checkPLAYER();
+extern int com_checkSOCKET();
+extern int com_checkTIMESEAL();
+extern int com_remplayer();
+extern int com_raisedead();
+extern int strcmpwild();
+extern int com_anews();
+extern int com_cnewsi();
+extern int com_cnewsf();
+extern int com_canewsi();
+extern int com_canewsf();
+extern int com_createadmnews();
+extern int com_summon();
+extern int com_addcomment();
+extern int com_showcomment();
+extern int com_admin();
+extern int com_asetmaxplayer();
+extern int com_quota();
+
+#endif /* _ADMINPROC_H */
+
blob - /dev/null
blob + b53b3a7580295e9e89923e7117a55a2387349493 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/adminproc.o differ
blob - /dev/null
blob + 10fad0c5feb2937d847f9cd8bb746394264b8a28 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/algcheck.c
+/* algcheck.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "algcheck.h"
+#include "movecheck.h"
+#include "board.h"
+#include "utils.h"
+
+/* Well, lets see if I can list the possibilities
+ * Piece moves
+ * Ne4
+ * Nxe4
+ * Nce4
+ * Ncxe4
+ * R2f3
+ * R2xf3
+ * Special pawn moves
+ * e4
+ * ed
+ * exd
+ * exd5
+ * ed5
+ * Drop moves (bughouse, board edit)
+ * P@f7 P*f7
+ * #f7 #Nf7
+ * (o-o, o-o-o) Castling is handled earlier, so don't worry about that
+ * Of course any of these can have a + or ++ or = string on the end, just
+ * cut that off.
+ */
+
+/* f - file
+ * r - rank
+ * p - piece
+ * x - x
+ * @ - drop character (bughouse)
+ */
+char *alg_list[] = {
+ "fxfr", "pxfr", /* These two get confused in case of bishop */
+ "ffr", "pfr", /* These two get confused in case of bishop */
+ "pffr",
+ "pfxfr",
+ "prfr",
+ "prxfr",
+ "fr",
+ "ff",
+ "fxf",
+ "p@fr",
+ "#fr",
+ "#pfr",
+ NULL
+};
+
+#define ALG_UNKNOWN -1
+/* #define ALG_DROP -2 IanO: this is in board.h, used in movecheck.c */
+
+PRIVATE int get_move_info(char *str, int *piece, int *ff, int *fr, int *tf, int *tr, int *bishconfusion)
+{
+ char tmp[1024];
+ char *s;
+ int i, j, len;
+ char c;
+ int matchVal = -1;
+ int lpiece, lff, lfr, ltf, ltr;
+
+ *bishconfusion = 0;
+ strcpy(tmp, str);
+ if ((s = index(tmp, '+'))) { /* Cut off any check marks */
+ *s = '\0';
+ }
+ if ((s = index(tmp, '='))) { /* Cut off any promotion marks */
+ *s = '\0';
+ }
+ *piece = *ff = *fr = *tf = *tr = ALG_UNKNOWN;
+ len = strlen(tmp);
+ for (i = 0; alg_list[i]; i++) {
+ lpiece = lff = lfr = ltf = ltr = ALG_UNKNOWN;
+ if (strlen(alg_list[i]) != len)
+ continue;
+ for (j = len - 1; j >= 0; j--) {
+ switch (alg_list[i][j]) {
+ case 'f':
+ if ((tmp[j] < 'a') || (tmp[j] > 'h'))
+ goto nomatch;
+ if (ltf == ALG_UNKNOWN)
+ ltf = tmp[j] - 'a';
+ else
+ lff = tmp[j] - 'a';
+ break;
+ case 'r':
+ if ((tmp[j] < '1') || (tmp[j] > '8'))
+ goto nomatch;
+ if (ltr == ALG_UNKNOWN)
+ ltr = tmp[j] - '1';
+ else
+ lfr = tmp[j] - '1';
+ break;
+ case 'p':
+ if (isupper(tmp[j]))
+ c = tolower(tmp[j]);
+ else
+ c = tmp[j];
+ if (c == 'k')
+ lpiece = KING;
+ else if (c == 'q')
+ lpiece = QUEEN;
+ else if (c == 'r')
+ lpiece = ROOK;
+ else if (c == 'b')
+ lpiece = BISHOP;
+ else if (c == 'n')
+ lpiece = KNIGHT;
+ else if (c == 'p')
+ lpiece = PAWN;
+ else
+ goto nomatch;
+ break;
+ case 'x':
+ if ((tmp[j] != 'x') && (tmp[j] != 'X'))
+ goto nomatch;
+ break;
+ case '@':
+ if (tmp[j] != '@' && tmp[j] != '*')
+ goto nomatch;
+ lff = lfr = ALG_DROP;
+ break;
+ case '#':
+ if (tmp[j] != '#')
+ goto nomatch;
+ lff = lfr = ALG_DROP;
+ break;
+ default:
+ fprintf(stderr, "Unknown character in algebraic parsing\n");
+ break;
+ }
+ }
+ if (lpiece == ALG_UNKNOWN)
+ lpiece = PAWN;
+ if (lpiece == PAWN && (lfr == ALG_UNKNOWN)) { /* ffr or ff */
+ if (lff != ALG_UNKNOWN) {
+ if (lff == ltf)
+ goto nomatch;
+ if ((lff - ltf != 1) && (ltf - lff != 1))
+ goto nomatch;
+ }
+ }
+ *piece = lpiece; /* We have a match */
+ *tf = ltf;
+ *tr = ltr;
+ *ff = lff;
+ *fr = lfr;
+ if (matchVal != -1) {
+ /* We have two matches, it must be that Bxc4 vs. bxc4 problem */
+ /* Or it could be the Bc4 vs bc4 problem */
+ *bishconfusion = 1;
+ }
+ matchVal = i;
+nomatch:;
+ }
+ if (matchVal != -1)
+ return MS_ALG;
+ else
+ return MS_NOTMOVE;
+}
+
+PUBLIC int alg_is_move(char *mstr)
+{
+ int piece, ff, fr, tf, tr, bc;
+
+ return get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc);
+}
+
+/* We already know it is algebraic, get the move squares */
+PUBLIC int alg_parse_move(char *mstr, game_state_t * gs, move_t * mt)
+{
+ int f, r, tmpr, posf, posr, posr2;
+ int piece, ff, fr, tf, tr, bc;
+
+ if (get_move_info(mstr, &piece, &ff, &fr, &tf, &tr, &bc) != MS_ALG) {
+ fprintf(stderr, "FICS: Shouldn't try to algebraicly parse non-algabraic move string.\n");
+ return MOVE_ILLEGAL;
+ }
+ /* Resolve ambiguities in to-ness */
+ if (tf == ALG_UNKNOWN)
+ return MOVE_AMBIGUOUS; /* Must always know to file */
+ if (tr == ALG_UNKNOWN) {
+ posr = posr2 = ALG_UNKNOWN;
+ if (piece != PAWN)
+ return MOVE_AMBIGUOUS;
+ if (ff == ALG_UNKNOWN)
+ return MOVE_AMBIGUOUS;
+ /* Need to find pawn on ff that can take to tf and fill in ranks */
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if ((ff != ALG_UNKNOWN) && (ff != f))
+ continue;
+ if (piecetype(gs->board[f][r]) != piece)
+ continue;
+ if (gs->onMove == WHITE) {
+ tmpr = r + 1;
+ } else {
+ tmpr = r - 1;
+ }
+/* if ((gs->board[tf][tmpr] == NOPIECE) ||
+ (iscolor(gs->board[tf][tmpr], gs->onMove))) continue;*/
+/* patch from Soso, added by Sparky 3/16/95 */
+ if (gs->board[tf][tmpr] == NOPIECE) {
+ if ((gs->ep_possible[((gs->onMove == WHITE) ? 0 : 1)][ff]) != (tf - ff))
+ continue;
+ } else {
+ if (iscolor(gs->board[tf][tmpr], gs->onMove))
+ continue;
+ }
+
+ if (legal_andcheck_move(gs, f, r, tf, tmpr)) {
+ if ((posr != ALG_UNKNOWN) && (posr2 != ALG_UNKNOWN))
+ return MOVE_AMBIGUOUS;
+ posr = tmpr;
+ posr2 = r;
+ }
+ }
+ tr = posr;
+ fr = posr2;
+ } else if (bc) { /* Could be bxc4 or Bxc4, tr is known */
+ ff = ALG_UNKNOWN;
+ fr = ALG_UNKNOWN;
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if ((piecetype(gs->board[f][r]) != PAWN) && (piecetype(gs->board[f][r]) != BISHOP))
+ continue;
+ if (legal_andcheck_move(gs, f, r, tf, tr)) {
+ if ((piecetype(gs->board[f][r]) == PAWN) && (f != 1))
+ continue;
+ if ((ff != ALG_UNKNOWN) && (fr != ALG_UNKNOWN))
+ return (MOVE_AMBIGUOUS);
+ ff = f;
+ fr = r;
+ }
+ }
+ } else { /* The from position is unknown */
+ posf = ALG_UNKNOWN;
+ posr = ALG_UNKNOWN;
+ if ((ff == ALG_UNKNOWN) || (fr == ALG_UNKNOWN)) {
+ /* Need to find a piece that can go to tf, tr */
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if ((ff != ALG_UNKNOWN) && (ff != f))
+ continue;
+ if ((fr != ALG_UNKNOWN) && (fr != r))
+ continue;
+ if (piecetype(gs->board[f][r]) != piece)
+ continue;
+ if (legal_andcheck_move(gs, f, r, tf, tr)) {
+ if ((posf != ALG_UNKNOWN) && (posr != ALG_UNKNOWN))
+ return MOVE_AMBIGUOUS;
+ posf = f;
+ posr = r;
+ }
+ }
+ } else if (ff == ALG_DROP) {
+ if (legal_andcheck_move(gs, ALG_DROP, piece, tf, tr)) {
+ posf = ALG_DROP;
+ posr = piece;
+ }
+ }
+ ff = posf;
+ fr = posr;
+ }
+ if ((tf == ALG_UNKNOWN) || (tr == ALG_UNKNOWN) ||
+ (ff == ALG_UNKNOWN) || (fr == ALG_UNKNOWN))
+ return MOVE_ILLEGAL;
+ mt->fromFile = ff;
+ mt->fromRank = fr;
+ mt->toFile = tf;
+ mt->toRank = tr;
+ return MOVE_OK;
+}
+
+/* A assumes the move has yet to be made on the board */
+/* this is the old stupid function, we are testing one from soso...
+PUBLIC char *alg_unparse( game_state_t *gs, move_t *mt )
+{
+ static char mStr[20];
+
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+ ((mt->fromFile == 4) && (mt->toFile == 6)) )
+ return "o-o";
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+ ((mt->fromFile == 4) && (mt->toFile == 2)) )
+ return "o-o-o";
+
+ sprintf( mStr, "%c%d%c%d", mt->fromFile+'a', mt->fromRank+1,
+ mt->toFile+'a', mt->toRank+1 );
+ return mStr;
+}
+*/
+
+
+/* A assumes the move has yet to be made on the board */
+
+
+/* Soso: rewrote alg_unparse function.
+ * Algebraic deparser - sets the mStr variable with move description
+ * in short notation. Used in last move report and in 'moves' command.
+ */
+
+PUBLIC char *alg_unparse(game_state_t * gs, move_t * mt)
+{
+ static char mStr[20];
+ char tmp[20];
+ int piece, f, r;
+ int ambig, r_ambig, f_ambig;
+ game_state_t fakeMove;
+
+ if (mt->fromFile == ALG_DROP) {
+ piece = mt->fromRank;
+ } else {
+ piece = piecetype(gs->board[mt->fromFile][mt->fromRank]);
+ }
+
+ if ((piece == KING) && ((mt->fromFile == 4) && (mt->toFile == 6))) {
+ strcpy(mStr, "O-O");
+ goto check;
+ }
+ if ((piece == KING) && ((mt->fromFile == 4) && (mt->toFile == 2))) {
+ strcpy(mStr, "O-O-O");
+ goto check;
+ }
+ strcpy(mStr, "");
+ switch (piece) {
+ case PAWN:
+ if (mt->fromFile == ALG_DROP) {
+ strcpy(mStr,"P");
+ } else if (mt->fromFile != mt->toFile) {
+ sprintf(tmp, "%c", mt->fromFile + 'a');
+ strcpy(mStr, tmp);
+ }
+ break;
+ case KNIGHT:
+ strcpy(mStr, "N");
+ break;
+ case BISHOP:
+ strcpy(mStr, "B");
+ break;
+ case ROOK:
+ strcpy(mStr, "R");
+ break;
+ case QUEEN:
+ strcpy(mStr, "Q");
+ break;
+ case KING:
+ strcpy(mStr, "K");
+ break;
+ default:
+ strcpy(mStr, "");
+ break;
+ }
+
+ if (mt->fromFile == ALG_DROP) {
+ strcat(mStr, DROP_STR);
+ } else {
+ /* Checks for ambiguity in short notation ( Ncb3, R8e8 or so) */
+ if (piece != PAWN) {
+ ambig = r_ambig = f_ambig = 0;
+ for (r = 0; r < 8; r++)
+ for (f = 0; f < 8; f++) {
+ if ((gs->board[f][r] != NOPIECE) && iscolor(gs->board[f][r], gs->onMove)
+ && (piecetype(gs->board[f][r]) == piece) &&
+ ((f != mt->fromFile) || (r != mt->fromRank))) {
+ if (legal_move(gs, f, r, mt->toFile, mt->toRank)) {
+ fakeMove = *gs;
+ fakeMove.board[f][r] = NOPIECE;
+ fakeMove.onMove = CToggle(fakeMove.onMove);
+ gs->onMove = CToggle(gs->onMove);
+
+ /* New bracketing below to try to fix 'ambiguous move' bug. */
+ if ((in_check(gs)) || !in_check(&fakeMove)) {
+ ambig++;
+ }
+ if (f == mt->fromFile) {
+ f_ambig++;
+ ambig++;
+ }
+ if (r == mt->fromRank) {
+ r_ambig++;
+ ambig++;
+ }
+ gs->onMove = CToggle(gs->onMove);
+ }
+ }
+ }
+ if (ambig > 0) {
+ /* Ambiguity in short notation, need to add file,rank or _both_ in
+ notation */
+ if (f_ambig == 0) {
+ sprintf(tmp, "%c", mt->fromFile + 'a');
+ strcat(mStr, tmp);
+ } else if (r_ambig == 0) {
+ sprintf(tmp, "%d", mt->fromRank + 1);
+ strcat(mStr, tmp);
+ } else {
+ sprintf(tmp, "%c%d", mt->fromFile + 'a', mt->fromRank + 1);
+ strcat(mStr, tmp);
+ }
+ }
+ }
+ if ((gs->board[mt->toFile][mt->toRank] != NOPIECE) ||
+ ((piece == PAWN) && (mt->fromFile != mt->toFile))) {
+ strcat(mStr, "x");
+ }
+ }
+ sprintf(tmp, "%c%d", mt->toFile + 'a', mt->toRank + 1);
+ strcat(mStr, tmp);
+
+ if ((piece == PAWN) && (mt->piecePromotionTo != NOPIECE)) {
+ strcat(mStr, "="); /* = before promoting piece */
+ switch (piecetype(mt->piecePromotionTo)) {
+ case KNIGHT:
+ strcat(mStr, "N");
+ break;
+ case BISHOP:
+ strcat(mStr, "B");
+ break;
+ case ROOK:
+ strcat(mStr, "R");
+ break;
+ case QUEEN:
+ strcat(mStr, "Q");
+ break;
+ default:
+ break;
+ }
+ }
+check:;
+ fakeMove = *gs;
+ execute_move(&fakeMove, mt, 0);
+ fakeMove.onMove = CToggle(fakeMove.onMove);
+ if (in_check(&fakeMove)) {
+ strcat(mStr, "+");
+ }
+ return mStr;
+}
blob - /dev/null
blob + 60d971bdc6208358ddb9fe4f5b93a1e795f4af6b (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/algcheck.h
+/* algcheck.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _ALGCHECK_H
+#define _ALGCHECK_H
+
+#ifndef _BOARD_H
+#include "board.h"
+#endif
+
+#define DROP_CHAR '@' /* used by algcheck.c and movecheck.c */
+#define DROP_STR "@"
+
+extern int alg_is_move(char *);
+extern int alg_parse_move(char *, game_state_t *, move_t *);
+extern char *alg_unparse(game_state_t *, move_t *);
+
+/* extern int tolower(); */
+
+#endif /* _ALGCHECK_H */
blob - /dev/null
blob + f16498a4c688e9b3cf3488e7a52fac1b23e736eb (mode 644)
Binary files /dev/null and FICS.DIST/FICS/algcheck.o differ
blob - /dev/null
blob + f3b4d4685cbeb5998bf9154f37bac3d4ffcee1c3 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/autoconfig.h
+/* autoconfig.h. Generated automatically by configure. */
+/* autoconfig.h.in. Generated automatically from configure.in by autoheader. */
+
+/* Define to empty if the keyword does not work. */
+/* #undef const */
+
+/* Define if you don't have vprintf but do have _doprnt. */
+/* #undef HAVE_DOPRNT */
+
+/* Define if you have <sys/wait.h> that is POSIX.1 compatible. */
+#define HAVE_SYS_WAIT_H 1
+
+/* Define if your struct tm has tm_zone. */
+#define HAVE_TM_ZONE 1
+
+/* Define if you don't have tm_zone but do have the external array
+ tzname. */
+/* #undef HAVE_TZNAME */
+
+/* Define if you have the vprintf function. */
+#define HAVE_VPRINTF 1
+
+/* Define if you have the wait3 system call. */
+#define HAVE_WAIT3 1
+
+/* Define to `long' if <sys/types.h> doesn't define. */
+/* #undef off_t */
+
+/* Define as the return type of signal handlers (int or void). */
+#define RETSIGTYPE void
+
+/* Define to `unsigned' if <sys/types.h> doesn't define. */
+/* #undef size_t */
+
+/* Define if you have the ANSI C header files. */
+#define STDC_HEADERS 1
+
+/* Define if you can safely include both <sys/time.h> and <time.h>. */
+#define TIME_WITH_SYS_TIME 1
+
+/* Define if your <sys/time.h> declares struct tm. */
+/* #undef TM_IN_SYS_TIME */
+
+/* Define this to be the return value of the time() function. */
+/* #undef time_t */
+
+/* Define, if you have a statfs() function which fills a struct
+ statfs, declared in sys/vfs.h. (NeXTStep) */
+/* #undef HAVE_STATFS_FILLING_STRUCT_STATFS */
+
+/* Define, if you have a statfs() function which fills a struct
+ fs_data, declared in sys/mount.h. (Ultrix) */
+/* #undef HAVE_STATFS_FILLING_STRUCT_FS_DATA */
+
+/* Define, if you have crypt() and it is declared in either
+ crypt.h or unistd.h. */
+/* #undef HAVE_CRYPT_DECLARED */
+
+/* Define this to be tv_usec, if your struct rusage has
+ a member ru_utime.tv_usec.
+ Define this to be tv_nsec, if your struct rusage has
+ a member ru_utime.tv_nsec. */
+#define TV_USEC tv_usec
+
+/* Define if you have the crypt function. */
+#define HAVE_CRYPT 1
+
+/* Define if you have the gethostname function. */
+#define HAVE_GETHOSTNAME 1
+
+/* Define if you have the gettimeofday function. */
+#define HAVE_GETTIMEOFDAY 1
+
+/* Define if you have the malloc_debug function. */
+/* #undef HAVE_MALLOC_DEBUG */
+
+/* Define if you have the malloc_size function. */
+/* #undef HAVE_MALLOC_SIZE */
+
+/* Define if you have the select function. */
+#define HAVE_SELECT 1
+
+/* Define if you have the socket function. */
+#define HAVE_SOCKET 1
+
+/* Define if you have the statfs function. */
+/* #undef HAVE_STATFS */
+
+/* Define if you have the strcspn function. */
+#define HAVE_STRCSPN 1
+
+/* Define if you have the strdup function. */
+#define HAVE_STRDUP 1
+
+/* Define if you have the strstr function. */
+#define HAVE_STRSTR 1
+
+/* Define if you have the <bstring.h> header file. */
+/* #undef HAVE_BSTRING_H */
+
+/* Define if you have the <crypt.h> header file. */
+/* #undef HAVE_CRYPT_H */
+
+/* Define if you have the <dirent.h> header file. */
+#define HAVE_DIRENT_H 1
+
+/* Define if you have the <fcntl.h> header file. */
+#define HAVE_FCNTL_H 1
+
+/* Define if you have the <math.h> header file. */
+#define HAVE_MATH_H 1
+
+/* Define if you have the <ndir.h> header file. */
+/* #undef HAVE_NDIR_H */
+
+/* Define if you have the <sys/cred.h> header file. */
+/* #undef HAVE_SYS_CRED_H */
+
+/* Define if you have the <sys/dir.h> header file. */
+/* #undef HAVE_SYS_DIR_H */
+
+/* Define if you have the <sys/file.h> header file. */
+#define HAVE_SYS_FILE_H 1
+
+/* Define if you have the <sys/filio.h> header file. */
+#define HAVE_SYS_FILIO_H 1
+
+/* Define if you have the <sys/ioctl.h> header file. */
+#define HAVE_SYS_IOCTL_H 1
+
+/* Define if you have the <sys/mount.h> header file. */
+#define HAVE_SYS_MOUNT_H 1
+
+/* Define if you have the <sys/ndir.h> header file. */
+/* #undef HAVE_SYS_NDIR_H */
+
+/* Define if you have the <sys/param.h> header file. */
+#define HAVE_SYS_PARAM_H 1
+
+/* Define if you have the <sys/resource.h> header file. */
+#define HAVE_SYS_RESOURCE_H 1
+
+/* Define if you have the <sys/rusage.h> header file. */
+/* #undef HAVE_SYS_RUSAGE_H */
+
+/* Define if you have the <sys/stat.h> header file. */
+#define HAVE_SYS_STAT_H 1
+
+/* Define if you have the <sys/time.h> header file. */
+#define HAVE_SYS_TIME_H 1
+
+/* Define if you have the <sys/vfs.h> header file. */
+#define HAVE_SYS_VFS_H 1
+
+/* Define if you have the <unistd.h> header file. */
+#define HAVE_UNISTD_H 1
+
+/* Define if you have the crypt library (-lcrypt). */
+/* #undef HAVE_LIBCRYPT */
+
+/* Define if you have the m library (-lm). */
+#define HAVE_LIBM 1
+
+/* Define if you have the nsl library (-lnsl). */
+#define HAVE_LIBNSL 1
+
+/* Define if you have the resolv library (-lresolv). */
+#define HAVE_LIBRESOLV 1
+
+/* Define if you have the socket library (-lsocket). */
+/* #undef HAVE_LIBSOCKET */
blob - /dev/null
blob + efffcfbca22f553fb2042d281b1b2d4dc5388721 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/board.c
+/* board.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "board.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "utils.h"
+
+extern int style1();
+extern int style2();
+extern int style3();
+extern int style4();
+extern int style5();
+extern int style6();
+extern int style7();
+extern int style8();
+extern int style9();
+extern int style10();
+extern int style11();
+extern int style12();
+extern int style13();
+
+PUBLIC char *wpstring[] = {" ", "P", "N", "B", "R", "Q", "K"};
+PUBLIC char *bpstring[] = {" ", "p", "n", "b", "r", "q", "k"};
+
+PUBLIC int pieceValues[7] = {0, 1, 3, 3, 5, 9, 0};
+PUBLIC int (*styleFuncs[MAX_STYLES]) () = {
+ style1,
+ style2,
+ style3,
+ style4,
+ style5,
+ style6,
+ style7,
+ style8,
+ style9,
+ style10,
+ style11,
+ style12,
+ style13
+};
+
+PRIVATE const int mach_type = (1<<7) | (1<<8) | (1<<9) | (1<<10) | (1<<11);
+#define IsMachineStyle(n) (((1<<(n)) & mach_type) != 0)
+
+PRIVATE char bstring[MAX_BOARD_STRING_LEGTH];
+
+PUBLIC int board_init(game_state_t *b, char *category, char *board)
+{
+ int retval;
+ int wval;
+
+ if (!category || !board || !category[0] || !board[0])
+ retval = board_read_file("standard", "standard", b);
+ else {
+ if (!strcmp(category, "wild")) {
+ if (sscanf(board, "%d", &wval) == 1 && wval >= 1 && wval <= 4)
+ wild_update(wval);
+ }
+ retval = board_read_file(category, board, b);
+ }
+ b->gameNum = -1;
+ return retval;
+}
+
+PUBLIC void board_calc_strength(game_state_t *b, int *ws, int *bs)
+{
+ int r, f;
+ int *p;
+
+ *ws = *bs = 0;
+ for (f = 0; f < 8; f++) {
+ for (r = 0; r < 8; r++) {
+ if (colorval(b->board[r][f]) == WHITE)
+ p = ws;
+ else
+ p = bs;
+ *p += pieceValues[piecetype(b->board[r][f])];
+ }
+ }
+ for (r = PAWN; r <= QUEEN; r++) {
+ *ws += b->holding[0][r-1] * pieceValues[r];
+ *bs += b->holding[1][r-1] * pieceValues[r];
+ }
+}
+
+PRIVATE char *holding_str(int *holding)
+{
+ static char tmp[30];
+ int p,i,j;
+
+ i = 0;
+ for (p = PAWN; p <= QUEEN; p++)
+ {
+ for (j = 0; j < holding[p-1]; j++)
+ {
+ tmp[i++] = wpstring[p][0];
+ }
+ }
+ tmp[i] = '\0';
+ return tmp;
+}
+
+PRIVATE char *append_holding_machine(char *buf, int g, int c, int p)
+{
+ game_state_t *gs = &garray[g].game_state;
+ char tmp[50];
+
+ sprintf(tmp, "<b1> game %d white [%s] black [", g+1, holding_str(gs->holding[0]));
+ strcat(tmp, holding_str(gs->holding[1]));
+ strcat(buf, tmp);
+ if (p) {
+ sprintf(tmp, "] <- %c%s\n", "WB"[c], wpstring[p]);
+ strcat(buf, tmp);
+ } else
+ strcat(buf, "]\n");
+ return buf;
+}
+
+PRIVATE char *append_holding_display(char *buf, game_state_t *gs, int white)
+{
+ if (white)
+ strcat(buf, "White holding: [");
+ else
+ strcat(buf, "Black holding: [");
+ strcat(buf, holding_str(gs->holding[white ? 0 : 1]));
+ strcat(buf, "]\n");
+ return buf;
+}
+
+PUBLIC void update_holding(int g, int pieceCaptured)
+{
+ int p = piecetype(pieceCaptured);
+ int c = colorval(pieceCaptured);
+ game_state_t *gs = &garray[g].game_state;
+ int pp, pl;
+ char tmp1[80], tmp2[80];
+
+ if (c == WHITE) {
+ c = 0;
+ pp = garray[g].white;
+ } else {
+ c = 1;
+ pp = garray[g].black;
+ }
+ gs->holding[c][p-1]++;
+ tmp1[0] = '\0';
+ append_holding_machine(tmp1, g, c, p);
+ sprintf(tmp2, "Game %d %s received: %s -> [%s]\n", g+1,
+ parray[pp].name, wpstring[p], holding_str(gs->holding[c]));
+ for (pl = 0; pl < p_num; pl++) {
+ if (parray[pl].status == PLAYER_EMPTY)
+ continue;
+ if (player_is_observe(pl, g) || (parray[pl].game == g)) {
+ pprintf_prompt(pl, IsMachineStyle(parray[pl].style) ? tmp1 : tmp2);
+ }
+ }
+}
+
+/* Globals used for each board */
+PRIVATE char *wName, *bName;
+PRIVATE int wTime, bTime;
+PRIVATE int orient;
+PRIVATE int forPlayer;
+PRIVATE int myTurn; /* 1 = my turn, 0 = observe, -1 = other turn */
+ /* 2 = examiner, -2 = observing examiner */
+ /* -3 = just send position (spos/refresh) */
+
+PUBLIC char *board_to_string(char *wn, char *bn,
+ int wt, int bt,
+ game_state_t *b, move_t *ml, int style,
+ int orientation, int relation,
+ int p)
+{
+ int bh = (b->gameNum >= 0 && garray[b->gameNum].link >= 0);
+ wName = wn;
+ bName = bn;
+ wTime = wt;
+ bTime = bt;
+ orient = orientation;
+ myTurn = relation;
+
+ forPlayer = p;
+ if ((style < 0) || (style >= MAX_STYLES))
+ return NULL;
+
+ if (style != 11) { /* game header */
+ sprintf(bstring, "Game %d (%s vs. %s)\n\n",
+ b->gameNum + 1,
+ garray[b->gameNum].white_name,
+ garray[b->gameNum].black_name);
+ } else
+ bstring[0] = '\0';
+ if (bh && !IsMachineStyle(style))
+ append_holding_display(bstring, b, orientation==BLACK);
+ if (styleFuncs[style] (b, ml))
+ return NULL;
+ if (bh) {
+ if (IsMachineStyle(style))
+ append_holding_machine(bstring, b->gameNum, 0, 0);
+ else
+ append_holding_display(bstring, b, orientation==WHITE);
+ }
+ return bstring;
+}
+
+PUBLIC char *move_and_time(move_t *m)
+{
+ static char tmp[20];
+ sprintf(tmp, "%-7s (%s)", m->algString, tenth_str(m->tookTime, 0));
+ return tmp;
+}
+
+/* The following take the game state and whole move list */
+
+PRIVATE int genstyle(game_state_t *b, move_t *ml, char *wp[], char *bp[],
+ char *wsqr, char *bsqr,
+ char *top, char *mid, char *start, char *end, char *label,
+ char *blabel)
+{
+ int f, r, count;
+ char tmp[80];
+ int first, last, inc;
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ if (orient == WHITE) {
+ first = 7;
+ last = 0;
+ inc = -1;
+ } else {
+ first = 0;
+ last = 7;
+ inc = 1;
+ }
+ strcat(bstring, top);
+ for (f = first, count = 7; f != last + inc; f += inc, count--) {
+ sprintf(tmp, " %d %s", f + 1, start);
+ strcat(bstring, tmp);
+ for (r = last; r != first - inc; r = r - inc) {
+ if (square_color(r, f) == WHITE)
+ strcat(bstring, wsqr);
+ else
+ strcat(bstring, bsqr);
+ if (piecetype(b->board[r][f]) == NOPIECE) {
+ if (square_color(r, f) == WHITE)
+ strcat(bstring, bp[0]);
+ else
+ strcat(bstring, wp[0]);
+ } else {
+ if (colorval(b->board[r][f]) == WHITE)
+ strcat(bstring, wp[piecetype(b->board[r][f])]);
+ else
+ strcat(bstring, bp[piecetype(b->board[r][f])]);
+ }
+ }
+ sprintf(tmp, "%s", end);
+ strcat(bstring, tmp);
+ switch (count) {
+ case 7:
+ sprintf(tmp, " Move # : %d (%s)", b->moveNum, CString(b->onMove));
+ strcat(bstring, tmp);
+ break;
+ case 6:
+/* if ((b->moveNum > 1) || (b->onMove == BLACK)) { */
+/* The change from the above line to the one below is a kludge by hersco. */
+ if (garray[b->gameNum].numHalfMoves > 0) {
+/* loon: think this fixes the crashing ascii board on takeback bug */
+ sprintf(tmp, " %s Moves : '%s'", CString(CToggle(b->onMove)),
+ move_and_time(&ml[garray[b->gameNum].numHalfMoves - 1]));
+ strcat(bstring, tmp);
+ }
+ break;
+ case 5:
+ break;
+ case 4:
+ sprintf(tmp, " Black Clock : %s", tenth_str(((bTime > 0) ? bTime : 0), 1));
+ strcat(bstring, tmp);
+ break;
+ case 3:
+ sprintf(tmp, " White Clock : %s", tenth_str(((wTime > 0) ? wTime : 0), 1));
+ strcat(bstring, tmp);
+ break;
+ case 2:
+ sprintf(tmp, " Black Strength : %d", bs);
+ strcat(bstring, tmp);
+ break;
+ case 1:
+ sprintf(tmp, " White Strength : %d", ws);
+ strcat(bstring, tmp);
+ break;
+ case 0:
+ break;
+ }
+ strcat(bstring, "\n");
+ if (count != 0)
+ strcat(bstring, mid);
+ else
+ strcat(bstring, top);
+ }
+ if (orient == WHITE)
+ strcat(bstring, label);
+ else
+ strcat(bstring, blabel);
+ return 0;
+}
+
+/* Experimental ANSI board for colour representation */
+PUBLIC int style13(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" ", "\033[37m\033[1m P ", "\033[37m\033[1m N ", "\033[37m\033[1m B ", "\033[37m\033[1m R ", "\033[37m\033[1m Q ", "\033[37m\033[1m K "};
+ static char *bp[] = {" ", "\033[21m\033[37m P ", "\033[21m\033[37m N ", "\033[21m\033[37m B ", "\033[21m\033[37m R ", "\033[21m\033[37m Q ", "\033[21m\033[37m K "};
+ static char *wsqr = "\033[40m";
+ static char *bsqr = "\033[45m";
+ static char *top = "\t+------------------------+\n";
+ static char *mid = "";
+ static char *start = "|";
+ static char *end = "\033[0m|";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Standard ICS */
+PUBLIC int style1(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" |", " P |", " N |", " B |", " R |", " Q |", " K |"};
+ static char *bp[] = {" |", " *P|", " *N|", " *B|", " *R|", " *Q|", " *K|"};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "\t---------------------------------\n";
+ static char *mid = "\t|---+---+---+---+---+---+---+---|\n";
+ static char *start = "|";
+ static char *end = "";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* USA-Today Sports Center-style board */
+PUBLIC int style2(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {"+ ", "P ", "N ", "B ", "R ", "Q ", "K "};
+ static char *bp[] = {"- ", "p' ", "n' ", "b' ", "r' ", "q' ", "k' "};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "";
+ static char *mid = "";
+ static char *start = "";
+ static char *end = "";
+ static char *label = "\ta b c d e f g h\n";
+ static char *blabel = "\th g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Experimental vt-100 ANSI board for dark backgrounds */
+PUBLIC int style3(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "};
+ static char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"};
+ static char *wsqr = "\033[0m";
+ static char *bsqr = "\033[7m";
+ static char *top = "\t+------------------------+\n";
+ static char *mid = "";
+ static char *start = "|";
+ static char *end = "\033[0m|";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Experimental vt-100 ANSI board for light backgrounds */
+PUBLIC int style4(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" ", " P ", " N ", " B ", " R ", " Q ", " K "};
+ static char *bp[] = {" ", " *P", " *N", " *B", " *R", " *Q", " *K"};
+ static char *wsqr = "\033[7m";
+ static char *bsqr = "\033[0m";
+ static char *top = "\t+------------------------+\n";
+ static char *mid = "";
+ static char *start = "|";
+ static char *end = "\033[0m|";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Style suggested by ajpierce@med.unc.edu */
+PUBLIC int style5(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" ", " o ", " :N:", " <B>", " |R|", " {Q}", " =K="};
+ static char *bp[] = {" ", " p ", " :n:", " <b>", " |r|", " {q}", " =k="};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = " . . . . . . . . .\n";
+ static char *mid = " . . . . . . . . .\n";
+ static char *start = "";
+ static char *end = "";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Email Board suggested by Thomas Fought (tlf@rsch.oclc.org) */
+PUBLIC int style6(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" |", " wp |", " WN |", " WB |", " WR |", " WQ |", " WK |"};
+ static char *bp[] = {" |", " bp |", " BN |", " BB |", " BR |", " BQ |", " BK |"};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "\t-----------------------------------------\n";
+ static char *mid = "\t-----------------------------------------\n";
+ static char *start = "|";
+ static char *end = "";
+ static char *label = "\t A B C D E F G H\n";
+ static char *blabel = "\t H G F E D C B A\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* Miniature board */
+PUBLIC int style7(game_state_t *b, move_t *ml)
+{
+ static char *wp[] = {" ", " P", " N", " B", " R", " Q", " K"};
+ static char *bp[] = {" -", " p", " n", " b", " r", " q", " k"};
+ static char *wsqr = "";
+ static char *bsqr = "";
+ static char *top = "\t:::::::::::::::::::::\n";
+ static char *mid = "";
+ static char *start = "..";
+ static char *end = " ..";
+ static char *label = "\t a b c d e f g h\n";
+ static char *blabel = "\t h g f e d c b a\n";
+
+ return genstyle(b, ml, wp, bp, wsqr, bsqr, top, mid, start, end, label, blabel);
+}
+
+/* ICS interface maker board-- raw data dump */
+PUBLIC int style8(game_state_t *b, move_t *ml)
+{
+ char tmp[80];
+ int f, r;
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum + 1,
+ garray[b->gameNum].white_name,
+ (orient == WHITE) ? "*" : ":",
+ garray[b->gameNum].black_name,
+ (orient == WHITE) ? ":" : "*");
+ strcat(bstring, tmp);
+ for (r = 0; r < 8; r++) {
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, " ");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ }
+ sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
+ garray[b->gameNum].numHalfMoves / 2 + 1,
+ (b->onMove == WHITE) ? "W" : "B",
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ garray[b->gameNum].numHalfMoves ?
+ ml[garray[b->gameNum].numHalfMoves - 1].algString :
+ "none",
+ garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00");
+ strcat(bstring, tmp);
+ return 0;
+}
+
+/* last 2 moves only (previous non-verbose mode) */
+PUBLIC int style9(game_state_t *b, move_t *ml)
+{
+ int i, count;
+ char tmp[80];
+ int startmove;
+
+ sprintf(tmp, "\nMove %-23s%s\n",
+ garray[b->gameNum].white_name,
+ garray[b->gameNum].black_name);
+ strcat(bstring, tmp);
+ sprintf(tmp, "---- -------------- --------------\n");
+ strcat(bstring, tmp);
+ startmove = ((garray[b->gameNum].numHalfMoves - 3) / 2) * 2;
+ if (startmove < 0)
+ startmove = 0;
+ for (i = startmove, count = 0;
+ i < garray[b->gameNum].numHalfMoves && count < 4;
+ i++, count++) {
+ if (!(i & 0x01)) {
+ sprintf(tmp, " %2d ", i / 2 + 1);
+ strcat(bstring, tmp);
+ }
+ sprintf(tmp, "%-23s", move_and_time(&ml[i]));
+ strcat(bstring, tmp);
+ if (i & 0x01)
+ strcat(bstring, "\n");
+ }
+ if (i & 0x01)
+ strcat(bstring, "\n");
+ return 0;
+}
+
+/* Sleator's 'new and improved' raw dump format... */
+PUBLIC int style10(game_state_t *b, move_t *ml)
+{
+ int f, r;
+ char tmp[80];
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(tmp, "<10>\n");
+ strcat(bstring, tmp);
+ for (r = 7; r >= 0; r--) {
+ strcat(bstring, "|");
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, " ");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ strcat(bstring, "|\n");
+ }
+ strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
+ if (garray[b->gameNum].numHalfMoves) {
+ sprintf(tmp, "%d ",
+ ml[garray[b->gameNum].numHalfMoves - 1].doublePawn);
+ } else {
+ sprintf(tmp, "-1 ");
+ }
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %d %d %d %d\n",
+ !(b->wkmoved || b->wkrmoved),
+ !(b->wkmoved || b->wqrmoved),
+ !(b->bkmoved || b->bkrmoved),
+ !(b->bkmoved || b->bqrmoved),
+ (garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 :
+ b->lastIrreversable)));
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",
+ b->gameNum,
+ garray[b->gameNum].white_name,
+ garray[b->gameNum].black_name,
+ myTurn,
+ garray[b->gameNum].wInitTime / 600,
+ garray[b->gameNum].wIncrement / 10,
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ garray[b->gameNum].numHalfMoves / 2 + 1,
+ garray[b->gameNum].numHalfMoves ?
+ ml[garray[b->gameNum].numHalfMoves - 1].moveString :
+ "none",
+ garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00",
+ garray[b->gameNum].numHalfMoves ?
+ ml[garray[b->gameNum].numHalfMoves - 1].algString :
+ "none",
+ (orient == WHITE) ? 0 : 1);
+ strcat(bstring, tmp);
+ sprintf(tmp, ">10<\n");
+ strcat(bstring, tmp);
+ return 0;
+}
+
+/* Same as 8, but with verbose moves ("P/e3-e4", instead of "e4") */
+PUBLIC int style11(game_state_t *b, move_t *ml)
+{
+ char tmp[80];
+ int f, r;
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(tmp, "#@#%03d%-16s%s%-16s%s", b->gameNum,
+ garray[b->gameNum].white_name,
+ (orient == WHITE) ? "*" : ":",
+ garray[b->gameNum].black_name,
+ (orient == WHITE) ? ":" : "*");
+ strcat(bstring, tmp);
+ for (r = 0; r < 8; r++) {
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, " ");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ }
+ sprintf(tmp, "%03d%s%02d%02d%05d%05d%-7s(%s)@#@\n",
+ garray[b->gameNum].numHalfMoves / 2 + 1,
+ (b->onMove == WHITE) ? "W" : "B",
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ garray[b->gameNum].numHalfMoves ?
+ ml[garray[b->gameNum].numHalfMoves - 1].moveString :
+ "none",
+ garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00");
+ strcat(bstring, tmp);
+ return 0;
+}
+
+/* Similar to style 10. See the "style12" help file for information */
+PUBLIC int style12(game_state_t *b, move_t *ml)
+{
+ int f, r;
+ char tmp[80];
+ int ws, bs;
+
+ board_calc_strength(b, &ws, &bs);
+ sprintf(bstring, "<12> ");
+ for (r = 7; r >= 0; r--) {
+ for (f = 0; f < 8; f++) {
+ if (b->board[f][r] == NOPIECE) {
+ strcat(bstring, "-");
+ } else {
+ if (colorval(b->board[f][r]) == WHITE)
+ strcat(bstring, wpstring[piecetype(b->board[f][r])]);
+ else
+ strcat(bstring, bpstring[piecetype(b->board[f][r])]);
+ }
+ }
+ strcat(bstring, " ");
+ }
+ strcat(bstring, (b->onMove == WHITE) ? "W " : "B ");
+ if (garray[b->gameNum].numHalfMoves) {
+ sprintf(tmp, "%d ",
+ ml[garray[b->gameNum].numHalfMoves - 1].doublePawn);
+ } else {
+ sprintf(tmp, "-1 ");
+ }
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %d %d %d %d ",
+ !(b->wkmoved || b->wkrmoved),
+ !(b->wkmoved || b->wqrmoved),
+ !(b->bkmoved || b->bkrmoved),
+ !(b->bkmoved || b->bqrmoved),
+ (garray[b->gameNum].numHalfMoves - ((b->lastIrreversable == -1) ? 0 : b->lastIrreversable)));
+ strcat(bstring, tmp);
+ sprintf(tmp, "%d %s %s %d %d %d %d %d %d %d %d %s (%s) %s %d\n",
+ b->gameNum + 1,
+ garray[b->gameNum].white_name,
+ garray[b->gameNum].black_name,
+ myTurn,
+ garray[b->gameNum].wInitTime / 600,
+ garray[b->gameNum].wIncrement / 10,
+ ws,
+ bs,
+ (wTime + 5) / 10,
+ (bTime + 5) / 10,
+ garray[b->gameNum].numHalfMoves / 2 + 1,
+ garray[b->gameNum].numHalfMoves ?
+ ml[garray[b->gameNum].numHalfMoves - 1].moveString :
+ "none",
+ garray[b->gameNum].numHalfMoves ?
+ tenth_str(ml[garray[b->gameNum].numHalfMoves - 1].tookTime, 0) :
+ "0:00",
+ garray[b->gameNum].numHalfMoves ?
+ ml[garray[b->gameNum].numHalfMoves - 1].algString :
+ "none", (orient == WHITE) ? 0 : 1);
+
+ strcat(bstring, tmp);
+ return 0;
+}
+
+PUBLIC int board_read_file(char *category, char *gname, game_state_t *gs)
+{
+ int f, r;
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE + 1];
+ int c;
+ int onNewLine = 1;
+ int onColor = -1;
+ int onPiece = -1;
+ int onFile = -1;
+ int onRank = -1;
+
+ sprintf(fname, "%s/%s/%s", board_dir, category, gname);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return 1;
+
+ for (f = 0; f < 8; f++)
+ for (r = 0; r < 8; r++)
+ gs->board[f][r] = NOPIECE;
+ for (f = 0; f < 2; f++) {
+ for (r = 0; r < 8; r++)
+ gs->ep_possible[f][r] = 0;
+ for (r = PAWN; r <= QUEEN; r++)
+ gs->holding[f][r-1] = 0;
+ }
+ gs->wkmoved = gs->wqrmoved = gs->wkrmoved = 0;
+ gs->bkmoved = gs->bqrmoved = gs->bkrmoved = 0;
+ gs->onMove = -1;
+ gs->moveNum = 1;
+ gs->lastIrreversable = -1;
+ while (!feof(fp)) {
+ c = fgetc(fp);
+ if (onNewLine) {
+ if (c == 'W') {
+ onColor = WHITE;
+ if (gs->onMove < 0)
+ gs->onMove = WHITE;
+ } else if (c == 'B') {
+ onColor = BLACK;
+ if (gs->onMove < 0)
+ gs->onMove = BLACK;
+ } else if (c == '#') {
+ while (!feof(fp) && c != '\n')
+ c = fgetc(fp); /* Comment line */
+ continue;
+ } else { /* Skip any line we don't understand */
+ while (!feof(fp) && c != '\n')
+ c = fgetc(fp);
+ continue;
+ }
+ onNewLine = 0;
+ } else {
+ switch (c) {
+ case 'P':
+ onPiece = PAWN;
+ break;
+ case 'R':
+ onPiece = ROOK;
+ break;
+ case 'N':
+ onPiece = KNIGHT;
+ break;
+ case 'B':
+ onPiece = BISHOP;
+ break;
+ case 'Q':
+ onPiece = QUEEN;
+ break;
+ case 'K':
+ onPiece = KING;
+ break;
+ case 'a':
+ case 'b':
+ case 'c':
+ case 'd':
+ case 'e':
+ case 'f':
+ case 'g':
+ case 'h':
+ onFile = c - 'a';
+ onRank = -1;
+ break;
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ onRank = c - '1';
+ if (onFile >= 0 && onColor >= 0 && onPiece >= 0)
+ gs->board[onFile][onRank] = onPiece | onColor;
+ break;
+ case '#':
+ while (!feof(fp) && c != '\n')
+ c = fgetc(fp); /* Comment line */
+ case '\n':
+ onNewLine = 1;
+ onColor = -1;
+ onPiece = -1;
+ onFile = -1;
+ onRank = -1;
+ break;
+ default:
+ break;
+ }
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+#define WHITE_SQUARE 1
+#define BLACK_SQUARE 0
+#define ANY_SQUARE -1
+#define SquareColor(f, r) ((f ^ r) & 1)
+
+PRIVATE void place_piece(board_t b, int piece, int squareColor)
+{
+ int r, f;
+ int placed = 0;
+
+ if (iscolor(piece, BLACK))
+ r = 7;
+ else
+ r = 0;
+
+ while (!placed) {
+ if (squareColor == ANY_SQUARE) {
+ f = rand() % 8;
+ } else {
+ f = (rand() % 4) * 2;
+ if (SquareColor(f, r) != squareColor)
+ f++;
+ }
+ if ((b)[f][r] == NOPIECE) {
+ (b)[f][r] = piece;
+ placed = 1;
+ }
+ }
+}
+
+PUBLIC void wild_update(int style)
+{
+ int f, r, i;
+ board_t b;
+
+ for (f = 0; f < 8; f++)
+ for (r = 0; r < 8; r++)
+ b[f][r] = NOPIECE;
+ for (f = 0; f < 8; f++) {
+ b[f][1] = W_PAWN;
+ b[f][6] = B_PAWN;
+ }
+ switch (style) {
+ case 1:
+ if (rand() & 0x01) {
+ b[4][0] = W_KING;
+ b[3][0] = W_QUEEN;
+ } else {
+ b[3][0] = W_KING;
+ b[4][0] = W_QUEEN;
+ }
+ if (rand() & 0x01) {
+ b[4][7] = B_KING;
+ b[3][7] = B_QUEEN;
+ } else {
+ b[3][7] = B_KING;
+ b[4][7] = B_QUEEN;
+ }
+ b[0][0] = b[7][0] = W_ROOK;
+ b[0][7] = b[7][7] = B_ROOK;
+ /* Must do bishops before knights to be sure opposite colored squares are
+ available. */
+ place_piece(b, W_BISHOP, WHITE_SQUARE);
+ place_piece(b, W_BISHOP, BLACK_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ place_piece(b, B_BISHOP, WHITE_SQUARE);
+ place_piece(b, B_BISHOP, BLACK_SQUARE);
+ place_piece(b, B_KNIGHT, ANY_SQUARE);
+ place_piece(b, B_KNIGHT, ANY_SQUARE);
+ break;
+ case 2:
+ place_piece(b, W_KING, ANY_SQUARE);
+ place_piece(b, W_QUEEN, ANY_SQUARE);
+ place_piece(b, W_ROOK, ANY_SQUARE);
+ place_piece(b, W_ROOK, ANY_SQUARE);
+ place_piece(b, W_BISHOP, ANY_SQUARE);
+ place_piece(b, W_BISHOP, ANY_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ place_piece(b, W_KNIGHT, ANY_SQUARE);
+ /* Black mirrors White */
+ for (i = 0; i < 8; i++) {
+ b[i][7] = b[i][0] | BLACK;
+ }
+ break;
+ case 3:
+ /* Generate White king on random square plus random set of pieces */
+ place_piece(b, W_KING, ANY_SQUARE);
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] != W_KING) {
+ b[i][0] = (rand() % 4) + 2;
+ }
+ }
+ /* Black mirrors White */
+ for (i = 0; i < 8; i++) {
+ b[i][7] = b[i][0] | BLACK;
+ }
+ break;
+ case 4:
+ /* Generate White king on random square plus random set of pieces */
+ place_piece(b, W_KING, ANY_SQUARE);
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] != W_KING) {
+ b[i][0] = (rand() % 4) + 2;
+ }
+ }
+ /* Black has same set of pieces, but randomly permuted, except that Black
+ must have the same number of bishops on white squares as White has on
+ black squares, and vice versa. So we must place Black's bishops first
+ to be sure there are enough squares left of the correct color. */
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] == W_BISHOP) {
+ place_piece(b, B_BISHOP, !SquareColor(i, 0));
+ }
+ }
+ for (i = 0; i < 8; i++) {
+ if (b[i][0] != W_BISHOP) {
+ place_piece(b, b[i][0] | BLACK, ANY_SQUARE);
+ }
+ }
+ break;
+ default:
+ return;
+ break;
+ }
+ {
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE + 1];
+ int onPiece;
+
+ sprintf(fname, "%s/wild/%d", board_dir, style);
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Can't write file name %s\n", fname);
+ return;
+ }
+ fprintf(fp, "W:");
+ onPiece = -1;
+ for (r = 1; r >= 0; r--) {
+ for (f = 0; f < 8; f++) {
+ if (onPiece < 0 || b[f][r] != onPiece) {
+ onPiece = b[f][r];
+ fprintf(fp, " %s", wpstring[piecetype(b[f][r])]);
+ }
+ fprintf(fp, " %c%c", f + 'a', r + '1');
+ }
+ }
+ fprintf(fp, "\nB:");
+ onPiece = -1;
+ for (r = 6; r < 8; r++) {
+ for (f = 0; f < 8; f++) {
+ if (onPiece < 0 || b[f][r] != onPiece) {
+ onPiece = b[f][r];
+ fprintf(fp, " %s", wpstring[piecetype(b[f][r])]);
+ }
+ fprintf(fp, " %c%c", f + 'a', r + '1');
+ }
+ }
+ fprintf(fp, "\n");
+ fclose(fp);
+ }
+}
+
+PUBLIC void wild_init()
+{
+ wild_update(1);
+ wild_update(2);
+ wild_update(3);
+ wild_update(4);
+}
blob - /dev/null
blob + 5db4fb9d40f20f1f0e266e8abbccbf8a14444b86 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/board.h
+/* board.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _BOARD_H
+#define _BOARD_H
+
+#define WHITE 0x00
+#define BLACK 0x80
+#define CString( c ) (((c) == WHITE) ? "White" : "Black" )
+#define CToggle( c ) (((c) == BLACK) ? WHITE : BLACK )
+
+/* These are indexes into an array so their values are not arbitrary */
+#define NOPIECE 0x00
+#define PAWN 0x01
+#define KNIGHT 0x02
+#define BISHOP 0x03
+#define ROOK 0x04
+#define QUEEN 0x05
+#define KING 0x06
+
+#define MAX_BOARD_STRING_LEGTH 1280 /* Abitrarily 80 * 16 */
+#define MAX_STYLES 13
+
+#define W_PAWN (PAWN | WHITE)
+#define W_KNIGHT (KNIGHT | WHITE)
+#define W_BISHOP (BISHOP | WHITE)
+#define W_ROOK (ROOK | WHITE)
+#define W_QUEEN (QUEEN | WHITE)
+#define W_KING (KING | WHITE)
+
+#define B_PAWN (PAWN | BLACK)
+#define B_KNIGHT (KNIGHT | BLACK)
+#define B_BISHOP (BISHOP | BLACK)
+#define B_ROOK (ROOK | BLACK)
+#define B_QUEEN (QUEEN | BLACK)
+#define B_KING (KING | BLACK)
+
+#define isblack(p) ((p) & BLACK)
+#define iswhite(p) (!isblack(p))
+#define iscolor(p,color) (((p) & BLACK) == (color))
+#define piecetype(p) ((p) & 0x7f)
+#define colorval(p) ((p) & 0x80)
+#define square_color(r,f) ((((r)+(f)) & 0x01) ? BLACK : WHITE)
+
+extern int pieceValues[7];
+
+/* Treated as [file][rank] */
+typedef int board_t[8][8];
+
+typedef struct _game_state_t {
+ board_t board;
+ /* for bughouse */
+ int holding[2][5];
+ /* For castling */
+ unsigned char wkmoved, wqrmoved, wkrmoved;
+ unsigned char bkmoved, bqrmoved, bkrmoved;
+ /* for ep */
+ int ep_possible[2][8];
+ /* For draws */
+ int lastIrreversable;
+ int onMove;
+ int moveNum;
+ /* Game num not saved, must be restored when read */
+ int gameNum;
+} game_state_t;
+
+#define ALG_DROP -2
+
+/* bughouse: if a drop move, then fromFile is ALG_DROP and fromRank is piece */
+
+typedef struct _move_t {
+ int color;
+ int fromFile, fromRank;
+ int toFile, toRank;
+ int pieceCaptured;
+ int piecePromotionTo;
+ int enPassant; /* 0 = no, 1=higher -1= lower */
+ int doublePawn; /* Only used for board display */
+ char moveString[8];
+ char algString[8];
+ unsigned char FENpos[74]; /* This replaces the boardList. */
+ unsigned atTime;
+ unsigned tookTime;
+} move_t;
+
+#define MoveToHalfMove( gs ) ((((gs)->moveNum - 1) * 2) + (((gs)->onMove == WHITE) ? 0 : 1))
+
+extern char *wpstring[];
+extern char *bpstring[];
+
+extern int board_init(game_state_t *, char *, char *);
+extern void board_calc_strength(game_state_t *, int *, int *);
+extern void update_holding(int, int);
+extern char *board_to_string(char *, char *, int, int, game_state_t *, move_t *, int, int, int, int);
+extern char *move_and_time(move_t *);
+extern int board_read_file(char *, char *, game_state_t *);
+extern void wild_update(int);
+extern void wild_init(void);
+
+extern int fgetc();
+
+#endif
blob - /dev/null
blob + d0e9b66718cb4fe74b4584ff074cfb1ab10d456d (mode 644)
Binary files /dev/null and FICS.DIST/FICS/board.o differ
blob - /dev/null
blob + 8ada4b9ffc5434b5d05be88856472e2e765fbf56 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/channel.c
+/* channel.c
+ *
+ */
+
+/* THIS SOURCE FILE IS NOW OBSOLETE - DAV */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "channel.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "playerdb.h"
+
+#if 0 /* ARGH!!! 256 * 256 * 4 = 256K! */
+/* old cheesy (as loon would put it :) ) code removed */
+PUBLIC int *channels[MAX_CHANNELS];
+PUBLIC int numOn[MAX_CHANNELS];
+
+PUBLIC void channel_init()
+{
+ int i;
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ channels[i] = rmalloc(max_connections * sizeof(int));
+ numOn[i] = 0;
+ }
+}
+
+PUBLIC int on_channel(int ch, int p)
+{
+ int i;
+
+ for (i = 0; i < numOn[ch]; i++)
+ if (p == channels[ch][i])
+ return 1;
+ return 0;
+}
+
+PUBLIC int channel_remove(int ch, int p)
+{
+ int i, found;
+
+ found = -1;
+ for (i = 0; i < numOn[ch] && found < 0; i++)
+ if (p == channels[ch][i])
+ found = i;
+ if (found < 0)
+ return 1;
+ for (i = found; i < numOn[ch] - 1; i++)
+ channels[ch][i] = channels[ch][i + 1];
+ numOn[ch] = numOn[ch] - 1;
+ --parray[p].nochannels;
+ return 0;
+}
+
+PUBLIC int channel_add(int ch, int p)
+{
+ if (numOn[ch] >= MAX_CHANNELS)
+ return 1;
+ if (on_channel(ch, p))
+ return 2;
+ if ((parray[p].nochannels == MAX_INCHANNELS) && (parray[p].adminLevel == 0)) {
+ return 3;
+ }
+ channels[ch][numOn[ch]] = p;
+ numOn[ch]++;
+ parray[p].nochannels++;
+ return 0;
+}
+
+/* this piece of replacement code appears in talkproc.c */
+PUBLIC int on_channel(int ch, int p)
+{
+ char tmp[10]; /* 9 digits ought to be enough :) */
+
+ sprintf (tmp,"%d",ch);
+ return in_list(p, L_CHANNEL,ch ) /* since needs ch converted to a string keep
+ hidden from view */
+}
+
+#endif
blob - /dev/null
blob + 9de48082769d81b65a62a82f6f13e474aa23dfd8 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/channel.h
+/* channel.h
+ *
+ */
+
+/* THIS SOURCE FILE IS NOW OBSOLETE - DAV */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _CHANNEL_H
+#define _CHANNEL_H
+
+#define MAX_CHANNELS 256
+
+extern int *channels[MAX_CHANNELS];
+extern int numOn[MAX_CHANNELS];
+
+extern void channel_init(void);
+extern int on_channel(int, int);
+extern int channel_remove(int, int);
+extern int channel_add(int, int);
+
+#endif /* _CHANNEL_H */
blob - /dev/null
blob + 267cfa2aab59815ce19ba97bd9db51ef9ccf9602 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/channel.o differ
blob - /dev/null
blob + a53f30583dd08be41e0c435e019e2cbd17031590 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/command.c
+/* command.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "rmalloc.h"
+#include "command.h"
+#include "command_list.h"
+#include "movecheck.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "ratings.h"
+#include "vers.h"
+#include "network.h"
+#include "shutdown.h"
+#include <sys/param.h>
+#ifdef TIMESEAL
+#include "timeseal.h"
+#endif
+/*#include "hostinfo.h" */
+
+PUBLIC char *mess_dir = DEFAULT_MESS;
+PUBLIC char *index_dir = DEFAULT_INDEX;
+PUBLIC char *help_dir[NUM_LANGS] = {DEFAULT_HELP, HELP_SPANISH, HELP_FRENCH, HELP_DANISH};
+PUBLIC char *comhelp_dir = DEFAULT_COMHELP;
+PUBLIC char *info_dir = DEFAULT_INFO;
+PUBLIC char *adhelp_dir = DEFAULT_ADHELP;
+PUBLIC char *uscf_dir = DEFAULT_USCF;
+PUBLIC char *stats_dir = DEFAULT_STATS;
+PUBLIC char *player_dir = DEFAULT_PLAYERS;
+PUBLIC char *adj_dir = DEFAULT_ADJOURNED;
+PUBLIC char *hist_dir = DEFAULT_HISTORY;
+PUBLIC char *journal_dir = DEFAULT_JOURNAL;
+PUBLIC char *board_dir = DEFAULT_BOARDS;
+PUBLIC char *def_prompt = DEFAULT_PROMPT;
+PUBLIC char *source_dir = DEFAULT_SOURCE;
+PUBLIC char *lists_dir = DEFAULT_LISTS;
+PUBLIC char *news_dir = DEFAULT_NEWS;
+PUBLIC char *usage_dir[NUM_LANGS] = {DEFAULT_USAGE, USAGE_SPANISH, USAGE_FRENCH, USAGE_DANISH};
+
+PUBLIC char *hadmin_handle = HADMINHANDLE;
+char *hadmin_email = HADMINEMAIL;
+char *reg_addr = REGMAIL;
+
+PUBLIC int startuptime;
+PUBLIC char fics_hostname[81];
+PUBLIC int player_high;
+PUBLIC int game_high;
+PUBLIC int MailGameResult;
+
+PUBLIC int commanding_player = -1; /* The player whose command your in */
+
+PRIVATE int lastCommandFound = -1;
+
+/* grimm */
+int player_notify_departure(int p);
+/* added for warnings */
+
+/* Copies command into comm, and returns pointer to parameters in
+ * parameters
+ */
+PRIVATE int parse_command(char *com_string,
+ char **comm,
+ char **parameters)
+{
+ *comm = com_string;
+ *parameters = eatword(com_string);
+ if (**parameters != '\0') {
+ **parameters = '\0';
+ (*parameters)++;
+ *parameters = eatwhite(*parameters);
+ }
+ if (strlen(*comm) >= MAX_COM_LENGTH) {
+ return COM_BADCOMMAND;
+ }
+ return COM_OK;
+}
+
+PUBLIC int alias_lookup(char *tmp, alias_type *alias_list, int numalias)
+/* numalias is the maximum number to search through */
+{
+ int i;
+
+ for (i = 0; (alias_list[i].comm_name && i < numalias); i++) {
+ if (!strcmp(tmp, alias_list[i].comm_name))
+ return i;
+ }
+ return -1; /* not found */
+}
+
+PUBLIC int alias_count(alias_type *alias_list)
+{
+ int i;
+
+ for (i = 0; alias_list[i].comm_name; i++);
+ return i;
+}
+
+
+/* Puts alias substitution into alias_string */
+PRIVATE void alias_substitute(alias_type *alias_list, int num_alias,
+ char *com_str, char outalias[])
+{
+ char *s = com_str;
+ char name[MAX_COM_LENGTH];
+ char *t = name;
+ int i = 0;
+ char *atpos, *aliasval;
+
+ /* Get first word of command, terminated by whitespace or by containing
+ punctuation */
+ while (*s && !iswhitespace(*s)) {
+ if (i++ >= MAX_COM_LENGTH) {
+ strcpy(outalias, com_str);
+ return;
+ }
+ if (ispunct(*t++ = *s++))
+ break;
+ }
+ *t = '\0';
+ if (*s && iswhitespace(*s))
+ s++;
+
+ i = alias_lookup(name, alias_list, num_alias);
+ if (i < 0) {
+ strcpy(outalias, com_str);
+ return;
+ }
+ aliasval = alias_list[i].alias;
+
+ /* See if alias contains an @ */
+ atpos = strchr(aliasval, '@');
+ if (atpos != NULL) {
+ strncpy(outalias, aliasval, atpos - aliasval);
+ outalias[atpos - aliasval] = '\0';
+ strcat(outalias, s);
+ strcat(outalias, atpos + 1);
+ } else {
+ strcpy(outalias, aliasval);
+ if (*s) {
+ strcat(outalias, " ");
+ strcat(outalias, s);
+ }
+ }
+}
+
+/* Returns pointer to command that matches */
+PRIVATE int match_command(char *comm, int p)
+{
+ int i = 0;
+ int gotIt = -1;
+ int len = strlen(comm);
+
+ while (command_list[i].comm_name) {
+ if (!strncmp(command_list[i].comm_name, comm, len)
+ && parray[p].adminLevel >= command_list[i].adminLevel) {
+ if (gotIt >= 0)
+ return -COM_AMBIGUOUS;
+ gotIt = i;
+ }
+ i++;
+ }
+ if (in_list(p, L_REMOVEDCOM, command_list[gotIt].comm_name)) {
+ pprintf(p, "Due to a bug - this command has been temporarily removed.\n");
+ return -COM_FAILED;
+ }
+ if (gotIt >= 0) {
+ lastCommandFound = gotIt;
+ return gotIt;
+ }
+ return -COM_FAILED;
+}
+
+/* Gets the parameters for this command */
+PRIVATE int get_parameters(int command, char *parameters, param_list params)
+{
+ int i, parlen;
+ int paramLower;
+ char c;
+ static char punc[2];
+
+ punc[1] = '\0'; /* Holds punc parameters */
+ for (i = 0; i < MAXNUMPARAMS; i++)
+ (params)[i].type = TYPE_NULL; /* Set all parameters to NULL */
+ parlen = strlen(command_list[command].param_string);
+ for (i = 0; i < parlen; i++) {
+ c = command_list[command].param_string[i];
+ if (isupper(c)) {
+ paramLower = 0;
+ c = tolower(c);
+ } else {
+ paramLower = 1;
+ }
+ switch (c) {
+ case 'w':
+ case 'o': /* word or optional word */
+ parameters = eatwhite(parameters);
+ if (!*parameters)
+ return (c == 'o' ? COM_OK : COM_BADPARAMETERS);
+ (params)[i].val.word = parameters;
+ (params)[i].type = TYPE_WORD;
+ if (ispunct(*parameters)) {
+ punc[0] = *parameters;
+ (params)[i].val.word = punc;
+ parameters++;
+ if (*parameters && iswhitespace(*parameters))
+ parameters++;
+ } else {
+ parameters = eatword(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ }
+ if (paramLower)
+ stolower((params)[i].val.word);
+ break;
+
+ case 'd':
+ case 'p': /* optional or required integer */
+ parameters = eatwhite(parameters);
+ if (!*parameters)
+ return (c == 'p' ? COM_OK : COM_BADPARAMETERS);
+ if (sscanf(parameters, "%d", &(params)[i].val.integer) != 1)
+ return COM_BADPARAMETERS;
+ (params)[i].type = TYPE_INT;
+ parameters = eatword(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ break;
+
+ case 'i':
+ case 'n': /* optional or required word or integer */
+ parameters = eatwhite(parameters);
+ if (!*parameters)
+ return (c == 'n' ? COM_OK : COM_BADPARAMETERS);
+ if (sscanf(parameters, "%d", &(params)[i].val.integer) != 1) {
+ (params)[i].val.word = parameters;
+ (params)[i].type = TYPE_WORD;
+ } else {
+ (params)[i].type = TYPE_INT;
+ }
+ if (ispunct(*parameters)) {
+ punc[0] = *parameters;
+ (params)[i].val.word = punc;
+ (params)[i].type = TYPE_WORD;
+ parameters++;
+ if (*parameters && iswhitespace(*parameters))
+ parameters++;
+ } else {
+ parameters = eatword(parameters);
+ if (*parameters != '\0') {
+ *parameters = '\0';
+ parameters++;
+ }
+ }
+ if ((params)[i].type == TYPE_WORD)
+ if (paramLower)
+ stolower((params)[i].val.word);
+ break;
+
+ case 's':
+ case 't': /* optional or required string to end */
+ if (!*parameters)
+ return (c == 't' ? COM_OK : COM_BADPARAMETERS);
+ (params)[i].val.string = parameters;
+ (params)[i].type = TYPE_STRING;
+ while (*parameters)
+ parameters = nextword(parameters);
+ if (paramLower)
+ stolower((params)[i].val.string);
+ break;
+ }
+ }
+ if (*parameters)
+ return COM_BADPARAMETERS;
+ else
+ return COM_OK;
+}
+
+PRIVATE void printusage(int p, char *command_str)
+{
+ int i, parlen, UseLang = parray[p].language;
+ int command;
+ char c;
+
+ char *filenames[1000]; /* enough for all usage names */
+
+ if ((command = match_command(command_str, p)) < 0) {
+ pprintf(p, " UNKNOWN COMMAND\n");
+ return;
+ }
+
+/*Usage added by DAV 11/19/95 */
+ /* First lets check if we have a text usage file for it */
+
+ i = search_directory(usage_dir[UseLang], command_str, filenames, 1000);
+ if (i == 0) { /* nope none in current Lang */
+ if (UseLang != LANG_DEFAULT) {
+ i += search_directory(usage_dir[LANG_DEFAULT], command_str, filenames, 1000);
+ if (i > 0) {
+ pprintf(p, "No usage available in %s; using %s instead.\n",
+ Language(UseLang), Language(LANG_DEFAULT));
+ UseLang = LANG_DEFAULT;
+ }
+ }
+ }
+
+ if (i != 0) {
+ if ((i == 1) || (!strcmp(*filenames, command_str))) { /* found it? then send */
+ if (psend_file(p, usage_dir[UseLang], *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Usage file %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ /* no need to print 'system' usage - should never happen */
+ }
+ return;
+ }
+ }
+
+ /* print the default 'system' usage files (which aren't much help!) */
+
+ pprintf(p, "Usage: %s", command_list[lastCommandFound].comm_name);
+
+ parlen = strlen(command_list[command].param_string);
+ for (i = 0; i < parlen; i++) {
+ c = command_list[command].param_string[i];
+ if (isupper(c))
+ c = tolower(c);
+ switch (c) {
+ case 'w': /* word */
+ pprintf(p, " word");
+ break;
+ case 'o': /* optional word */
+ pprintf(p, " [word]");
+ break;
+ case 'd': /* integer */
+ pprintf(p, " integer");
+ break;
+ case 'p': /* optional integer */
+ pprintf(p, " [integer]");
+ break;
+ case 'i': /* word or integer */
+ pprintf(p, " {word, integer}");
+ break;
+ case 'n': /* optional word or integer */
+ pprintf(p, " [{word, integer}]");
+ break;
+ case 's': /* string to end */
+ pprintf(p, " string");
+ break;
+ case 't': /* optional string to end */
+ pprintf(p, " [string]");
+ break;
+ }
+ }
+ pprintf(p, "\nSee 'help %s' for a complete description.\n", command_list[lastCommandFound].comm_name);
+}
+
+PUBLIC int process_command(int p, char *com_string, char **cmd)
+{
+ int which_command, retval;
+ param_list params;
+ static char alias_string1[MAX_STRING_LENGTH * 4], alias_string2[MAX_STRING_LENGTH * 4];
+ char *comm, *parameters;
+
+#ifdef DEBUG
+ if (strcasecmp(parray[p].name, parray[p].login)) {
+ fprintf(stderr, "FICS: PROBLEM Name=%s, Login=%s\n", parray[p].name, parray[p].login);
+ }
+#endif
+ if (!com_string)
+ return COM_FAILED;
+#ifdef DEBUG
+ fprintf(stderr, "%s, %s, %d: >%s<\n", parray[p].name, parray[p].login, parray[p].socket, com_string);
+#endif
+ alias_substitute(parray[p].alias_list, parray[p].numAlias,
+ com_string, alias_string1);
+ alias_substitute(g_alias_list, 999,
+ alias_string1, alias_string2);
+#ifdef DEBUG
+ if (strcmp(com_string, alias_string2) != 0)
+ fprintf(stderr, "%s -alias-: >%s<\n", parray[p].name, alias_string2);
+#endif
+ if ((retval = parse_command(alias_string2, &comm, ¶meters)))
+ return retval;
+ if (is_move(comm))
+ return COM_ISMOVE;
+ stolower(comm); /* All commands are case-insensitive */
+ *cmd = comm;
+ if ((which_command = match_command(comm, p)) < 0)
+ return -which_command;
+ if (parray[p].adminLevel < command_list[which_command].adminLevel) {
+ return COM_RIGHTS;
+ }
+ if ((retval = get_parameters(which_command, parameters, params)))
+ return retval;
+ return command_list[which_command].comm_func(p, params);
+}
+
+PRIVATE int process_login(int p, char *loginname)
+{
+ int problem = 1;
+
+ loginname = eatwhite(loginname);
+
+ if (!*loginname) { /* do something in here? */
+ } else {
+ char *loginnameii = strdup(loginname);
+ stolower(loginname);
+ if (!alphastring(loginname)) {
+ pprintf(p, "\nSorry, names can only consist of lower and upper case letters. Try again.\n");
+ } else if (strlen(loginname) < 3) {
+ pprintf(p, "\nA name should be at least three characters long! Try again.\n");
+ } else if (strlen(loginname) > 17) {
+ pprintf(p, "\nSorry, names may be at most 17 characters long. Try again.\n");
+ } else if (in_list(p, L_BAN, loginnameii)) {
+ pprintf(p, "\nPlayer \"%s\" is banned.\n", loginname);
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ } else if ((!in_list(p, L_ADMIN, loginnameii)) && (player_count(0) >= max_connections - 10)) {
+ psend_raw_file(p, mess_dir, MESS_FULL);
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ } else {
+ problem = 0;
+ if (player_read(p, loginname)) {
+ strcpy(parray[p].name, loginnameii);
+ if (in_list(p, L_FILTER, dotQuad(parray[p].thisHost))) {
+ pprintf(p, "\nDue to abusive behavior, nobody from your site may login.\n");
+ pprintf(p, "If you wish to use this server please email %s\n", reg_addr);
+ pprintf(p, "Include details of a nick-name to be called here, e-mail address and your real name.\n");
+ pprintf(p, "We will send a password to you. Thanks.\n");
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ }
+ if ((player_count(0)) >= MAX(max_connections - 60, 200)) {
+ psend_raw_file(p, mess_dir, MESS_FULL_UNREG);
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ }
+ pprintf_noformat(p, "\n\"%s\" is not a registered name. You may use this name to play unrated games.\n(After logging in, do \"help register\" for more info on how to register.)\n\nPress return to enter the FICS as \"%s\":",
+ parray[p].name, parray[p].name);
+ } else {
+ pprintf_noformat(p, "\n\"%s\" is a registered name. If it is yours, type the password.\nIf not, just hit return to try another name.\n\npassword: ", parray[p].name);
+ }
+ parray[p].status = PLAYER_PASSWORD;
+ turn_echo_off(parray[p].socket);
+ rfree(loginnameii);
+ if (strcasecmp(loginname, parray[p].name)) {
+ pprintf(p, "\nYou've got a bad name field in your playerfile -- please report this to an admin!\n");
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ }
+ if ((parray[p].adminLevel != 0) && (!in_list(p, L_ADMIN, parray[p].name))) {
+ pprintf(p, "\nYou've got a bad playerfile -- please report this to an admin!\n");
+ pprintf(p, "Your handle is missing!");
+ pprintf(p, "Please log on as an unreg until an admin can correct this.\n");
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ }
+ if ((parray[p].registered) && (parray[p].fullName == NULL)) {
+ pprintf(p, "\nYou've got a bad playerfile -- please report this to an admin!\n");
+ pprintf(p, "Your FullName is missing!");
+ pprintf(p, "Please log on as an unreg until an admin can correct this.\n");
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ }
+ if ((parray[p].registered) && (parray[p].emailAddress == NULL)) {
+ pprintf(p, "\nYou've got a bad playerfile -- please report this to an admin!\n");
+ pprintf(p, "Your Email address is missing\n");
+ pprintf(p, "Please log on as an unreg until an admin can correct this.\n");
+ rfree(loginnameii);
+ return COM_LOGOUT;
+ }
+ }
+ }
+
+ if (problem) {
+ psend_raw_file(p, mess_dir, MESS_LOGIN);
+ pprintf(p, "login: ");
+ }
+ return 0;
+}
+
+void boot_out(int p, int p1)
+{
+ int fd;
+ pprintf(p, "\n **** %s is already logged in - kicking them out. ****\n", parray[p].name);
+ pprintf(p1, "**** %s has arrived - you can't both be logged in. ****\n", parray[p].name);
+ fd = parray[p1].socket;
+ process_disconnection(fd);
+ net_close_connection(fd);
+}
+
+PUBLIC void rscan_news(FILE *fp, int p, int lc) {
+
+ char junk[MAX_LINE_SIZE], count[10];
+ int crtime;
+ char *junkp;
+
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ return;
+ sscanf(junk, "%d %s", &crtime, count);
+
+ if (crtime - lc < 0)
+ return;
+ else {
+ rscan_news(fp, p, lc);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ }
+}
+
+PRIVATE void check_news(int p, int admin)
+{
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+ char junk[MAX_LINE_SIZE];
+ char *junkp;
+ int crtime;
+ int lc = player_lastconnect(p);
+ char count[10];
+
+ if (admin) {
+
+ sprintf(filename, "%s/newadminnews.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find admin news index.\n");
+ return;
+ }
+
+ if (num_anews == -1) {
+ num_anews = count_lines(fp);
+ fclose(fp);
+ fp = fopen(filename, "r");
+ }
+
+ fgets(junk, MAX_LINE_SIZE, fp);
+ sscanf(junk, "%d %s", &crtime, count);
+ if ((crtime - lc) < 0) {
+ pprintf(p, "There are no new admin news items since your last login.\n\n");
+ fclose(fp);
+ return;
+ } else {
+ pprintf(p, "Index of new admin news items:\n");
+ rscan_news(fp, p, lc);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ pprintf(p, "(\"anews %d\" will display the most recent admin news file)\n", num_anews);
+ }
+
+ } else {
+
+ sprintf(filename, "%s/newnews.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find news index.\n");
+ return;
+ }
+
+ if (num_news == -1) {
+ num_news = count_lines(fp);
+ fclose(fp);
+ fp = fopen(filename, "r");
+ }
+
+ fgets(junk, MAX_LINE_SIZE, fp);
+ sscanf(junk, "%d %s", &crtime, count);
+ if ((crtime - lc) < 0) {
+ pprintf(p, "There are no new news items since your last login (%s).\n", strltime(&lc));
+ fclose(fp);
+ return;
+ } else {
+ pprintf(p, "Index of new news items:\n");
+ rscan_news(fp, p, lc);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ pprintf(p, "(\"news %d\" will display the most recent admin news file)\n", num_news);
+ }
+ }
+
+ fclose(fp);
+}
+
+PRIVATE int process_password(int p, char *password)
+{
+ int p1;
+ char salt[3];
+ int fd;
+ unsigned int fromHost;
+ int messnum;
+/*
+ struct hostent *hp;
+*/
+ int dummy; /* (to hold a return value) */
+
+ turn_echo_on(parray[p].socket);
+
+/* if (password[0] == '\n') {
+ parray[p].status = PLAYER_LOGIN;
+ return 0;
+ }*/
+
+ if (parray[p].passwd && parray[p].registered) {
+ salt[0] = parray[p].passwd[0];
+ salt[1] = parray[p].passwd[1];
+ salt[2] = '\0';
+ if (strcmp(crypt(password, salt), parray[p].passwd)) {
+ fd = parray[p].socket;
+ fromHost = parray[p].thisHost;
+ player_clear(p);
+ parray[p].logon_time = parray[p].last_command_time = time(0);
+ parray[p].status = PLAYER_LOGIN;
+ parray[p].socket = fd;
+ parray[p].thisHost = fromHost;
+ if (*password)
+ pprintf(p, "\n\n**** Invalid password! ****\n\n");
+ return COM_LOGOUT;
+ }
+ }
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].name != NULL) {
+ if ((!strcasecmp(parray[p].name, parray[p1].name)) && (p != p1)) {
+ if (parray[p].registered == 0) {
+ pprintf(p, "\n*** Sorry %s is already logged in ***\n", parray[p].name);
+ return COM_LOGOUT;
+ }
+ boot_out(p, p1);
+ }
+ }
+ }
+ if (parray[p].adminLevel > 0) {
+ psend_raw_file(p, mess_dir, MESS_ADMOTD);
+ } else {
+ psend_raw_file(p, mess_dir, MESS_MOTD);
+ }
+ if (!parray[p].passwd && parray[p].registered)
+ pprintf(p, "\n*** You have no password. Please set one with the password command.");
+ if (!parray[p].registered)
+ psend_raw_file(p, mess_dir, MESS_UNREGISTERED);
+ parray[p].status = PLAYER_PROMPT;
+ player_write_login(p);
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+#if 0 /* deleted by mann */
+ if (parray[p1].thisHost == parray[p].thisHost) {
+ fprintf(stderr, "FICS: Players %s and %s - same host: %s\n",
+ parray[p].name, parray[p1].name, dotQuad(parray[p].thisHost));
+ }
+#endif
+ if (!parray[p1].i_login)
+ continue;
+ if (parray[p1].adminLevel > 0) {
+/*
+ hp = gethostbyaddr((const char*)&(parray[p].thisHost), sizeof(parray[p].thisHost), AF_INET);
+*/
+ pprintf_prompt(p1, "\n[%s (%s: %s) has connected.]\n", parray[p].name,
+ (parray[p].registered ? "R" : "U"),
+ dotQuad(parray[p].thisHost));
+ } else {
+ pprintf_prompt(p1, "\n[%s has connected.]\n", parray[p].name);
+ }
+ }
+ parray[p].num_comments = player_num_comments(p);
+ messnum = player_num_messages(p);
+
+/* loon: don't send unreg any news. when you change this, feel free to
+ put all the news junk in one source file:) no reason for identical code
+ in command.c and comproc.c */
+ if (parray[p].registered) {
+ check_news(p, 0);
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, "\n");
+ check_news(p, 1);
+ }
+ }
+ if (messnum) {
+ pprintf(p, "\nYou have %d messages.\nUse \"messages\" to display them, or \"clearmessages\" to remove them.\n", messnum);
+ }
+ player_notify_present(p);
+ player_notify(p, "arrived", "arrival");
+ showstored(p);
+ if (parray[p].registered && (parray[p].lastHost != 0) &&
+ (parray[p].lastHost != parray[p].thisHost)) {
+#if 0 /* removed by DAV - we don't need to know this rubbish */
+ fprintf(stderr, "FICS: Player %s: Last login: %s ", parray[p].name,
+ dotQuad(parray[p].lastHost));
+ fprintf(stderr, "This login: %s\n", dotQuad(parray[p].thisHost));
+#endif
+ pprintf(p, "\nPlayer %s: Last login: %s ", parray[p].name,
+ dotQuad(parray[p].lastHost));
+ pprintf(p, "This login: %s", dotQuad(parray[p].thisHost));
+ }
+ parray[p].lastHost = parray[p].thisHost;
+ if (parray[p].registered && !parray[p].timeOfReg)
+ parray[p].timeOfReg = time(0);
+ parray[p].logon_time = parray[p].last_command_time = time(0);
+ dummy = check_and_print_shutdown(p); /*Tells the user if we are going to shutdown */
+ pprintf(p, "\n%s", parray[p].prompt);
+ return 0;
+}
+
+PRIVATE int process_prompt(int p, char *command)
+{
+ int retval;
+ char *cmd = "";
+
+ command = eattailwhite(eatwhite(command));
+ if (!*command) {
+ pprintf(p, "%s", parray[p].prompt);
+ return COM_OK;
+ }
+ retval = process_command(p, command, &cmd);
+ switch (retval) {
+ case COM_OK:
+ retval = COM_OK;
+ pprintf(p, "%s", parray[p].prompt);
+ break;
+ case COM_OK_NOPROMPT:
+ retval = COM_OK;
+ break;
+ case COM_ISMOVE:
+ retval = COM_OK;
+
+#ifdef TIMESEAL
+ if (parray[p].game >= 0 && garray[parray[p].game].status == GAME_ACTIVE
+ && parray[p].side == garray[parray[p].game].game_state.onMove
+ && garray[parray[p].game].flag_pending != FLAG_NONE) {
+ ExecuteFlagCmd(parray[p].game, con[parray[p].socket].time);
+ }
+#endif
+ process_move(p, command);
+ pprintf(p, "%s", parray[p].prompt);
+
+ break;
+ case COM_RIGHTS:
+ pprintf(p, "%s: Insufficient rights.\n", cmd);
+ pprintf(p, "%s", parray[p].prompt);
+ retval = COM_OK;
+ break;
+ case COM_AMBIGUOUS:
+/* pprintf(p, "%s: Ambiguous command.\n", cmd); */
+ {
+ int len = strlen(cmd);
+ int i = 0;
+ pprintf(p, "Ambiguous command. Matches:");
+ while (command_list[i].comm_name) {
+ if ((!strncmp(command_list[i].comm_name, cmd, len)) &&
+ (parray[p].adminLevel >= command_list[i].adminLevel)) {
+ pprintf(p, " %s", command_list[i].comm_name);
+ }
+ i++;
+ }
+ }
+ pprintf(p, "\n%s", parray[p].prompt);
+ retval = COM_OK;
+ break;
+ case COM_BADPARAMETERS:
+ printusage(p, command_list[lastCommandFound].comm_name);
+ pprintf(p, "%s", parray[p].prompt);
+ retval = COM_OK;
+ break;
+ case COM_FAILED:
+ case COM_BADCOMMAND:
+ pprintf(p, "%s: Command not found.\n", cmd);
+ retval = COM_OK;
+ pprintf(p, "%s", parray[p].prompt);
+ break;
+ case COM_LOGOUT:
+ retval = COM_LOGOUT;
+ break;
+ }
+ return retval;
+}
+
+/* Return 1 to disconnect */
+PUBLIC int process_input(int fd, char *com_string)
+{
+ int p = player_find(fd);
+ int retval = 0;
+
+ if (p < 0) {
+ fprintf(stderr, "FICS: Input from a player not in array!\n");
+ return -1;
+ }
+
+ commanding_player = p;
+ parray[p].last_command_time = time(0);
+
+ switch (parray[p].status) {
+ case PLAYER_EMPTY:
+ fprintf(stderr, "FICS: Command from an empty player!\n");
+ break;
+ case PLAYER_NEW:
+ fprintf(stderr, "FICS: Command from a new player!\n");
+ break;
+ case PLAYER_INQUEUE:
+ /* Ignore input from player in queue */
+ break;
+ case PLAYER_LOGIN:
+ retval = process_login(p, com_string);
+ if (retval == COM_LOGOUT && com_string != NULL)
+ fprintf (stderr, "%s tried to log in and failed.\n", com_string);
+ break;
+ case PLAYER_PASSWORD:
+ retval = process_password(p, com_string);
+ break;
+ case PLAYER_PROMPT:
+ parray[p].busy[0] = '\0';
+ /* added this to stop buggy admin levels; shane */
+ if (parray[p].adminLevel < 10)
+ parray[p].adminLevel = 0;
+ retval = process_prompt(p, com_string);
+ break;
+ }
+
+ commanding_player = -1;
+ return retval;
+}
+
+PUBLIC int process_new_connection(int fd, unsigned int fromHost)
+{
+ int p = player_new();
+
+ parray[p].status = PLAYER_LOGIN;
+ parray[p].socket = fd;
+ parray[p].thisHost = fromHost;
+ parray[p].logon_time = time(0);
+ psend_raw_file(p, mess_dir, MESS_WELCOME);
+ pprintf(p, "Head admin : %s Complaints to : %s\n", hadmin_handle, hadmin_email);
+ pprintf(p, "Server location: %s Server version : %s\n", fics_hostname, VERS_NUM);
+ psend_raw_file(p, mess_dir, MESS_LOGIN);
+ pprintf(p, "login: ");
+ return 0;
+}
+
+PUBLIC int process_disconnection(int fd)
+{
+ int p = player_find(fd);
+ int p1;
+
+ if (p < 0) {
+ fprintf(stderr, "FICS: Disconnect from a player not in array!\n");
+ return -1;
+ }
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pcommand(p, "unexamine");
+ }
+ if ((parray[p].game >=0) &&in_list(p, L_ABUSER, parray[p].name)) {
+ pcommand(p, "resign");
+ }
+ if (parray[p].status == PLAYER_PROMPT) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_login)
+ continue;
+ pprintf_prompt(p1, "\n[%s has disconnected.]\n", parray[p].name);
+ }
+ player_notify(p, "departed", "departure");
+ player_notify_departure(p);
+ player_write_logout(p);
+ if (parray[p].registered) {
+ parray[p].totalTime += time(0) - parray[p].logon_time;
+ player_save(p);
+ } else { /* delete unreg history file */
+ char fname[MAX_FILENAME_SIZE];
+ sprintf(fname, "%s/player_data/%c/%s.games", stats_dir, parray[p].login[0], parray[p].login);
+ unlink(fname);
+ }
+ }
+ player_remove(p);
+ return 0;
+}
+
+/* Called every few seconds */
+PUBLIC int process_heartbeat(int *fd)
+{
+ static int last_space = 0;
+ static int last_comfile = 0;
+/* static int last_ratings = 0; */
+ static int lastcalled = 0;
+ int time_since_last;
+ int p;
+/* static int rpid = 0; */
+ int now = time(0);
+
+/* game_update_times(); */
+
+ if (lastcalled == 0)
+ time_since_last = 0;
+ else
+ time_since_last = now - lastcalled;
+ lastcalled = now;
+
+ /* Check for timed out connections */
+ for (p = 0; p < p_num; p++) {
+ if (((parray[p].status == PLAYER_LOGIN) ||
+ (parray[p].status == PLAYER_PASSWORD)) &&
+ (player_idle(p) > MAX_LOGIN_IDLE)) {
+ pprintf(p, "\n**** LOGIN TIMEOUT ****\n");
+ *fd = parray[p].socket;
+ return COM_LOGOUT;
+ }
+ if ((parray[p].status == PLAYER_PROMPT) &&
+ (player_idle(p) > MAX_IDLE_TIME) &&
+ (parray[p].adminLevel == 0) &&
+ (!in_list(p, L_TD, parray[p].name))) {
+ pprintf(p, "\n**** Auto-logout because you were idle "
+ "more than one hour. ****\n");
+ *fd = parray[p].socket;
+ return COM_LOGOUT;
+ }
+ }
+/* loon: turning this fork off temporarily (28 Oct) for lag */
+#if 0
+ if (rpid) { /* Rating calculating going on */
+ int statusp;
+
+ if (wait3(&statusp, WNOHANG, NULL) == rpid) {
+ fprintf(stderr, "FICS: Reinitting statistics.\n");
+ rating_init(); /* Child finished, get the results. */
+ rpid = 0;
+ }
+ }
+ /* Recalc ratings every 3 hours */
+ /* This is done because the ratings stats and players can get out of sync
+ if there is a system crash. */
+ /* This is done as a child process and read results when complete */
+ if (last_ratings == 0)
+ last_ratings = (now - (5 * 60 * 60)) + 120; /* Do one in 2 minutes */
+ else {
+ if (last_ratings + 6 * 60 * 60 < now) {
+ last_ratings = now;
+ rpid = fork();
+ if (rpid < 0) {
+ fprintf(stderr, "FICS: Couldn't fork\n");
+ } else {
+ if (rpid == 0) { /* The child */
+ rating_recalc();
+ exit(0);
+ fprintf(stderr, "Recalc process should never get here!\n");
+ ASSERT(0);
+ }
+ }
+ }
+ }
+#endif
+ /* Check for the communication file from mail updates every 10 minutes */
+ /* That is probably too often, but who cares */
+ if (MailGameResult) {
+ if (last_comfile == 0)
+ last_comfile = now;
+ else {
+ if (last_comfile + 10 * 60 < now) {
+ last_comfile = now;
+ /* Check for com file */
+/* hostinfo_checkcomfile(); */
+ }
+ }
+ }
+ if (last_space == 0)
+ last_space = now;
+ else {
+ if (last_space + 60 < now) {/* Check the disk space every minute */
+ last_space = now;
+ if (available_space() < 1000000) {
+ server_shutdown(60, " **** Disk space is dangerously low!!! ****\n");
+ }
+ /* Check for com file */
+ /* hostinfo_checkcomfile(); */
+ }
+ }
+ ShutHeartBeat();
+ return COM_OK;
+}
+
+PUBLIC void commands_init()
+{
+ FILE *fp, *afp;
+ char fname[MAX_FILENAME_SIZE];
+ int i = 0;
+
+ sprintf(fname, "%s/commands", comhelp_dir);
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Could not write commands help file.\n");
+ return;
+ }
+ sprintf(fname, "%s/admin_commands", adhelp_dir);
+ afp = fopen(fname, "w");
+ if (!afp) {
+ fprintf(stderr, "FICS: Could not write admin_commands help file.\n");
+ fclose(fp);
+ return;
+ }
+ while (command_list[i].comm_name) {
+ if (command_list[i].adminLevel >= ADMIN_ADMIN) {
+ fprintf(afp, "%s\n", command_list[i].comm_name);
+ } else {
+ fprintf(fp, "%s\n", command_list[i].comm_name);
+ }
+ i++;
+ }
+ fclose(fp);
+ fclose(afp);
+}
+
+/* Need to save rated games */
+PUBLIC void TerminateCleanup()
+{
+ int p1;
+ int g;
+
+ for (g = 0; g < g_num; g++) {
+ if (garray[g].status != GAME_ACTIVE)
+ continue;
+ if (garray[g].rated) {
+ game_ended(g, WHITE, END_ADJOURN);
+ }
+ }
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status == PLAYER_EMPTY)
+ continue;
+ pprintf(p1, "\n **** Server shutting down immediately. ****\n\n");
+ if (parray[p1].status != PLAYER_PROMPT) {
+ close(parray[p1].socket);
+ } else {
+ pprintf(p1, "Logging you out.\n");
+ psend_raw_file(p1, mess_dir, MESS_LOGOUT);
+ player_write_logout(p1);
+ if (parray[p1].registered)
+ parray[p1].totalTime += time(0) - parray[p1].logon_time;
+ player_save(p1);
+ }
+ }
+}
blob - /dev/null
blob + c4e5648871beac7bb4fdbea4cbe14f9937f52bf4 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/command.h
+/* command.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _COMMAND_H
+#define _COMMAND_H
+
+#include "variable.h"
+#include "stdinclude.h"
+
+extern char *mess_dir;
+extern char *index_dir;
+extern char *help_dir[NUM_LANGS];
+extern char *comhelp_dir;
+extern char *info_dir;
+extern char *adhelp_dir;
+extern char *uscf_dir;
+extern char *stats_dir;
+extern char *config_dir;
+extern char *player_dir;
+extern char *adj_dir;
+extern char *hist_dir;
+extern char *journal_dir;
+extern char *board_dir;
+extern char *def_prompt;
+extern char *source_dir;
+extern char *lists_dir;
+extern char *news_dir;
+extern char *usage_dir[NUM_LANGS];
+
+extern char *hadmin_handle;
+
+extern int startuptime;
+extern char fics_hostname[81];
+extern int player_high;
+extern int game_high;
+extern int MailGameResult;
+
+/* Maximum length of a login name */
+#define MAX_LOGIN_NAME 20
+
+/* Maximum number of parameters per command */
+#define MAXNUMPARAMS 10
+
+/* Maximum string length of a single command word */
+#define MAX_COM_LENGTH 50
+
+/* Maximum string length of the whole command line */
+#define MAX_STRING_LENGTH 1024
+
+#define COM_OK 0
+#define COM_FAILED 1
+#define COM_ISMOVE 2
+#define COM_AMBIGUOUS 3
+#define COM_BADPARAMETERS 4
+#define COM_BADCOMMAND 5
+#define COM_LOGOUT 6
+#define COM_FLUSHINPUT 7
+#define COM_RIGHTS 8
+#define COM_OK_NOPROMPT 9
+
+#define ADMIN_USER 0
+#define ADMIN_ADMIN 10
+#define ADMIN_MASTER 20
+#define ADMIN_DEMIGOD 60
+#define ADMIN_GOD 100
+
+#define TYPE_NULL 0
+/*#define TYPE_NULL NULL <-- this is WRONG WRONG WRONG! --mann 5/10/95 */
+#define TYPE_WORD 1
+#define TYPE_STRING 2
+#define TYPE_INT 3
+typedef struct u_parameter {
+ int type;
+ union {
+ char *word;
+ char *string;
+ int integer;
+ } val;
+} parameter;
+
+typedef parameter param_list[MAXNUMPARAMS];
+
+typedef struct s_command_type {
+ char *comm_name;
+ char *param_string;
+ int (*comm_func)();
+ int adminLevel;
+} command_type;
+
+typedef struct s_alias_type {
+ char *comm_name;
+ char *alias;
+} alias_type;
+
+extern int commanding_player; /* The player whose command you're in */
+
+extern int process_input(int, char *);
+extern int process_new_connection(int, unsigned int);
+extern int process_disconnection(int);
+/* extern int process_incomplete(int, char *); */
+extern int process_heartbeat(int *);
+
+extern void commands_init(void);
+
+extern void TerminateCleanup(void);
+extern int process_command(int, char *, char **);
+
+
+extern int alias_lookup();
+extern int gethostname();
+
+#if defined(SGI) || defined(NETBSD)
+#else
+extern int wait3();
+/* extern char tolower(); */
+/* extern int sscanf(); */
+#endif
+
+#endif /* _COMMAND_H */
blob - /dev/null
blob + 1d5d47f350621be8d64c42c4ac7ed3c8602aba4a (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/command.h.orig
+/* command.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "variable.h"
+#ifndef _COMMAND_H
+#define _COMMAND_H
+
+extern char *mess_dir;
+extern char *index_dir;
+extern char *help_dir[NUM_LANGS];
+extern char *comhelp_dir;
+extern char *info_dir;
+extern char *adhelp_dir;
+extern char *stats_dir;
+extern char *config_dir;
+extern char *player_dir;
+extern char *adj_dir;
+extern char *hist_dir;
+extern char *board_dir;
+extern char *def_prompt;
+extern char *source_dir;
+extern char *lists_dir;
+extern char *news_dir;
+
+extern char *hadmin_handle;
+
+extern int startuptime;
+extern char fics_hostname[81];
+extern int player_high;
+extern int game_high;
+extern int MailGameResult;
+
+/* Maximum length of a login name */
+#define MAX_LOGIN_NAME 20
+
+/* Maximum number of parameters per command */
+#define MAXNUMPARAMS 10
+
+/* Maximum string length of a single command word */
+#define MAX_COM_LENGTH 50
+
+/* Maximum string length of the whole command line */
+#define MAX_STRING_LENGTH 1024
+
+#define COM_OK 0
+#define COM_FAILED 1
+#define COM_ISMOVE 2
+#define COM_AMBIGUOUS 3
+#define COM_BADPARAMETERS 4
+#define COM_BADCOMMAND 5
+#define COM_LOGOUT 6
+#define COM_FLUSHINPUT 7
+#define COM_RIGHTS 8
+#define COM_OK_NOPROMPT 9
+
+#define ADMIN_USER 0
+#define ADMIN_ADMIN 10
+#define ADMIN_MASTER 20
+#define ADMIN_DEMIGOD 60
+#define ADMIN_GOD 100
+
+#define TYPE_NULL 0
+/*#define TYPE_NULL NULL <-- this is WRONG WRONG WRONG! --mann 5/10/95 */
+#define TYPE_WORD 1
+#define TYPE_STRING 2
+#define TYPE_INT 3
+typedef struct u_parameter {
+ int type;
+ union {
+ char *word;
+ char *string;
+ int integer;
+ } val;
+} parameter;
+
+typedef parameter param_list[MAXNUMPARAMS];
+
+typedef struct s_command_type {
+ char *comm_name;
+ char *param_string;
+ int (*comm_func)();
+ int adminLevel;
+} command_type;
+
+typedef struct s_alias_type {
+ char *comm_name;
+ char *alias;
+} alias_type;
+
+extern int commanding_player; /* The player whose command you're in */
+
+extern int process_input(int, char *);
+extern int process_new_connection(int, unsigned int);
+extern int process_disconnection(int);
+/* extern int process_incomplete(int, char *); */
+extern int process_heartbeat(int *);
+
+extern void commands_init(void);
+
+extern void TerminateCleanup(void);
+extern int process_command(int, char *, char **);
+
+
+extern int alias_lookup();
+extern int gethostname();
+
+#if defined(SGI)
+#else
+extern int wait3();
+/* extern char tolower(); */
+/* extern int sscanf(); */
+#endif
+
+#endif /* _COMMAND_H */
blob - /dev/null
blob + a749f6b9afa86e07634776ccd0399e0fbc28f596 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/command.o differ
blob - /dev/null
blob + 104bf81c9a7a0b506fcd1ec3360e703ced642240 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/command_list.h
+/* command_list.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _COMMAND_LIST_H
+#define _COMMAND_LIST_H
+
+#include "comproc.h"
+#include "matchproc.h"
+#include "talkproc.h"
+#include "lists.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "adminproc.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "eco.h"
+#include "rating_conv.h"
+#include "shutdown.h"
+
+/*
+ Parameter string format
+ w - a word
+ o - an optional word
+ d - integer
+ p - optional integer
+ i - word or integer
+ n - optional word or integer
+ s - string to end
+ t - optional string to end
+
+ If the parameter option is given in lower case then the parameter is
+ converted to lower case before being passsed to the function. If it is
+ in upper case, then the parameter is passed as typed.
+ */
+/* Try to keep this list in alpha order, that is the way it is shown to
+ * the 'help commands' command.
+ */
+ /* Name Options Functions Security */
+PUBLIC command_type command_list[] = {
+
+ {"abort", "", com_abort, ADMIN_USER },
+ {"accept", "n", com_accept, ADMIN_USER },
+ {"addlist", "ww", com_addlist, ADMIN_USER },
+ {"adjourn", "", com_adjourn, ADMIN_USER },
+ {"alias", "oT", com_alias, ADMIN_USER },
+ {"allobservers", "n", com_allobservers, ADMIN_USER },
+ {"assess", "oo", com_assess, ADMIN_USER },
+ {"backward", "p", com_backward, ADMIN_USER },
+ {"bell", "", com_bell, ADMIN_USER },
+ {"best", "o", com_best, ADMIN_USER },
+ {"boards", "o", com_boards, ADMIN_USER },
+/* {"channel", "p", com_channel, ADMIN_USER }, */
+ {"clearmessages", "n", com_clearmessages, ADMIN_USER },
+ {"convert_bcf", "d", com_CONVERT_BCF, ADMIN_USER },
+ {"convert_elo", "d", com_CONVERT_ELO, ADMIN_USER },
+ {"convert_uscf", "d", com_CONVERT_USCF, ADMIN_USER },
+ {"cshout", "S", com_cshout, ADMIN_USER },
+ {"date", "", com_date, ADMIN_USER },
+ {"decline", "n", com_decline, ADMIN_USER },
+ {"draw", "", com_draw, ADMIN_USER },
+ {"eco", "n", com_eco, ADMIN_USER },
+ {"examine", "on", com_examine, ADMIN_USER },
+ {"finger", "o", com_stats, ADMIN_USER },
+ {"flag", "", com_flag, ADMIN_USER },
+ {"flip", "", com_flip, ADMIN_USER },
+ {"forward", "p", com_forward, ADMIN_USER },
+ {"games", "o", com_games, ADMIN_USER },
+ {"getpi", "w", com_getpi, ADMIN_USER },
+ {"goboard", "w", com_goboard, ADMIN_USER },
+ {"gonum", "d", com_gonum, ADMIN_USER },
+ {"handles", "w", com_handles, ADMIN_USER },
+ {"hbest", "o", com_hbest, ADMIN_USER },
+ {"help", "o", com_help, ADMIN_USER },
+ {"history", "o", com_history, ADMIN_USER },
+ {"hrank", "oo", com_hrank, ADMIN_USER },
+ {"inchannel", "n", com_inchannel, ADMIN_USER },
+ {"index", "o", com_index, ADMIN_USER },
+ {"info", "", com_info, ADMIN_USER },
+ {"it", "T", com_it, ADMIN_USER },
+ {"journal", "o", com_journal, ADMIN_USER },
+ {"jsave", "wwi", com_jsave, ADMIN_USER },
+ {"kibitz", "S", com_kibitz, ADMIN_USER },
+ {"limits", "", com_limits, ADMIN_USER },
+ {"llogons", "", com_llogons, ADMIN_USER },
+/* {"load", "ww", com_load, ADMIN_USER }, */
+ {"logons", "o", com_logons, ADMIN_USER },
+ {"mailhelp", "o", com_mailhelp, ADMIN_USER },
+ {"mailmess", "", com_mailmess, ADMIN_USER },
+ {"mailmoves", "n", com_mailmoves, ADMIN_USER },
+ {"mailoldmoves", "o", com_mailoldmoves, ADMIN_USER },
+ {"mailsource", "o", com_mailsource, ADMIN_USER },
+ {"mailstored", "wi", com_mailstored, ADMIN_USER },
+ {"match", "wt", com_match, ADMIN_USER },
+ {"messages", "nT", com_messages, ADMIN_USER },
+ {"mexamine", "w", com_mexamine, ADMIN_USER },
+ {"moretime", "d", com_moretime, ADMIN_USER },
+ {"moves", "n", com_moves, ADMIN_USER },
+ {"news", "o", com_news, ADMIN_USER },
+ {"next", "", com_more, ADMIN_USER },
+ {"observe", "n", com_observe, ADMIN_USER },
+ {"oldmoves", "o", com_oldmoves, ADMIN_USER },
+ {"open", "", com_open, ADMIN_USER },
+ {"partner", "o", com_partner, ADMIN_USER },
+ {"password", "WW", com_password, ADMIN_USER },
+ {"pause", "", com_pause, ADMIN_USER },
+ {"pending", "", com_pending, ADMIN_USER },
+ {"prefresh", "", com_prefresh, ADMIN_USER },
+ {"promote", "w", com_promote, ADMIN_USER },
+ {"ptell", "S", com_ptell, ADMIN_USER },
+ {"qtell", "iS", com_qtell, ADMIN_USER },
+ {"quit", "", com_quit, ADMIN_USER },
+ {"rank", "oo", com_rank, ADMIN_USER },
+ {"refresh", "n", com_refresh, ADMIN_USER },
+ {"revert", "", com_revert, ADMIN_USER },
+ {"resign", "o", com_resign, ADMIN_USER },
+ {"say", "S", com_say, ADMIN_USER },
+ {"servers", "", com_servers, ADMIN_USER },
+ {"set", "wT", com_set, ADMIN_USER },
+ {"shout", "T", com_shout, ADMIN_USER },
+ {"showlist", "o", com_showlist, ADMIN_USER },
+ {"simabort", "", com_simabort, ADMIN_USER },
+ {"simallabort", "", com_simallabort,ADMIN_USER },
+ {"simadjourn", "", com_simadjourn, ADMIN_USER },
+ {"simalladjourn", "", com_simalladjourn,ADMIN_USER },
+ {"simgames", "o", com_simgames, ADMIN_USER },
+ {"simmatch", "w", com_simmatch, ADMIN_USER },
+ {"simnext", "", com_simnext, ADMIN_USER },
+ {"simopen", "", com_simopen, ADMIN_USER },
+ {"simpass", "", com_simpass, ADMIN_USER },
+ {"simprev", "", com_simprev, ADMIN_USER },
+ {"smoves", "wi", com_smoves, ADMIN_USER },
+ {"sposition", "ww", com_sposition, ADMIN_USER },
+ {"statistics", "", com_statistics, ADMIN_USER },
+ {"stored", "o", com_stored, ADMIN_USER },
+ {"style", "d", com_style, ADMIN_USER },
+ {"sublist", "ww", com_sublist, ADMIN_USER },
+ {"switch", "", com_switch, ADMIN_USER },
+ {"takeback", "p", com_takeback, ADMIN_USER },
+ {"tell", "nS", com_tell, ADMIN_USER },
+ {"time", "n", com_time, ADMIN_USER },
+ {"unalias", "w", com_unalias, ADMIN_USER },
+ {"unexamine", "", com_unexamine, ADMIN_USER },
+ {"unobserve", "n", com_unobserve, ADMIN_USER },
+ {"unpause", "", com_unpause, ADMIN_USER },
+ {"uptime", "", com_uptime, ADMIN_USER },
+ {"uscf", "o", com_uscf, ADMIN_USER },
+ {"variables", "o", com_variables, ADMIN_USER },
+ {"whenshut", "", com_whenshut, ADMIN_USER },
+ {"whisper", "S", com_whisper, ADMIN_USER },
+ {"who", "T", com_who, ADMIN_USER },
+ {"withdraw", "n", com_withdraw, ADMIN_USER },
+ {"xtell", "wS", com_xtell, ADMIN_USER },
+ {"znotify", "", com_znotify, ADMIN_USER },
+
+ {"addcomment", "wS", com_addcomment, ADMIN_ADMIN },
+ {"addplayer", "WWS", com_addplayer, ADMIN_ADMIN },
+ {"adjudicate", "www", com_adjudicate, ADMIN_ADMIN },
+ {"ahelp", "o", com_adhelp, ADMIN_ADMIN },
+ {"admin", "", com_admin, ADMIN_ADMIN },
+ {"anews", "o", com_anews, ADMIN_ADMIN },
+ {"announce", "S", com_announce, ADMIN_ADMIN },
+ {"annunreg", "S", com_annunreg, ADMIN_ADMIN },
+ {"asetv", "wS", com_asetv, ADMIN_ADMIN },
+ {"asetadmin", "wd", com_asetadmin, ADMIN_ADMIN },
+ {"asetblitz", "wdpppp",com_asetblitz, ADMIN_ADMIN },
+ {"asetemail", "wO", com_asetemail, ADMIN_ADMIN },
+ {"asethandle", "WW", com_asethandle, ADMIN_ADMIN },
+ {"asetlight", "wdpppp",com_asetlight, ADMIN_ADMIN },
+ {"asetpasswd", "wW", com_asetpasswd, ADMIN_ADMIN },
+ {"asetrealname", "wT", com_asetrealname, ADMIN_ADMIN },
+ {"asetstd", "wdpppp",com_asetstd, ADMIN_ADMIN },
+ {"asetwild", "wdpppp",com_asetwild, ADMIN_ADMIN },
+ {"chkip", "w", com_checkIP, ADMIN_ADMIN },
+ {"chkgame", "i", com_checkGAME, ADMIN_ADMIN },
+ {"chkpl", "w", com_checkPLAYER, ADMIN_ADMIN },
+ {"chksc", "d", com_checkSOCKET, ADMIN_ADMIN },
+ {"chkts", "", com_checkTIMESEAL, ADMIN_ADMIN },
+ {"cmuzzle", "o", com_cmuzzle, ADMIN_ADMIN },
+ {"cnewsi", "S", com_cnewsi, ADMIN_ADMIN },
+ {"cnewsf", "dS", com_cnewsf, ADMIN_ADMIN },
+ {"canewsi", "S", com_canewsi, ADMIN_ADMIN },
+ {"canewsf", "dS", com_canewsf, ADMIN_ADMIN },
+ {"muzzle", "o", com_muzzle, ADMIN_ADMIN },
+ {"nuke", "w", com_nuke, ADMIN_ADMIN },
+ {"pose", "wS", com_pose, ADMIN_GOD },
+ {"asetmaxplayers", "p", com_asetmaxplayer, ADMIN_ADMIN },
+ {"quota", "p", com_quota, ADMIN_ADMIN },
+ {"raisedead", "WO", com_raisedead, ADMIN_ADMIN },
+ {"remplayer", "w", com_remplayer, ADMIN_ADMIN },
+ {"rerank", "w", com_fixrank, ADMIN_ADMIN },
+ {"showcomment", "w", com_showcomment, ADMIN_ADMIN },
+ {"shutdown", "oT", com_shutdown, ADMIN_ADMIN },
+ {"summon", "w", com_summon, ADMIN_ADMIN },
+
+ {NULL, NULL, NULL, ADMIN_USER}
+};
+
+PUBLIC alias_type g_alias_list[] = {
+ {"comment", "addcomment"},
+ {"adhelp", "ahelp"},
+ {"w", "who"},
+ {"h", "help"},
+ {"t", "tell"},
+ {"m", "match"},
+ {"go", "goboard"},
+ {"goto", "goboard"},
+ {"f", "finger"},
+ {"a", "accept"},
+ {"saa", "simallabort"},
+ {"saab", "simallaabort"},
+ {"sab", "simabort"},
+ {"sadj", "simadjourn"},
+ {"saadj", "simalladjourn"},
+ {"sh", "shout"},
+ {"sn", "simnext"},
+ {"sp", "simprev"},
+ {"vars", "variables"},
+ {"g", "games"},
+ {"players", "who a"},
+ {"p", "who a"},
+ {"pl", "who a"},
+ {"o", "observe"},
+ {"r", "refresh"},
+ {"re", "refresh"}, /* So r/re doesn't resign! */
+ {"ch", "channel"},
+ {"cls", "help cls"},
+ {"in", "inchannel"},
+ {".", "tell ."},
+ {",", "tell ,"},
+ {"`", "tell ."},
+ {"!", "shout"},
+ {"I", "it"},
+ {"i", "it"},
+ {":", "it"},
+ {"?", "help"},
+ {"exit", "quit"},
+ {"logout", "quit"},
+ {"bye", "quit"},
+ {"*", "kibitz"},
+ {"#", "whisper"},
+ {"ma", "match"},
+ {"more", "next"},
+ {"n", "next"},
+ {"znotl", "znotify"},
+ {"+", "addlist"},
+ {"-", "sublist"},
+ {"=", "showlist"},
+ {NULL, NULL}
+};
+
+#endif /* _COMMAND_LIST_H */
blob - /dev/null
blob + b8afce6f3c7de8a654ae0fad8772dc6d1696816b (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/common.h
+/*
+ * File: common.h
+ * Copyright 1993, Richard V. Nash
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _COMMON_H
+#define _COMMON_H
+
+#include "vers.h"
+#include "legal.h"
+
+#define PUBLIC
+#define PRIVATE static
+
+#ifndef NULL
+#define NULL ((void *)0)
+#endif
+
+#define SWAP(a,b,type) {\
+ type tmp; \
+ tmp = (a);\
+ (a) = (b);\
+ (b) = tmp;\
+}
+
+#ifdef DEBUG
+#define ASSERT(expression) \
+ while (((expression) ? 0 : \
+ (fprintf (stderr, "Assertion failed: file %s, line %d.\n", \
+ __FILE__, __LINE__), \
+ abort (), 0)))
+#else
+#define ASSERT(expression) while(0)
+#endif /* DEBUG */
+
+#endif /* _COMMON_H */
blob - /dev/null
blob + b2d251c59ab6a347051385bdf1a7993912ba3047 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/comproc.c
+/* comproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ foxbat 95/03/11 added filters in cmatch.
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "command.h"
+#include "utils.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "variable.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "board.h"
+/* #include "hostinfo.h" */
+#include "multicol.h"
+#include "ratings.h"
+#include "formula.h"
+#include "lists.h"
+#include "eco.h"
+#include "network.h"
+#include <string.h>
+
+#include <sys/resource.h>
+
+/* grimm */
+#if defined(SGI)
+#else
+/* int system(char *arg); */
+#endif
+
+const none = 0;
+const blitz_rat = 1;
+const std_rat = 2;
+const wild_rat = 3;
+const light_rat = 4;
+
+
+PUBLIC int com_rating_recalc(int p, param_list param)
+{
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ rating_recalc();
+ return COM_OK;
+}
+
+PUBLIC int com_more(int p, param_list param)
+{
+ pmore_file(p);
+ return COM_OK;
+}
+
+PUBLIC int num_news = -1;
+
+PUBLIC void rscan_news2(FILE *fp, int p, int num)
+{
+ char junk[MAX_LINE_SIZE], count[10];
+ int crtime;
+ char *junkp;
+
+ if (num == 0)
+ return;
+
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ return;
+ sscanf(junk, "%d %s", &crtime, count);
+ rscan_news2(fp, p, num - 1);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+}
+
+PUBLIC int com_news(int p, param_list param)
+{
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+ char junk[MAX_LINE_SIZE];
+ char *junkp;
+ int crtime, found = 0;
+ char count[10];
+
+ sprintf(filename, "%s/newnews.index", news_dir);
+ fp = fopen(filename, "r");
+
+ if (!fp) {
+ fprintf(stderr, "Can\'t find news index.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == 0) {
+
+ /* no params - then just display index of last ten news items */
+
+ pprintf(p,"Index of recent news items:\n");
+ fgets(junk, MAX_LINE_SIZE, fp);
+ sscanf(junk, "%d %s", &crtime, count);
+ rscan_news2(fp, p, 9);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ fclose(fp);
+
+ } else if ((param[0].type == TYPE_WORD) && !strcmp(param[0].val.word,"all")) {
+
+ /* param all - displays index all news items */
+
+ pprintf(p, "Index of all news items:\n");
+ fgets(junk, MAX_LINE_SIZE, fp);
+ sscanf(junk, "%d %s", &crtime, count);
+ rscan_news(fp, p, 0);
+ junkp = junk;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, fix_time(strltime(&crtime)), junkp);
+ fclose(fp);
+
+ } else {
+
+ /* check if the specific news file exist in index */
+
+ while (!feof(fp) && !found) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ sscanf(junkp, "%d %s", &crtime, count);
+ if (!strcmp(count, param[0].val.word)) {
+ found = 1;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "NEWS %3s (%s) %s\n", count, fix_time(strltime(&crtime)),
+ junkp);
+ }
+ }
+
+ fclose(fp);
+
+ if (!found) {
+ pprintf(p, "Bad index number!\n");
+ return COM_OK;
+ }
+
+ /* file exists - show it */
+ sprintf(filename, "%s/news.%s", news_dir, param[0].val.word);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pprintf(p, "No more info.\n");
+ return COM_OK;
+ }
+
+ fclose(fp);
+
+ sprintf(filename, "news.%s", param[0].val.word);
+ if (psend_file(p, news_dir, filename) < 0) {
+ pprintf(p, "Internal error - couldn't send news file!\n");
+ }
+ }
+
+ return COM_OK;
+}
+
+PUBLIC int com_quit(int p, param_list param)
+{
+ if ((parray[p].game >= 0) && (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pcommand(p, "unexamine");
+ }
+
+ if (parray[p].game >= 0) {
+ pprintf(p, "You can't quit while you are playing a game.\nType 'resign' to resign the game, or you can request an abort with 'abort'.\n");
+ return COM_OK;
+ }
+ psend_logoutfile(p, mess_dir, MESS_LOGOUT);
+ return COM_LOGOUT;
+}
+
+PUBLIC int com_set(int p, param_list param)
+{
+ int result;
+ int which;
+ char *val;
+
+ if (param[1].type == TYPE_NULL)
+ val = NULL;
+ else
+ val = param[1].val.string;
+ result = var_set(p, param[0].val.word, val, &which);
+ switch (result) {
+ case VAR_OK:
+ break;
+ case VAR_BADVAL:
+ pprintf(p, "Bad value given for variable %s.\n", param[0].val.word);
+ break;
+ case VAR_NOSUCH:
+ pprintf(p, "No such variable name %s.\n", param[0].val.word);
+ break;
+ case VAR_AMBIGUOUS:
+ pprintf(p, "Ambiguous variable name %s.\n", param[0].val.word);
+ break;
+ }
+ /* player_save(p); */
+ return COM_OK;
+}
+
+PUBLIC int FindPlayer(int p, char* name, int *p1, int *connected)
+{
+ *p1 = player_search(p, name);
+ if (*p1 == 0)
+ return 0;
+ if (*p1 < 0) { /* player had to be connected and will be
+ removed later */
+ *connected = 0;
+ *p1 = (-*p1) - 1;
+ } else {
+ *connected = 1;
+ *p1 = *p1 - 1;
+ }
+ return 1;
+}
+
+PRIVATE void com_stats_andify(int *numbers, int howmany, char *dest)
+{
+ char tmp[10];
+
+ *dest = '\0';
+ while (howmany--) {
+ sprintf(tmp, "%d", numbers[howmany]);
+ strcat(dest, tmp);
+ if (howmany > 1)
+ sprintf(tmp, ", ");
+ else if (howmany == 1)
+ sprintf(tmp, " and ");
+ else
+ sprintf(tmp, ".\n");
+ strcat(dest, tmp);
+ }
+ return;
+}
+
+PRIVATE void com_stats_rating(char *hdr, statistics * stats, char *dest)
+{
+ char tmp[100];
+
+ sprintf(dest, "%-10s%4s %5.1f %4d %4d %4d %4d",
+ hdr, ratstr(stats->rating), stats->sterr, stats->win, stats->los, stats->dra, stats->num);
+ if (stats->whenbest) {
+ sprintf(tmp, " %d", stats->best);
+ strcat(dest, tmp);
+ strftime(tmp, sizeof(tmp), " (%d-%b-%y)", localtime((time_t *) & stats->whenbest));
+ strcat(dest, tmp);
+ }
+ strcat(dest, "\n");
+ return;
+}
+
+PUBLIC int com_stats(int p, param_list param)
+{
+ int g, i, t;
+ int p1, connected;
+ char line[255], tmp[255];
+ int numbers[MAX_OBSERVE > MAX_SIMUL ? MAX_OBSERVE : MAX_SIMUL];
+ int onTime;
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(line, "\nStatistics for %-11s ", parray[p1].name);
+ if ((connected) && (parray[p1].status == PLAYER_PROMPT)) {
+ sprintf(tmp, "On for: %s", hms_desc(player_ontime(p1)));
+ strcat(line, tmp);
+ sprintf(tmp, " Idle: %s\n", hms_desc(player_idle(p1)));
+ } else {
+ if ((t = player_lastdisconnect(p1)))
+ sprintf(tmp, "(Last disconnected %s):\n", strltime(&t));
+ else
+ sprintf(tmp, "(Never connected.)\n");
+ }
+ strcat(line, tmp);
+ pprintf(p, "%s", line);
+ if (parray[p1].simul_info.numBoards) {
+ for (i = 0, t = 0; i < parray[p1].simul_info.numBoards; i++) {
+ if ((numbers[t] = parray[p1].simul_info.boards[i] + 1) != 0)
+ t++;
+ }
+ pprintf(p, "%s is giving a simul: game%s ", parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ } else if (parray[p1].game >= 0) {
+ g = parray[p1].game;
+ if (garray[g].status == GAME_EXAMINE) {
+ pprintf(p, "(Examining game %d: %s vs. %s)\n", g + 1,
+ garray[g].white_name, garray[g].black_name);
+ } else {
+ pprintf(p, "(playing game %d: %s vs. %s)\n", g + 1,
+ parray[garray[g].white].name, parray[garray[g].black].name);
+ if (garray[g].link >= 0) {
+ pprintf(p, "(partner is playing game %d: %s vs. %s)\n", garray[g].link + 1,
+ parray[garray[garray[g].link].white].name,
+ parray[garray[garray[g].link].black].name);
+ }
+ }
+ }
+ if (parray[p1].num_observe) {
+ for (i = 0, t = 0; i < parray[p1].num_observe; i++) {
+ g = parray[p1].observe_list[i];
+ if ((g != -1) && ((parray[p].adminLevel >= ADMIN_ADMIN) || (garray[g].private == 0)))
+ numbers[t++] = g + 1;
+ }
+ if (t) {
+ pprintf(p, "%s is observing game%s ", parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ }
+ }
+ if (parray[p1].busy[0]) {
+ pprintf(p, "(%s %s)\n", parray[p1].name, parray[p1].busy);
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "%s is NOT a registered player.\n\n", parray[p1].name);
+ } else {
+ pprintf(p, "\n rating RD win loss draw total best\n");
+ com_stats_rating("Blitz", &parray[p1].b_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Standard", &parray[p1].s_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Lightning", &parray[p1].l_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Wild", &parray[p1].w_stats, tmp);
+ pprintf(p, tmp);
+ }
+ pprintf(p, "\n");
+ if (parray[p1].adminLevel > 0) {
+ pprintf(p, "Admin Level: ");
+ switch (parray[p1].adminLevel) {
+ case 5:
+ pprintf(p, "Authorized Helper Person\n");
+ break;
+ case 10:
+ pprintf(p, "Administrator\n");
+ break;
+ case 15:
+ pprintf(p, "Help File Librarian/Administrator\n");
+ break;
+ case 20:
+ pprintf(p, "Master Administrator\n");
+ break;
+ case 50:
+ pprintf(p, "Master Help File Librarian/Administrator\n");
+ break;
+ case 60:
+ pprintf(p, "Assistant Super User\n");
+ break;
+ case 100:
+ pprintf(p, "Super User\n");
+ break;
+ default:
+ pprintf(p, "%d\n", parray[p1].adminLevel);
+ break;
+ }
+ }
+ if (parray[p].adminLevel > 0)
+ pprintf(p, "Full Name : %s\n", (parray[p1].fullName ? parray[p1].fullName : "(none)"));
+ if (((p1 == p) && (parray[p1].registered)) || (parray[p].adminLevel > 0))
+ pprintf(p, "Address : %s\n", (parray[p1].emailAddress ? parray[p1].emailAddress : "(none)"));
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, "Host : %s\n",
+ dotQuad(connected ? parray[p1].thisHost : parray[p1].lastHost));
+ }
+ if ((parray[p].adminLevel > 0) && (parray[p1].registered))
+ if (parray[p1].num_comments)
+ pprintf(p, "Comments : %d\n", parray[p1].num_comments);
+
+ if (connected && parray[p1].registered && (p==p1 ||
+ (parray[p].adminLevel > 0))) {
+ char *timeToStr = ctime((time_t *) &parray[p1].timeOfReg);
+
+ timeToStr[strlen(timeToStr)-1]='\0';
+ pprintf(p, "\n");
+ onTime = (time(0) - parray[p1].logon_time) + parray[p1].totalTime;
+
+ pprintf(p, "Total time on-line: %s\n", hms_desc(onTime) );
+ pprintf(p, "%% of life on-line: %3.1f (since %s)\n",
+ (double)((onTime*100)/(double)(time(0)-parray[p1].timeOfReg)),
+ timeToStr);
+ }
+
+#ifdef TIMESEAL
+ if (connected)
+ pprintf(p, "\nTimeseal : %s\n",
+ (con[parray[p1].socket].timeseal) ? "On" : "Off");
+ if ((parray[p].adminLevel > 0) && (connected)) {
+ if (findConnection(parray[p1].socket) && con[parray[p1].socket].timeseal) {
+ pprintf(p, "Unix acc : %s\nSystem/OS : %s\n",
+ con[parray[p1].socket].user,
+ con[parray[p1].socket].sys);
+ }
+ }
+#endif
+
+ if (parray[p1].num_plan) {
+ pprintf(p, "\n");
+ for (i = 0; i < parray[p1].num_plan; i++)
+ pprintf(p, "%2d: %s\n", i + 1, (parray[p1].planLines[i] != NULL) ? parray[p1].planLines[i] : "");
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_password(int p, param_list param)
+{
+ char *oldpassword = param[0].val.word;
+ char *newpassword = param[1].val.word;
+ char salt[3];
+
+ if (!parray[p].registered) {
+ pprintf(p, "Setting a password is only for registered players.\n");
+ return COM_OK;
+ }
+ if (parray[p].passwd) {
+ salt[0] = parray[p].passwd[0];
+ salt[1] = parray[p].passwd[1];
+ salt[2] = '\0';
+ if (strcmp(crypt(oldpassword, salt), parray[p].passwd)) {
+ pprintf(p, "Incorrect password, password not changed!\n");
+ return COM_OK;
+ }
+ rfree(parray[p].passwd);
+ parray[p].passwd = NULL;
+ }
+ salt[0] = 'a' + rand() % 26;
+ salt[1] = 'a' + rand() % 26;
+ salt[2] = '\0';
+ parray[p].passwd = strdup(crypt(newpassword, salt));
+ pprintf(p, "Password changed to \"%s\".\n", newpassword);
+ return COM_OK;
+}
+
+PUBLIC int com_uptime(int p, param_list param)
+{
+ unsigned long uptime = time(0) - startuptime;
+ struct rusage ru;
+ int days = (uptime / (60*60*24));
+ int hours = ((uptime % (60*60*24)) / (60*60));
+ int mins = (((uptime % (60*60*24)) % (60*60)) / 60);
+ int secs = (((uptime % (60*60*24)) % (60*60)) % 60);
+
+ pprintf(p, "Server location: %s Server version : %s\n", fics_hostname,VERS_NUM);
+ pprintf(p, "The server has been up since %s.\n", strltime(&startuptime));
+ if ((days==0) && (hours==0) && (mins==0)) {
+ pprintf(p, "(Up for %d second%s)\n",
+ secs, (secs==1) ? "" : "s");
+ } else if ((days==0) && (hours==0)) {
+ pprintf(p, "(Up for %d minute%s and %d second%s)\n",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else if (days==0) {
+ pprintf(p, "(Up for %d hour%s, %d minute%s and %d second%s)\n",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else {
+ pprintf(p, "(Up for %d day%s, %d hour%s, %d minute%s and %d second%s)\n",
+ days, (days==1) ? "" : "s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ }
+ pprintf(p, "\nAllocs: %u Frees: %u Allocs In Use: %u\n",
+ malloc_count, free_count, malloc_count - free_count);
+ if (parray[p].adminLevel >= ADMIN_ADMIN) {
+ pprintf(p, "\nplayer size:%d, game size:%d, con size:%d, g_num:%d\n",
+ sizeof(player), sizeof(game), net_consize(), g_num);
+ getrusage(RUSAGE_SELF, &ru);
+ pprintf(p, "pagesize = %d, maxrss = %d, total = %d\n", getpagesize(), ru.ru_maxrss, getpagesize() * ru.ru_maxrss);
+ }
+ pprintf(p, "\nPlayer limit: %d\n", max_connections-10);
+ pprintf(p, "\nThere are currently %d players, with a high of %d since last restart.\n", player_count(1), player_high);
+ pprintf(p, "There are currently %d games, with a high of %d since last restart.\n", game_count(), game_high);
+ pprintf(p, "\nCompiled on %s\n", COMP_DATE);
+ return COM_OK;
+}
+
+PUBLIC int com_date(int p, param_list param)
+{
+ int t = time(0);
+ pprintf(p, "Local time - %s\n", strltime(&t));
+ pprintf(p, "Greenwich time - %s\n", strgtime(&t));
+ return COM_OK;
+}
+
+char *inout_string[] = {
+ "login", "logout"
+};
+
+PRIVATE int plogins(p, fname)
+int p;
+char *fname;
+{
+ FILE *fp;
+ int inout, thetime, registered;
+ char loginName[MAX_LOGIN_NAME + 1];
+ char ipstr[20];
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no login information available.\n");
+ return COM_OK;
+ }
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime,
+ ®istered, ipstr) != 5) {
+ fprintf(stderr, "FICS: Error in login info format. %s\n", fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ pprintf(p, "%s: %-17s %-6s", strltime(&thetime), loginName,
+ inout_string[inout]);
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, " from %s\n", ipstr);
+ } else
+ pprintf(p, "\n");
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+PUBLIC int com_llogons(int p, param_list param)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%s", stats_dir, STATS_LOGONS);
+ return plogins(p, fname);
+}
+
+PUBLIC int com_logons(int p, param_list param)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, param[0].val.word[0], param[0].val.word, STATS_LOGONS);
+ } else {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS);
+ }
+ return plogins(p, fname);
+}
+
+#define WHO_OPEN 0x01
+#define WHO_CLOSED 0x02
+#define WHO_RATED 0x04
+#define WHO_UNRATED 0x08
+#define WHO_FREE 0x10
+#define WHO_PLAYING 0x20
+#define WHO_REGISTERED 0x40
+#define WHO_UNREGISTERED 0x80
+#define WHO_BUGTEAM 0x100
+
+#define WHO_ALL 0xff
+
+void AddPlayerLists (int p1, char *ptmp)
+{
+ if ((parray[p1].adminLevel >= 10) && (parray[p1].i_admin))
+ strcat(ptmp, "(*)");
+ if (in_list(p1, L_COMPUTER, parray[p1].name))
+ strcat(ptmp, "(C)");
+ if (in_list(p1, L_FM, parray[p1].name))
+ strcat(ptmp, "(FM)");
+ if (in_list(p1, L_IM, parray[p1].name))
+ strcat(ptmp, "(IM)");
+ if (in_list(p1, L_GM, parray[p1].name))
+ strcat(ptmp, "(GM)");
+ if (in_list(p1, L_TD, parray[p1].name))
+ strcat(ptmp, "(TD)");
+ if (in_list(p1, L_TEAMS, parray[p1].name))
+ strcat(ptmp, "(T)");
+ if (in_list(p1, L_BLIND, parray[p1].name))
+ strcat(ptmp, "(B)");
+}
+
+PRIVATE void who_terse(int p, int num, int *plist, int type)
+{
+ char ptmp[80 + 20]; /* for highlight */
+ multicol *m = multicol_start(PARRAY_SIZE);
+ int i;
+ int p1;
+ int rat;
+
+ /* altered DAV 3/15/95 */
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+
+ if (type == blitz_rat)
+ rat = parray[p1].b_stats.rating;
+ else if (type == wild_rat)
+ rat = parray[p1].w_stats.rating;
+ else if (type == std_rat)
+ rat = parray[p1].s_stats.rating;
+ else if (type == light_rat)
+ rat = parray[p1].l_stats.rating;
+
+ if (type == none) {
+ sprintf(ptmp, " ");
+ } else {
+ sprintf(ptmp, "%-4s", ratstrii(rat, parray[p1].registered));
+ if (parray[p1].simul_info.numBoards) {
+ strcat(ptmp, "~");
+ } else if ((parray[p1].game >= 0) && (garray[parray[p1].game].status == GAME_EXAMINE)) {
+ strcat(ptmp, "#");
+ } else if (parray[p1].game >= 0) {
+ strcat(ptmp, "^");
+ } else if (!parray[p1].open) {
+ strcat(ptmp, ":");
+ } else if (player_idle(p1) > 300) {
+ strcat(ptmp, ".");
+ } else {
+ strcat(ptmp, " ");
+ }
+ }
+
+ if (p == p1) {
+ psprintf_highlight(p, ptmp + strlen(ptmp), "%s", parray[p1].name);
+ } else {
+ strcat(ptmp, parray[p1].name);
+ }
+
+ AddPlayerLists(p1, ptmp);
+ multicol_store(m, ptmp);
+ }
+ multicol_pprint(m, p, 80, 2);
+ multicol_end(m);
+ pprintf(p, "\n %d players displayed (of %d). (*) indicates system administrator.\n", num, player_count(1));
+}
+
+PRIVATE void who_verbose(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* +8 for highlight */
+ char p1WithAttrs[255];
+
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+ pprintf(p,
+ " | User Standard Blitz On for Idle |\n"
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+
+ strcpy(playerLine, " |");
+
+ if (parray[p1].game >= 0)
+ sprintf(tmp, "%3d", parray[p1].game + 1);
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (!parray[p1].open)
+ sprintf(tmp, "X");
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (parray[p1].registered)
+ if (parray[p1].rated) {
+ sprintf(tmp, " ");
+ } else {
+ sprintf(tmp, "u");
+ }
+ else
+ sprintf(tmp, "U");
+ strcat(playerLine, tmp);
+
+ /* Modified by hersco to include lists in 'who v.' */
+ strcpy (p1WithAttrs, parray[p1].name);
+ AddPlayerLists(p1, p1WithAttrs);
+ p1WithAttrs[17] = '\0';
+
+ /* Modified by DAV 3/15/95 */
+ if (p == p1) {
+ strcpy(tmp, " ");
+ psprintf_highlight(p, tmp + strlen(tmp), "%-17s", p1WithAttrs);
+ } else {
+ sprintf(tmp, " %-17s", p1WithAttrs);
+ }
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, " %4s %-4s %5s ",
+ ratstrii(parray[p1].s_stats.rating, parray[p1].registered),
+ ratstrii(parray[p1].b_stats.rating, parray[p1].registered),
+ hms(player_ontime(p1), 0, 0, 0));
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s |\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " |\n");
+ }
+ strcat(playerLine, tmp);
+ pprintf(p, "%s", playerLine);
+ }
+
+ pprintf(p,
+ " | |\n"
+ );
+ pprintf(p,
+ " | %3d Players Displayed |\n",
+ num
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+}
+
+PRIVATE void who_winloss(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* for highlight */
+ char p1WithAttrs[255];
+
+ pprintf(p,
+ "Name Stand win loss draw Blitz win loss draw idle\n"
+ );
+ pprintf(p,
+ "---------------- ----- ------------- ----- ------------- ----\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ playerLine[0] = '\0';
+ p1 = plist[i];
+
+ /* Modified by hersco to include lists in 'who n.' */
+ strcpy (p1WithAttrs, parray[p1].name);
+ AddPlayerLists(p1, p1WithAttrs);
+ p1WithAttrs[17] = '\0';
+
+ if (p1 == p) {
+ psprintf_highlight(p, playerLine, "%-17s", p1WithAttrs);
+ } else {
+ sprintf(playerLine, "%-17s", p1WithAttrs);
+ }
+ sprintf(tmp, " %4s %4d %4d %4d ",
+ ratstrii(parray[p1].s_stats.rating, parray[p1].registered),
+ (int) parray[p1].s_stats.win,
+ (int) parray[p1].s_stats.los,
+ (int) parray[p1].s_stats.dra);
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, "%4s %4d %4d %4d ",
+ ratstrii(parray[p1].b_stats.rating, parray[p1].registered),
+ (int) parray[p1].b_stats.win,
+ (int) parray[p1].b_stats.los,
+ (int) parray[p1].b_stats.dra);
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " \n");
+ }
+ strcat(playerLine, tmp);
+
+ pprintf(p, "%s", playerLine);
+ }
+ pprintf(p, " %3d Players Displayed.\n", num);
+}
+
+PRIVATE int who_ok(int p, unsigned int sel_bits)
+{
+ int p2;
+ if (parray[p].status != PLAYER_PROMPT)
+ return 0;
+ if (sel_bits == WHO_ALL)
+ return 1;
+ if (sel_bits & WHO_OPEN)
+ if (!parray[p].open)
+ return 0;
+ if (sel_bits & WHO_CLOSED)
+ if (parray[p].open)
+ return 0;
+ if (sel_bits & WHO_RATED)
+ if (!parray[p].rated)
+ return 0;
+ if (sel_bits & WHO_UNRATED)
+ if (parray[p].rated)
+ return 0;
+ if (sel_bits & WHO_FREE)
+ if (parray[p].game >= 0)
+ return 0;
+ if (sel_bits & WHO_PLAYING)
+ if (parray[p].game < 0)
+ return 0;
+ if (sel_bits & WHO_REGISTERED)
+ if (!parray[p].registered)
+ return 0;
+ if (sel_bits & WHO_UNREGISTERED)
+ if (parray[p].registered)
+ return 0;
+ if (sel_bits & WHO_BUGTEAM) {
+ p2 = parray[p].partner;
+ if (p2 < 0 || parray[p2].partner != p)
+ return 0;
+ }
+ return 1;
+}
+
+
+PRIVATE int blitz_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].b_stats.rating > parray[p2].b_stats.rating)
+ return -1;
+ if (parray[p1].b_stats.rating < parray[p2].b_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int light_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].l_stats.rating > parray[p2].l_stats.rating)
+ return -1;
+ if (parray[p1].l_stats.rating < parray[p2].l_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int stand_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].s_stats.rating > parray[p2].s_stats.rating)
+ return -1;
+ if (parray[p1].s_stats.rating < parray[p2].s_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int wild_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].w_stats.rating > parray[p2].w_stats.rating)
+ return -1;
+ if (parray[p1].w_stats.rating < parray[p2].w_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int alpha_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PUBLIC void sort_players(int players[PARRAY_SIZE],
+ int ((*cmp_func) (const void *, const void *)))
+{
+ int i;
+
+ for (i = 0; i < p_num; i++) {
+ players[i] = i;
+ }
+ qsort(players, p_num, sizeof(int), cmp_func);
+}
+
+/* This is the of the most compliclicated commands in terms of parameters */
+PUBLIC int com_who(int p, param_list param)
+{
+ int style = 0;
+ float stop_perc = 1.0;
+ float start_perc = 0;
+ unsigned int sel_bits = WHO_ALL;
+ int sortlist[PARRAY_SIZE], plist[PARRAY_SIZE];
+ int ((*cmp_func) (const void *, const void *)) = blitz_cmp;
+ int startpoint;
+ int stoppoint;
+ int i, len;
+ int tmpI, tmpJ;
+ char c;
+ int p1, count, num_who;
+ int sort_type = blitz_rat;
+
+ if (param[0].type != TYPE_NULL) {
+ len = strlen(param[0].val.string);
+ for (i = 0; i < len; i++) {
+ c = param[0].val.string[i];
+ if (isdigit(c)) {
+ if (i == 0 || !isdigit(param[0].val.string[i - 1])) {
+ tmpI = c - '0';
+ if (tmpI == 1) {
+ start_perc = 0.0;
+ stop_perc = 0.333333;
+ } else if (tmpI == 2) {
+ start_perc = 0.333333;
+ stop_perc = 0.6666667;
+ } else if (tmpI == 3) {
+ start_perc = 0.6666667;
+ stop_perc = 1.0;
+ } else if ((i == len - 1) || (!isdigit(param[0].val.string[i + 1])))
+ return COM_BADPARAMETERS;
+ } else {
+ tmpI = c - '0';
+ tmpJ = param[0].val.string[i - 1] - '0';
+ if (tmpI == 0)
+ return COM_BADPARAMETERS;
+ if (tmpJ > tmpI)
+ return COM_BADPARAMETERS;
+ start_perc = ((float) tmpJ - 1.0) / (float) tmpI;
+ stop_perc = ((float) tmpJ) / (float) tmpI;
+ }
+ } else {
+ switch (c) {
+ case ' ':
+ case '\n':
+ case '\t':
+ break;
+ case 'o':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_OPEN;
+ else
+ sel_bits |= WHO_OPEN;
+ break;
+ case 'r':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_RATED;
+ else
+ sel_bits |= WHO_RATED;
+ break;
+ case 'f':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_FREE;
+ else
+ sel_bits |= WHO_FREE;
+ break;
+ case 'a':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_FREE | WHO_OPEN;
+ else
+ sel_bits |= (WHO_FREE | WHO_OPEN);
+ break;
+ case 'R':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_REGISTERED;
+ else
+ sel_bits |= WHO_REGISTERED;
+ break;
+ case 'l': /* Sort order */
+ cmp_func = alpha_cmp;
+ sort_type = none;
+ break;
+ case 'A': /* Sort order */
+ cmp_func = alpha_cmp;
+ break;
+ case 'w': /* Sort order */
+ cmp_func = wild_cmp;
+ sort_type = wild_rat;
+ break;
+ case 's': /* Sort order */
+ cmp_func = stand_cmp;
+ sort_type = std_rat;
+ break;
+ case 'b': /* Sort order */
+ cmp_func = blitz_cmp;
+ sort_type = blitz_rat;
+ break;
+ case 'L': /* Sort order */
+ cmp_func = light_cmp;
+ sort_type = light_rat;
+ break;
+ case 't': /* format */
+ style = 0;
+ break;
+ case 'v': /* format */
+ style = 1;
+ break;
+ case 'n': /* format */
+ style = 2;
+ break;
+ case 'U':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_UNREGISTERED;
+ else
+ sel_bits |= WHO_UNREGISTERED;
+ break;
+ case 'B':
+ if (sel_bits == WHO_ALL)
+ sel_bits = WHO_BUGTEAM;
+ else
+ sel_bits |= WHO_BUGTEAM;
+ break;
+ default:
+ return COM_BADPARAMETERS;
+ break;
+ }
+ }
+ }
+ }
+ sort_players(sortlist, cmp_func);
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ count++;
+ }
+ startpoint = floor((float) count * start_perc);
+ stoppoint = ceil((float) count * stop_perc) - 1;
+ num_who = 0;
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ if ((count >= startpoint) && (count <= stoppoint)) {
+ plist[num_who++] = sortlist[p1];
+ }
+ count++;
+ }
+
+ if (num_who == 0) {
+ pprintf(p, "No logged in players match the flags in your who request.\n");
+ return COM_OK;
+ }
+
+ switch (style) {
+ case 0: /* terse */
+ who_terse(p, num_who, plist, sort_type);
+ break;
+ case 1: /* verbose */
+ who_verbose(p, num_who, plist);
+ break;
+ case 2: /* win-loss */
+ who_winloss(p, num_who, plist);
+ break;
+ default:
+ return COM_BADPARAMETERS;
+ break;
+ }
+
+ return COM_OK;
+}
+
+PUBLIC int com_refresh(int p, param_list param)
+{
+ int g, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >= 0) {
+ send_board_to(parray[p].game, p);
+ } else { /* Do observing in here */
+ if (parray[p].num_observe) {
+ for (g = 0; g < parray[p].num_observe; g++) {
+ send_board_to(parray[p].observe_list[g], p);
+ }
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ }
+ } else {
+ g = GameNumFromParam (p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ if ((g >= g_num) || ((garray[g].status != GAME_ACTIVE)
+ && (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "No such game.\n");
+ } else if (garray[g].private && parray[p].adminLevel==ADMIN_USER) {
+ pprintf (p, "Sorry, game %d is a private game.\n", g+1);
+ } else {
+ if (garray[g].private)
+ pprintf(p, "Refreshing PRIVATE game %d\n", g+1);
+ send_board_to(g, p);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_prefresh(int p, param_list param)
+{
+ int retval, part = parray[p].partner;
+
+ if (part < 0) {
+ pprintf(p, "You do not have a partner.\n");
+ return COM_OK;
+ }
+ retval = pcommand (p, "refresh %s", parray[part].name);
+ if (retval == COM_OK)
+ return COM_OK_NOPROMPT;
+ else
+ return retval;
+}
+
+PUBLIC int com_open(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set open")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_simopen(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set simopen")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_bell(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set bell")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_flip(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set flip")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_highlight(int p, param_list param)
+{
+ pprintf(p, "Obsolete command. Please do set highlight <0-15>.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_style(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_INT);
+ if ((retval = pcommand(p, "set style %d", param[0].val.integer)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_promote(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_WORD);
+ if ((retval = pcommand(p, "set promote %s", param[0].val.word)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_alias(int p, param_list param)
+{
+ int al;
+
+ if (param[0].type == TYPE_NULL) {
+ for (al = 0; al < parray[p].numAlias; al++) {
+ pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name,
+ parray[p].alias_list[al].alias);
+ }
+ return COM_OK;
+ }
+ al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias);
+ if (param[1].type == TYPE_NULL) {
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name,
+ parray[p].alias_list[al].alias);
+ }
+ } else {
+ if (al < 0) {
+ if (parray[p].numAlias >= MAX_ALIASES - 1) {
+ pprintf(p, "You have your maximum of %d aliases.\n", MAX_ALIASES - 1);
+ } else {
+
+ if (!strcmp(param[0].val.string, "quit")) { /* making sure they
+ can't alias quit */
+ pprintf(p, "You can't alias this command.\n");
+ } else if (!strcmp(param[0].val.string, "unalias")) { /* making sure they
+ can't alias unalias
+ :) */
+ pprintf(p, "You can't alias this command.\n");
+ } else {
+ parray[p].alias_list[parray[p].numAlias].comm_name =
+ strdup(param[0].val.word);
+ parray[p].alias_list[parray[p].numAlias].alias =
+ strdup(param[1].val.string);
+ parray[p].numAlias++;
+ pprintf(p, "Alias set.\n");
+
+ }
+ }
+ } else {
+ rfree(parray[p].alias_list[al].alias);
+ parray[p].alias_list[al].alias = strdup(param[1].val.string);
+ pprintf(p, "Alias replaced.\n");
+ }
+ parray[p].alias_list[parray[p].numAlias].comm_name = NULL;
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unalias(int p, param_list param)
+{
+ int al;
+ int i;
+
+ ASSERT(param[0].type == TYPE_WORD);
+ al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias);
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ rfree(parray[p].alias_list[al].comm_name);
+ rfree(parray[p].alias_list[al].alias);
+ for (i = al; i < parray[p].numAlias; i++) {
+ parray[p].alias_list[i].comm_name = parray[p].alias_list[i + 1].comm_name;
+ parray[p].alias_list[i].alias = parray[p].alias_list[i + 1].alias;
+ }
+ parray[p].numAlias--;
+ parray[p].alias_list[parray[p].numAlias].comm_name = NULL;
+ pprintf(p, "Alias removed.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_servers(int p, param_list param)
+{
+/*
+ int i;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (numServers == 0) {
+ */ pprintf(p, "There are no other servers known to this server.\n");
+ return COM_OK;
+}
+ /* pprintf(p, "There are %d known servers.\n", numServers); pprintf(p, "(Not
+ all of these may be active)\n"); pprintf(p, "%-30s%-7s\n", "HOST",
+ "PORT"); for (i = 0; i < numServers; i++) pprintf(p, "%-30s%-7d\n",
+ serverNames[i], serverPorts[i]); return COM_OK; } */
+
+PUBLIC int com_index(int p, param_list param)
+{
+ int i;
+ char index_default[] = "_index";
+ char *iwant, *filenames[100]; /* enough for all index filenames */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = index_default;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in category %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+
+ i = search_directory(index_dir, iwant, filenames, 1000);
+ if (i == 0) {
+ pprintf(p, "No index entry for \"%s\".\n", iwant);
+ } else if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, index_dir, *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Index file %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ pprintf(p, "Matches:");
+ display_directory(p, filenames, i);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_help(int p, param_list param)
+{
+ int i, UseLang = parray[p].language;
+ char help_default[] = "_help";
+ char *iwant, *filenames[1000]; /* enough for all helpfile names */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = help_default;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in command %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+ i = search_directory(help_dir[UseLang], iwant, filenames, 1000);
+ if (i == 0) {
+ if (UseLang != LANG_DEFAULT) {
+ i += search_directory(help_dir[LANG_DEFAULT], iwant, filenames, 1000);
+ if (i > 0) {
+ pprintf(p, "No help available in %s; using %s instead.\n",
+ Language(UseLang), Language(LANG_DEFAULT));
+ UseLang = LANG_DEFAULT;
+ }
+ }
+ if (i==0) {
+ pprintf(p, "No help available on \"%s\".\n", iwant);
+ return COM_OK;
+ }
+ }
+ if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, help_dir[UseLang], *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Helpfile %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ pprintf(p, "Matches:");
+ display_directory(p, filenames, i);
+ pprintf(p, "[Type \"info\" for a list of FICS general information files.]\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_info(int p, param_list param)
+{
+ int n;
+ char *filenames[1000];
+
+ if ((n = search_directory(info_dir, NULL, filenames, 1000)) > 0)
+ display_directory(p, filenames, n);
+ return COM_OK;
+}
+
+PRIVATE int FindAndShowFile(int p, param_list param, char *dir)
+{
+ int i;
+ static char nullify = '\0';
+ char *iwant, *filenames[1000]; /* enough for all helpfile names */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in filename %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+
+ i = search_directory(dir, iwant, filenames, 1000);
+ if (i == 0) {
+ pprintf(p, "No information available on \"%s\".\n", iwant);
+ } else if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, dir, *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "File %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ if (*iwant)
+ pprintf(p, "Matches:\n");
+ display_directory(p, filenames, i);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_uscf(int p, param_list param)
+{
+ return FindAndShowFile (p, param, uscf_dir);
+}
+
+PUBLIC int com_adhelp(int p, param_list param)
+{
+ return FindAndShowFile (p, param, adhelp_dir);
+}
+
+PUBLIC int com_mailsource(int p, param_list param)
+{
+ static char nullify = '\0';
+ char *iwant, *buffer[1000];
+ char subj[81], fname[MAX_FILENAME_SIZE];
+ int count;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailsource command.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ }
+
+ count = search_directory(source_dir, iwant, buffer, 1000);
+ if (count == 0) {
+ pprintf(p, "Found no source file matching \"%s\".\n", iwant);
+ } else if ((count == 1) || !strcmp(iwant, *buffer)) {
+ sprintf(subj, "FICS source file from server %s: %s",fics_hostname,*buffer);
+ sprintf(fname, "%s/%s",source_dir, *buffer);
+ mail_file_to_user (p, subj, fname);
+ pprintf(p, "Source file %s sent to %s\n", *buffer, parray[p].emailAddress);
+ } else {
+ pprintf(p, "Found %d source files matching that:\n", count);
+ if (*iwant)
+ display_directory(p, buffer, count);
+ else { /* this junk is to get *.c *.h */
+ multicol *m = multicol_start(count);
+ char *s;
+ int i;
+ for (i=0; i < count; i++) {
+ if (((s = buffer[i] + strlen(buffer[i]) - 2) >= buffer[i]) && (!strcmp(s, ".c") || !strcmp(s, ".h")))
+ multicol_store(m, buffer[i]);
+ }
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_mailhelp(int p, param_list param)
+{ /* Sparky */
+ char subj[81], fname[MAX_FILENAME_SIZE];
+ char *iwant, *buffer[1000];
+
+ int lang = parray[p].language;
+ int count;
+ static char nullify = '\0';
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailhelp command.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL)
+ iwant = &nullify;
+ else
+ iwant = param[0].val.word;
+
+ count = search_directory(help_dir[lang], iwant, buffer, 1000);
+ if (count == 0 && lang != LANG_DEFAULT) {
+ count += search_directory(help_dir[LANG_DEFAULT], iwant, buffer, 1000);
+ if (count > 0) {
+ pprintf(p, "No help available in %s; using %s instead.\n",
+ Language(lang), Language(LANG_DEFAULT));
+ lang = LANG_DEFAULT;
+ }
+ }
+ if (count == 0) {
+ pprintf(p, "Found no help file matching \"%s\".\n", iwant);
+ } else if (count == 1 || !strcmp(*buffer, iwant)) {
+ sprintf(subj, "FICS help file from server %s: %s", fics_hostname, *buffer);
+ sprintf(fname, "%s/%s",help_dir[lang], *buffer);
+ mail_file_to_user (p, subj, fname);
+ pprintf(p, "Help file %s sent to %s\n", *buffer, parray[p].emailAddress);
+ } else {
+ pprintf(p, "Found %d helpfiles matching that:\n", count);
+ display_directory(p, buffer, count);
+ }
+
+ return COM_OK;
+}
+
+PUBLIC int com_handles(int p, param_list param)
+{
+ char *buffer[1000];
+ char pdir[MAX_FILENAME_SIZE];
+ int count;
+
+ sprintf(pdir, "%s/%c", player_dir, param[0].val.word[0]);
+ count = search_directory(pdir, param[0].val.word, buffer, 1000);
+ pprintf(p, "Found %d names.\n", count);
+ if (count > 0)
+ display_directory(p, buffer, count);
+ return COM_OK;
+}
+
+PUBLIC int com_getpi(int p, param_list param)
+{
+ int p1;
+
+ if (!in_list(p, L_TD, parray[p].name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ if (((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) {
+ /* Darkside suggested not to return anything */
+ return COM_OK;
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "*getpi %s -1 -1 -1*\n", parray[p1].name);
+ } else {
+ pprintf(p, "*getpi %s %d %d %d*\n", parray[p1].name,
+ parray[p1].w_stats.rating,
+ parray[p1].b_stats.rating,
+ parray[p1].s_stats.rating);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_getps(int p, param_list param)
+{
+ int p1;
+
+ if ((((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) || (parray[p1].game < 0)) {
+
+ pprintf(p, "*status %s 1*\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf(p, "*status %s 0 %s*\n", parray[p1].name, parray[(parray[p1].opponent)].name);
+ return COM_OK;
+}
+PUBLIC int com_limits(int p, param_list param)
+{
+ pprintf(p, "\nCurrent hardcoded limits:\n");
+ pprintf(p, " Max number of players: %d\n", MAX_PLAYER);
+ pprintf(p, " Max number of channels and max capacity: %d\n", MAX_CHANNELS);
+ pprintf(p, " Max number of channels one can be in: %d\n", MAX_INCHANNELS);
+ pprintf(p, " Max number of people on the notify list: %d\n", MAX_NOTIFY);
+ pprintf(p, " Max number of aliases: %d\n", MAX_ALIASES - 1);
+ pprintf(p, " Max number of games you can observe at a time: %d\n", MAX_OBSERVE);
+ pprintf(p, " Max number of requests pending: %d\n", MAX_PENDING);
+ pprintf(p, " Max number of people on the censor list: %d\n", MAX_CENSOR);
+ pprintf(p, " Max number of people in a simul game: %d\n", MAX_SIMUL);
+ pprintf(p, " Max number of messages one can receive: %d\n", MAX_MESSAGES);
+ pprintf(p, " Min number of games to be active: %d\n", PROVISIONAL);
+ if ((parray[p].adminLevel < ADMIN_ADMIN) && (!titled_player(p,parray[p].login))) {
+ pprintf(p, " Size of journal (entries): %d\n", MAX_JOURNAL);
+ } else {
+ pprintf(p, " Size of journal (entries): 26\n");
+ }
+ pprintf(p, "\nAdmin settable limits:\n");
+ pprintf(p, " Shout quota gives two shouts per %d seconds.\n", quota_time);
+ return COM_OK;
+}
blob - /dev/null
blob + 2ec74e3fdd724770bbe4bd5906efbe50615576d9 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/comproc.c.orig
+/* comproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ foxbat 95/03/11 added filters in cmatch.
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "command.h"
+#include "utils.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "channel.h"
+#include "variable.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "board.h"
+/* #include "hostinfo.h" */
+#include "multicol.h"
+#include "ratings.h"
+#include "formula.h"
+#include "lists.h"
+#include "eco.h"
+#include "network.h"
+#include <string.h>
+
+#include <sys/resource.h>
+
+/* grimm */
+#if defined(SGI)
+#else
+/* int system(char *arg); */
+#endif
+
+const none = 0;
+const blitz_rat = 1;
+const std_rat = 2;
+const wild_rat = 3;
+
+
+PUBLIC int com_rating_recalc(int p, param_list param)
+{
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ rating_recalc();
+ return COM_OK;
+}
+
+PUBLIC int com_more(int p, param_list param)
+{
+/* in_push(IN_HELP); */
+ pmore_file(p);
+ return COM_OK;
+}
+
+PUBLIC int num_news = -1;
+
+PUBLIC int com_news(int p, param_list param)
+{
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+ char junk[MAX_LINE_SIZE];
+ char *junkp;
+ int crtime, found = 0;
+ char count[10];
+
+ if (num_news == -1) {
+ sprintf(filename, "%s/news.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Cant find news index.\n");
+ return COM_OK;
+ }
+ num_news = count_lines(fp);
+ fclose(fp); /* It's customary to close files after use! */
+ }
+
+ if (param[0].type == 0) {
+ /* no params - then just display index over news */
+ sprintf(filename, "%s/news.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find news index.\n");
+ return COM_OK;
+ }
+ pprintf(p,"Index of recent news items:\n");
+ while (!feof(fp)) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (strlen(junk) > 1) {
+ sscanf(junkp, "%d %s", &crtime, count);
+ if (atoi(count) > num_news - 10) {
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, strltime(&crtime), junkp);
+ }
+ }
+ }
+ fclose(fp);
+ } else if ((param[0].type == TYPE_WORD) && !strcmp(param[0].val.word, "all")) {
+ /* param all - displays all news items */
+ sprintf(filename, "%s/news.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find news index.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Index of all news items:\n");
+ while (!feof(fp)) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (strlen(junk) > 1) {
+ sscanf(junkp, "%d %s", &crtime, count);
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "%3s (%s) %s", count, strltime(&crtime), junkp);
+ }
+ }
+ fclose(fp); /* It's customary to close files after use! */
+ } else { /* check if the specific news file exist in index */
+ sprintf(filename, "%s/news.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find news index.\n");
+ return COM_OK;
+ }
+ while (!feof(fp) && !found) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (strlen(junk) > 1) {
+ sscanf(junkp, "%d %s", &crtime, count);
+ if (!strcmp(count, param[0].val.word)) {
+ found = 1;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "NEWS %3s (%s) %s\n", count, strltime(&crtime), junkp);
+ }
+ }
+ }
+ fclose(fp);
+ if (!found) {
+ pprintf(p, "Bad index number!\n");
+ return COM_OK;
+ }
+ /* file exists - show it */
+ sprintf(filename, "%s/news.%s", news_dir, param[0].val.word);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pprintf(p, "No more info.\n");
+ return COM_OK;
+ }
+ fclose(fp);
+ sprintf(filename, "news.%s", param[0].val.word);
+ if (psend_file(p, news_dir, filename) < 0) {
+ pprintf(p, "Internal error - couldn't send news file!\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_quit(int p, param_list param)
+{
+ if ((parray[p].game >= 0) && (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pcommand(p, "unexamine");
+ }
+
+ if (parray[p].game >= 0) {
+ pprintf(p, "You can't quit while you are playing a game.\nType 'resign' to resign the game, or you can request an abort with 'abort'.\n");
+ return COM_OK;
+ }
+ psend_logoutfile(p, mess_dir, MESS_LOGOUT);
+ return COM_LOGOUT;
+}
+
+PUBLIC int com_set(int p, param_list param)
+{
+ int result;
+ int which;
+ char *val;
+
+ if (param[1].type == TYPE_NULL)
+ val = NULL;
+ else
+ val = param[1].val.string;
+ result = var_set(p, param[0].val.word, val, &which);
+ switch (result) {
+ case VAR_OK:
+ break;
+ case VAR_BADVAL:
+ pprintf(p, "Bad value given for variable %s.\n", param[0].val.word);
+ break;
+ case VAR_NOSUCH:
+ pprintf(p, "No such variable name %s.\n", param[0].val.word);
+ break;
+ case VAR_AMBIGUOUS:
+ pprintf(p, "Ambiguous variable name %s.\n", param[0].val.word);
+ break;
+ }
+ player_save(p);
+ return COM_OK;
+}
+
+PUBLIC int FindPlayer(int p, parameter * param, int *p1, int *connected)
+{
+ if (param->type == TYPE_WORD) {
+ *p1 = player_search(p, param->val.word);
+ if (*p1 == 0)
+ return 0;
+ if (*p1 < 0) { /* player had to be connected and will be
+ removed later */
+ *connected = 0;
+ *p1 = (-*p1) - 1;
+ } else {
+ *connected = 1;
+ *p1 = *p1 - 1;
+ }
+ } else {
+ *p1 = p;
+ *connected = 1;
+ }
+ return 1;
+}
+
+PRIVATE void com_stats_andify(int *numbers, int howmany, char *dest)
+{
+ char tmp[10];
+
+ *dest = '\0';
+ while (howmany--) {
+ sprintf(tmp, "%d", numbers[howmany]);
+ strcat(dest, tmp);
+ if (howmany > 1)
+ sprintf(tmp, ", ");
+ else if (howmany == 1)
+ sprintf(tmp, " and ");
+ else
+ sprintf(tmp, ".\n");
+ strcat(dest, tmp);
+ }
+ return;
+}
+
+PRIVATE void com_stats_rating(char *hdr, statistics * stats, char *dest)
+{
+ char tmp[100];
+
+ sprintf(dest, "%-10s%4s %5.1f %4d %4d %4d %4d",
+ hdr, ratstr(stats->rating), stats->sterr, stats->win, stats->los, stats->dra, stats->num);
+ if (stats->whenbest) {
+ sprintf(tmp, " %d", stats->best);
+ strcat(dest, tmp);
+ strftime(tmp, sizeof(tmp), " (%d-%b-%y)", localtime((time_t *) & stats->whenbest));
+ strcat(dest, tmp);
+ }
+ strcat(dest, "\n");
+ return;
+}
+
+PUBLIC int com_stats(int p, param_list param)
+{
+ int g, i, t;
+ int p1, connected;
+ char line[255], tmp[255];
+ int numbers[MAX_OBSERVE > MAX_SIMUL ? MAX_OBSERVE : MAX_SIMUL];
+ int days, hours, mins, secs, onTime;
+
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ sprintf(line, "\nStatistics for %-11s ", parray[p1].name);
+ if ((connected) && (parray[p1].status == PLAYER_PROMPT)) {
+ sprintf(tmp, "On for: %s", hms(player_ontime(p1), 0, 0, 0));
+ strcat(line, tmp);
+ sprintf(tmp, " Idle: %s\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ if ((t = player_lastdisconnect(p1)))
+ sprintf(tmp, "(Last disconnected %s):\n", strltime(&t));
+ else
+ sprintf(tmp, "(Never connected.)\n");
+ }
+ strcat(line, tmp);
+ pprintf(p, "%s", line);
+ if (parray[p1].simul_info.numBoards) {
+ for (i = 0, t = 0; i < parray[p1].simul_info.numBoards; i++) {
+ if ((numbers[t] = parray[p1].simul_info.boards[i] + 1) != 0)
+ t++;
+ }
+ pprintf(p, "%s is giving a simul: game%s ", parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ } else if (parray[p1].game >= 0) {
+ g = parray[p1].game;
+ if (garray[g].status == GAME_EXAMINE) {
+ pprintf(p, "(Examining game %d: %s vs. %s)\n", g + 1,
+ garray[g].white_name, garray[g].black_name);
+ } else {
+ pprintf(p, "(playing game %d: %s vs. %s)\n", g + 1,
+ parray[garray[g].white].name, parray[garray[g].black].name);
+ }
+ }
+ if (parray[p1].num_observe) {
+ for (i = 0, t = 0; i < parray[p1].num_observe; i++) {
+ g = parray[p1].observe_list[i];
+ if ((g != -1) && ((parray[p].adminLevel >= ADMIN_ADMIN) || (garray[g].private == 0)))
+ numbers[t++] = g + 1;
+ }
+ if (t) {
+ pprintf(p, "%s is observing game%s ", parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ }
+ }
+ if (parray[p1].busy[0]) {
+ pprintf(p, "(%s %s)\n", parray[p1].name, parray[p1].busy);
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "%s is NOT a registered player.\n\n", parray[p1].name);
+ } else {
+ pprintf(p, "\n rating RD win loss draw total best\n");
+ com_stats_rating("Blitz", &parray[p1].b_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Standard", &parray[p1].s_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Wild", &parray[p1].w_stats, tmp);
+ pprintf(p, tmp);
+ }
+ pprintf(p, "\n");
+ if (parray[p1].adminLevel > 0) {
+ pprintf(p, "Admin Level: ");
+ switch (parray[p1].adminLevel) {
+/*
+ case 0:
+ pprintf(p, "Normal User\n");
+ break;
+ case 5:
+ pprintf(p, "Extra Cool User\n"); vek wants to be 5
+ break;
+
+ Forget it - you can do some admin stuff if your level is > than 0 - DAV
+
+*/
+ case 5:
+ pprintf(p, "Authorized Helper Person\n");
+ break;
+ case 10:
+ pprintf(p, "Administrator\n");
+ break;
+ case 15:
+ pprintf(p, "Help File Librarian/Administrator\n");
+ break;
+ case 20:
+ pprintf(p, "Master Administrator\n");
+ break;
+ case 50:
+ pprintf(p, "Master Help File Librarian/Administrator\n");
+ break;
+ case 60:
+ pprintf(p, "Assistant Super User\n");
+ break;
+ case 100:
+ pprintf(p, "Super User\n");
+ break;
+ default:
+ pprintf(p, "%d\n", parray[p1].adminLevel);
+ break;
+ }
+ }
+ if (parray[p].adminLevel > 0)
+ pprintf(p, "Full Name : %s\n", (parray[p1].fullName ? parray[p1].fullName : "(none)"));
+ if (((p1 == p) && (parray[p1].registered)) || (parray[p].adminLevel > 0))
+ pprintf(p, "Address : %s\n", (parray[p1].emailAddress ? parray[p1].emailAddress : "(none)"));
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, "Host : %s\n",
+/*
+ ((hp = gethostbyaddr((const char*) (connected ? &parray[p1].thisHost : &parray[p1].lastHost), sizeof(parray[p1].thisHost), AF_INET)) == 0) ? "" : hp->h_name,
+*/
+ dotQuad(connected ? parray[p1].thisHost : parray[p1].lastHost));
+ }
+ if ((parray[p].adminLevel > 0) && (parray[p1].registered))
+ if (parray[p1].num_comments)
+ pprintf(p, "Comments : %d\n", parray[p1].num_comments);
+
+ if (connected && parray[p1].registered && (p==p1 ||
+ (parray[p].adminLevel > 0))) {
+ char *timeToStr = ctime((time_t *) &parray[p1].timeOfReg);
+
+ timeToStr[strlen(timeToStr)-1]='\0';
+ pprintf(p, "\n");
+ onTime = (time(0) - parray[p1].logon_time) + parray[p1].totalTime;
+ days = (onTime / (60*60*24));
+ hours = ((onTime % (60*60*24)) / (60*60));
+ mins = (((onTime % (60*60*24)) % (60*60)) / 60);
+ secs = (((onTime % (60*60*24)) % (60*60)) % 60);
+ if ((days==0) && (hours==0) && (mins==0)) {
+ pprintf(p, "Total time on-line: %d second%s\n",
+ secs, (secs==1) ? "" : "s");
+ } else if ((days==0) && (hours==0)) {
+ pprintf(p, "Total time on-line: %d minute%s and %d second%s\n",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else if (days==0) {
+ pprintf(p, "Total time on-line: %d hour%s, %d minute%s and %d "
+ "second%s\n",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else {
+ pprintf(p, "Total time on-line: %d day%s, %d hour%s, %d minute%s "
+ "and %d second%s\n",
+ days, (days==1) ? "" : "s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ }
+ pprintf(p, "%% of life on-line: %3.1f (since %s)\n",
+ (double)((onTime*100)/(double)(time(0)-parray[p1].timeOfReg)),
+ timeToStr);
+ }
+
+#ifdef TIMESEAL
+
+ if (connected)
+ pprintf(p, "\nTimeseal : %s\n", (con[parray[p1].socket].timeseal)
+? "On" : "Off");
+ if ((parray[p].adminLevel > 0) && (connected)) {
+ if (findConnection(parray[p1].socket)) {
+ pprintf(p, "Unix acc : %s\nSystem/OS : %s\n",
+ con[parray[p1].socket].user,
+ con[parray[p1].socket].sys);
+ }
+ }
+
+#endif
+
+ if (parray[p1].num_plan) {
+ pprintf(p, "\n");
+ for (i = 0; i < parray[p1].num_plan; i++)
+ pprintf(p, "%2d: %s\n", i + 1, (parray[p1].planLines[i] != NULL) ? parray[p1].planLines[i] : "");
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_variables(int p, param_list param)
+{
+ int p1, connected;
+ int i;
+
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ pprintf(p, "Variable settings of %s:\n", parray[p1].name);
+/* if (parray[p1].fullName)
+ pprintf(p, " Realname: %s\n", parray[p1].fullName);
+*/
+ if (parray[p1].uscfRating)
+ pprintf(p, " USCF: %d\n", parray[p1].uscfRating);
+ pprintf(p, " time=%-3d inc=%-3d private=%d Lang=%s\n",
+ parray[p1].d_time, parray[p1].d_inc, parray[p1].private,
+ Language(parray[p1].language));
+ pprintf(p, " rated=%d ropen=%d open=%d simopen=%d\n",
+ parray[p1].rated, parray[p1].ropen, parray[p1].open, parray[p1].sopen);
+ pprintf(p, " shout=%d cshout=%d kib=%d tell=%d notifiedby=%d\n",
+ parray[p1].i_shout, parray[p1].i_cshout, parray[p1].i_kibitz, parray[p1].i_tell, parray[p1].notifiedby);
+ pprintf(p, " pin=%d gin=%d style=%-3d flip=%d\n",
+ parray[p1].i_login, parray[p1].i_game, parray[p1].style + 1, parray[p1].flip);
+ pprintf(p, " highlight=%d bell=%d auto=%d mailmess=%d pgn=%d\n",
+ parray[p1].highlight, parray[p1].bell, parray[p1].automail, parray[p1].i_mailmess, parray[p1].pgn);
+ pprintf(p, " width=%-3d height=%-3d\n",
+ parray[p1].d_width, parray[p1].d_height);
+ if (parray[p1].prompt && parray[p1].prompt != def_prompt)
+ pprintf(p, " Prompt: %s\n", parray[p1].prompt);
+
+ { /* added code to print channels */
+ int count = 0;
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (on_channel(i, p1)) {
+ if (!count)
+ pprintf(p, "\n Channels:");
+ pprintf(p, " %d", i);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, "\n");
+ }
+/* if (parray[p1].numAlias && (p == p1)) {
+ pprintf(p, "\n Aliases:\n");
+ for (i = 0; i < parray[p1].numAlias; i++) {
+ pprintf(p, " %s %s\n", parray[p1].alias_list[i].comm_name,
+ parray[p1].alias_list[i].alias);
+ }
+ }
+*/
+ if (parray[p1].num_formula) {
+ pprintf(p, "\n");
+ for (i = 0; i < parray[p1].num_formula; i++) {
+ if (parray[p1].formulaLines[i] != NULL)
+ pprintf(p, " f%d: %s\n", i + 1, parray[p1].formulaLines[i]);
+ else
+ pprintf(p, " f%d:\n", i + 1);
+ }
+ }
+ if (parray[p1].formula != NULL)
+ pprintf(p, "\nFormula: %s\n", parray[p1].formula);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_password(int p, param_list param)
+{
+ char *oldpassword = param[0].val.word;
+ char *newpassword = param[1].val.word;
+ char salt[3];
+
+ if (!parray[p].registered) {
+ pprintf(p, "Setting a password is only for registered players.\n");
+ return COM_OK;
+ }
+ if (parray[p].passwd) {
+ salt[0] = parray[p].passwd[0];
+ salt[1] = parray[p].passwd[1];
+ salt[2] = '\0';
+ if (strcmp(crypt(oldpassword, salt), parray[p].passwd)) {
+ pprintf(p, "Incorrect password, password not changed!\n");
+ return COM_OK;
+ }
+ rfree(parray[p].passwd);
+ parray[p].passwd = NULL;
+ }
+ salt[0] = 'a' + rand() % 26;
+ salt[1] = 'a' + rand() % 26;
+ salt[2] = '\0';
+ parray[p].passwd = strdup(crypt(newpassword, salt));
+ pprintf(p, "Password changed to \"%s\".\n", newpassword);
+ return COM_OK;
+}
+
+PUBLIC int com_uptime(int p, param_list param)
+{
+ unsigned long uptime = time(0) - startuptime;
+ struct rusage ru;
+ int days = (uptime / (60*60*24));
+ int hours = ((uptime % (60*60*24)) / (60*60));
+ int mins = (((uptime % (60*60*24)) % (60*60)) / 60);
+ int secs = (((uptime % (60*60*24)) % (60*60)) % 60);
+
+ pprintf(p, "Server location: %s Server version : %s\n", fics_hostname,VERS_NUM);
+ pprintf(p, "The server has been up since %s.\n", strltime(&startuptime));
+ if ((days==0) && (hours==0) && (mins==0)) {
+ pprintf(p, "(Up for %d second%s)\n",
+ secs, (secs==1) ? "" : "s");
+ } else if ((days==0) && (hours==0)) {
+ pprintf(p, "(Up for %d minute%s and %d second%s)\n",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else if (days==0) {
+ pprintf(p, "(Up for %d hour%s, %d minute%s and %d second%s)\n",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else {
+ pprintf(p, "(Up for %d day%s, %d hour%s, %d minute%s and %d second%s)\n",
+ days, (days==1) ? "" : "s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ }
+ pprintf(p, "\nAllocs: %u Frees: %u Allocs In Use: %u\n",
+ malloc_count, free_count, malloc_count - free_count);
+ if (parray[p].adminLevel >= ADMIN_ADMIN) {
+ pprintf(p, "\nplayer size:%d, game size:%d, con size:%d, g_num:%d\n",
+ sizeof(player), sizeof(game), net_consize(), g_num);
+ getrusage(RUSAGE_SELF, &ru);
+ pprintf(p, "pagesize = %d, maxrss = %d, total = %d\n", getpagesize(), ru.ru_maxrss, getpagesize() * ru.ru_maxrss);
+ }
+ pprintf(p, "\nPlayer limit: %d\n", max_connections);
+ pprintf(p, "\nThere are currently %d players, with a high of %d since last restart.\n", player_count(), player_high);
+ pprintf(p, "There are currently %d games, with a high of %d since last restart.\n", game_count(), game_high);
+ pprintf(p, "\nCompiled on %s\n", COMP_DATE);
+ return COM_OK;
+}
+
+PUBLIC int com_date(int p, param_list param)
+{
+ int t = time(0);
+ pprintf(p, "Local time - %s\n", strltime(&t));
+ pprintf(p, "Greenwich time - %s\n", strgtime(&t));
+ return COM_OK;
+}
+
+char *inout_string[] = {
+ "login", "logout"
+};
+
+PRIVATE int plogins(p, fname)
+int p;
+char *fname;
+{
+ FILE *fp;
+ int inout, thetime, registered;
+ char loginName[MAX_LOGIN_NAME + 1];
+ char ipstr[20];
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no login information available.\n");
+ return COM_OK;
+ }
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime,
+ ®istered, ipstr) != 5) {
+ fprintf(stderr, "FICS: Error in login info format. %s\n", fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ pprintf(p, "%s: %-17s %-6s", strltime(&thetime), loginName,
+ inout_string[inout]);
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, " from %s\n", ipstr);
+ } else
+ pprintf(p, "\n");
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+PUBLIC int com_llogons(int p, param_list param)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%s", stats_dir, STATS_LOGONS);
+ return plogins(p, fname);
+}
+
+PUBLIC int com_logons(int p, param_list param)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, param[0].val.word[0], param[0].val.word, STATS_LOGONS);
+ } else {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS);
+ }
+ return plogins(p, fname);
+}
+
+#define WHO_OPEN 0x01
+#define WHO_CLOSED 0x02
+#define WHO_RATED 0x04
+#define WHO_UNRATED 0x08
+#define WHO_FREE 0x10
+#define WHO_PLAYING 0x20
+#define WHO_REGISTERED 0x40
+#define WHO_UNREGISTERED 0x80
+
+PRIVATE void who_terse(int p, int num, int *plist, int type)
+{
+ char ptmp[80 + 20]; /* for highlight */
+ multicol *m = multicol_start(PARRAY_SIZE);
+ int i;
+ int p1;
+ int rat;
+
+ /* altered DAV 3/15/95 */
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+ if (type == blitz_rat)
+ rat = parray[p1].b_stats.rating;
+ if (type == wild_rat)
+ rat = parray[p1].w_stats.rating;
+ if (type == std_rat)
+ rat = parray[p1].s_stats.rating;
+
+ if (type == none) {
+ sprintf(ptmp, " ");
+ } else {
+ sprintf(ptmp, "%-4s", ratstrii(rat, parray[p1].registered));
+ if (parray[p1].simul_info.numBoards) {
+ strcat(ptmp, "~");
+ } else if ((parray[p1].game >= 0) && (garray[parray[p1].game].status == GAME_EXAMINE)) {
+ strcat(ptmp, "#");
+ } else if (parray[p1].game >= 0) {
+ strcat(ptmp, "^");
+ } else if (!parray[p1].open) {
+ strcat(ptmp, ":");
+ } else if (player_idle(p1) > 300) {
+ strcat(ptmp, ".");
+ } else {
+ strcat(ptmp, " ");
+ }
+ }
+ if (p == p1) {
+ psprintf_highlight(p, ptmp + strlen(ptmp), "%s", parray[p1].name);
+ } else {
+ strcat(ptmp, parray[p1].name);
+ }
+ if ((parray[p1].adminLevel >= 10) && (parray[p1].i_admin))
+ strcat(ptmp, "(*)");
+ if (in_list("computer", parray[p1].name))
+ strcat(ptmp, "(C)");
+/* grimm's fishlist
+ if (in_list("fish", parray[p1].name)) strcat(ptmp, "(Fish)");
+*/
+ if (in_list("fm", parray[p1].name))
+ strcat(ptmp, "(FM)");
+ if (in_list("im", parray[p1].name))
+ strcat(ptmp, "(IM)");
+ if (in_list("gm", parray[p1].name))
+ strcat(ptmp, "(GM)");
+ if (in_list("td", parray[p1].name))
+ strcat(ptmp, "(TD)");
+ multicol_store(m, ptmp);
+ }
+ multicol_pprint(m, p, 80, 2);
+ multicol_end(m);
+ pprintf(p, "\n %d Players displayed (of %d). (*) indicates system administrator.\n", num, player_count());
+}
+
+PRIVATE void who_verbose(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* +8 for highlight */
+
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+ pprintf(p,
+ " | User Standard Blitz On for Idle |\n"
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+
+ strcpy(playerLine, " |");
+
+ if (parray[p1].game >= 0)
+ sprintf(tmp, "%3d", parray[p1].game + 1);
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (!parray[p1].open)
+ sprintf(tmp, "X");
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (parray[p1].registered)
+ if (parray[p1].rated) {
+ sprintf(tmp, " ");
+ } else {
+ sprintf(tmp, "u");
+ }
+ else
+ sprintf(tmp, "U");
+ strcat(playerLine, tmp);
+
+ /* Modified by DAV 3/15/95 */
+ if (p == p1) {
+ strcpy(tmp, " ");
+ psprintf_highlight(p, tmp + strlen(tmp), "%-17s", parray[p1].name);
+ } else {
+ sprintf(tmp, " %-17s", parray[p1].name);
+ }
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, " %4s %-4s %5s ",
+ ratstrii(parray[p1].s_stats.rating, parray[p1].registered),
+ ratstrii(parray[p1].b_stats.rating, parray[p1].registered),
+ hms(player_ontime(p1), 0, 0, 0));
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s |\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " |\n");
+ }
+ strcat(playerLine, tmp);
+ pprintf(p, "%s", playerLine);
+ }
+
+ pprintf(p,
+ " | |\n"
+ );
+ pprintf(p,
+ " | %3d Players Displayed |\n",
+ num
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+}
+
+PRIVATE void who_winloss(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* for highlight */
+
+ pprintf(p,
+ "Name Stand win loss draw Blitz win loss draw idle\n"
+ );
+ pprintf(p,
+ "---------------- ----- ------------- ----- ------------- ----\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+ if (p1 == p) {
+ psprintf_highlight(p, playerLine, "%-17s", parray[p1].name);
+ } else {
+ sprintf(playerLine, "%-17s", parray[p1].name);
+ }
+ sprintf(tmp, " %4s %4d %4d %4d ",
+ ratstrii(parray[p1].s_stats.rating, parray[p1].registered),
+ (int) parray[p1].s_stats.win,
+ (int) parray[p1].s_stats.los,
+ (int) parray[p1].s_stats.dra);
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, "%4s %4d %4d %4d ",
+ ratstrii(parray[p1].b_stats.rating, parray[p1].registered),
+ (int) parray[p1].b_stats.win,
+ (int) parray[p1].b_stats.los,
+ (int) parray[p1].b_stats.dra);
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " \n");
+ }
+ strcat(playerLine, tmp);
+
+ pprintf(p, "%s", playerLine);
+ }
+ pprintf(p, " %3d Players Displayed.\n", num);
+}
+
+PRIVATE int who_ok(p, sel_bits)
+int p;
+unsigned int sel_bits;
+{
+ if (parray[p].status != PLAYER_PROMPT)
+ return 0;
+ if (sel_bits == 0xff)
+ return 1;
+ if (sel_bits & WHO_OPEN)
+ if (!parray[p].open)
+ return 0;
+ if (sel_bits & WHO_CLOSED)
+ if (parray[p].open)
+ return 0;
+ if (sel_bits & WHO_RATED)
+ if (!parray[p].rated)
+ return 0;
+ if (sel_bits & WHO_UNRATED)
+ if (parray[p].rated)
+ return 0;
+ if (sel_bits & WHO_FREE)
+ if (parray[p].game >= 0)
+ return 0;
+ if (sel_bits & WHO_PLAYING)
+ if (parray[p].game < 0)
+ return 0;
+ if (sel_bits & WHO_REGISTERED)
+ if (!parray[p].registered)
+ return 0;
+ if (sel_bits & WHO_UNREGISTERED)
+ if (parray[p].registered)
+ return 0;
+ return 1;
+}
+
+
+PRIVATE int blitz_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].b_stats.rating > parray[p2].b_stats.rating)
+ return -1;
+ if (parray[p1].b_stats.rating < parray[p2].b_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int stand_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].s_stats.rating > parray[p2].s_stats.rating)
+ return -1;
+ if (parray[p1].s_stats.rating < parray[p2].s_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int wild_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].w_stats.rating > parray[p2].w_stats.rating)
+ return -1;
+ if (parray[p1].w_stats.rating < parray[p2].w_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int alpha_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PUBLIC void sort_players(int players[PARRAY_SIZE],
+ int ((*cmp_func) (const void *, const void *)))
+{
+ int i;
+
+ for (i = 0; i < p_num; i++) {
+ players[i] = i;
+ }
+ qsort(players, p_num, sizeof(int), cmp_func);
+}
+
+/* This is the of the most compliclicated commands in terms of parameters */
+PUBLIC int com_who(int p, param_list param)
+{
+ int style = 0;
+ float stop_perc = 1.0;
+ float start_perc = 0;
+ unsigned int sel_bits = 0xff;
+ int sortlist[PARRAY_SIZE], plist[PARRAY_SIZE];
+ int ((*cmp_func) (const void *, const void *)) = blitz_cmp;
+ int startpoint;
+ int stoppoint;
+ int i, len;
+ int tmpI, tmpJ;
+ char c;
+ int p1, count, num_who;
+ int sort_type = blitz_rat;
+
+ if (param[0].type == TYPE_WORD) {
+ len = strlen(param[0].val.word);
+ for (i = 0; i < len; i++) {
+ c = param[0].val.word[i];
+ if (isdigit(c)) {
+ if (i == 0 || !isdigit(param[0].val.word[i - 1])) {
+ tmpI = c - '0';
+ if (tmpI == 1) {
+ start_perc = 0.0;
+ stop_perc = 0.333333;
+ } else if (tmpI == 2) {
+ start_perc = 0.333333;
+ stop_perc = 0.6666667;
+ } else if (tmpI == 3) {
+ start_perc = 0.6666667;
+ stop_perc = 1.0;
+ } else if ((i == len - 1) || (!isdigit(param[0].val.word[i + 1])))
+ return COM_BADPARAMETERS;
+ } else {
+ tmpI = c - '0';
+ tmpJ = param[0].val.word[i - 1] - '0';
+ if (tmpI == 0)
+ return COM_BADPARAMETERS;
+ if (tmpJ > tmpI)
+ return COM_BADPARAMETERS;
+ start_perc = ((float) tmpJ - 1.0) / (float) tmpI;
+ stop_perc = ((float) tmpJ) / (float) tmpI;
+ }
+ } else {
+ switch (c) {
+ case 'o':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_OPEN;
+ else
+ sel_bits |= WHO_OPEN;
+ break;
+ case 'r':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_RATED;
+ else
+ sel_bits |= WHO_RATED;
+ break;
+ case 'f':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_FREE;
+ else
+ sel_bits |= WHO_FREE;
+ break;
+ case 'a':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_FREE | WHO_OPEN;
+ else
+ sel_bits |= (WHO_FREE | WHO_OPEN);
+ break;
+ case 'R':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_REGISTERED;
+ else
+ sel_bits |= WHO_REGISTERED;
+ break;
+ case 'l': /* Sort order */
+ cmp_func = alpha_cmp;
+ sort_type = none;
+ break;
+ case 'A': /* Sort order */
+ cmp_func = alpha_cmp;
+ break;
+ case 'w': /* Sort order */
+ cmp_func = wild_cmp;
+ sort_type = wild_rat;
+ break;
+ case 's': /* Sort order */
+ cmp_func = stand_cmp;
+ sort_type = std_rat;
+ break;
+ case 'b': /* Sort order */
+ cmp_func = blitz_cmp;
+ sort_type = blitz_rat;
+ break;
+ case 't': /* format */
+ style = 0;
+ break;
+ case 'v': /* format */
+ style = 1;
+ break;
+ case 'n': /* format */
+ style = 2;
+ break;
+ case 'U':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_UNREGISTERED;
+ else
+ sel_bits |= WHO_UNREGISTERED;
+ break;
+ default:
+ return COM_BADPARAMETERS;
+ break;
+ }
+ }
+ }
+ }
+ sort_players(sortlist, cmp_func);
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ count++;
+ }
+ startpoint = floor((float) count * start_perc);
+ stoppoint = ceil((float) count * stop_perc) - 1;
+ num_who = 0;
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ if ((count >= startpoint) && (count <= stoppoint)) {
+ plist[num_who++] = sortlist[p1];
+ }
+ count++;
+ }
+ if (num_who == 0) {
+ pprintf(p, "No logged in players match the flags in your who request.\n");
+ return COM_OK;
+ }
+ switch (style) {
+ case 0: /* terse */
+ who_terse(p, num_who, plist, sort_type);
+ break;
+ case 1: /* verbose */
+ who_verbose(p, num_who, plist);
+ break;
+ case 2: /* win-loss */
+ who_winloss(p, num_who, plist);
+ break;
+ default:
+ return COM_BADPARAMETERS;
+ break;
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_refresh(int p, param_list param)
+{
+ int g, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >= 0) {
+ send_board_to(parray[p].game, p);
+ } else { /* Do observing in here */
+ if (parray[p].num_observe) {
+ for (g = 0; g < parray[p].num_observe; g++) {
+ send_board_to(parray[p].observe_list[g], p);
+ }
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ }
+ } else {
+ g = GameNumFromParam (p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ if ((g >= g_num) || ((garray[g].status != GAME_ACTIVE)
+ && (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "No such game.\n");
+ } else if (garray[g].private && parray[p].adminLevel==ADMIN_USER) {
+ pprintf (p, "Sorry, game %d is a private game.\n", g+1);
+ } else {
+ if (garray[g].private)
+ pprintf(p, "Refreshing PRIVATE game %d\n", g+1);
+ send_board_to(g, p);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_open(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set open")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_simopen(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set simopen")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_bell(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set bell")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_flip(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set flip")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_highlight(int p, param_list param)
+{
+ pprintf(p, "Obsolete command. Please do set highlight <0-15>.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_style(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_INT);
+ if ((retval = pcommand(p, "set style %d", param[0].val.integer)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_promote(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_WORD);
+ if ((retval = pcommand(p, "set promote %s", param[0].val.word)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_alias(int p, param_list param)
+{
+ int al;
+
+ if (param[0].type == TYPE_NULL) {
+ for (al = 0; al < parray[p].numAlias; al++) {
+ pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name,
+ parray[p].alias_list[al].alias);
+ }
+ return COM_OK;
+ }
+ al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias);
+ if (param[1].type == TYPE_NULL) {
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name,
+ parray[p].alias_list[al].alias);
+ }
+ } else {
+ if (al < 0) {
+ if (parray[p].numAlias >= MAX_ALIASES - 1) {
+ pprintf(p, "You have your maximum of %d aliases.\n", MAX_ALIASES - 1);
+ } else {
+
+ if (!strcmp(param[0].val.string, "quit")) { /* making sure they
+ can't alias quit */
+ pprintf(p, "You can't alias this command.\n");
+ } else if (!strcmp(param[0].val.string, "unalias")) { /* making sure they
+ can't alias unalias
+ :) */
+ pprintf(p, "You can't alias this command.\n");
+ } else {
+ parray[p].alias_list[parray[p].numAlias].comm_name =
+ strdup(param[0].val.word);
+ parray[p].alias_list[parray[p].numAlias].alias =
+ strdup(param[1].val.string);
+ parray[p].numAlias++;
+ pprintf(p, "Alias set.\n");
+
+ }
+ }
+ } else {
+ rfree(parray[p].alias_list[al].alias);
+ parray[p].alias_list[al].alias = strdup(param[1].val.string);
+ pprintf(p, "Alias replaced.\n");
+ }
+ parray[p].alias_list[parray[p].numAlias].comm_name = NULL;
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unalias(int p, param_list param)
+{
+ int al;
+ int i;
+
+ ASSERT(param[0].type == TYPE_WORD);
+ al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias);
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ rfree(parray[p].alias_list[al].comm_name);
+ rfree(parray[p].alias_list[al].alias);
+ for (i = al; i < parray[p].numAlias; i++) {
+ parray[p].alias_list[i].comm_name = parray[p].alias_list[i + 1].comm_name;
+ parray[p].alias_list[i].alias = parray[p].alias_list[i + 1].alias;
+ }
+ parray[p].numAlias--;
+ parray[p].alias_list[parray[p].numAlias].comm_name = NULL;
+ pprintf(p, "Alias removed.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_servers(int p, param_list param)
+{
+/*
+ int i;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (numServers == 0) {
+ */ pprintf(p, "There are no other servers known to this server.\n");
+ return COM_OK;
+}
+ /* pprintf(p, "There are %d known servers.\n", numServers); pprintf(p, "(Not
+ all of these may be active)\n"); pprintf(p, "%-30s%-7s\n", "HOST",
+ "PORT"); for (i = 0; i < numServers; i++) pprintf(p, "%-30s%-7d\n",
+ serverNames[i], serverPorts[i]); return COM_OK; } */
+
+PUBLIC int com_index(int p, param_list param)
+{
+ int i;
+ char index_default[] = "_index";
+ char *iwant, *filenames[100]; /* enough for all index filenames */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = index_default;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in category %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+
+ i = search_directory(index_dir, iwant, filenames, 1000);
+ if (i == 0) {
+ pprintf(p, "No index entry for \"%s\".\n", iwant);
+ } else if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, index_dir, *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Index file %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ pprintf(p, "Matches:");
+ display_directory(p, filenames, i);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_help(int p, param_list param)
+{
+ int i, UseLang = parray[p].language;
+ char help_default[] = "_help";
+ char *iwant, *filenames[1000]; /* enough for all helpfile names */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = help_default;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in command %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+ i = search_directory(help_dir[UseLang], iwant, filenames, 1000);
+ if (i == 0) {
+ if (UseLang != LANG_DEFAULT) {
+ i += search_directory(help_dir[LANG_DEFAULT], iwant, filenames, 1000);
+ if (i > 0) {
+ pprintf(p, "No help available in %s; using %s instead.\n",
+ Language(UseLang), Language(LANG_DEFAULT));
+ UseLang = LANG_DEFAULT;
+ }
+ }
+ if (i==0) {
+ pprintf(p, "No help available on \"%s\".\n", iwant);
+ return COM_OK;
+ }
+ }
+ if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, help_dir[UseLang], *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Helpfile %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ pprintf(p, "Matches:");
+ display_directory(p, filenames, i);
+ pprintf(p, "[Type \"info\" for a list of FICS general information files.]\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_info(int p, param_list param)
+{
+ int n;
+ char *filenames[1000];
+
+ if ((n = search_directory(info_dir, NULL, filenames, 1000)) > 0)
+ display_directory(p, filenames, n);
+ return COM_OK;
+}
+
+PUBLIC int com_adhelp(int p, param_list param)
+{
+ int i;
+ static char nullify = '\0';
+ char *iwant, *filenames[1000]; /* enough for all helpfile names */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in command %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+
+ i = search_directory(adhelp_dir, iwant, filenames, 1000);
+ if (i == 0) {
+ pprintf(p, "No help available on \"%s\".\n", iwant);
+ } else if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, adhelp_dir, *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Helpfile %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ if (*iwant)
+ pprintf(p, "Matches:\n");
+ display_directory(p, filenames, i);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_mailsource(int p, param_list param)
+{
+ static char nullify = '\0';
+ char *iwant, *buffer[1000];
+ char subj[81], fname[MAX_FILENAME_SIZE];
+ int count;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailsource command.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ }
+
+ count = search_directory(source_dir, iwant, buffer, 1000);
+ if (count == 0) {
+ pprintf(p, "Found no source file matching \"%s\".\n", iwant);
+ } else if ((count == 1) || !strcmp(iwant, *buffer)) {
+ sprintf(subj, "FICS source file from server %s: %s",fics_hostname,*buffer);
+ sprintf(fname, "%s/%s",source_dir, *buffer);
+ mail_file_to_user (p, subj, fname);
+ pprintf(p, "Source file %s sent to %s\n", *buffer, parray[p].emailAddress);
+ } else {
+ pprintf(p, "Found %d source files matching that:\n", count);
+ if (*iwant)
+ display_directory(p, buffer, count);
+ else { /* this junk is to get *.c *.h */
+ multicol *m = multicol_start(count);
+ char *s;
+ int i;
+ for (i=0; i < count; i++) {
+ if (((s = buffer[i] + strlen(buffer[i]) - 2) >= buffer[i]) && (!strcmp(s, ".c") || !strcmp(s, ".h")))
+ multicol_store(m, buffer[i]);
+ }
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_mailhelp(int p, param_list param)
+{ /* Sparky */
+ char subj[81], fname[MAX_FILENAME_SIZE];
+ char *iwant, *buffer[1000];
+
+ int count;
+ static char nullify = '\0';
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailhelp command.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL)
+ iwant = &nullify;
+ else
+ iwant = param[0].val.word;
+
+ count = search_directory(help_dir[parray[p].language], iwant, buffer, 1000);
+ if (count == 0) {
+ pprintf(p, "Found no help file matching \"%s\".\n", iwant);
+ } else if (count == 1) {
+ sprintf(subj, "FICS help file from server %s: %s", fics_hostname, *buffer);
+ sprintf(fname, "%s/%s",help_dir[parray[p].language], *buffer);
+ mail_file_to_user (p, subj, fname);
+ pprintf(p, "Help file %s sent to %s\n", *buffer, parray[p].emailAddress);
+ } else {
+ pprintf(p, "Found %d helpfiles matching that:\n", count);
+ display_directory(p, buffer, count);
+ }
+
+ return COM_OK;
+}
+
+PUBLIC int com_handles(int p, param_list param)
+{
+ char *buffer[1000];
+ char pdir[MAX_FILENAME_SIZE];
+ int count;
+
+ sprintf(pdir, "%s/%c", player_dir, param[0].val.word[0]);
+ count = search_directory(pdir, param[0].val.word, buffer, 1000);
+ pprintf(p, "Found %d names.\n", count);
+ if (count > 0)
+ display_directory(p, buffer, count);
+ return COM_OK;
+}
+
+PUBLIC int com_getpi(int p, param_list param)
+{
+ int p1;
+
+ if (!in_list("td", parray[p].name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ if (((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) {
+ /* Darkside suggested not to return anything */
+ return COM_OK;
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "*getpi %s -1 -1 -1*\n", parray[p1].name);
+ } else {
+ pprintf(p, "*getpi %s %d %d %d*\n", parray[p1].name,
+ parray[p1].w_stats.rating,
+ parray[p1].b_stats.rating,
+ parray[p1].s_stats.rating);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_getps(int p, param_list param)
+{
+ int p1;
+
+ if ((((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) || (parray[p1].game < 0)) {
+ pprintf(p, "*status %s 1*\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf(p, "*status %s 0 %s*\n", parray[p1].name, parray[(parray[p1].opponent)].name);
+ return COM_OK;
+}
+PUBLIC int com_limits(int p, param_list param)
+{
+ pprintf(p, "\nCurrent hardcoded limits:\n");
+ pprintf(p, " Max number of players: %d\n", MAX_PLAYER);
+ pprintf(p, " Max number of channels and max capacity: %d\n", MAX_CHANNELS);
+ pprintf(p, " Max number of channels one can be in: %d\n", MAX_INCHANNELS);
+ pprintf(p, " Max number of people on the notify list: %d\n", MAX_NOTIFY);
+ pprintf(p, " Max number of aliases: %d\n", MAX_ALIASES - 1);
+ pprintf(p, " Max number of games you can observe at a time: %d\n", MAX_OBSERVE);
+ pprintf(p, " Max number of requests pending: %d\n", MAX_PENDING);
+ pprintf(p, " Max number of people on the censor list: %d\n", MAX_CENSOR);
+ pprintf(p, " Max number of people in a simul game: %d\n", MAX_SIMUL);
+ pprintf(p, " Max number of messages one can receive: %d\n", MAX_MESSAGES);
+ pprintf(p, " Min number of games to be active: %d\n", PROVISIONAL);
+ pprintf(p, "\nAdmin settable limits:\n");
+ pprintf(p, " Quota list gives two shouts per %d seconds.\n", quota_time);
+ return COM_OK;
+}
blob - /dev/null
blob + 20c68d4bcf91c438f0a12bcdf642e3c3bf459786 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/comproc.h
+/* comproc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _COMPROC_H
+#define _COMPROC_H
+
+extern const none; /* = 0; */
+extern const blitz_rat; /* = 1; */
+extern const std_rat; /* = 2; */
+extern const wild_rat; /* = 3; */
+extern const light_rat;
+extern int com_rating_recalc();
+extern int com_more();
+extern void rscan_news(FILE *, int, int);
+extern void rscan_news2(FILE *, int, int);
+extern int num_news; /* The number of news items in the index file. */
+
+extern int com_quit();
+extern int com_index();
+extern int com_help();
+extern int com_info();
+extern int com_adhelp();
+extern int com_uscf();
+extern int com_set();
+extern int FindPlayer();
+extern int com_stats();
+extern int com_password();
+extern int com_uptime();
+extern int com_date();
+extern int com_llogons();
+extern int com_logons();
+extern int com_who();
+extern int com_refresh();
+extern int com_prefresh();
+extern int com_open();
+extern int com_simopen();
+extern int com_bell();
+extern int com_flip();
+extern int com_highlight();
+extern int com_style();
+extern int com_promote();
+extern int com_alias();
+extern int com_unalias();
+extern int com_servers();
+extern int com_mailsource();
+extern int com_mailhelp();
+extern int com_handles();
+extern int com_news();
+extern int com_getpi();
+extern int com_getps();
+extern int com_limits();
+
+#endif /* _COMPROC_H */
blob - /dev/null
blob + 153f6e52ef0c82ce0d07d8568e84cdea197544d3 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/comproc.o differ
blob - /dev/null
blob + 92386ed8924fd134a66a9ecca68e37f5381ef0be (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/comproc.old.c
+/* comproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ foxbat 95/03/11 added filters in cmatch.
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "comproc.h"
+#include "command.h"
+#include "utils.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "channel.h"
+#include "variable.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "board.h"
+/* #include "hostinfo.h" */
+#include "multicol.h"
+#include "ratings.h"
+#include "formula.h"
+#include "lists.h"
+#include "eco.h"
+#include <string.h>
+
+#include <sys/resource.h>
+
+/* grimm */
+#if defined(SGI)
+#else
+/* int system(char *arg); */
+#endif
+
+const none = 0;
+const blitz_rat = 1;
+const std_rat = 2;
+const wild_rat = 3;
+
+int quota_time;
+
+PUBLIC int com_rating_recalc(int p, param_list param)
+{
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ rating_recalc();
+ return COM_OK;
+}
+
+PUBLIC int com_more(int p, param_list param)
+{
+/* in_push(IN_HELP); */
+ pmore_file(p);
+ return COM_OK;
+}
+
+PUBLIC int com_news(int p, param_list param)
+{
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+ char junk[MAX_LINE_SIZE];
+ char *junkp;
+ int crtime;
+ char count[10];
+ int flag, len;
+
+ if (((param[0].type == 0) || (!strcmp(param[0].val.word, "all")))) {
+
+/* no params - then just display index over news */
+
+ pprintf(p, "\n **** BULLETIN BOARD ****\n\n");
+ sprintf(filename, "%s/news.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find news index.\n");
+ return COM_OK;
+ }
+ flag = 0;
+ while (!feof(fp)) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if ((len = strlen(junk)) > 1) {
+ junk[len - 1] = '\0';
+ sscanf(junkp, "%d %s", &crtime, count);
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ if (((param[0].type == TYPE_WORD) && (!strcmp(param[0].val.word, "all")))) {
+ pprintf(p, "%3s (%s) %s\n", count, strltime(&crtime), junkp);
+ flag = 1;
+ } else {
+ if ((crtime - player_lastconnect(p)) > 0) {
+ pprintf(p, "%3s (%s) %s\n", count, strltime(&crtime), junkp);
+ flag = 1;
+ }
+ }
+ }
+ }
+ fclose(fp);
+ crtime = player_lastconnect(p);
+ if (!flag) {
+ pprintf(p, "There are no news since your last login (%s).\n", strltime(&crtime));
+ } else {
+ pprintf(p, "\n");
+ }
+ } else {
+
+/* check if the specific news file exist in index */
+
+ sprintf(filename, "%s/news.index", news_dir);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Can't find news index.\n");
+ return COM_OK;
+ }
+ flag = 0;
+ while ((!feof(fp)) && (!flag)) {
+ junkp = junk;
+ fgets(junk, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if ((len = strlen(junk)) > 1) {
+ junk[len - 1] = '\0';
+ sscanf(junkp, "%d %s", &crtime, count);
+ if (!strcmp(count, param[0].val.word)) {
+ flag = 1;
+ junkp = nextword(junkp);
+ junkp = nextword(junkp);
+ pprintf(p, "\nNEWS %3s (%s)\n\n %s\n\n", count, strltime(&crtime), junkp);
+ }
+ }
+ }
+ fclose(fp);
+ if (!flag) {
+ pprintf(p, "Bad index number!\n");
+ return COM_OK;
+ }
+/* file exists - show it */
+
+ sprintf(filename, "%s/news.%s", news_dir, param[0].val.word);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pprintf(p, "No more info.\n");
+ return COM_OK;
+ }
+ fclose(fp);
+ sprintf(filename, "news.%s", param[0].val.word);
+ if (psend_file(p, news_dir, filename) < 0) {
+ pprintf(p, "Internal error - couldn't send news file!\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_quit(int p, param_list param)
+{
+ if ((parray[p].game >= 0) && (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pcommand(p, "unexamine");
+ }
+
+ if (parray[p].game >= 0) {
+ pprintf(p, "You can't quit while you are playing a game.\nType 'resign' to resign the game, or you can request an abort with 'abort'.\n");
+ return COM_OK;
+ }
+ psend_file(p, mess_dir, MESS_LOGOUT);
+ return COM_LOGOUT;
+}
+
+/*
+
+PUBLIC int com_query(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the query command.\n");
+ return COM_OK;
+ }
+ if (parray[p].muzzled) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ if (!parray[p].query_log) {
+ parray[p].query_log = tl_new(5);
+ } else {
+ if (tl_numinlast(parray[p].query_log, 60 * 60) >= 2) {
+ pprintf(p, "Your can only query twice per hour.\n");
+ return COM_OK;
+ }
+ }
+ in_push(IN_SHOUT);
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ if (parray[p1].highlight) {
+ pprintf_prompt(p1, "\n\033[7m%s queries:\033[0m %s\n", parray[p].name,
+ param[0].val.string);
+ } else {
+ pprintf_prompt(p1, "\n%s queries: %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ }
+ pprintf(p, "Query heard by %d player(s).\n", count);
+ tl_logevent(parray[p].query_log, 1);
+ in_pop();
+ return COM_OK;
+}
+
+*/
+
+int CheckShoutQuota(int p)
+{
+ int timenow = time(0);
+ int timeleft = 0;
+ if (in_list("quota", parray[p].name)) {
+ if ((timeleft = timenow - parray[p].lastshout_a) < quota_time) {
+ return (quota_time - timeleft);
+ } else {
+ return 0;
+ }
+ } else {
+ return 0;
+ }
+}
+
+PUBLIC int com_shout(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+ int timeleft; /* time left for quota if applicable */
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the shout command.\n");
+ return COM_OK;
+ }
+ if (parray[p].muzzled) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (in_list("quota", parray[p].name)) {
+ pprintf(p, "[You are on the quota list.]\n");
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Next shout available in %d seconds.\n", timeleft);
+ } else {
+ pprintf(p, "Your next shout is ready for use.\n");
+ }
+ } else {
+ pprintf(p, "[You are not on the quota list.]\n");
+ pprintf(p, "Please specify what it is you want to shout.\n");
+ }
+ return COM_OK;
+ }
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "[You are on the quota list.]\n");
+ pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ parray[p].lastshout_a = parray[p].lastshout_b;
+ parray[p].lastshout_b = time(0);
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* in_push(IN_SHOUT); */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_shout)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n%s shouts: %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ pprintf(p, "(%d) %s shouts: %s\n", count, parray[p].name,
+ param[0].val.string);
+/* in_pop(); */
+ if ((in_list("quota", parray[p].name)) && (timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "[You are on the quota list.]\n");
+ pprintf(p, "Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_cshout(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the cshout command.\n");
+ return COM_OK;
+ }
+ if (parray[p].cmuzzled) {
+ pprintf(p, "You are c-muzzled.\n");
+ return COM_OK;
+ }
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* in_push(IN_SHOUT); */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_cshout)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n%s c-shouts: %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ pprintf(p, "(%d) %s c-shouts: %s\n", count, parray[p].name,
+ param[0].val.string);
+/* in_pop(); */
+ return COM_OK;
+}
+
+PUBLIC int com_it(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+ int timeleft;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the it command.\n");
+ return COM_OK;
+ }
+ if (parray[p].muzzled) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (in_list("quota", parray[p].name)) {
+ pprintf(p, "[You are on the quota list.]\n");
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Next shout available in %d seconds.\n", timeleft);
+ } else {
+ pprintf(p, "Your next shout is ready for use.\n");
+ }
+ } else {
+ pprintf(p, "[You are not on the quota list.]\n");
+ pprintf(p, "Please specify what it is you want to shout.\n");
+ }
+ return COM_OK;
+ }
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "[You are on the quota list.]\n");
+ pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ parray[p].lastshout_a = parray[p].lastshout_b;
+ parray[p].lastshout_b = time(0);
+
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* in_push(IN_SHOUT); */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_shout)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ if ((!strncmp(param[0].val.string, "\'", 1)) ||
+ (!strncmp(param[0].val.string, ",", 1)) ||
+ (!strncmp(param[0].val.string, ".", 1))) {
+ pprintf_prompt(p1, "\n--> %s%s\n", parray[p].name,
+ param[0].val.string);
+ } else {
+ pprintf_prompt(p1, "\n--> %s %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ }
+ if ((!strncmp(param[0].val.string, "\'", 1)) ||
+ (!strncmp(param[0].val.string, ",", 1)) ||
+ (!strncmp(param[0].val.string, ".", 1))) {
+ pprintf(p, "(%d) --> %s%s\n", count, parray[p].name, param[0].val.string);
+ } else {
+ pprintf(p, "(%d) --> %s %s\n", count, parray[p].name, param[0].val.string);
+ }
+/* in_pop(); */
+ if ((in_list("quota", parray[p].name)) && (timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "[You are on the quota list.]\n");
+ pprintf(p, "Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ return COM_OK;
+}
+
+#define TELL_TELL 0
+#define TELL_SAY 1
+#define TELL_WHISPER 2
+#define TELL_KIBITZ 3
+#define TELL_CHANNEL 4
+PRIVATE int tell(int p, int p1, char *msg, int why, int ch)
+{
+ char tmp[MAX_LINE_SIZE];
+
+ if (!printablestring(msg)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* if (p1 == p) {
+ * pprintf(p, "Quit talking to yourself! It's embarrassing.\n");
+ * return COM_OK;
+ * }
+ */
+ if ((!parray[p1].i_tell) && (!parray[p].registered)) {
+ pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
+ parray[p1].name);
+ return COM_OK;
+ }
+ if ((player_censored(p1, p)) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ return COM_OK;
+ }
+/* in_push(IN_TELL); */
+ switch (why) {
+ case TELL_SAY:
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ pprintf_prompt(p1, " says: %s\n", msg);
+ break;
+ case TELL_WHISPER:
+ pprintf(p1, "\n%s", parray[p].name);
+ pprintf_prompt(p1, " whispers: %s\n", msg);
+ break;
+ case TELL_KIBITZ:
+ pprintf(p1, "\n%s", parray[p].name);
+ pprintf_prompt(p1, " kibitzes: %s\n", msg);
+ break;
+ case TELL_CHANNEL:
+ pprintf(p1, "\n%s", parray[p].name);
+ pprintf_prompt(p1, "(%d): %s\n", ch, msg);
+ break;
+ case TELL_TELL:
+ default:
+ if (parray[p1].highlight) {
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ } else {
+ pprintf(p1, "\n%s", parray[p].name);
+ }
+ pprintf_prompt(p1, " tells you: %s\n", msg);
+ break;
+ }
+ tmp[0] = '\0';
+ if (!(parray[p1].busy[0] == '\0')) {
+ sprintf(tmp, ", who %s (idle: %d minutes)", parray[p1].busy,
+ ((player_idle(p1) % 3600) / 60));
+ } else {
+ if (((player_idle(p1) % 3600) / 60) > 2) {
+ sprintf(tmp, ", who has been idle %d minutes", ((player_idle(p1) % 3600) / 60));
+ }
+ /* else sprintf(tmp," "); */
+ }
+ if ((why == TELL_SAY) || (why == TELL_TELL)) {
+ pprintf(p, "(told %s%s)\n", parray[p1].name,
+ (((parray[p1].game>=0) && (garray[parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ (parray[p1].game >= 0 && (parray[p1].game != parray[p].game))
+ ? ", who is playing" : tmp));
+ parray[p].last_tell = p1;
+ }
+/* in_pop(); */
+ return COM_OK;
+}
+
+PRIVATE int chtell(int p, int ch, char *msg)
+{
+ int p1;
+ int i, count = 0, listening = 0;
+
+ if ((ch == 0) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Only admins may send tells to channel 0.\n");
+ return COM_OK;
+ }
+ if (ch < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ if (ch >= MAX_CHANNELS) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+/* in_push(IN_TELL); */
+ for (i = 0; i < numOn[ch]; i++) {
+ p1 = channels[ch][i];
+ if (p1 == p) {
+ listening = 1;
+ continue;
+ }
+ if (player_censored(p1, p))
+ continue;
+ if ((parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN))
+ continue;
+ tell(p, p1, msg, TELL_CHANNEL, ch);
+ count++;
+ }
+ if (count) {
+ /* parray[p].last_tell = -1; */
+ parray[p].last_channel = ch;
+ }
+ pprintf(p, "(%d->(%d))", ch, count);
+ if (!listening)
+ pprintf(p, " (You're not listening to channel %d.)", ch);
+ pprintf(p, "\n");
+/* in_pop(); */
+ return COM_OK;
+}
+
+PUBLIC int com_whisper(int p, param_list param)
+{
+ int g;
+ int p1;
+ int count = 0;
+
+ if (!parray[p].num_observe && parray[p].game < 0) {
+ pprintf(p, "You are not playing or observing a game.\n");
+ return COM_OK;
+ }
+ if (!parray[p].registered && (parray[p].game == -1)) {
+ pprintf(p, "You must be registered to whisper other people's games.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >= 0)
+ g = parray[p].game;
+ else
+ g = parray[p].observe_list[0];
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g)) {
+ tell(p, p1, param[0].val.string, TELL_WHISPER, 0);
+ if ((parray[p].adminLevel >= ADMIN_ADMIN) || !garray[g].private)
+ count++;
+ }
+ }
+ pprintf(p, "whispered to %d.\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_kibitz(int p, param_list param)
+{
+ int g;
+ int p1;
+ int count = 0;
+
+ if (!parray[p].num_observe && parray[p].game < 0) {
+ pprintf(p, "You are not playing or observing a game.\n");
+ return COM_OK;
+ }
+ if (!parray[p].registered && (parray[p].game == -1)) {
+ pprintf(p, "You must be registered to kibitz other people's games.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >= 0)
+ g = parray[p].game;
+ else
+ g = parray[p].observe_list[0];
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ tell(p, p1, param[0].val.string, TELL_KIBITZ, 0);
+ if ((parray[p].adminLevel >= ADMIN_ADMIN) || !garray[g].private || (parray[p1].game == g))
+ count++;
+ }
+ }
+ pprintf(p, "kibitzed to %d.\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_tell(int p, param_list param)
+{
+ int p1;
+
+ if (param[0].type == TYPE_NULL)
+ return COM_BADPARAMETERS;
+ if (param[0].type == TYPE_WORD) {
+ stolower(param[0].val.word);
+ if (!strcmp(param[0].val.word, ".")) {
+ if (parray[p].last_tell < 0) {
+ pprintf(p, "No one to tell anything to.\n");
+ return COM_OK;
+ } else {
+ return tell(p, parray[p].last_tell, param[1].val.string, TELL_TELL, 0);
+ }
+ }
+ if (!strcmp(param[0].val.word, ",")) {
+ if (parray[p].last_channel < 0) {
+ pprintf(p, "No previous channel.\n");
+ return COM_OK;
+ } else {
+ return chtell(p, parray[p].last_channel, param[1].val.string);
+ }
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ return tell(p, p1, param[1].val.string, TELL_TELL, 0);
+ } else { /* Channel */
+ return chtell(p, param[0].val.integer, param[1].val.string);
+ }
+}
+
+PUBLIC int com_xtell(int p, param_list param)
+{
+ int p1;
+ char *msg;
+ char tmp[2048];
+
+ msg = param[1].val.string;
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (!printablestring(msg)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ if ((!parray[p1].i_tell) && (!parray[p].registered)) {
+ pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
+ parray[p1].name);
+ return COM_OK;
+ }
+ if ((player_censored(p1, p)) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (parray[p1].highlight) {
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ } else {
+ pprintf(p1, "\n%s", parray[p].name);
+ }
+ pprintf_prompt(p1, " tells you: %s\n", msg);
+
+ tmp[0] = '\0';
+ if (!(parray[p1].busy[0] == '\0')) {
+ sprintf(tmp, ", who %s (idle: %d minutes)", parray[p1].busy,
+ ((player_idle(p1) % 3600) / 60));
+ } else {
+ if (((player_idle(p1) % 3600) / 60) > 2) {
+ sprintf(tmp, ", who has been idle %d minutes", ((player_idle(p1) % 3600) / 60));
+ }
+ }
+ pprintf(p, "(told %s%s)\n", parray[p1].name,
+ (((parray[p1].game>=0) && (garray[parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ (parray[p1].game >= 0 && (parray[p1].game != parray[p].game))
+ ? ", who is playing" : tmp));
+ return COM_OK;
+}
+
+PUBLIC int com_say(int p, param_list param)
+{
+ if (parray[p].opponent < 0) {
+ if (parray[p].last_opponent < 0) {
+ pprintf(p, "No one to say anything to, try tell.\n");
+ return COM_OK;
+ } else {
+ return tell(p, parray[p].last_opponent, param[0].val.string, TELL_SAY, 0);
+ }
+ }
+ return tell(p, parray[p].opponent, param[0].val.string, TELL_SAY, 0);
+}
+
+PUBLIC int com_set(int p, param_list param)
+{
+ int result;
+ int which;
+ char *val;
+
+ if (param[1].type == TYPE_NULL)
+ val = NULL;
+ else
+ val = param[1].val.string;
+ result = var_set(p, param[0].val.word, val, &which);
+ switch (result) {
+ case VAR_OK:
+ break;
+ case VAR_BADVAL:
+ pprintf(p, "Bad value given for variable %s.\n", param[0].val.word);
+ break;
+ case VAR_NOSUCH:
+ pprintf(p, "No such variable name %s.\n", param[0].val.word);
+ break;
+ case VAR_AMBIGUOUS:
+ pprintf(p, "Ambiguous variable name %s.\n", param[0].val.word);
+ break;
+ }
+ player_save(p);
+ return COM_OK;
+}
+
+PUBLIC int FindPlayer(int p, parameter * param, int *p1, int *connected)
+{
+ if (param->type == TYPE_WORD) {
+ *p1 = player_search(p, param->val.word);
+ if (*p1 == 0)
+ return 0;
+ if (*p1 < 0) { /* player had to be connected and will be
+ removed later */
+ *connected = 0;
+ *p1 = (-*p1) - 1;
+ } else {
+ *connected = 1;
+ *p1 = *p1 - 1;
+ }
+ } else {
+ *p1 = p;
+ *connected = 1;
+ }
+ return 1;
+}
+
+PRIVATE void com_stats_andify(int *numbers, int howmany, char *dest)
+{
+ char tmp[10];
+
+ *dest = '\0';
+ while (howmany--) {
+ sprintf(tmp, "%d", numbers[howmany]);
+ strcat(dest, tmp);
+ if (howmany > 1)
+ sprintf(tmp, ", ");
+ else if (howmany == 1)
+ sprintf(tmp, " and ");
+ else
+ sprintf(tmp, ".\n");
+ strcat(dest, tmp);
+ }
+ return;
+}
+
+PRIVATE void com_stats_rating(char *hdr, statistics * stats, char *dest)
+{
+ char tmp[100];
+
+ sprintf(dest, "%-10s%4s %5.1f %4d %4d %4d %4d",
+ hdr, ratstr(stats->rating), stats->sterr, stats->win, stats->los, stats->dra, stats->num);
+ if (stats->whenbest) {
+ sprintf(tmp, " %d", stats->best);
+ strcat(dest, tmp);
+ strftime(tmp, sizeof(tmp), " (%d-%b-%y)", localtime((time_t *) & stats->whenbest));
+ strcat(dest, tmp);
+ }
+ strcat(dest, "\n");
+ return;
+}
+
+PUBLIC int com_stats(int p, param_list param)
+{
+ int g, i, t;
+ int p1, connected;
+ char line[255], tmp[255];
+ int numbers[MAX_OBSERVE > MAX_SIMUL ? MAX_OBSERVE : MAX_SIMUL];
+
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ sprintf(line, "\nStatistics for %-11s ", parray[p1].name);
+ if ((connected) && (parray[p1].status == PLAYER_PROMPT)) {
+ sprintf(tmp, "On for: %s", hms(player_ontime(p1), 0, 0, 0));
+ strcat(line, tmp);
+ sprintf(tmp, " Idle: %s\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ if ((t = player_lastdisconnect(p1)))
+ sprintf(tmp, "(Last disconnected %s):\n", strltime(&t));
+ else
+ sprintf(tmp, "(Never connected.)\n");
+ }
+ strcat(line, tmp);
+ pprintf(p, "%s", line);
+ if (parray[p1].simul_info.numBoards) {
+ for (i = 0, t = 0; i < parray[p1].simul_info.numBoards; i++) {
+ if ((numbers[t] = parray[p1].simul_info.boards[i] + 1) != 0)
+ t++;
+ }
+ pprintf(p, "%s is giving a simul: game%s ", parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ } else if (parray[p1].game >= 0) {
+ g = parray[p1].game;
+ if (garray[g].status == GAME_EXAMINE) {
+ pprintf(p, "(Examining game %d: %s vs. %s)\n", g + 1,
+ parray[garray[g].white].name, parray[garray[g].black].name);
+ } else {
+ pprintf(p, "(playing game %d: %s vs. %s)\n", g + 1,
+ parray[garray[g].white].name, parray[garray[g].black].name);
+ }
+ }
+ if (parray[p1].num_observe) {
+ for (i = 0, t = 0; i < parray[p1].num_observe; i++) {
+ g = parray[p1].observe_list[i];
+ if ((g != -1) && ((parray[p].adminLevel >= ADMIN_ADMIN) || (garray[g].private == 0)))
+ numbers[t++] = g + 1;
+ }
+ if (t) {
+ pprintf(p, "%s is observing game%s ", parray[p1].name, ((t > 1) ? "s" : ""));
+ com_stats_andify(numbers, t, tmp);
+ pprintf(p, tmp);
+ }
+ }
+ if (parray[p1].busy[0]) {
+ pprintf(p, "(%s %s)\n", parray[p1].name, parray[p1].busy);
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "%s is NOT a registered player.\n\n", parray[p1].name);
+ } else {
+ pprintf(p, "\n rating RD win loss draw total best\n");
+ com_stats_rating("Blitz", &parray[p1].b_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Standard", &parray[p1].s_stats, tmp);
+ pprintf(p, tmp);
+ com_stats_rating("Wild", &parray[p1].w_stats, tmp);
+ pprintf(p, tmp);
+ }
+ pprintf(p, "\n");
+ if (parray[p1].adminLevel > 0) {
+ pprintf(p, "Admin Level: ");
+ switch (parray[p1].adminLevel) {
+/*
+ case 0:
+ pprintf(p, "Normal User\n");
+ break;
+ case 5:
+ pprintf(p, "Extra Cool User\n"); vek wants to be 5
+ break;
+
+ Forget it - you can do some admin stuff if your level is > than 0 - DAV
+
+*/
+ case 5:
+ pprintf(p, "Authorized Helper Person\n");
+ break;
+ case 10:
+ pprintf(p, "Administrator\n");
+ break;
+ case 15:
+ pprintf(p, "Help File Librarian/Administrator\n");
+ break;
+ case 20:
+ pprintf(p, "Master Administrator\n");
+ break;
+ case 50:
+ pprintf(p, "Master Help File Librarian/Administrator\n");
+ break;
+ case 60:
+ pprintf(p, "Assistant Super User\n");
+ break;
+ case 100:
+ pprintf(p, "Super User\n");
+ break;
+ default:
+ pprintf(p, "%d\n", parray[p1].adminLevel);
+ break;
+ }
+ }
+ if (parray[p].adminLevel > 0)
+ pprintf(p, "Full Name : %s\n", (parray[p1].fullName ? parray[p1].fullName : "(none)"));
+ if (((p1 == p) && (parray[p1].registered)) || (parray[p].adminLevel > 0))
+ pprintf(p, "Address : %s\n", (parray[p1].emailAddress ? parray[p1].emailAddress : "(none)"));
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, "Host : %s\n",
+/*
+ ((hp = gethostbyaddr((const char*) (connected ? &parray[p1].thisHost : &parray[p1].lastHost), sizeof(parray[p1].thisHost), AF_INET)) == 0) ? "" : hp->h_name,
+*/
+ dotQuad(connected ? parray[p1].thisHost : parray[p1].lastHost));
+ }
+ if ((parray[p].adminLevel > 0) && (parray[p1].registered))
+ if (parray[p1].num_comments)
+ pprintf(p, "Comments : %d\n", parray[p1].num_comments);
+
+ if (parray[p1].num_plan) {
+ pprintf(p, "\n");
+ for (i = 0; i < parray[p1].num_plan; i++)
+ pprintf(p, "%2d: %s\n", i + 1, (parray[p1].planLines[i] != NULL) ? parray[p1].planLines[i] : "");
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+
+
+PUBLIC int com_variables(int p, param_list param)
+{
+ int p1, connected;
+ int i;
+
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ pprintf(p, "Variable settings of %s:\n", parray[p1].name);
+/* if (parray[p1].fullName)
+ pprintf(p, " Realname: %s\n", parray[p1].fullName);
+*/
+ if (parray[p1].uscfRating)
+ pprintf(p, " USCF: %d\n", parray[p1].uscfRating);
+ pprintf(p, " time=%-3d inc=%-3d private=%d\n",
+ parray[p1].d_time, parray[p1].d_inc, parray[p1].private);
+ pprintf(p, " rated=%d ropen=%d open=%d simopen=%d\n",
+ parray[p1].rated, parray[p1].ropen, parray[p1].open, parray[p1].sopen);
+ pprintf(p, " shout=%d cshout=%d kib=%d tell=%d notifiedby=%d\n",
+ parray[p1].i_shout, parray[p1].i_cshout, parray[p1].i_kibitz, parray[p1].i_tell, parray[p1].notifiedby);
+ pprintf(p, " pin=%d gin=%d style=%-3d flip=%d\n",
+ parray[p1].i_login, parray[p1].i_game, parray[p1].style + 1, parray[p1].flip);
+ pprintf(p, " highlight=%d bell=%d auto=%d mailmess=%d pgn=%d\n",
+ parray[p1].highlight, parray[p1].bell, parray[p1].automail, parray[p1].i_mailmess, parray[p1].pgn);
+ pprintf(p, " width=%-3d height=%-3d\n",
+ parray[p1].d_width, parray[p1].d_height);
+ if (parray[p1].prompt && parray[p1].prompt != def_prompt)
+ pprintf(p, " Prompt: %s\n", parray[p1].prompt);
+
+ { /* added code to print channels */
+ int count = 0;
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (on_channel(i, p1)) {
+ if (!count)
+ pprintf(p, "\n Channels:");
+ pprintf(p, " %d", i);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, "\n");
+ }
+/* if (parray[p1].numAlias && (p == p1)) {
+ pprintf(p, "\n Aliases:\n");
+ for (i = 0; i < parray[p1].numAlias; i++) {
+ pprintf(p, " %s %s\n", parray[p1].alias_list[i].comm_name,
+ parray[p1].alias_list[i].alias);
+ }
+ }
+*/
+ if (parray[p1].num_formula) {
+ pprintf(p, "\n");
+ for (i = 0; i < parray[p1].num_formula; i++) {
+ if (parray[p1].formulaLines[i] != NULL)
+ pprintf(p, " f%d: %s\n", i + 1, parray[p1].formulaLines[i]);
+ else
+ pprintf(p, " f%d:\n", i + 1);
+ }
+ }
+ if (parray[p1].formula != NULL)
+ pprintf(p, "\nFormula: %s\n", parray[p1].formula);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+
+
+PUBLIC int com_password(int p, param_list param)
+{
+ char *oldpassword = param[0].val.word;
+ char *newpassword = param[1].val.word;
+ char salt[3];
+
+ if (!parray[p].registered) {
+ pprintf(p, "Setting a password is only for registered players.\n");
+ return COM_OK;
+ }
+ if (parray[p].passwd) {
+ salt[0] = parray[p].passwd[0];
+ salt[1] = parray[p].passwd[1];
+ salt[2] = '\0';
+ if (strcmp(crypt(oldpassword, salt), parray[p].passwd)) {
+ pprintf(p, "Incorrect password, password not changed!\n");
+ return COM_OK;
+ }
+ rfree(parray[p].passwd);
+ parray[p].passwd = NULL;
+ }
+ salt[0] = 'a' + rand() % 26;
+ salt[1] = 'a' + rand() % 26;
+ salt[2] = '\0';
+ parray[p].passwd = strdup(crypt(newpassword, salt));
+ pprintf(p, "Password changed to \"%s\".\n", newpassword);
+ return COM_OK;
+}
+
+PUBLIC int com_uptime(int p, param_list param)
+{
+ unsigned long uptime = time(0) - startuptime;
+ struct rusage ru;
+ int days = (uptime / (60*60*24));
+ int hours = ((uptime % (60*60*24)) / (60*60));
+ int mins = (((uptime % (60*60*24)) % (60*60)) / 60);
+ int secs = (((uptime % (60*60*24)) % (60*60)) % 60);
+
+ pprintf(p, "Server location: %s Server version : %s\n", fics_hostname,VERS_NUM);
+ pprintf(p, "The server has been up since %s.\n", strltime(&startuptime));
+ if ((days==0) && (hours==0) && (mins==0)) {
+ pprintf(p, "(Up for %d second%s)\n",
+ secs, (secs==1) ? "" : "s");
+ } else if ((days==0) && (hours==0)) {
+ pprintf(p, "(Up for %d minute%s and %d second%s)\n",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else if (days==0) {
+ pprintf(p, "(Up for %d hour%s, %d minute%s and %d second%s)\n",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else {
+ pprintf(p, "(Up for %d day%s, %d hour%s, %d minute%s and %d second%s)\n",
+ days, (days==1) ? "" : "s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ }
+ pprintf(p, "\nAllocs: %u Frees: %u Allocs In Use: %u\n",
+ malloc_count, free_count, malloc_count - free_count);
+ if (parray[p].adminLevel >= ADMIN_ADMIN) {
+ pprintf(p, "\nplayer size:%d, game size:%d, con size:%d, g_num:%d\n",
+ sizeof(player), sizeof(game), net_consize(), g_num);
+ getrusage(RUSAGE_SELF, &ru);
+ pprintf(p, "pagesize = %d, maxrss = %d, total = %d\n", getpagesize(), ru.ru_maxrss, getpagesize() * ru.ru_maxrss);
+ }
+ pprintf(p, "\nPlayer limit: %d\n", max_connections);
+ pprintf(p, "\nThere are currently %d players, with a high of %d since last restart.\n", player_count(), player_high);
+ pprintf(p, "There are currently %d games, with a high of %d since last restart.\n", game_count(), game_high);
+ pprintf(p, "\nCompiled on %s\n", COMP_DATE);
+ return COM_OK;
+}
+
+PUBLIC int com_date(int p, param_list param)
+{
+ int t = time(0);
+ pprintf(p, "Local time - %s\n", strltime(&t));
+ pprintf(p, "Greenwich time - %s\n", strgtime(&t));
+ return COM_OK;
+}
+
+char *inout_string[] = {
+ "login", "logout"
+};
+
+PRIVATE int plogins(p, fname)
+int p;
+char *fname;
+{
+ FILE *fp;
+ int inout, thetime, registered;
+ char loginName[MAX_LOGIN_NAME + 1];
+ char ipstr[20];
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no login information available.\n");
+ return COM_OK;
+ }
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime,
+ ®istered, ipstr) != 5) {
+ fprintf(stderr, "FICS: Error in login info format. %s\n", fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ pprintf(p, "%s: %-17s %-6s", strltime(&thetime), loginName,
+ inout_string[inout]);
+ if (parray[p].adminLevel > 0) {
+ pprintf(p, " from %s\n", ipstr);
+ } else
+ pprintf(p, "\n");
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+PUBLIC int com_llogons(int p, param_list param)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%s", stats_dir, STATS_LOGONS);
+ return plogins(p, fname);
+}
+
+PUBLIC int com_logons(int p, param_list param)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, param[0].val.word[0], param[0].val.word, STATS_LOGONS);
+ } else {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS);
+ }
+ return plogins(p, fname);
+}
+
+#define WHO_OPEN 0x01
+#define WHO_CLOSED 0x02
+#define WHO_RATED 0x04
+#define WHO_UNRATED 0x08
+#define WHO_FREE 0x10
+#define WHO_PLAYING 0x20
+#define WHO_REGISTERED 0x40
+#define WHO_UNREGISTERED 0x80
+
+PRIVATE void who_terse(int p, int num, int *plist, int type)
+{
+ char ptmp[80 + 20]; /* for highlight */
+ multicol *m = multicol_start(PARRAY_SIZE);
+ int i;
+ int p1;
+ int rat;
+
+ /* altered DAV 3/15/95 */
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+ if (type == blitz_rat)
+ rat = parray[p1].b_stats.rating;
+ if (type == wild_rat)
+ rat = parray[p1].w_stats.rating;
+ if (type == std_rat)
+ rat = parray[p1].s_stats.rating;
+
+ if (type == none) {
+ sprintf(ptmp, " ");
+ } else {
+ sprintf(ptmp, "%-4s", ratstrii(rat, parray[p1].registered));
+ if (parray[p1].simul_info.numBoards) {
+ strcat(ptmp, "~");
+ } else if ((parray[p1].game >= 0) && (garray[parray[p1].game].status == GAME_EXAMINE)) {
+ strcat(ptmp, "#");
+ } else if (parray[p1].game >= 0) {
+ strcat(ptmp, "^");
+ } else if (!parray[p1].open) {
+ strcat(ptmp, ":");
+ } else if (player_idle(p1) > 300) {
+ strcat(ptmp, ".");
+ } else {
+ strcat(ptmp, " ");
+ }
+ }
+ if (p == p1) {
+ psprintf_highlight(p, ptmp + strlen(ptmp), "%s", parray[p1].name);
+ } else {
+ strcat(ptmp, parray[p1].name);
+ }
+ if ((parray[p1].adminLevel >= 10) && (parray[p1].i_admin))
+ strcat(ptmp, "(*)");
+ if (in_list("computer", parray[p1].name))
+ strcat(ptmp, "(C)");
+/* grimm's fishlist
+ if (in_list("fish", parray[p1].name)) strcat(ptmp, "(Fish)");
+*/
+ if (in_list("fm", parray[p1].name))
+ strcat(ptmp, "(FM)");
+ if (in_list("im", parray[p1].name))
+ strcat(ptmp, "(IM)");
+ if (in_list("gm", parray[p1].name))
+ strcat(ptmp, "(GM)");
+ if (in_list("td", parray[p1].name))
+ strcat(ptmp, "(TD)");
+ multicol_store(m, ptmp);
+ }
+ multicol_pprint(m, p, 80, 2);
+ multicol_end(m);
+ pprintf(p, "\n %d Players displayed (of %d). (*) indicates system administrator.\n", num, player_count());
+}
+
+PRIVATE void who_verbose(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* +8 for highlight */
+
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+ pprintf(p,
+ " | User Standard Blitz On for Idle |\n"
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+
+ strcpy(playerLine, " |");
+
+ if (parray[p1].game >= 0)
+ sprintf(tmp, "%3d", parray[p1].game + 1);
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (!parray[p1].open)
+ sprintf(tmp, "X");
+ else
+ sprintf(tmp, " ");
+ strcat(playerLine, tmp);
+
+ if (parray[p1].registered)
+ if (parray[p1].rated) {
+ sprintf(tmp, " ");
+ } else {
+ sprintf(tmp, "u");
+ }
+ else
+ sprintf(tmp, "U");
+ strcat(playerLine, tmp);
+
+ /* Modified by DAV 3/15/95 */
+ if (p == p1) {
+ strcpy(tmp, " ");
+ psprintf_highlight(p, tmp + strlen(tmp), "%-17s", parray[p1].name);
+ } else {
+ sprintf(tmp, " %-17s", parray[p1].name);
+ }
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, " %4s %-4s %5s ",
+ ratstrii(parray[p1].s_stats.rating, parray[p1].registered),
+ ratstrii(parray[p1].b_stats.rating, parray[p1].registered),
+ hms(player_ontime(p1), 0, 0, 0));
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s |\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " |\n");
+ }
+ strcat(playerLine, tmp);
+ pprintf(p, "%s", playerLine);
+ }
+
+ pprintf(p,
+ " | |\n"
+ );
+ pprintf(p,
+ " | %3d Players Displayed |\n",
+ num
+ );
+ pprintf(p,
+ " +---------------------------------------------------------------+\n"
+ );
+}
+
+PRIVATE void who_winloss(p, num, plist)
+int p;
+int num;
+int plist[];
+{
+ int i, p1;
+ char playerLine[255], tmp[255]; /* for highlight */
+
+ pprintf(p,
+ "Name Stand win loss draw Blitz win loss draw idle\n"
+ );
+ pprintf(p,
+ "---------------- ----- ------------- ----- ------------- ----\n"
+ );
+
+ for (i = 0; i < num; i++) {
+ p1 = plist[i];
+ if (p1 == p) {
+ psprintf_highlight(p, playerLine, "%-17s", parray[p1].name);
+ } else {
+ sprintf(playerLine, "%-17s", parray[p1].name);
+ }
+ sprintf(tmp, " %4s %4d %4d %4d ",
+ ratstrii(parray[p1].s_stats.rating, parray[p1].registered),
+ (int) parray[p1].s_stats.win,
+ (int) parray[p1].s_stats.los,
+ (int) parray[p1].s_stats.dra);
+ strcat(playerLine, tmp);
+
+ sprintf(tmp, "%4s %4d %4d %4d ",
+ ratstrii(parray[p1].b_stats.rating, parray[p1].registered),
+ (int) parray[p1].b_stats.win,
+ (int) parray[p1].b_stats.los,
+ (int) parray[p1].b_stats.dra);
+ strcat(playerLine, tmp);
+
+ if (player_idle(p1) >= 60) {
+ sprintf(tmp, "%5s\n", hms(player_idle(p1), 0, 0, 0));
+ } else {
+ sprintf(tmp, " \n");
+ }
+ strcat(playerLine, tmp);
+
+ pprintf(p, "%s", playerLine);
+ }
+ pprintf(p, " %3d Players Displayed.\n", num);
+}
+
+PRIVATE int who_ok(p, sel_bits)
+int p;
+unsigned int sel_bits;
+{
+ if (parray[p].status != PLAYER_PROMPT)
+ return 0;
+ if (sel_bits == 0xff)
+ return 1;
+ if (sel_bits & WHO_OPEN)
+ if (!parray[p].open)
+ return 0;
+ if (sel_bits & WHO_CLOSED)
+ if (parray[p].open)
+ return 0;
+ if (sel_bits & WHO_RATED)
+ if (!parray[p].rated)
+ return 0;
+ if (sel_bits & WHO_UNRATED)
+ if (parray[p].rated)
+ return 0;
+ if (sel_bits & WHO_FREE)
+ if (parray[p].game >= 0)
+ return 0;
+ if (sel_bits & WHO_PLAYING)
+ if (parray[p].game < 0)
+ return 0;
+ if (sel_bits & WHO_REGISTERED)
+ if (!parray[p].registered)
+ return 0;
+ if (sel_bits & WHO_UNREGISTERED)
+ if (parray[p].registered)
+ return 0;
+ return 1;
+}
+
+
+PRIVATE int blitz_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].b_stats.rating > parray[p2].b_stats.rating)
+ return -1;
+ if (parray[p1].b_stats.rating < parray[p2].b_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int stand_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].s_stats.rating > parray[p2].s_stats.rating)
+ return -1;
+ if (parray[p1].s_stats.rating < parray[p2].s_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int wild_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ if (parray[p1].w_stats.rating > parray[p2].w_stats.rating)
+ return -1;
+ if (parray[p1].w_stats.rating < parray[p2].w_stats.rating)
+ return 1;
+ if (parray[p1].registered > parray[p2].registered)
+ return -1;
+ if (parray[p1].registered < parray[p2].registered)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PRIVATE int alpha_cmp(const void *pp1, const void *pp2)
+{
+ register int p1 = *(int *) pp1;
+ register int p2 = *(int *) pp2;
+ if (parray[p1].status != PLAYER_PROMPT) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 0;
+ else
+ return -1;
+ }
+ if (parray[p2].status != PLAYER_PROMPT)
+ return 1;
+ return strcmp(parray[p1].login, parray[p2].login);
+}
+
+PUBLIC void sort_players(int players[PARRAY_SIZE],
+ int ((*cmp_func) (const void *, const void *)))
+{
+ int i;
+
+ for (i = 0; i < p_num; i++) {
+ players[i] = i;
+ }
+ qsort(players, p_num, sizeof(int), cmp_func);
+}
+
+/* This is the of the most compliclicated commands in terms of parameters */
+PUBLIC int com_who(int p, param_list param)
+{
+ int style = 0;
+ float stop_perc = 1.0;
+ float start_perc = 0;
+ unsigned int sel_bits = 0xff;
+ int sortlist[PARRAY_SIZE], plist[PARRAY_SIZE];
+ int ((*cmp_func) (const void *, const void *)) = blitz_cmp;
+ int startpoint;
+ int stoppoint;
+ int i, len;
+ int tmpI, tmpJ;
+ char c;
+ int p1, count, num_who;
+ int sort_type = blitz_rat;
+
+ if (param[0].type == TYPE_WORD) {
+ len = strlen(param[0].val.word);
+ for (i = 0; i < len; i++) {
+ c = param[0].val.word[i];
+ if (isdigit(c)) {
+ if (i == 0 || !isdigit(param[0].val.word[i - 1])) {
+ tmpI = c - '0';
+ if (tmpI == 1) {
+ start_perc = 0.0;
+ stop_perc = 0.333333;
+ } else if (tmpI == 2) {
+ start_perc = 0.333333;
+ stop_perc = 0.6666667;
+ } else if (tmpI == 3) {
+ start_perc = 0.6666667;
+ stop_perc = 1.0;
+ } else if ((i == len - 1) || (!isdigit(param[0].val.word[i + 1])))
+ return COM_BADPARAMETERS;
+ } else {
+ tmpI = c - '0';
+ tmpJ = param[0].val.word[i - 1] - '0';
+ if (tmpI == 0)
+ return COM_BADPARAMETERS;
+ if (tmpJ > tmpI)
+ return COM_BADPARAMETERS;
+ start_perc = ((float) tmpJ - 1.0) / (float) tmpI;
+ stop_perc = ((float) tmpJ) / (float) tmpI;
+ }
+ } else {
+ switch (c) {
+ case 'o':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_OPEN;
+ else
+ sel_bits |= WHO_OPEN;
+ break;
+ case 'r':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_RATED;
+ else
+ sel_bits |= WHO_RATED;
+ break;
+ case 'f':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_FREE;
+ else
+ sel_bits |= WHO_FREE;
+ break;
+ case 'a':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_FREE | WHO_OPEN;
+ else
+ sel_bits |= (WHO_FREE | WHO_OPEN);
+ break;
+ case 'R':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_REGISTERED;
+ else
+ sel_bits |= WHO_REGISTERED;
+ break;
+ case 'l': /* Sort order */
+ cmp_func = alpha_cmp;
+ sort_type = none;
+ break;
+ case 'A': /* Sort order */
+ cmp_func = alpha_cmp;
+ break;
+ case 'w': /* Sort order */
+ cmp_func = wild_cmp;
+ sort_type = wild_rat;
+ break;
+ case 's': /* Sort order */
+ cmp_func = stand_cmp;
+ sort_type = std_rat;
+ break;
+ case 'b': /* Sort order */
+ cmp_func = blitz_cmp;
+ sort_type = blitz_rat;
+ break;
+ case 't': /* format */
+ style = 0;
+ break;
+ case 'v': /* format */
+ style = 1;
+ break;
+ case 'n': /* format */
+ style = 2;
+ break;
+ case 'U':
+ if (sel_bits == 0xff)
+ sel_bits = WHO_UNREGISTERED;
+ else
+ sel_bits |= WHO_UNREGISTERED;
+ break;
+ default:
+ return COM_BADPARAMETERS;
+ break;
+ }
+ }
+ }
+ }
+ sort_players(sortlist, cmp_func);
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ count++;
+ }
+ startpoint = floor((float) count * start_perc);
+ stoppoint = ceil((float) count * stop_perc) - 1;
+ num_who = 0;
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (!who_ok(sortlist[p1], sel_bits))
+ continue;
+ if ((count >= startpoint) && (count <= stoppoint)) {
+ plist[num_who++] = sortlist[p1];
+ }
+ count++;
+ }
+ if (num_who == 0) {
+ pprintf(p, "No logged in players match the flags in your who request.\n");
+ return COM_OK;
+ }
+ switch (style) {
+ case 0: /* terse */
+ who_terse(p, num_who, plist, sort_type);
+ break;
+ case 1: /* verbose */
+ who_verbose(p, num_who, plist);
+ break;
+ case 2: /* win-loss */
+ who_winloss(p, num_who, plist);
+ break;
+ default:
+ return COM_BADPARAMETERS;
+ break;
+ }
+ return COM_OK;
+}
+
+
+
+
+PRIVATE int notorcen(int p, param_list param, int *num, int max,
+ char **list, char *listname)
+{
+ int i, p1, connected;
+
+ if (param[0].type != TYPE_WORD) {
+ if (!*num) {
+ pprintf(p, "Your %s list is empty.\n", listname);
+ return COM_OK;
+ } else
+ pprintf(p, "-- Your %s list contains %d names: --", listname, *num);
+ /* New code to print names in columns */
+ {
+ multicol *m = multicol_start(MAX_NOTIFY + 1);
+ for (i = 0; i < *num; i++)
+ multicol_store_sorted(m, list[i]);
+ multicol_pprint(m, p, 78, 2);
+ multicol_end(m);
+ }
+ return COM_OK;
+ }
+ if (*num >= max) {
+ pprintf(p, "Sorry, your %s list is already full.\n", listname);
+ return COM_OK;
+ }
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ for (i = 0; i < *num; i++) {
+ if (!strcasecmp(list[i], param[0].val.word)) {
+ pprintf(p, "Your %s list already includes %s.\n",
+ listname, parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ if (p1 == p) {
+ pprintf(p, "You can't %s yourself.\n", listname);
+ return COM_OK;
+ }
+ list[*num] = strdup(parray[p1].name);
+ ++(*num);
+ pprintf(p, "%s is now on your %s list.\n", parray[p1].name, listname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+
+PRIVATE int unnotorcen(int p, param_list param, int *num, int max,
+ char **list, char *listname)
+{
+ char *pname = NULL;
+ int i, j;
+ int unc = 0;
+
+ if (param[0].type == TYPE_WORD) {
+ pname = param[0].val.word;
+ }
+ for (i = 0; i < *num; i++) {
+ if (!pname || !strcasecmp(pname, list[i])) {
+ pprintf(p, "%s is removed from your %s list.\n",
+ list[i], listname);
+ rfree(list[i]);
+ list[i] = NULL;
+ unc++;
+ }
+ }
+ if (unc) {
+ i = 0;
+ j = 0;
+ while (j < *num) {
+ if (list[j] != NULL) {
+ list[i++] = list[j];
+ }
+ j++;
+ }
+ while (i < j) {
+ list[i++] = NULL;
+ }
+ (*num) -= unc;
+ } else {
+ pprintf(p, "No one was removed from your %s list.\n", listname);
+ }
+ return COM_OK;
+}
+
+
+PUBLIC int com_notify(int p, param_list param)
+{
+ return notorcen(p, param, &parray[p].num_notify, MAX_NOTIFY,
+ parray[p].notifyList, "notify");
+}
+
+PUBLIC int com_censor(int p, param_list param)
+{
+ return notorcen(p, param, &parray[p].num_censor, MAX_CENSOR,
+ parray[p].censorList, "censor");
+}
+
+PUBLIC int com_unnotify(int p, param_list param)
+{
+ return unnotorcen(p, param, &parray[p].num_notify, MAX_NOTIFY,
+ parray[p].notifyList, "notify");
+}
+
+PUBLIC int com_uncensor(int p, param_list param)
+{
+ return unnotorcen(p, param, &parray[p].num_censor, MAX_CENSOR,
+ parray[p].censorList, "censor");
+}
+
+
+PUBLIC int com_channel(int p, param_list param)
+{
+ int i, err;
+
+ if (param[0].type == TYPE_NULL) { /* Turn off all channels */
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (!channel_remove(i, p))
+ pprintf(p, "Channel %d turned off.\n", i);
+ }
+ } else {
+ i = param[0].val.integer;
+ if ((i == 0) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Only admins may join channel 0.\n");
+ return COM_OK;
+ }
+ if (i < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ if (i >= MAX_CHANNELS) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ if (on_channel(i, p)) {
+ if (!channel_remove(i, p))
+ pprintf(p, "Channel %d turned off.\n", i);
+ } else {
+ if (!(err = channel_add(i, p)))
+ pprintf(p, "Channel %d turned on.\n", i);
+ else {
+ if (err == 1)
+ pprintf(p, "Channel %d is already full.\n", i);
+ if (err == 2)
+ pprintf(p, "Maximum channel number exceeded.\n");
+ }
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_inchannel(int p, param_list param)
+{
+ int c1, c2;
+ int i, j, count = 0;
+
+ if (param[0].type == TYPE_NULL) { /* List everyone on every channel */
+ c1 = -1;
+ c2 = -1;
+ } else if (param[1].type == TYPE_NULL) { /* One parameter */
+ c1 = param[0].val.integer;
+ if (c1 < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ c2 = -1;
+ } else { /* Two parameters */
+ c1 = param[0].val.integer;
+ c2 = param[2].val.integer;
+ if ((c1 < 0) || (c2 < 0)) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Two parameter inchannel is not implemented.\n");
+ return COM_OK;
+ }
+ if ((c1 >= MAX_CHANNELS) || (c2 >= MAX_CHANNELS)) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (numOn[i] && ((c1 < 0) || (i == c1))) {
+ pprintf(p, "Channel %d:", i);
+ for (j = 0; j < numOn[i]; j++) {
+ pprintf(p, " %s", parray[channels[i][j]].name);
+ }
+ count++;
+ pprintf(p, "\n");
+ }
+ }
+ if (!count) {
+ if (c1 < 0)
+ pprintf(p, "No channels in use.\n");
+ else
+ pprintf(p, "Channel not in use.\n");
+ }
+ return COM_OK;
+}
+
+
+PUBLIC int create_new_match(int white_player, int black_player,
+ int wt, int winc, int bt, int binc,
+ int rated, char *category, char *board,
+ int white)
+{
+ int g = game_new(), p;
+ char outStr[1024];
+ int reverse = 0;
+
+ if (g < 0)
+ return COM_FAILED;
+ if (white == 0) {
+ reverse = 1;
+ } else if (white == -1) {
+ if (!bt) {
+ if (parray[white_player].lastColor == parray[black_player].lastColor) {
+ if ((parray[white_player].num_white - parray[white_player].num_black) >
+ (parray[black_player].num_white - parray[black_player].num_black))
+ reverse = 1;
+ } else if (parray[white_player].lastColor == WHITE)
+ reverse = 1;
+ } else
+ reverse = 1; /* Challenger is always white in unbalanced
+ match */
+ }
+ if (reverse) {
+ int tmp = white_player;
+ white_player = black_player;
+ black_player = tmp;
+ }
+ player_remove_request(white_player, black_player, PEND_MATCH);
+ player_remove_request(black_player, white_player, PEND_MATCH);
+ player_remove_request(white_player, black_player, PEND_SIMUL);
+ player_remove_request(black_player, white_player, PEND_SIMUL);
+ player_decline_offers(white_player, -1, PEND_MATCH);
+ player_withdraw_offers(white_player, -1, PEND_MATCH);
+ player_decline_offers(black_player, -1, PEND_MATCH);
+ player_withdraw_offers(black_player, -1, PEND_MATCH);
+ player_withdraw_offers(white_player, -1, PEND_SIMUL);
+ player_withdraw_offers(black_player, -1, PEND_SIMUL);
+
+ wt = wt * 60; /* To Seconds */
+ bt = bt * 60;
+ garray[g].white = white_player;
+ garray[g].black = black_player;
+ strcpy(garray[g].white_name, parray[white_player].name);
+ strcpy(garray[g].black_name, parray[black_player].name);
+ garray[g].status = GAME_ACTIVE;
+ garray[g].type = game_isblitz(wt / 60, winc, bt / 60, binc, category, board);
+ if ((garray[g].type == TYPE_UNTIMED) || (garray[g].type == TYPE_NONSTANDARD))
+ garray[g].rated = 0;
+ else
+ garray[g].rated = rated;
+ garray[g].private = parray[white_player].private ||
+ parray[black_player].private;
+ garray[g].white = white_player;
+ if (garray[g].type == TYPE_BLITZ) {
+ garray[g].white_rating = parray[white_player].b_stats.rating;
+ garray[g].black_rating = parray[black_player].b_stats.rating;
+ } else if (garray[g].type == TYPE_WILD) {
+ garray[g].white_rating = parray[white_player].w_stats.rating;
+ garray[g].black_rating = parray[black_player].w_stats.rating;
+ } else {
+ garray[g].white_rating = parray[white_player].s_stats.rating;
+ garray[g].black_rating = parray[black_player].s_stats.rating;
+ }
+ if (board_init(&garray[g].game_state, category, board)) {
+ pprintf(white_player, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ pprintf(black_player, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD %s %s. Game Aborted.\n",
+ category, board);
+ }
+ garray[g].game_state.gameNum = g;
+ garray[g].wTime = wt * 10;
+ garray[g].wInitTime = wt * 10;
+ garray[g].wIncrement = winc * 10;
+ if (bt == 0) {
+ garray[g].bTime = wt * 10;
+ } else {
+ garray[g].bTime = bt * 10;
+ }
+ garray[g].bInitTime = bt * 10;
+ garray[g].bIncrement = binc * 10;
+ if (garray[g].game_state.onMove == BLACK) { /* Start with black */
+ garray[g].numHalfMoves = 1;
+ garray[g].moveListSize = 1;
+ garray[g].moveList = (move_t *) rmalloc(sizeof(move_t));
+ garray[g].moveList[0].fromFile = -1;
+ garray[g].moveList[0].fromRank = -1;
+ garray[g].moveList[0].toFile = -1;
+ garray[g].moveList[0].toRank = -1;
+ garray[g].moveList[0].color = WHITE;
+ strcpy(garray[g].moveList[0].moveString, "NONE");
+ strcpy(garray[g].moveList[0].algString, "NONE");
+ } else {
+ garray[g].numHalfMoves = 0;
+ garray[g].moveListSize = 0;
+ garray[g].moveList = NULL;
+ }
+ garray[g].timeOfStart = tenth_secs();
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ garray[g].clockStopped = 0;
+ sprintf(outStr, "\n{Game %d (%s vs. %s) Creating %s %s match.}\n",
+ g + 1, parray[white_player].name,
+ parray[black_player].name,
+ rstr[garray[g].rated],
+ bstr[garray[g].type]);
+ pprintf(white_player, "%s", outStr);
+ pprintf(black_player, "%s", outStr);
+
+ for (p = 0; p < p_num; p++) {
+ if ((p == white_player) || (p == black_player))
+ continue;
+ if (parray[p].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p].i_game)
+ continue;
+ pprintf_prompt(p, "%s", outStr);
+ }
+ parray[white_player].game = g;
+ parray[white_player].opponent = black_player;
+ parray[white_player].side = WHITE;
+ parray[white_player].promote = QUEEN;
+ parray[black_player].game = g;
+ parray[black_player].opponent = white_player;
+ parray[black_player].side = BLACK;
+ parray[black_player].promote = QUEEN;
+ send_boards(g);
+
+ strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g));
+
+ return COM_OK;
+}
+
+PRIVATE int accept_match(int p, int p1)
+{
+ int g, adjourned, foo;
+ int wt, winc, bt, binc, rated, white;
+ char *category, *board;
+ pending *pend;
+ char tmp[100];
+
+ unobserveAll(p); /* stop observing when match starts */
+ unobserveAll(p1);
+
+ pend = &parray[p].p_from_list[player_find_pendfrom(p, p1, PEND_MATCH)];
+ wt = pend->param1;
+ winc = pend->param2;
+ bt = pend->param3;
+ binc = pend->param4;
+ rated = pend->param5;
+ category = pend->char1;
+ board = pend->char2;
+ white = (pend->param6 == -1) ? -1 : 1 - pend->param6;
+
+ pprintf(p, "You accept the challenge of %s.\n", parray[p1].name);
+ pprintf(p1, "\n%s accepts your challenge.\n", parray[p].name);
+ player_remove_request(p, p1, -1);
+ player_remove_request(p1, p, -1);
+
+ while ((foo = player_find_pendto(p, -1, -1)) != -1) {
+ foo = parray[p].p_to_list[foo].whoto;
+ pprintf_prompt(foo, "\n%s, who was challenging you, has joined a match with %s.\n", parray[p].name, parray[p1].name);
+ pprintf(p, "Challenge to %s withdrawn.\n", parray[foo].name);
+ player_remove_request(p, foo, -1);
+ }
+
+ while ((foo = player_find_pendto(p1, -1, -1)) != -1) {
+ foo = parray[p1].p_to_list[foo].whoto;
+ pprintf_prompt(foo, "\n%s, who was challenging you, has joined a match with %s.\n", parray[p1].name, parray[p].name);
+ pprintf(p1, "Challenge to %s withdrawn.\n", parray[foo].name);
+ player_remove_request(p1, foo, -1);
+ }
+
+ while ((foo = player_find_pendfrom(p, -1, -1)) != -1) {
+ foo = parray[p].p_from_list[foo].whofrom;
+ pprintf_prompt(foo, "\n%s, whom you were challenging, has joined a match with %s.\n", parray[p].name, parray[p1].name);
+ pprintf(p, "Challenge from %s removed.\n", parray[foo].name);
+ player_remove_request(foo, p, -1);
+ }
+
+ while ((foo = player_find_pendfrom(p1, -1, -1)) != -1) {
+ foo = parray[p1].p_from_list[foo].whofrom;
+ pprintf_prompt(foo, "\n%s, whom you were challenging, has joined a match with %s.\n", parray[p1].name, parray[p].name);
+ pprintf(p1, "Challenge from %s removed.\n", parray[foo].name);
+ player_remove_request(foo, p1, -1);
+ }
+
+ g = game_new();
+ adjourned = 0;
+ if (game_read(g, p, p1) >= 0)
+ adjourned = 1;
+ else if (game_read(g, p1, p) >= 0) {
+ int swap;
+ adjourned = 1;
+ swap = p;
+ p = p1;
+ p1 = swap;
+ }
+ if (!adjourned) { /* no adjourned game, so begin a new game */
+ game_remove(g);
+
+ if (create_new_match(p, p1, wt, winc, bt, binc, rated, category, board, white) != COM_OK) {
+ sprintf(tmp, "There was a problem creating the new match.\n");
+ pprintf(p, tmp);
+ pprintf_prompt(p1, tmp);
+ }
+ } else { /* resume adjourned game */
+ game_delete(p, p1);
+
+ sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s match.}\n", g + 1, parray[p].name, parray[p1].name, rstr[garray[g].rated], bstr[garray[g].type]);
+ pprintf(p, tmp);
+ pprintf(p1, tmp);
+
+ garray[g].white = p;
+ garray[g].black = p1;
+ garray[g].status = GAME_ACTIVE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ parray[p].game = g;
+ parray[p].opponent = p1;
+ parray[p].side = WHITE;
+ parray[p1].game = g;
+ parray[p1].opponent = p;
+ parray[p1].side = BLACK;
+ send_boards(g);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_match(int p, param_list param)
+{
+ int adjourned; /* adjourned game? */
+ int g; /* more adjourned game junk */
+ int p1;
+ int pendfrom, pendto;
+ int ppend, p1pend;
+ int wt = -1; /* white start time */
+ int winc = -1; /* white increment */
+ int bt = -1; /* black start time */
+ int binc = -1; /* black increment */
+ int rated = -1; /* 1 = rated, 0 = unrated */
+ int white = -1; /* 1 = want white, 0 = want black */
+ char category[100], board[100], parsebuf[100];
+ char strFormula[MAX_STRING_LENGTH];
+ char *val;
+ int type;
+ int confused = 0;
+ char *colorstr[] = {"", "[black] ", "[white] "};
+ char *adjustr[] = {"", " (adjourned)"};
+
+ if ((parray[p].game >= 0) && (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You can't challenge while you are examining a game.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >= 0) {
+ pprintf(p, "You can't challenge while you are playing a game.\n");
+ return COM_OK;
+ }
+ stolower(param[0].val.word);
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+
+ if (p1 == p) { /* Allowing to match yourself to enter analysis mode */
+ pprintf(p, "Starting a game in examine mode.\n");
+ {
+ int g = game_new();
+
+ unobserveAll(p);
+
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+
+ garray[g].wInitTime = garray[g].wIncrement = 0;
+ garray[g].bInitTime = garray[g].bIncrement = 0;
+ garray[g].timeOfStart = tenth_secs();
+ garray[g].wTime = garray[g].bTime = 0;
+ garray[g].rated = 0;
+ garray[g].clockStopped = 0;
+ garray[g].type = TYPE_UNTIMED;
+ garray[g].white = garray[g].black = p;
+ garray[g].status = GAME_EXAMINE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+
+ parray[p].side = WHITE; /* oh well... */
+ parray[p].game = g;
+
+ category[0]='\0'; board[0]='\0';
+ if (board_init(&garray[g].game_state, category, board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD %s %s. Game Aborted.\n",
+ category, board);
+ }
+ garray[g].game_state.gameNum = g;
+ strcpy(garray[g].white_name, parray[p].name);
+ strcpy(garray[g].black_name, parray[p].name);
+ garray[g].white_rating = garray[g].black_rating = parray[p].s_stats.rating;
+
+ send_boards(g);
+
+ strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g));
+
+ }
+ return COM_OK;
+ }
+
+ if (parray[p].open == 0) {
+ parray[p].open = 1;
+ pprintf(p, "Setting you open for matches.\n");
+ }
+ if (player_censored(p1, p)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (player_censored(p, p1)) {
+ pprintf(p, "You are censoring \"%s\".\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (!parray[p1].open) {
+ pprintf(p, "Player \"%s\" is not open to match requests.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (parray[p1].game >= 0) {
+ pprintf(p, "Player \"%s\" is involved in another game.\n", parray[p1].name);
+ return COM_OK;
+ }
+/* look for an adjourned game between p and p1 */
+ g = game_new();
+ adjourned = ((game_read(g, p, p1) < 0) && (game_read(g, p1, p) < 0)) ? 0 : 1;
+ if (adjourned) {
+ type = garray[g].type;
+ wt = garray[g].wInitTime / 600;
+ bt = garray[g].bInitTime / 600;
+ winc = garray[g].wIncrement / 10;
+ binc = garray[g].bIncrement / 10;
+ rated = garray[g].rated;
+ }
+ game_remove(g);
+
+ pendto = player_find_pendto(p, p1, PEND_MATCH);
+ pendfrom = player_find_pendfrom(p, p1, PEND_MATCH);
+ category[0] = '\0';
+ board[0] = '\0';
+
+ if (!adjourned) {
+ if (param[1].type != TYPE_NULL) {
+ int numba; /* temp for atoi() */
+
+ val = param[1].val.string;
+ while (!confused && (sscanf(val, " %99s", parsebuf) == 1)) {
+ val = eatword(eatwhite(val));
+ if ((category[0] != '\0') && (board[0] == '\0'))
+ strcpy(board, parsebuf);
+ else if (isdigit(*parsebuf)) {
+ if ((numba = atoi(parsebuf)) < 0) {
+ pprintf(p, "You can't specify negative time controls.\n");
+ return COM_OK;
+ } else if (wt == -1) {
+ wt = numba;
+ } else if (winc == -1) {
+ winc = numba;
+ } else if (bt == -1) {
+ bt = numba;
+ } else if (binc == -1) {
+ binc = numba;
+ } else {
+ confused = 1;
+ }
+ } else if (strstr("rated", parsebuf) != NULL) {
+ if (rated == -1)
+ rated = 1;
+ else
+ confused = 1;
+ } else if (strstr("unrated", parsebuf) != NULL) {
+ if (rated == -1)
+ rated = 0;
+ else
+ confused = 1;
+ } else if (strstr("white", parsebuf) != NULL) {
+ if (white == -1)
+ white = 1;
+ else
+ confused = 1;
+ } else if (strstr("black", parsebuf) != NULL) {
+ if (white == -1)
+ white = 0;
+ else
+ confused = 1;
+ } else if (category[0] == '\0')
+ strcpy(category, parsebuf);
+ else
+ confused = 1;
+ }
+ if (confused) {
+ pprintf(p, "Can't interpret %s in match command.\n", parsebuf);
+ return COM_OK;
+ }
+ }
+ rated = ((rated == -1) ? parray[p].rated : rated) && parray[p1].registered && parray[p].registered;
+ if (winc == -1)
+ winc = (wt == -1) ? parray[p].d_inc : 0; /* match 5 == match 5 0 */
+ if (wt == -1)
+ wt = parray[p].d_time;
+ if (bt == -1)
+ bt = 0;
+ if (binc == -1)
+ binc = winc;
+
+ if (category[0] && !board[0]) {
+ pprintf(p, "You must specify a board and a category.\n");
+ return COM_OK;
+ }
+ if (category[0]) {
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%s/%s", board_dir, category, board);
+ if (!file_exists(fname)) {
+ pprintf(p, "No such category/board: %s/%s\n", category, board);
+ return COM_OK;
+ }
+ }
+ if ((pendfrom < 0) && (parray[p1].ropen == 0) && (rated != parray[p1].rated)) {
+ pprintf(p, "%s only wants to play %s games.\n", parray[p1].name,
+ rstr[parray[p1].rated]);
+ pprintf(p1, "Ignoring %srated match request from %s.\n",
+ (parray[p1].rated ? "un" : ""), parray[p].name);
+ return COM_OK;
+ }
+ type = game_isblitz(wt, winc, bt, binc, category, board);
+ if (rated && (type == TYPE_STAND || type == TYPE_BLITZ || type == TYPE_WILD)) {
+ if (parray[p].network_player == parray[p1].network_player) {
+ rated = 1;
+ } else {
+ pprintf(p, "Network vs. local player forced to not rated\n");
+ rated = 0;
+ }
+ }
+ if (rated && (type == TYPE_NONSTANDARD)) {
+ pprintf(p, "Game is non-standard - reverting to unrated\n");
+ rated = 0;
+ }
+ if (rated && (type == TYPE_UNTIMED)) {
+ pprintf(p, "Game is untimed - reverting to unrated\n");
+ rated = 0;
+ }
+ /* Now check formula. */
+ if ((pendfrom < 0 || param[1].type != TYPE_NULL) &&
+ !GameMatchesFormula(p, p1, wt, winc, bt, binc, rated, type, strFormula)) {
+ pprintf(p, "Match request does not fit formula for %s:\n",
+ parray[p1].name);
+ pprintf(p, "%s's formula: %s\n", parray[p1].name, parray[p1].formula);
+ pprintf(p, "Evaluated: %s\n", strFormula);
+ pprintf_prompt(p1, "Ignoring (formula): %s (%d) %s (%d) %s.\n",
+ parray[p].name,
+ GetRating(&parray[p], type),
+ parray[p1].name,
+ GetRating(&parray[p1], type),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ return COM_OK;
+ }
+ /* Ok match offer will be made */
+
+ } /* adjourned games shouldn't have to worry
+ about that junk? */
+ if (pendto >= 0) {
+ pprintf(p, "Updating offer already made to \"%s\".\n", parray[p1].name);
+ }
+ if (pendfrom >= 0) {
+ if (pendto >= 0) {
+ pprintf(p, "Internal error\n");
+ fprintf(stderr, "FICS: This shouldn't happen. You can't have a match pending from and to the same person.\n");
+ return COM_OK;
+ }
+ if (adjourned || ((wt == parray[p].p_from_list[pendfrom].param1) &&
+ (winc == parray[p].p_from_list[pendfrom].param2) &&
+ (bt == parray[p].p_from_list[pendfrom].param3) &&
+ (binc == parray[p].p_from_list[pendfrom].param4) &&
+ (rated == parray[p].p_from_list[pendfrom].param5) &&
+ ((white == -1) || (white + parray[p].p_from_list[pendfrom].param6 == 1)) &&
+ (!strcmp(category, parray[p].p_from_list[pendfrom].char1)) &&
+ (!strcmp(board, parray[p].p_from_list[pendfrom].char2)))) {
+ /* Identical match, should accept! */
+ accept_match(p, p1);
+ return COM_OK;
+ } else {
+ player_remove_pendfrom(p, p1, PEND_MATCH);
+ player_remove_pendto(p1, p, PEND_MATCH);
+ }
+ }
+ if (pendto < 0) {
+ ppend = player_new_pendto(p);
+ if (ppend < 0) {
+ pprintf(p, "Sorry you can't have any more pending matches.\n");
+ return COM_OK;
+ }
+ p1pend = player_new_pendfrom(p1);
+ if (p1pend < 0) {
+ pprintf(p, "Sorry %s can't have any more pending matches.\n", parray[p1].name);
+ parray[p].num_to = parray[p].num_to - 1;
+ return COM_OK;
+ }
+ } else {
+ ppend = pendto;
+ p1pend = player_find_pendfrom(p1, p, PEND_MATCH);
+ }
+ parray[p].p_to_list[ppend].param1 = wt;
+ parray[p].p_to_list[ppend].param2 = winc;
+ parray[p].p_to_list[ppend].param3 = bt;
+ parray[p].p_to_list[ppend].param4 = binc;
+ parray[p].p_to_list[ppend].param5 = rated;
+ parray[p].p_to_list[ppend].param6 = white;
+ strcpy(parray[p].p_to_list[ppend].char1, category);
+ strcpy(parray[p].p_to_list[ppend].char2, board);
+ parray[p].p_to_list[ppend].type = PEND_MATCH;
+ parray[p].p_to_list[ppend].whoto = p1;
+ parray[p].p_to_list[ppend].whofrom = p;
+
+ parray[p1].p_from_list[p1pend].param1 = wt;
+ parray[p1].p_from_list[p1pend].param2 = winc;
+ parray[p1].p_from_list[p1pend].param3 = bt;
+ parray[p1].p_from_list[p1pend].param4 = binc;
+ parray[p1].p_from_list[p1pend].param5 = rated;
+ parray[p1].p_from_list[p1pend].param6 = white;
+ strcpy(parray[p1].p_from_list[p1pend].char1, category);
+ strcpy(parray[p1].p_from_list[p1pend].char2, board);
+ parray[p1].p_from_list[p1pend].type = PEND_MATCH;
+ parray[p1].p_from_list[p1pend].whoto = p1;
+ parray[p1].p_from_list[p1pend].whofrom = p;
+
+ if (pendfrom >= 0) {
+ pprintf(p, "Declining offer from %s and offering new match parameters.\n", parray[p1].name);
+ pprintf(p1, "\n%s declines your match offer a match with these parameters:", parray[p].name);
+ }
+ if (pendto >= 0) {
+ pprintf(p, "Updating match request to: ");
+ pprintf(p1, "\n%s updates the match request.\n", parray[p].name);
+ } else {
+ pprintf(p, "Issuing: ");
+ pprintf(p1, "\n", parray[p].name);
+ }
+
+ pprintf(p, "%s (%s) %s", parray[p].name,
+ ratstrii(GetRating(&parray[p], type), parray[p].registered),
+ colorstr[white + 1]);
+ pprintf_highlight(p, "%s", parray[p1].name);
+ pprintf(p, " (%s) %s%s.\n",
+ ratstrii(GetRating(&parray[p1], type), parray[p1].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board),
+ adjustr[adjourned]);
+ pprintf(p1, "Challenge: ");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf(p1, " (%s) %s", ratstrii(GetRating(&parray[p], type), parray[p].registered), colorstr[white + 1]);
+ pprintf(p1, "%s (%s) %s%s.\n", parray[p1].name,
+ ratstrii(GetRating(&parray[p1], type), parray[p1].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board),
+ adjustr[adjourned]);
+ if (parray[p1].bell == 1)
+ pprintf_noformat(p1, "\007");
+ if (in_list("computer", parray[p].name)) {
+ pprintf(p1, "--** %s is a ", parray[p].name);
+ pprintf_highlight(p1, "computer");
+ pprintf(p1, " **--\n");
+ }
+ if (in_list("computer", parray[p1].name)) {
+ pprintf(p, "--** %s is a ", parray[p1].name);
+ pprintf_highlight(p, "computer");
+ pprintf(p, " **--\n");
+ }
+ if (in_list("abuser", parray[p].name)) {
+ pprintf(p1, "--** %s is in the ", parray[p].name);
+ pprintf_highlight(p1, "abuser");
+ pprintf(p1, " list **--\n");
+ }
+ if (in_list("abuser", parray[p1].name)) {
+ pprintf(p, "--** %s is in the ", parray[p1].name);
+ pprintf_highlight(p, "abuser");
+ pprintf(p, " list **--\n");
+ }
+ if (rated) {
+ int win, draw, loss;
+ double newsterr;
+
+ rating_sterr_delta(p1, p, type, time(0), RESULT_WIN, &win, &newsterr);
+ rating_sterr_delta(p1, p, type, time(0), RESULT_DRAW, &draw, &newsterr);
+ rating_sterr_delta(p1, p, type, time(0), RESULT_LOSS, &loss, &newsterr);
+ pprintf(p1, "Your %s rating will change: Win: %s%d, Draw: %s%d, Loss: %s%d\n",
+ bstr[type],
+ (win >= 0) ? "+" : "", win,
+ (draw >= 0) ? "+" : "", draw,
+ (loss >= 0) ? "+" : "", loss);
+ pprintf(p1, "Your new RD will be %5.1f\n", newsterr);
+
+ rating_sterr_delta(p, p1, type, time(0), RESULT_WIN, &win, &newsterr);
+ rating_sterr_delta(p, p1, type, time(0), RESULT_DRAW, &draw, &newsterr);
+ rating_sterr_delta(p, p1, type, time(0), RESULT_LOSS, &loss, &newsterr);
+ pprintf(p, "Your %s rating will change: Win: %s%d, Draw: %s%d, Loss: %s%d\n",
+ bstr[type],
+ (win >= 0) ? "+" : "", win,
+ (draw >= 0) ? "+" : "", draw,
+ (loss >= 0) ? "+" : "", loss);
+ pprintf(p, "Your new RD will be %5.1f\n", newsterr);
+ }
+ pprintf_prompt(p1, "You can \"accept\" or \"decline\", or propose different parameters.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_accept(int p, param_list param)
+{
+ int acceptNum = -1;
+ int type = -1;
+ int p1;
+
+ if (parray[p].num_from == 0) {
+ pprintf(p, "You have no offers to accept.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].num_from != 1) {
+ pprintf(p, "You have more than one offer to accept.\nUse \"pending\" to see them and \"accept n\" to choose which one.\n");
+ return COM_OK;
+ }
+ acceptNum = 0;
+ } else if (param[0].type == TYPE_INT) {
+ if ((param[0].val.integer < 1) || (param[0].val.integer > parray[p].num_from)) {
+ pprintf(p, "Out of range. Use \"pending\" to see the list of offers.\n");
+ return COM_OK;
+ }
+ acceptNum = param[0].val.integer - 1;
+ } else if (param[0].type == TYPE_WORD) {
+ if (!strcmp(param[0].val.word, "draw")) {
+ type = PEND_DRAW;
+ } else if (!strcmp(param[0].val.word, "pause")) {
+ type = PEND_PAUSE;
+ } else if (!strcmp(param[0].val.word, "adjourn")) {
+ type = PEND_ADJOURN;
+ } else if (!strcmp(param[0].val.word, "abort")) {
+ type = PEND_ABORT;
+ } else if (!strcmp(param[0].val.word, "takeback")) {
+ type = PEND_TAKEBACK;
+ }
+ if (!strcmp(param[0].val.word, "simmatch")) {
+ type = PEND_SIMUL;
+ }
+ if (!strcmp(param[0].val.word, "switch")) {
+ type = PEND_SWITCH;
+ }
+ if (!strcmp(param[0].val.word, "all")) {
+ while (parray[p].num_from != 0) {
+ pcommand(p, "accept 1");
+ }
+ return COM_OK;
+ }
+ if (type > 0) {
+ if ((acceptNum = player_find_pendfrom(p, -1, type)) < 0) {
+ pprintf(p, "There are no pending %s offers.\n", param[0].val.word);
+ return COM_OK;
+ }
+ } else { /* Word must be a name */
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if ((acceptNum = player_find_pendfrom(p, p1, -1)) < 0) {
+ pprintf(p, "There are no pending offers from %s.\n", parray[p1].name);
+ return COM_OK;
+ }
+ }
+ }
+ switch (parray[p].p_from_list[acceptNum].type) {
+ case PEND_MATCH:
+ accept_match(p, parray[p].p_from_list[acceptNum].whofrom);
+ return (COM_OK);
+ break;
+ case PEND_DRAW:
+ pcommand(p, "draw");
+ break;
+ case PEND_PAUSE:
+ pcommand(p, "pause");
+ break;
+ case PEND_ABORT:
+ pcommand(p, "abort");
+ break;
+ case PEND_TAKEBACK:
+ pcommand(p, "takeback %d", parray[p].p_from_list[acceptNum].param1);
+ break;
+ case PEND_SIMUL:
+ pcommand(p, "simmatch %s",
+ parray[parray[p].p_from_list[acceptNum].whofrom].name);
+ break;
+ case PEND_SWITCH:
+ pcommand(p, "switch");
+ break;
+ case PEND_ADJOURN:
+ pcommand(p, "adjourn");
+ break;
+ }
+ return COM_OK_NOPROMPT;
+}
+
+
+
+PUBLIC int com_decline(int p, param_list param)
+{
+ int declineNum;
+ int p1 = -1, type = -1;
+ int count;
+
+ if (parray[p].num_from == 0) {
+ pprintf(p, "You have no pending offers from other players.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].num_from == 1) {
+ p1 = parray[p].p_from_list[0].whofrom;
+ type = parray[p].p_from_list[0].type;
+ } else {
+ pprintf(p, "You have more than one pending offer. Please specify which one\nyou wish to decline.\n'Pending' will give you the list.\n");
+ return COM_OK;
+ }
+ } else {
+ if (param[0].type == TYPE_WORD) {
+ /* Draw adjourn match takeback abort or <name> */
+ if (!strcmp(param[0].val.word, "match")) {
+ type = PEND_MATCH;
+ } else if (!strcmp(param[0].val.word, "draw")) {
+ type = PEND_DRAW;
+ } else if (!strcmp(param[0].val.word, "pause")) {
+ type = PEND_PAUSE;
+ } else if (!strcmp(param[0].val.word, "abort")) {
+ type = PEND_ABORT;
+ } else if (!strcmp(param[0].val.word, "takeback")) {
+ type = PEND_TAKEBACK;
+ } else if (!strcmp(param[0].val.word, "adjourn")) {
+ type = PEND_ADJOURN;
+ } else if (!strcmp(param[0].val.word, "switch")) {
+ type = PEND_SWITCH;
+ } else if (!strcmp(param[0].val.word, "simul")) {
+ type = PEND_SIMUL;
+ } else if (!strcmp(param[0].val.word, "all")) {
+ } else {
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ } else { /* Must be an integer */
+ declineNum = param[0].val.integer - 1;
+ if (declineNum >= parray[p].num_from || declineNum < 0) {
+ pprintf(p, "Invalid offer number. Must be between 1 and %d.\n", parray[p].num_from);
+ return COM_OK;
+ }
+ p1 = parray[p].p_from_list[declineNum].whofrom;
+ type = parray[p].p_from_list[declineNum].type;
+ }
+ }
+ count = player_decline_offers(p, p1, type);
+ if (count != 1)
+ pprintf(p, "%d offers declined\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_withdraw(int p, param_list param)
+{
+ int withdrawNum;
+ int p1 = -1, type = -1;
+ int count;
+
+ if (parray[p].num_to == 0) {
+ pprintf(p, "You have no pending offers to other players.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].num_to == 1) {
+ p1 = parray[p].p_to_list[0].whoto;
+ type = parray[p].p_to_list[0].type;
+ } else {
+ pprintf(p, "You have more than one pending offer. Please specify which one\nyou wish to withdraw.\n'Pending' will give you the list.\n");
+ return COM_OK;
+ }
+ } else {
+ if (param[0].type == TYPE_WORD) {
+ /* Draw adjourn match takeback abort or <name> */
+ if (!strcmp(param[0].val.word, "match")) {
+ type = PEND_MATCH;
+ } else if (!strcmp(param[0].val.word, "draw")) {
+ type = PEND_DRAW;
+ } else if (!strcmp(param[0].val.word, "pause")) {
+ type = PEND_PAUSE;
+ } else if (!strcmp(param[0].val.word, "abort")) {
+ type = PEND_ABORT;
+ } else if (!strcmp(param[0].val.word, "takeback")) {
+ type = PEND_TAKEBACK;
+ } else if (!strcmp(param[0].val.word, "adjourn")) {
+ type = PEND_ADJOURN;
+ } else if (!strcmp(param[0].val.word, "switch")) {
+ type = PEND_SWITCH;
+ } else if (!strcmp(param[0].val.word, "simul")) {
+ type = PEND_SIMUL;
+ } else if (!strcmp(param[0].val.word, "all")) {
+ } else {
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ } else { /* Must be an integer */
+ withdrawNum = param[0].val.integer - 1;
+ if (withdrawNum >= parray[p].num_to || withdrawNum < 0) {
+ pprintf(p, "Invalid offer number. Must be between 1 and %d.\n", parray[p].num_to);
+ return COM_OK;
+ }
+ p1 = parray[p].p_to_list[withdrawNum].whoto;
+ type = parray[p].p_to_list[withdrawNum].type;
+ }
+ }
+ count = player_withdraw_offers(p, p1, type);
+ if (count != 1)
+ pprintf(p, "%d offers withdrawn\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_pending(int p, param_list param)
+{
+ int i;
+
+ if (!parray[p].num_to) {
+ pprintf(p, "There are no offers pending TO other players.\n");
+ } else {
+ pprintf(p, "Offers TO other players:\n");
+ for (i = 0; i < parray[p].num_to; i++) {
+ pprintf(p, " ");
+ player_pend_print(p, &parray[p].p_to_list[i]);
+ }
+ }
+ if (!parray[p].num_from) {
+ pprintf(p, "\nThere are no offers pending FROM other players.\n");
+ } else {
+ pprintf(p, "\nOffers FROM other players:\n");
+ for (i = 0; i < parray[p].num_from; i++) {
+ pprintf(p, " %d: ", i + 1);
+ player_pend_print(p, &parray[p].p_from_list[i]);
+ }
+ pprintf(p, "\nIf you wish to accept any of these offers type 'accept n'\nor just 'accept' if there is only one offer.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_refresh(int p, param_list param)
+{
+ int g, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >= 0) {
+ send_board_to(parray[p].game, p);
+ } else { /* Do observing in here */
+ if (parray[p].num_observe) {
+ for (g = 0; g < parray[p].num_observe; g++) {
+ send_board_to(parray[p].observe_list[g], p);
+ }
+ } else {
+ pprintf(p, "You are neither playing nor observing a game.\n");
+ return COM_OK;
+ }
+ }
+ } else {
+ g = GameNumFromParam (p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ if ((g >= g_num) || ((garray[g].status != GAME_ACTIVE)
+ && (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "No such game.\n");
+ } else if (garray[g].private && parray[p].adminLevel==ADMIN_USER) {
+ pprintf (p, "Sorry, game %d is a private game.\n", g+1);
+ } else {
+ if (garray[g].private)
+ pprintf(p, "Refreshing PRIVATE game %d\n", g+1);
+ send_board_to(g, p);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_open(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set open")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_simopen(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set simopen")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_bell(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set bell")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_flip(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((retval = pcommand(p, "set flip")) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_highlight(int p, param_list param)
+{
+ pprintf(p, "Obsolete command. Please do set highlight <0-15>.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_style(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_INT);
+ if ((retval = pcommand(p, "set style %d", param[0].val.integer)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_promote(int p, param_list param)
+{
+ int retval;
+ ASSERT(param[0].type == TYPE_WORD);
+ if ((retval = pcommand(p, "set promote %s", param[0].val.word)) != COM_OK)
+ return retval;
+ else
+ return COM_OK_NOPROMPT;
+}
+
+PUBLIC int com_alias(int p, param_list param)
+{
+ int al;
+
+ if (param[0].type == TYPE_NULL) {
+ for (al = 0; al < parray[p].numAlias; al++) {
+ pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name,
+ parray[p].alias_list[al].alias);
+ }
+ return COM_OK;
+ }
+ al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias);
+ if (param[1].type == TYPE_NULL) {
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ pprintf(p, "%s -> %s\n", parray[p].alias_list[al].comm_name,
+ parray[p].alias_list[al].alias);
+ }
+ } else {
+ if (al < 0) {
+ if (parray[p].numAlias >= MAX_ALIASES - 1) {
+ pprintf(p, "You have your maximum of %d aliases.\n", MAX_ALIASES - 1);
+ } else {
+
+ if (!strcmp(param[0].val.string, "quit")) { /* making sure they
+ can't alias quit */
+ pprintf(p, "You can't alias this command.\n");
+ } else if (!strcmp(param[0].val.string, "unalias")) { /* making sure they
+ can't alias unalias
+ :) */
+ pprintf(p, "You can't alias this command.\n");
+ } else {
+ parray[p].alias_list[parray[p].numAlias].comm_name =
+ strdup(param[0].val.word);
+ parray[p].alias_list[parray[p].numAlias].alias =
+ strdup(param[1].val.string);
+ parray[p].numAlias++;
+ pprintf(p, "Alias set.\n");
+
+ }
+ }
+ } else {
+ rfree(parray[p].alias_list[al].alias);
+ parray[p].alias_list[al].alias = strdup(param[1].val.string);
+ pprintf(p, "Alias replaced.\n");
+ }
+ parray[p].alias_list[parray[p].numAlias].comm_name = NULL;
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unalias(int p, param_list param)
+{
+ int al;
+ int i;
+
+ ASSERT(param[0].type == TYPE_WORD);
+ al = alias_lookup(param[0].val.word, parray[p].alias_list, parray[p].numAlias);
+ if (al < 0) {
+ pprintf(p, "You have no alias named '%s'.\n", param[0].val.word);
+ } else {
+ rfree(parray[p].alias_list[al].comm_name);
+ rfree(parray[p].alias_list[al].alias);
+ for (i = al; i < parray[p].numAlias; i++) {
+ parray[p].alias_list[i].comm_name = parray[p].alias_list[i + 1].comm_name;
+ parray[p].alias_list[i].alias = parray[p].alias_list[i + 1].alias;
+ }
+ parray[p].numAlias--;
+ parray[p].alias_list[parray[p].numAlias].comm_name = NULL;
+ pprintf(p, "Alias removed.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_servers(int p, param_list param)
+{
+/*
+ int i;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (numServers == 0) {
+ */ pprintf(p, "There are no other servers known to this server.\n");
+ return COM_OK;
+}
+ /* pprintf(p, "There are %d known servers.\n", numServers); pprintf(p, "(Not
+ all of these may be active)\n"); pprintf(p, "%-30s%-7s\n", "HOST",
+ "PORT"); for (i = 0; i < numServers; i++) pprintf(p, "%-30s%-7d\n",
+ serverNames[i], serverPorts[i]); return COM_OK; } */
+PUBLIC int com_sendmessage(int p, param_list param)
+{
+ int p1, connected = 1;
+
+ if (!parray[p].registered) {
+ pprintf(p, "You are not registered and cannot send messages.\n");
+ return COM_OK;
+ }
+ if ((param[0].type == TYPE_NULL) || (param[1].type == TYPE_NULL)) {
+ pprintf(p, "No message sent.\n");
+ return COM_OK;
+ }
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ if ((player_censored(p1, p)) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (player_add_message(p1, p, param[1].val.string)) {
+ pprintf(p, "Couldn't send message to %s. Message buffer full.\n",
+ parray[p1].name);
+ } else {
+ if (connected)
+ pprintf_prompt(p1, "\n%s just sent you a message.\n", parray[p].name);
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+
+PUBLIC int com_messages(int p, param_list param)
+{
+ if (param[0].type != TYPE_NULL) {
+ if (param[1].type != TYPE_NULL)
+ return com_sendmessage(p, param);
+ else {
+ ShowMsgsBySender(p, param);
+ return COM_OK;
+ }
+ }
+ if (player_num_messages(p) <= 0) {
+ pprintf(p, "You have no messages.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Messages:\n");
+ player_show_messages(p);
+ return COM_OK;
+}
+
+PUBLIC int com_clearmessages(int p, param_list param)
+{
+ if (player_num_messages(p) <= 0) {
+ pprintf(p, "You have no messages.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ pprintf(p, "Messages cleared.\n");
+ player_clear_messages(p);
+ return COM_OK;
+ }
+ ClearMsgsBySender(p, param);
+ return COM_OK;
+}
+
+PUBLIC int com_help(int p, param_list param)
+{
+ int i;
+ static char nullify = '\0';
+ char *iwant, *filenames[1000]; /* enough for all helpfile names */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in command %s.\n", iwant);
+ return COM_OK;
+#if 0
+ } else {
+ char sublist[][8] = {"talk", "play", ""};
+
+ for (i=0; (sublist[i][0] != '\0') && strcmp(iwant, sublist[i]); i++);
+ if (sublist[i][0] != '\0') {
+ char searchdir[MAX_FILENAME_SIZE];
+ pprintf(p, "The following \"%s\" commands are available.\n\n",
+ sublist[i]);
+ sprintf(searchdir, "%s/../%s_help", comhelp_dir, sublist[i]);
+ i = search_directory(searchdir, NULL, filenames, 1000);
+ display_directory(p, filenames, i);
+ pprintf(p, "\nType \"help [command]\" for more specific help.\n");
+ return COM_OK;
+ }
+#endif
+ }
+ }
+
+ i = search_directory((*iwant) ? help_dir : comhelp_dir, iwant, filenames, 1000);
+ if (i == 0) {
+ pprintf(p, "No help available on \"%s\".\n", iwant);
+ } else if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, help_dir, *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Helpfile %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ if (*iwant)
+ pprintf(p, "Matches:");
+ display_directory(p, filenames, i);
+ pprintf(p, "[Type \"info\" for a list of FICS general information files.]\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_info(int p, param_list param)
+{
+ int n;
+ char *filenames[1000];
+
+ if ((n = search_directory(info_dir, NULL, filenames, 1000)) > 0)
+ display_directory(p, filenames, n);
+ return COM_OK;
+}
+
+PUBLIC int com_adhelp(int p, param_list param)
+{
+ int i;
+ static char nullify = '\0';
+ char *iwant, *filenames[1000]; /* enough for all helpfile names */
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ if (!safestring(iwant)) {
+ pprintf(p, "Illegal character in command %s.\n", iwant);
+ return COM_OK;
+ }
+ }
+
+ i = search_directory(adhelp_dir, iwant, filenames, 1000);
+ if (i == 0) {
+ pprintf(p, "No help available on \"%s\".\n", iwant);
+ } else if ((i == 1) || !strcmp(*filenames, iwant)) {
+ if (psend_file(p, adhelp_dir, *filenames)) {
+ /* we should never reach this unless the file was just deleted */
+ pprintf(p, "Helpfile %s could not be found! ", *filenames);
+ pprintf(p, "Please inform an admin of this. Thank you.\n");
+ }
+ } else {
+ if (*iwant)
+ pprintf(p, "Matches:\n");
+ display_directory(p, filenames, i);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_mailsource(int p, param_list param)
+{
+ static char nullify = '\0';
+ char *iwant, *buffer[1000];
+/* char command[MAX_FILENAME_SIZE]; */
+ char subj[81], fname[MAX_FILENAME_SIZE];
+ int count;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailsource command.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ iwant = &nullify;
+ } else {
+ iwant = param[0].val.word;
+ }
+
+ count = search_directory(source_dir, iwant, buffer, 1000);
+ if (count == 0) {
+ pprintf(p, "Found no source file matching \"%s\".\n", iwant);
+ } else if ((count == 1) || !strcmp(iwant, *buffer)) {
+ /* sprintf(command, "%s -s\"FICS sourcefile: %s\" %s < %s/%s&", MAILPROGRAM,
+ *buffer, parray[p].emailAddress, source_dir, *buffer);
+ system(command); */
+
+ sprintf(subj, "FICS source file from server %s: %s", fics_hostname, *buffer);
+ sprintf(fname, "%s/%s",source_dir, *buffer);
+ mail_file_to_user (p, subj, fname);
+ pprintf(p, "Source file %s sent to %s\n", *buffer, parray[p].emailAddress);
+ } else {
+ pprintf(p, "Found %d source files matching that:\n", count);
+ if (*iwant)
+ display_directory(p, buffer, count);
+ else { /* this junk is to get *.c *.h */
+ multicol *m = multicol_start(count);
+ char *s;
+ int i;
+ for (i=0; i < count; i++) {
+ if (((s = buffer[i] + strlen(buffer[i]) - 2) >= buffer[i]) && (!strcmp(s, ".c") || !strcmp(s, ".h")))
+ multicol_store(m, buffer[i]);
+ }
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_mailhelp(int p, param_list param)
+{ /* Sparky */
+ /* FILE *fp; char tmp[MAX_LINE_SIZE]; char fname[MAX_FILENAME_SIZE]; */
+ char command[MAX_FILENAME_SIZE];
+ char subj[81], fname[MAX_FILENAME_SIZE];
+ char *iwant, *buffer[1000];
+
+ int count;
+ static char nullify = '\0';
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailhelp command.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL)
+ iwant = &nullify;
+ else
+ iwant = param[0].val.word;
+
+ count = search_directory(help_dir, iwant, buffer, 1000);
+ if (count == 0) {
+ pprintf(p, "Found no help file matching \"%s\".\n", iwant);
+ } else if (count == 1) {
+ /* sprintf(command, "%s -s \"FICS helpfile: %s\" %s < %s/%s&", MAILPROGRAM,
+ *buffer, parray[p].emailAddress, help_dir, *buffer);
+ system(command);a */
+
+
+ sprintf(subj, "FICS help file from server %s: %s", fics_hostname, *buffer);
+ sprintf(fname, "%s/%s",help_dir, *buffer);
+ mail_file_to_user (p, subj, fname);
+
+ pprintf(p, "Help file %s sent to %s\n", *buffer, parray[p].emailAddress);
+ } else {
+ pprintf(p, "Found %d helpfiles matching that:\n", count);
+ display_directory(p, buffer, count);
+ }
+
+ return COM_OK;
+}
+
+PUBLIC int com_mailmess(int p, param_list param)
+{
+ char command[MAX_FILENAME_SIZE];
+ char *buffer[1000];
+ char mdir[MAX_FILENAME_SIZE];
+ char filename[MAX_FILENAME_SIZE];
+ char subj[81], fname[MAX_FILENAME_SIZE];
+
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailmess command.\n");
+ return COM_OK;
+ }
+ sprintf(filename, "%s.messages", parray[p].login);
+ sprintf(mdir, "%s/player_data/%c/", stats_dir, parray[p].login[0]);
+
+ if (search_directory(mdir, filename, buffer, 1000)) {
+/* Sprintf(command, "%s -s \"Your FICS messages\" %s < %s%s&", MAILPROGRAM,
+ parray[p].emailAddress, mdir, filename);
+ system(command); */
+
+ sprintf(subj, "Your FICS messages from server %s", fics_hostname);
+ sprintf(fname, "%s/%s", mdir, filename);
+ mail_file_to_user (p, subj, fname);
+
+
+
+ pprintf(p, "Messages sent to %s\n", parray[p].emailAddress);
+ } else {
+ pprintf(p, "You have no messages.\n");
+ }
+ return COM_OK;
+
+}
+
+PUBLIC int com_handles(int p, param_list param)
+{
+ char *buffer[1000];
+ char pdir[MAX_FILENAME_SIZE];
+ int count;
+
+ sprintf(pdir, "%s/%c", player_dir, param[0].val.word[0]);
+ count = search_directory(pdir, param[0].val.word, buffer, 1000);
+ pprintf(p, "Found %d names.\n", count);
+ if (count > 0)
+ display_directory(p, buffer, count);
+ return COM_OK;
+}
+
+PUBLIC int com_znotify(int p, param_list param)
+{
+ int p1, count = 0;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (player_notified(p, p1)) {
+ if (!count)
+ pprintf(p, "Present company on your notify list:\n ");
+ pprintf(p, " %s", parray[p1].name);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ else
+ pprintf(p, "No one from your notify list is logged on.\n");
+
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (player_notified(p1, p)) {
+ if (!count)
+ pprintf(p,
+ "The following players have you on their notify list:\n ");
+ pprintf(p, " %s", parray[p1].name);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ else
+ pprintf(p, "No one logged in has you on their notify list.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_qtell(int p, param_list param)
+{
+ int p1;
+ char tmp[MAX_STRING_LENGTH];
+ char dummy[2];
+ char buffer1[MAX_STRING_LENGTH]; /* no highlight and no bell */
+ char buffer2[MAX_STRING_LENGTH]; /* no highlight and bell */
+ char buffer3[MAX_STRING_LENGTH]; /* highlight and no bell */
+ char buffer4[MAX_STRING_LENGTH]; /* highlight and and bell */
+ int i, count;
+/* FILE *fp; */
+
+ if (!in_list("td", parray[p].name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ strcpy(buffer1, ":\0");
+ strcpy(buffer2, ":\0");
+ strcpy(buffer3, ":\0");
+ strcpy(buffer4, ":\0");
+
+ sprintf(tmp, "%s", param[1].val.string);
+ for (i = 0, count = 0; ((tmp[i] != '\0') && (count < 1029));) {
+ if ((tmp[i] == '\\') && (tmp[i + 1] == 'n')) {
+ strcat(buffer1, "\n:");
+ strcat(buffer2, "\n:");
+ strcat(buffer3, "\n:");
+ strcat(buffer4, "\n:");
+ count += 2;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'b')) {
+ strcat(buffer2, "\007");
+ strcat(buffer4, "\007");
+ count++;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'H')) {
+ strcat(buffer3, "\033[7m");
+ strcat(buffer4, "\033[7m");
+ count += 4;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'h')) {
+ strcat(buffer3, "\033[0m");
+ strcat(buffer4, "\033[0m");
+ count += 4;
+ i += 2;
+ } else {
+ dummy[0] = tmp[i];
+ dummy[1] = '\0';
+ strcat(buffer1, dummy);
+ strcat(buffer2, dummy);
+ strcat(buffer3, dummy);
+ strcat(buffer4, dummy);
+ count++;
+ i++;
+ }
+ }
+
+ if (param[0].type == TYPE_WORD) {
+/*
+ fp = fopen("/tmp/fics-log", "a");
+ fprintf(fp, "PLAYER \"%s\" - MESSAGE \"%s\"\n", param[0].val.word, param[1].val.string);
+ fclose(fp);
+*/
+ if ((p1 = player_find_bylogin(param[0].val.word)) < 0) {
+ pprintf(p, "*qtell %s 1*\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf_prompt(p1, "\n%s\n", (parray[p1].highlight && parray[p1].bell) ? buffer4 :
+ (parray[p1].highlight && !parray[p1].bell) ? buffer3 :
+ (!parray[p1].highlight && parray[p1].bell) ? buffer2 :
+ buffer1);
+ pprintf(p, "*qtell %s 0*\n", parray[p1].name);
+
+ } else {
+ int p1;
+ int i;
+ int ch = param[0].val.integer;
+
+/*
+ fp = fopen("/tmp/fics-log", "a");
+ fprintf(fp, "CHANNEL \"%d\" - MESSAGE \"%s\"\n", param[0].val.integer, param[1].val.string);
+ fclose(fp);
+*/
+
+ if (ch == 0) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ if (ch < 0) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ if (ch >= MAX_CHANNELS) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ for (i = 0; i < numOn[ch]; i++) {
+ p1 = channels[ch][i];
+ if (p1 == p)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ if ((parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN))
+ continue;
+ pprintf_prompt(p1, "\n%s\n", (parray[p1].highlight && parray[p1].bell) ? buffer4 :
+ (parray[p1].highlight && !parray[p1].bell) ? buffer3 :
+ (!parray[p1].highlight && parray[p1].bell) ? buffer2 :
+ buffer1);
+ }
+ pprintf(p, "*qtell %d 0*\n", param[0].val.integer);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_getpi(int p, param_list param)
+{
+ int p1;
+
+ if (!in_list("td", parray[p].name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ if (((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) {
+ /* Darkside suggested not to return anything */
+ return COM_OK;
+ }
+ if (!parray[p1].registered) {
+ pprintf(p, "*getpi %s -1 -1 -1*\n", parray[p1].name);
+ } else {
+ pprintf(p, "*getpi %s %d %d %d*\n", parray[p1].name,
+ parray[p1].w_stats.rating,
+ parray[p1].b_stats.rating,
+ parray[p1].s_stats.rating);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_getps(int p, param_list param)
+{
+ int p1;
+
+ if ((((p1 = player_find_bylogin(param[0].val.word)) < 0) || (parray[p1].registered == 0)) || (parray[p1].game < 0)) {
+ pprintf(p, "*status %s 1*\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf(p, "*status %s 0 %s*\n", parray[p1].name, parray[(parray[p1].opponent)].name);
+ return COM_OK;
+}
+PUBLIC int com_limits(int p, param_list param)
+{
+ pprintf(p, "\nCurrent hardcoded limits:\n");
+ pprintf(p, " Max number of players: %d\n", MAX_PLAYER);
+ pprintf(p, " Max number of channels and max capacity: %d\n", MAX_CHANNELS);
+ pprintf(p, " Max number of channels one can be in: %d\n", MAX_INCHANNELS);
+ pprintf(p, " Max number of people on the notify list: %d\n", MAX_NOTIFY);
+ pprintf(p, " Max number of aliases: %d\n", MAX_ALIASES);
+ pprintf(p, " Max number of games you can observe at a time: %d\n", MAX_OBSERVE);
+ pprintf(p, " Max number of requests pending: %d\n", MAX_PENDING);
+ pprintf(p, " Max number of people on the censor list: %d\n", MAX_CENSOR);
+ pprintf(p, " Max number of people in a simul game: %d\n", MAX_SIMUL);
+ pprintf(p, " Max number of messages one can receive: %d\n", MAX_MESSAGES);
+ pprintf(p, " Min number of games to be active: %d\n", PROVISIONAL);
+ pprintf(p, "\nAdmin settable limits:\n");
+ pprintf(p, " Quota list gives two shouts per %d seconds.\n", quota_time);
+ return COM_OK;
+}
blob - /dev/null
blob + dde09a9569cc45a16a92a556d9625158d1968d25 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/config.h
+/* config.h
+ *
+ */
+
+/* Configure file locations in this include file. */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 94/03/08 Created
+ Sparky 95/12/30 Beautified.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+/* CONFIGURE THIS: The port on which the server binds */
+
+#define DEFAULT_PORT 5000
+
+/* Must be a dns recognisable host name */
+
+#define SERVER_HOSTNAME "fics.nastycode.com"
+
+/* At AFICS we just use 'fics' but for your server you might want to change this
+ eg to BICS, EICS, DICS etc */
+
+#define SERVER_NAME "Xfics" /* for pgn output */
+
+#define SERVER_LOCATION "Unconfigured City, Country" /* for pgn output */
+
+
+/* Which is the default language for help files, see variable.h for the
+ current available settings */
+
+#define LANG_DEFAULT LANG_ENGLISH
+
+/* CONFIGURE THESE: Locations of the data, players, and games directories */
+/* These must be absolute paths because some mail daemons may be called */
+/* from outside the pwd */
+
+#define DEFAULT_MESS "/home/TiK/FICS.DIST/data/messages"
+#define DEFAULT_INDEX "/home/TiK/FICS.DIST/data/index"
+#define DEFAULT_HELP "/home/TiK/FICS.DIST/data/help"
+#define DEFAULT_COMHELP "/home/TiK/FICS.DIST/data/com_help"
+#define HELP_SPANISH "/home/TiK/FICS.DIST/data/Spanish"
+#define HELP_FRENCH "/home/TiK/FICS.DIST/data/French"
+#define HELP_DANISH "/home/TiK/FICS.DIST/data/Danish"
+#define DEFAULT_INFO "/home/TiK/FICS.DIST/data/info"
+#define DEFAULT_ADHELP "/home/TiK/FICS.DIST/data/admin"
+#define DEFAULT_USCF "/home/TiK/FICS.DIST/data/uscf"
+#define DEFAULT_STATS "/home/TiK/FICS.DIST/data/stats"
+#define DEFAULT_CONFIG "/home/TiK/FICS.DIST/config"
+#define DEFAULT_PLAYERS "/home/TiK/FICS.DIST/players"
+#define DEFAULT_ADJOURNED "/home/TiK/FICS.DIST/games/adjourned"
+#define DEFAULT_HISTORY "/home/TiK/FICS.DIST/games/history"
+#define DEFAULT_JOURNAL "/home/TiK/FICS.DIST/games/journal"
+#define DEFAULT_BOARDS "/home/TiK/FICS.DIST/data/boards"
+#define DEFAULT_SOURCE "/home/TiK/FICS.DIST/FICS"
+#define DEFAULT_LISTS "/home/TiK/FICS.DIST/data/lists"
+#define DEFAULT_NEWS "/home/TiK/FICS.DIST/data/news"
+#define DEFAULT_BOOK "/home/TiK/FICS.DIST/data/book"
+#define MESS_FULL "/home/TiK/FICS.DIST/data/messages/full"
+#define MESS_FULL_UNREG "/home/TiK/FICS.DIST/data/messages/full_unreg"
+#define DEFAULT_USAGE "/home/TiK/FICS.DIST/data/usage"
+#define USAGE_SPANISH "/home/TiK/FICS.DIST/data/usage_spanish"
+#define USAGE_FRENCH "/home/TiK/FICS.DIST/data/usage_french"
+#define USAGE_DANISH "/home/TiK/FICS.DIST/data/usage_danish"
+
+
+/* Where the standard ucb mail program is */
+
+#define MAILPROGRAM "/usr/bin/mail"
+
+/* SENDMAILPROG is a faster and more reliable means of sending mail if
+ defined. Make sure your system mailer agent is defined here properly
+ for your system with respect to name, location and options. These may
+ differ significatly depending on the type of system and what mailer is
+ installed */
+/* The floowing works fine for SunOS4.1.X with berkeley sendmail */
+
+/* #define SENDMAILPROG "/usr/lib/sendmail -t" */
+
+/* Details of the head admin */
+
+#define HADMINHANDLE "AdminGuy"
+#define HADMINEMAIL "AdminGuy@this.place"
+
+/* Registration mail address */
+
+#define REGMAIL "AdminGuy@this.place"
+
+#endif /* _CONFIG_H */
blob - /dev/null
blob + 0257657657c4d66e16222d22895a5dcec60890be (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/config.h.dist
+/* config.h
+ *
+ */
+
+/* Configure file locations in this include file. */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 94/03/08 Created
+ Sparky 95/12/30 Beautified.
+*/
+
+#ifndef _CONFIG_H
+#define _CONFIG_H
+
+/* CONFIGURE THIS: The port on which the server binds */
+
+#define DEFAULT_PORT 5000
+
+/* Must be a dns recognisable host name */
+
+#define SERVER_HOSTNAME "fics.somewhere.domain"
+
+/* At AFICS we just use 'fics' but for your server you might want to change this
+ eg to BICS, EICS, DICS etc */
+
+#define SERVER_NAME "Xfics" /* for pgn output */
+
+#define SERVER_LOCATION "Unconfigured City, Country" /* for pgn output */
+
+
+/* Which is the default language for help files, see variable.h for the
+ current available settings */
+
+#define LANG_DEFAULT LANG_ENGLISH
+
+/* CONFIGURE THESE: Locations of the data, players, and games directories */
+/* These must be absolute paths because some mail daemons may be called */
+/* from outside the pwd */
+
+#define DEFAULT_MESS "/usr/home/fics/FICS.DIST/data/messages"
+#define DEFAULT_INDEX "/usr/home/fics/FICS.DIST/data/index"
+#define DEFAULT_HELP "/usr/home/fics/FICS.DIST/data/help"
+#define DEFAULT_COMHELP "/usr/home/fics/FICS.DIST/data/com_help"
+#define HELP_SPANISH "/usr/home/fics/FICS.DIST/data/Spanish"
+#define HELP_FRENCH "/usr/home/fics/FICS.DIST/data/French"
+#define HELP_DANISH "/usr/home/fics/FICS.DIST/data/Danish"
+#define DEFAULT_INFO "/usr/home/fics/FICS.DIST/data/info"
+#define DEFAULT_ADHELP "/usr/home/fics/FICS.DIST/data/admin"
+#define DEFAULT_USCF "/usr/home/fics/FICS.DIST/data/uscf"
+#define DEFAULT_STATS "/usr/home/fics/FICS.DIST/data/stats"
+#define DEFAULT_CONFIG "/usr/home/fics/FICS.DIST/config"
+#define DEFAULT_PLAYERS "/usr/home/fics/FICS.DIST/players"
+#define DEFAULT_ADJOURNED "/usr/home/fics/FICS.DIST/games/adjourned"
+#define DEFAULT_HISTORY "/usr/home/fics/FICS.DIST/games/history"
+#define DEFAULT_JOURNAL "/usr/home/fics/FICS.DIST/games/journal"
+#define DEFAULT_BOARDS "/usr/home/fics/FICS.DIST/data/boards"
+#define DEFAULT_SOURCE "/usr/home/fics/FICS.DIST/FICS"
+#define DEFAULT_LISTS "/usr/home/fics/FICS.DIST/data/lists"
+#define DEFAULT_NEWS "/usr/home/fics/FICS.DIST/data/news"
+#define DEFAULT_BOOK "/usr/home/fics/FICS.DIST/data/book"
+#define MESS_FULL "/usr/home/fics/FICS.DIST/data/messages/full"
+#define MESS_FULL_UNREG "/usr/home/fics/FICS.DIST/data/messages/full_unreg"
+#define DEFAULT_USAGE "/usr/home/fics/FICS.DIST/data/usage"
+#define USAGE_SPANISH "/usr/home/fics/FICS.DIST/data/usage_spanish"
+#define USAGE_FRENCH "/usr/home/fics/FICS.DIST/data/usage_french"
+#define USAGE_DANISH "/usr/home/fics/FICS.DIST/data/usage_danish"
+
+
+/* Where the standard ucb mail program is */
+
+#define MAILPROGRAM "/usr/ucb/mail"
+
+/* SENDMAILPROG is a faster and more reliable means of sending mail if
+ defined. Make sure your system mailer agent is defined here properly
+ for your system with respect to name, location and options. These may
+ differ significatly depending on the type of system and what mailer is
+ installed */
+/* The floowing works fine for SunOS4.1.X with berkeley sendmail */
+
+/* #define SENDMAILPROG "/usr/lib/sendmail -t" */
+
+/* Details of the head admin */
+
+#define HADMINHANDLE "AdminGuy"
+#define HADMINEMAIL "AdminGuy@this.place"
+
+/* Registration mail address */
+
+#define REGMAIL "AdminGuy@this.place"
+
+#endif /* _CONFIG_H */
blob - /dev/null
blob + ebd9e4db73b3ae298c29aa0de50e52b5ab7e999e (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/dfree.c
+/* Free a block of memory allocated by `malloc'.
+ Copyright 1990, 1991, 1992, 1994 Free Software Foundation, Inc.
+ Written May 1989 by Mike Haertel.
+
+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; see the file COPYING.LIB. If
+not, write to the Free Software Foundation, Inc., 675 Mass Ave,
+Cambridge, MA 02139, USA.
+
+ The author may be reached (Email) at the address mike@ai.mit.edu,
+ or (US mail) as Mike Haertel c/o Free Software Foundation. */
+
+#ifndef _MALLOC_INTERNAL
+#define _MALLOC_INTERNAL
+#include <malloc.h>
+#endif
+
+/* Debugging hook for free. */
+void (*__free_hook) __P ((__ptr_t __ptr));
+
+/* List of blocks allocated by memalign. */
+struct alignlist *_aligned_blocks = NULL;
+
+/* Return memory to the heap.
+ Like `free' but don't call a __free_hook if there is one. */
+void
+_free_internal (ptr)
+ __ptr_t ptr;
+{
+ int type;
+ __malloc_size_t block, blocks;
+ register __malloc_size_t i;
+ struct list *prev, *next;
+
+ block = BLOCK (ptr);
+
+ type = _heapinfo[block].busy.type;
+ switch (type)
+ {
+ case 0:
+ /* Get as many statistics as early as we can. */
+ --_chunks_used;
+ _bytes_used -= _heapinfo[block].busy.info.size * BLOCKSIZE;
+ _bytes_free += _heapinfo[block].busy.info.size * BLOCKSIZE;
+
+ /* Find the free cluster previous to this one in the free list.
+ Start searching at the last block referenced; this may benefit
+ programs with locality of allocation. */
+ i = _heapindex;
+ if (i > block)
+ while (i > block)
+ i = _heapinfo[i].free.prev;
+ else
+ {
+ do
+ i = _heapinfo[i].free.next;
+ while (i > 0 && i < block);
+ i = _heapinfo[i].free.prev;
+ }
+
+ /* Determine how to link this block into the free list. */
+ if (block == i + _heapinfo[i].free.size)
+ {
+ /* Coalesce this block with its predecessor. */
+ _heapinfo[i].free.size += _heapinfo[block].busy.info.size;
+ block = i;
+ }
+ else
+ {
+ /* Really link this block back into the free list. */
+ _heapinfo[block].free.size = _heapinfo[block].busy.info.size;
+ _heapinfo[block].free.next = _heapinfo[i].free.next;
+ _heapinfo[block].free.prev = i;
+ _heapinfo[i].free.next = block;
+ _heapinfo[_heapinfo[block].free.next].free.prev = block;
+ ++_chunks_free;
+ }
+
+ /* Now that the block is linked in, see if we can coalesce it
+ with its successor (by deleting its successor from the list
+ and adding in its size). */
+ if (block + _heapinfo[block].free.size == _heapinfo[block].free.next)
+ {
+ _heapinfo[block].free.size
+ += _heapinfo[_heapinfo[block].free.next].free.size;
+ _heapinfo[block].free.next
+ = _heapinfo[_heapinfo[block].free.next].free.next;
+ _heapinfo[_heapinfo[block].free.next].free.prev = block;
+ --_chunks_free;
+ }
+
+ /* Now see if we can return stuff to the system. */
+ blocks = _heapinfo[block].free.size;
+ if (blocks >= FINAL_FREE_BLOCKS && block + blocks == _heaplimit
+ && (*__morecore) (0) == ADDRESS (block + blocks))
+ {
+ register __malloc_size_t bytes = blocks * BLOCKSIZE;
+ _heaplimit -= blocks;
+ (*__morecore) (-bytes);
+ _heapinfo[_heapinfo[block].free.prev].free.next
+ = _heapinfo[block].free.next;
+ _heapinfo[_heapinfo[block].free.next].free.prev
+ = _heapinfo[block].free.prev;
+ block = _heapinfo[block].free.prev;
+ --_chunks_free;
+ _bytes_free -= bytes;
+ }
+
+ /* Set the next search to begin at this block. */
+ _heapindex = block;
+ break;
+
+ default:
+ /* Do some of the statistics. */
+ --_chunks_used;
+ _bytes_used -= 1 << type;
+ ++_chunks_free;
+ _bytes_free += 1 << type;
+
+ /* Get the address of the first free fragment in this block. */
+ prev = (struct list *) ((char *) ADDRESS (block) +
+ (_heapinfo[block].busy.info.frag.first << type));
+
+ if (_heapinfo[block].busy.info.frag.nfree == (BLOCKSIZE >> type) - 1)
+ {
+ /* If all fragments of this block are free, remove them
+ from the fragment list and free the whole block. */
+ next = prev;
+ for (i = 1; i < (__malloc_size_t) (BLOCKSIZE >> type); ++i)
+ next = next->next;
+ prev->prev->next = next;
+ if (next != NULL)
+ next->prev = prev->prev;
+ _heapinfo[block].busy.type = 0;
+ _heapinfo[block].busy.info.size = 1;
+
+ /* Keep the statistics accurate. */
+ ++_chunks_used;
+ _bytes_used += BLOCKSIZE;
+ _chunks_free -= BLOCKSIZE >> type;
+ _bytes_free -= BLOCKSIZE;
+
+ free (ADDRESS (block));
+ }
+ else if (_heapinfo[block].busy.info.frag.nfree != 0)
+ {
+ /* If some fragments of this block are free, link this
+ fragment into the fragment list after the first free
+ fragment of this block. */
+
+ /****** Test for no double frees --mann ********/
+ {
+#include <stdio.h>
+ struct list* tmp = prev;
+
+ while (tmp != NULL && BLOCK(tmp) == BLOCK(ptr)) {
+ if (tmp == ptr) {
+ fprintf(stderr, "Freeing already freed memory!\n");
+ abort();
+ }
+ tmp = tmp->next;
+ }
+ }
+ /************************************************/
+
+ next = (struct list *) ptr;
+ next->next = prev->next;
+ next->prev = prev;
+ prev->next = next;
+ if (next->next != NULL)
+ next->next->prev = next;
+ ++_heapinfo[block].busy.info.frag.nfree;
+ }
+ else
+ {
+ /* No fragments of this block are free, so link this
+ fragment into the fragment list and announce that
+ it is the first free fragment of this block. */
+ prev = (struct list *) ptr;
+ _heapinfo[block].busy.info.frag.nfree = 1;
+ _heapinfo[block].busy.info.frag.first = (unsigned long int)
+ ((unsigned long int) ((char *) ptr - (char *) NULL)
+ % BLOCKSIZE >> type);
+ prev->next = _fraghead[type].next;
+ prev->prev = &_fraghead[type];
+ prev->prev->next = prev;
+ if (prev->next != NULL)
+ prev->next->prev = prev;
+ }
+ break;
+ }
+}
+
+/* Return memory to the heap. */
+void
+free (ptr)
+ __ptr_t ptr;
+{
+ register struct alignlist *l;
+
+ if (ptr == NULL)
+ return;
+
+ for (l = _aligned_blocks; l != NULL; l = l->next)
+ if (l->aligned == ptr)
+ {
+ l->aligned = NULL; /* Mark the slot in the list as free. */
+ ptr = l->exact;
+ break;
+ }
+
+ if (__free_hook != NULL)
+ (*__free_hook) (ptr);
+ else
+ _free_internal (ptr);
+}
blob - /dev/null
blob + 80b1196c61dd712d497beff22fa29eefbc75cd42 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/eco.c
+#include "stdinclude.h"
+#include "board.h"
+#include "gamedb.h"
+#include "command.h"
+#include "playerdb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "utils.h"
+#include "common.h"
+#include "config.h"
+
+PUBLIC char *book_dir = DEFAULT_BOOK;
+
+typedef struct {
+ char ECO[4];
+ char FENpos[80];
+} ECO_entry;
+
+typedef struct {
+ char NIC[6];
+ char FENpos[80];
+} NIC_entry;
+
+typedef struct {
+ char LONG[80];
+ char FENpos[80];
+} LONG_entry;
+
+ECO_entry *ECO_book[1096];
+NIC_entry *NIC_book[1096];
+LONG_entry *LONG_book[4096];
+
+int ECO_entries, NIC_entries, LONG_entries;
+
+char *boardToFEN(int g)
+{
+ int i,j;
+ static char FENstring[80];
+ int FENcount = 0;
+ int space = 0;
+
+ for(i=7; i>=0; i--) {
+ for(j=0; j<8; j++) {
+ switch(garray[g].game_state.board[j][i]) {
+ case W_PAWN:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='P';
+ break;
+ case W_ROOK:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='R';
+ break;
+ case W_KNIGHT:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='N';
+ break;
+ case W_BISHOP:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='B';
+ break;
+ case W_QUEEN:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='Q';
+ break;
+ case W_KING:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='K';
+ break;
+ case B_PAWN:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='p';
+ break;
+ case B_ROOK:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='r';
+ break;
+ case B_KNIGHT:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='n';
+ break;
+ case B_BISHOP:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='b';
+ break;
+ case B_QUEEN:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='q';
+ break;
+ case B_KING:
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='k';
+ break;
+ default:
+ space++;
+ break;
+ }
+ }
+ if (space>0) {
+ FENstring[FENcount++]=space+'0';
+ space=0;
+ }
+ FENstring[FENcount++]='/';
+ }
+ FENstring[--FENcount]=' ';
+ FENstring[++FENcount]=(garray[g].game_state.onMove==WHITE) ? 'w' : 'b';
+ FENstring[++FENcount]='\0';
+ return FENstring;
+}
+
+void ECO_init()
+{
+ FILE *fp;
+ char tmp[1024];
+ char *ptmp= tmp;
+ char FENpos[73], ECO[4], onMove[2];
+ char filename[1024];
+ int i=0;
+
+ sprintf(filename, "%s/eco999.idx", book_dir);
+ fp= fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Could not open ECO file\n");
+ exit(1);
+ }
+ while (!feof(fp)) {
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove);
+ sprintf(FENpos, "%s %s", FENpos, onMove);
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[0-z]", ECO);
+ ECO_book[i]= (ECO_entry *) malloc(sizeof(ECO_entry));
+ if (ECO_book[i]==NULL) {
+ fprintf(stderr, "Cound not alloc mem for ECO entry %d.\n", i);
+ exit(1);
+ }
+ strcpy(ECO_book[i]->ECO, ECO);
+ strcpy(ECO_book[i]->FENpos, FENpos);
+ ++i;
+ }
+ fclose(fp);
+ ECO_book[i]=NULL;
+ fprintf(stderr, "%d entries in ECO book\n", i);
+ ECO_entries = i;
+
+ while (--i >= 0)
+ if (ECO_book[i] == NULL)
+ fprintf(stderr, "ERROR! ECO book position number %d is NULL.", i);
+}
+
+void NIC_init()
+{
+ FILE *fp;
+ char tmp[1024];
+ char *ptmp= tmp;
+ char FENpos[73], NIC[6], onMove[2];
+ char filename[1024];
+ int i=0;
+
+ sprintf(filename, "%s/nic999.idx", book_dir);
+ fp= fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Could not open NIC file\n");
+ exit(1);
+ }
+ while (!feof(fp)) {
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove);
+ sprintf(FENpos, "%s %s", FENpos, onMove);
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[.-z]", NIC);
+ NIC_book[i]= (NIC_entry *) malloc(sizeof(NIC_entry));
+ if (NIC_book[i]==NULL) {
+ fprintf(stderr, "Cound not alloc mem for NIC entry %d.\n", i);
+ exit(1);
+ }
+ strcpy(NIC_book[i]->NIC, NIC);
+ strcpy(NIC_book[i]->FENpos, FENpos);
+ ++i;
+ }
+ fclose(fp);
+ NIC_book[i]=NULL;
+ fprintf(stderr, "%d entries in NIC book\n", i);
+ NIC_entries = i;
+}
+
+void LONG_init()
+{
+ FILE *fp;
+ char tmp[1024];
+ char *ptmp= tmp;
+ char FENpos[73], LONG[256], onMove[2];
+ char filename[1024];
+ int i=0;
+
+ sprintf(filename, "%s/long999.idx", book_dir);
+ fp= fopen(filename, "r");
+ if (!fp) {
+ fprintf(stderr, "Could not open LONG file\n");
+ exit(1);
+ }
+ while (!feof(fp)) {
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[\x21-z] %s", FENpos, onMove);
+ sprintf(FENpos, "%s %s", FENpos, onMove);
+ strcpy(ptmp, "");
+ fgets(ptmp, 1024, fp);
+ if (feof(fp)) continue;
+ sscanf(ptmp, "%[^*\n]", LONG);
+ LONG_book[i]= (LONG_entry *) malloc(sizeof(LONG_entry));
+ if (LONG_book[i]==NULL) {
+ fprintf(stderr, "Cound not alloc mem for LONG entry %d.\n", i);
+ exit(1);
+ }
+ strcpy(LONG_book[i]->LONG, LONG);
+ strcpy(LONG_book[i]->FENpos, FENpos);
+ ++i;
+ }
+ fclose(fp);
+ LONG_book[i]=NULL;
+ fprintf(stderr, "%d entries in LONG book\n", i);
+ LONG_entries = i;
+}
+
+void BookInit()
+{
+ ECO_init();
+ NIC_init();
+ LONG_init();
+}
+
+char *getECO(int g)
+{
+ static char ECO[4];
+
+#ifndef IGNORE_ECO
+
+ int i, flag, l = 0, r = ECO_entries - 1, x;
+
+
+ if ((parray[garray[g].white].private) || (parray[garray[g].black].private)) {
+ strcpy(ECO, "---");
+ return ECO;
+ } else {
+ if (garray[g].type == TYPE_WILD) {
+ strcpy(ECO, "---");
+ return ECO;
+ } else if (garray[g].moveList == NULL) {
+ strcpy(ECO, "***");
+ return ECO;
+ } else {
+ strcpy(ECO, "A00");
+ }
+ }
+
+ for (flag=0,i=garray[g].numHalfMoves; (i>0 && !flag); i--) {
+ l = 0;
+ r = ECO_entries - 1;
+ while ((r >= l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(garray[g].moveList[i].FENpos, ECO_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(garray[g].moveList[i].FENpos, ECO_book[x]->FENpos)) {
+ strcpy(ECO, ECO_book[x]->ECO);
+ flag=1;
+ }
+ }
+ }
+#else
+
+ strcpy(ECO, "---");
+
+#endif
+
+
+ return ECO;
+}
+
+PUBLIC int com_eco(int p, param_list param)
+{
+
+#ifndef IGNORE_ECO
+
+ int i, flag = 0, x, l, r;
+ int g1, p1;
+
+
+ if (param[0].type == TYPE_NULL) { /* own game */
+ if (parray[p].game < 0) {
+ pprintf(p, "You are not playing or examining a game.\n");
+ return COM_OK;
+ }
+ g1=parray[p].game;
+ if (garray[g1].status != GAME_EXAMINE && !pIsPlaying(p))
+ return COM_OK;
+ } else {
+ g1 = GameNumFromParam (p, &p1, ¶m[0]);
+ if (g1 < 0) return COM_OK;
+ if ((g1 >= g_num) || ((garray[g1].status != GAME_ACTIVE) &&
+ (garray[g1].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ }
+
+ if ((((parray[garray[g1].white].private) ||
+ (parray[garray[g1].black].private))) &&
+ (parray[p].adminLevel==0)) {
+ pprintf(p, "Sorry - that game is private.\n");
+ return COM_OK;
+ } else {
+ if (garray[g1].type == TYPE_WILD) {
+ pprintf(p, "That game is a wild game.\n");
+ return COM_OK;
+ }
+ }
+
+ pprintf(p, "Info about game %d: \"%s vs. %s\"\n\n", g1+1,
+ garray[g1].white_name,
+ garray[g1].black_name);
+
+ if (garray[g1].moveList==NULL) {
+ return COM_OK;
+ }
+
+ for (flag=0,i=garray[g1].numHalfMoves; (i>0 && !flag); i--) {
+ l = 0;
+ r = ECO_entries - 1;
+ while ((r >= l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(garray[g1].moveList[i].FENpos, ECO_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(garray[g1].moveList[i].FENpos, ECO_book[x]->FENpos)) {
+ pprintf(p, " ECO[%3d]: %s\n", i, ECO_book[x]->ECO);
+ flag=1;
+ }
+ }
+ }
+
+ for (flag=0, i=garray[g1].numHalfMoves; ((i>0) && (!flag)); i--) {
+ l = 0;
+ r = NIC_entries - 1;
+ while ((r >=l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(garray[g1].moveList[i].FENpos, NIC_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(garray[g1].moveList[i].FENpos, NIC_book[x]->FENpos)) {
+ pprintf(p, " NIC[%3d]: %s\n", i, NIC_book[x]->NIC);
+ flag=1;
+ }
+ }
+ }
+
+ for (flag=0, i=garray[g1].numHalfMoves; ((i>0) && (!flag)); i--) {
+ l = 0;
+ r = LONG_entries - 1;
+ while ((r >=l) && !flag) {
+ x = (l+r)/2;
+ if ((strcmp(garray[g1].moveList[i].FENpos, LONG_book[x]->FENpos)) < 0)
+ r = x - 1;
+ else
+ l = x + 1;
+ if (!strcmp(garray[g1].moveList[i].FENpos, LONG_book[x]->FENpos)) {
+ pprintf(p, " LONG[%3d]: %s\n", i, LONG_book[x]->LONG);
+ flag=1;
+ }
+ }
+ }
+
+#else
+
+ pprintf(p, "ECO not available... out of service!.\n");
+
+#endif
+
+ return COM_OK;
+}
blob - /dev/null
blob + 92e8d0bc16fed4f00d2fc554b3756195e6cdd014 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/eco.h
+#ifndef _ECO_H
+#define _ECO_H
+
+extern char *boardToFEN();
+extern void ECO_init();
+extern void NIC_init();
+extern void LONG_init();
+extern void BookInit();
+extern int com_eco();
+extern char *getECO();
+
+#endif
blob - /dev/null
blob + cde3da118e7f0c966aeaa51816b57305cf53e9fc (mode 644)
Binary files /dev/null and FICS.DIST/FICS/eco.o differ
blob - /dev/null
blob + b1889b2654421fa5f72d4706abfb4ee8fcf1e5e5 (mode 755)
Binary files /dev/null and FICS.DIST/FICS/fics differ
blob - /dev/null
blob + 520f8e1555a21ec87e7d88fb266689b48098730f (mode 644)
Binary files /dev/null and FICS.DIST/FICS/fics.core differ
blob - /dev/null
blob + acbf73178ca80d1270ad196d42852e0817a7a6e8 (mode 755)
Binary files /dev/null and FICS.DIST/FICS/fics_addplayer differ
blob - /dev/null
blob + 55a2fbdc55ce8dcba50b2def324ba0d5c5589f3d (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/fics_addplayer.c
+/* fics_addplayer.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1994 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 94/03/07 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "utils.h"
+#include "playerdb.h"
+/* #include "hostinfo.h" */
+#include "command.h"
+
+#include <string.h>
+
+extern time_t time();
+/* extern int printf(); */
+
+PRIVATE void usage(char *progname)
+{
+ fprintf(stderr, "Usage: %s [-l] [-n] UserName FullName EmailAddress\n", progname);
+ exit(1);
+}
+
+/* Parameters */
+int local = 1;
+char *funame = NULL, *fname = NULL, *email = NULL;
+
+#define PASSLEN 4
+PUBLIC int main(int argc, char *argv[])
+{
+ int i;
+ int p;
+ char password[PASSLEN + 1];
+ char salt[3];
+ char text[2048];
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'l':
+ local = 1;
+ break;
+ case 'n':
+ local = 0;
+ break;
+ default:
+ usage(argv[0]);
+ break;
+ }
+ } else {
+ if (!funame)
+ funame = argv[i];
+ else if (!fname)
+ fname = argv[i];
+ else if (!email)
+ email = argv[i];
+ else
+ usage(argv[0]);
+ }
+ }
+ if (!funame || !fname || !email)
+ usage(argv[0]);
+
+ /* Add the player here */
+ if (strlen(funame) >= MAX_LOGIN_NAME) {
+ fprintf(stderr, "Player name is too long\n");
+ exit(0);
+ }
+ if (strlen(funame) < 3) {
+ fprintf(stderr, "Player name is too short\n");
+ exit(0);
+ }
+ if (!alphastring(funame)) {
+ fprintf(stderr, "Illegal characters in player name. Only A-Za-z allowed.\n");
+ exit(0);
+ }
+
+/* loon: see if we can deliver mail to this email address. */
+/*
+ printf("Verifying email address %s...\n", email);
+ if (check_emailaddr(email)) {
+ fprintf(stderr, "The email address %s looks bad.\n", email);
+ exit(0);
+ }
+*/
+/*
+ if (local)
+ iamserver = 0;
+ else
+ iamserver = 1;
+*/
+/* if (hostinfo_init()) {
+ if (iamserver) {
+ fprintf(stderr, "Can't read from hostinfo file.\n");
+ fprintf(stderr, "Remember you need -l for local.\n");
+ exit(1);
+ } else {
+ }
+ } */
+ player_init(0);
+ srand(time(0));
+ p = player_new();
+ if (!player_read(p, funame)) {
+ fprintf(stderr, "%s already exists.\n", funame);
+ exit(0);
+ }
+ parray[p].name = strdup(funame);
+ parray[p].login = strdup(funame);
+ stolower(parray[p].login);
+ parray[p].fullName = strdup(fname);
+ parray[p].emailAddress = strdup(email);
+ for (i = 0; i < PASSLEN; i++) {
+ password[i] = 'a' + rand() % 26;
+ }
+ password[i] = '\0';
+ salt[0] = 'a' + rand() % 26;
+ salt[1] = 'a' + rand() % 26;
+ salt[2] = '\0';
+ parray[p].passwd = strdup(crypt(password, salt));
+ parray[p].registered = 1;
+/* parray[p].network_player = !local; */
+ parray[p].rated = 1;
+ player_save(p);
+/* changed by Sparky 12/15/95 Dropped reference to 'Network' players
+ and spiffed it up */
+/*
+ printf("Added %s player >%s< >%s< >%s< >%s<\n", local ? "local" : "network",
+ funame, fname, email, password);
+ sprintf(text, "\nYou have been added as a %s player.\nIf this is a network account it may take a while to show up on all of the\nclients.\n\nLogin Name: %s\nFull Name: %s\nEmail Address: %s\nInitial Password: %s\n\nIf any of this information is incorrect, please contact the administrator\nto get it corrected.\nPlease write down your password, as it will be your initial passoword\non all of the servers.\n", local ? "local" : "network", funame, fname, email, password);
+*/
+
+ printf("Added player account: >%s< >%s< >%s< >%s<\n",
+ funame, fname, email, password);
+
+ sprintf(text, "\nYour player account has been created.\n\n"
+ "Login Name: %s\nFull Name: %s\nEmail Address: %s\nInitial Password: %s\n\n"
+ "If any of this information is incorrect, please contact the administrator\n"
+ "to get it corrected.\n\n"
+ "You may change your password with the password command on the the server.\n"
+ "\nPlease be advised that if this is an unauthorized duplicate account for\n"
+ "you, by using it you take the risk of being banned from accessing this\n"
+ "chess server.\n\nTo connect to the server and use this account:\n\n"
+ " telnet %s 5000\n\nand enter your handle name and password.\n\n"
+ "Regards,\n\nThe FICS admins\n",
+ funame, fname, email, password, fics_hostname);
+
+ mail_string_to_address(email, "FICS Account Created", text);
+ exit(0);
+}
blob - /dev/null
blob + 8d0b12c131b1310a352c620852d2ac458656e9e7 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/fics_addplayer.core differ
blob - /dev/null
blob + 5d67402900bac030010ec44471e4b9fd6d707386 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/fics_addplayer.o differ
blob - /dev/null
blob + b1882f360b51ebc3b65c285a7ae46fcef3512d91 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/ficsmain.c
+/* ficsmain.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "network.h"
+#include "command.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "utils.h"
+/*#include "hostinfo.h" */
+#include "board.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "shutdown.h"
+#ifndef IGNORE_ECO
+#include "eco.h"
+#endif
+#include <sys/param.h>
+
+/* Arguments */
+PUBLIC int port;
+PUBLIC int withConsole;
+
+/* grimm */
+void player_array_init(void);
+/* for warning */
+
+PRIVATE void usage(char *progname)
+{
+ fprintf(stderr, "Usage: %s [-p port] [-C] [-h]\n", progname);
+ fprintf(stderr, "\t\t-p port\t\tSpecify port. (Default=5000)\n");
+ fprintf(stderr, "\t\t-C\t\tStart with console player connected to stdin.\n");
+ fprintf(stderr, "\t\t-h\t\tDisplay this information.\n");
+ exit(1);
+}
+
+PRIVATE void GetArgs(int argc, char *argv[])
+{
+ int i;
+
+ port = DEFAULT_PORT;
+ withConsole = 0;
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'p':
+ if (i == argc - 1)
+ usage(argv[0]);
+ i++;
+ if (sscanf(argv[i], "%d", &port) != 1)
+ usage(argv[0]);
+ break;
+ case 'C':
+ fprintf(stderr, "-C Not implemented!\n");
+ exit(1);
+ withConsole = 1;
+ break;
+ case 'h':
+ usage(argv[0]);
+ break;
+ }
+ } else {
+ usage(argv[0]);
+ }
+ }
+}
+
+PRIVATE void main_event_loop(void) {
+int current_socket;
+char command_string[MAX_STRING_LENGTH];
+
+ while (1) {
+ ngc2(command_string, HEARTBEATTIME);
+ if (process_heartbeat(¤t_socket) == COM_LOGOUT) {
+ process_disconnection(current_socket);
+ net_close_connection(current_socket);
+ }
+ }
+}
+
+void TerminateServer(int sig)
+{
+ fprintf(stderr, "FICS: Got signal %d\n", sig);
+ output_shut_mess();
+ TerminateCleanup();
+ net_close();
+ exit(1);
+}
+
+void BrokenPipe(int sig)
+{
+ fprintf(stderr, "FICS: Got Broken Pipe\n");
+}
+
+PUBLIC int main(int argc, char *argv[])
+{
+
+#ifdef DEBUG
+#ifdef HAVE_MALLOC_DEBUG
+ malloc_debug(16);
+#endif
+#endif
+ GetArgs(argc, argv);
+ signal(SIGTERM, TerminateServer);
+ signal(SIGINT, TerminateServer);
+ signal(SIGPIPE, BrokenPipe);
+ if (net_init(port)) {
+ fprintf(stderr, "FICS: Network initialize failed on port %d.\n", port);
+ exit(1);
+ }
+ startuptime = time(0);
+/* Using the value defined in config.h now instead of the real hostname.
+ This is used as the return address in email, so it needs to be a real
+ DNS resolvable hostname! Sparky */
+/* gethostname(fics_hostname, 80); */
+ strcpy ( fics_hostname, SERVER_HOSTNAME );
+ quota_time = 60;
+ player_high = 0;
+ game_high = 0;
+ srand(startuptime);
+ fprintf(stderr, "FICS: Initialized on port %d at %s.\n", port, strltime(&startuptime));
+/* iamserver = 0; */
+/* if (hostinfo_init()) {
+ MailGameResult = 0;
+ fprintf(stderr, "FICS: No ratings server connection.\n");
+ } else {
+ if (iamserver) {
+ fprintf(stderr, "FICS: I don't know how to be a ratings server, refusing.\n");
+ MailGameResult = 0;
+ } else {
+ fprintf(stderr, "FICS: Ratings server set to: %s\n", hArray[0].email_address);
+ MailGameResult = 1;
+ }
+ } */
+/* if (mail_log_file)
+ fclose(mail_log_file); */
+ fprintf(stderr, "FICS: commands_init()\n");
+ commands_init();
+/* fprintf(stderr, "FICS: channel_init()\n");
+ channel_init(); */
+ fprintf(stderr, "FICS: rating_init()\n");
+ rating_init();
+ fprintf(stderr, "FICS: wild_init()\n");
+ wild_init();
+#ifndef IGNORE_ECO
+ fprintf(stderr, "FICS: book init()\n");
+ BookInit();
+#endif
+ fprintf(stderr, "FICS: player_array_init()\n");
+ player_array_init();
+ player_init(withConsole);
+ main_event_loop();
+ fprintf(stderr, "FICS: Closing down.\n");
+ output_shut_mess();
+ net_close();
+ return 0;
+}
blob - /dev/null
blob + d8ad0a1f5e3a423ab3b54639d70f0aa056b6ac00 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/ficsmain.c.orig
+/* ficsmain.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "network.h"
+#include "command.h"
+#include "channel.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "utils.h"
+/*#include "hostinfo.h" */
+#include "board.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "eco.h"
+
+/* Arguments */
+PUBLIC int port;
+PUBLIC int withConsole;
+
+/* grimm */
+void player_array_init(void);
+/* for warning */
+
+PRIVATE void usage(char *progname)
+{
+ fprintf(stderr, "Usage: %s [-p port] [-C] [-h]\n", progname);
+ fprintf(stderr, "\t\t-p port\t\tSpecify port. (Default=5000)\n");
+ fprintf(stderr, "\t\t-C\t\tStart with console player connected to stdin.\n");
+ fprintf(stderr, "\t\t-h\t\tDisplay this information.\n");
+ exit(1);
+}
+
+PRIVATE void GetArgs(int argc, char *argv[])
+{
+ int i;
+
+ port = DEFAULT_PORT;
+ withConsole = 0;
+
+ for (i = 1; i < argc; i++) {
+ if (argv[i][0] == '-') {
+ switch (argv[i][1]) {
+ case 'p':
+ if (i == argc - 1)
+ usage(argv[0]);
+ i++;
+ if (sscanf(argv[i], "%d", &port) != 1)
+ usage(argv[0]);
+ break;
+ case 'C':
+ fprintf(stderr, "-C Not implemented!\n");
+ exit(1);
+ withConsole = 1;
+ break;
+ case 'h':
+ usage(argv[0]);
+ break;
+ }
+ } else {
+ usage(argv[0]);
+ }
+ }
+}
+
+PRIVATE void main_event_loop(void) {
+int current_socket;
+char command_string[MAX_STRING_LENGTH];
+
+ while (1) {
+ ngc2(command_string, HEARTBEATTIME);
+ if (process_heartbeat(¤t_socket) == COM_LOGOUT) {
+ process_disconnection(current_socket);
+ net_close_connection(current_socket);
+ }
+ }
+}
+
+void TerminateServer(int sig)
+{
+ fprintf(stderr, "FICS: Got signal %d\n", sig);
+ TerminateCleanup();
+ net_close();
+ exit(1);
+}
+
+void BrokenPipe(int sig)
+{
+ fprintf(stderr, "FICS: Got Broken Pipe\n");
+}
+
+PUBLIC int main(int argc, char *argv[])
+{
+#ifdef SYSTEM_NEXT
+#ifdef DEBUG
+ malloc_debug(16);
+#endif
+#endif
+ GetArgs(argc, argv);
+ signal(SIGTERM, TerminateServer);
+ signal(SIGINT, TerminateServer);
+ signal(SIGPIPE, BrokenPipe);
+ if (net_init(port)) {
+ fprintf(stderr, "FICS: Network initialize failed on port %d.\n", port);
+ exit(1);
+ }
+ startuptime = time(0);
+ gethostname(fics_hostname, 80);
+ quota_time = 60;
+ player_high = 0;
+ game_high = 0;
+ srand(startuptime);
+ fprintf(stderr, "FICS: Initialized on port %d at %s.\n", port, strltime(&startuptime));
+/* iamserver = 0; */
+/* if (hostinfo_init()) {
+ MailGameResult = 0;
+ fprintf(stderr, "FICS: No ratings server connection.\n");
+ } else {
+ if (iamserver) {
+ fprintf(stderr, "FICS: I don't know how to be a ratings server, refusing.\n");
+ MailGameResult = 0;
+ } else {
+ fprintf(stderr, "FICS: Ratings server set to: %s\n", hArray[0].email_address);
+ MailGameResult = 1;
+ }
+ } */
+/* if (mail_log_file)
+ fclose(mail_log_file); */
+ fprintf(stderr, "FICS: commands_init()\n");
+ commands_init();
+ fprintf(stderr, "FICS: channel_init()\n");
+ channel_init();
+ fprintf(stderr, "FICS: rating_init()\n");
+ rating_init();
+ fprintf(stderr, "FICS: wild_init()\n");
+ wild_init();
+ fprintf(stderr, "FICS: book init()\n");
+ BookInit();
+ fprintf(stderr, "FICS: player_array_init()\n");
+ player_array_init();
+ player_init(withConsole);
+ main_event_loop();
+ fprintf(stderr, "FICS: Closing down.\n");
+ net_close();
+ return 0;
+}
blob - /dev/null
blob + dd7d98d6742e53a066b715e9915e58851649a508 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/ficsmain.h
+/* ficsmain.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _FICSMAIN_H
+#define _FICSMAIN_H
+
+/* Heartbead functions occur approx in this time, including checking for
+ * new connections and decrementing timeleft counters. */
+#define HEARTBEATTIME 2
+
+/* Number of seconds that an idle connection can stand at login or password
+ * prompt. */
+#define MAX_LOGIN_IDLE 120
+
+/* Players who have been idle for more than 1 hour is logged out */
+#define MAX_IDLE_TIME 3600
+
+/* This is the socket that the current command came in on */
+extern int current_socket;
+
+#define DEFAULT_PROMPT "fics% "
+
+#define MESS_WELCOME "welcome"
+#define MESS_LOGIN "login"
+#define MESS_LOGOUT "logout"
+#define MESS_MOTD "motd"
+#define MESS_ADMOTD "admotd"
+#define MESS_UNREGISTERED "unregistered"
+
+#define STATS_MESSAGES "messages"
+#define STATS_LOGONS "logons"
+#define STATS_GAMES "games"
+#define STATS_JOURNAL "journal"
+
+/* Arguments */
+extern int port;
+extern int withConsole;
+extern time_t time();
+
+#endif /* _FICSMAIN_H */
blob - /dev/null
blob + 14dc55bcd42cc34f7252c8f668a5d87935d607a9 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/ficsmain.o differ
blob - /dev/null
blob + dbdd79867af31b90d824363602daa29270d0a98b (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/formula.c
+/* Formula program for FICS. Written by Dave Herscovici
+ (dhersco@math.nps.navy.mil)
+ Edited by DAV to include wild,non-std and untimed
+ lightning flags
+
+ Operators allowed, in order of precedence:
+ ! (not), - (unary),
+ *, /,
+ +, -,
+ <, <=, =<, >, >=, =>, (<= and =< are equivalent, as are >= and =>)
+ =, ==, !=, <>, (two ways of saying both equals and not equals)
+ &, &&, (both "and")
+ |, ||, (both "or").
+
+ Parentheses () are also allowed, as is a pound sign '#' for comments.
+ The program will divide by a fudge factor of .001 instead of 0.
+
+ Variables allowed:
+ time, inc, rating, myrating, rated, blitz, standard, lightning, registered,
+ assesswin, assessdraw, assessloss, timeseal,
+ ratingdiff = rating - myrating, private, wild, untimed, nonstandard,
+ maxtime(n) = maximum time n moves will take (in seconds),
+ mymaxtime(n) = same, but just count my time.
+ f1, f2, f3, f4, f5, f6, f7, f8, f9.
+
+ The code for translating blitz and standard variables may have to be
+ redone. F1 through f9 are user-defined formula variables. They can
+ be used to avoid having to retype your entire formula when you want
+ to change one part of it, or to compensate for the lack of a 'mood'
+ variable.
+
+ For example:
+ set f1 rated & time=5 & inc=0 # rated 5 minute games
+ set f2 rating - myrating
+ set f3 # this line is a random comment.
+ set f4 f2>400 # I want a REAL fight
+
+ Then you can type:
+ set formula f1 # rated 5 min. games only
+ set formula etime >= 10 & f2 > -100 # long games, decent competition
+ set formula f1 & !f4
+ or set formula f2 >= 0 | blitz
+ depending on your mood.
+
+ Further modifications could account for starting positions, time
+ odds games, provisional or established opponents, etc. Maybe f0
+ should be reserved for your formula upon logging in; i.e. if f0
+ is set, your formula is automatically set to f0 when you log in.
+*/
+
+#include <ctype.h>
+#include "config.h"
+#include "formula.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "command.h"
+#include "common.h"
+#include "stdinclude.h"
+#include "utils.h"
+#include "rmalloc.h"
+#include "lists.h"
+#include "network.h"
+#include "ratings.h"
+
+extern player parray[];
+
+PRIVATE char *GetPlayersFormula (player *pWho, int clause)
+{
+ if (clause==MAX_FORMULA) return (pWho->formula);
+ else return (pWho->formulaLines[clause]);
+}
+
+/* In MoveIndexPastString, *i is treated as the index into string[];
+ this function returns 1 if the character string beginning with
+ string[*i] match *text, and 0 otherwise. In the former case, *i
+ is incremented to move the index past *text.
+*/
+int MoveIndexPastString (char *string, int *i, char *text)
+{
+ int n = strlen(text);
+ if (strncasecmp(text, string + *i, n)) return (0);
+ *i += n;
+ return (n);
+} /* end of function MoveIndexPastString. */
+
+/* GetRating simply chooses between blitz, standard and ratings. */
+int GetRating(player *p, int gametype)
+{
+ if (gametype == TYPE_BLITZ) return (p->b_stats.rating);
+ else if (gametype == TYPE_STAND) return (p->s_stats.rating);
+ else if (gametype == TYPE_WILD) return (p->w_stats.rating);
+ else if (gametype == TYPE_LIGHT) return (p->l_stats.rating);
+ else if (gametype == TYPE_BUGHOUSE) return (p->bug_stats.rating);
+ else return 0;
+} /* end of function GetRating. */
+
+int GetNumberInsideParens (game *g, int clause, int *i, int *token,
+ int eval)
+{
+ char *string = GetPlayersFormula(&parray[g->black], clause);
+ int ret;
+
+ while (string[*i] != '\0' && isspace(string[*i])) (*i)++;
+ if (!MoveIndexPastString(string, i, "(")) return (ERR_BADCHAR);
+
+ ret = CheckFormula(g, clause, i, OPTYPE_PAREN, token, eval);
+ if (ret != ERR_NONE)
+ return (ret);
+ if (MoveIndexPastString(string, i, ")")) return (ERR_NONE);
+ else return (ERR_PAREN);
+}
+
+int Maxtime (game *g, int numMoves, int numPlayers)
+{
+ int max;
+
+ if ((g->bInitTime == g->wInitTime) && (g->bIncrement == g->wIncrement)) {
+ max = numPlayers * (60 * g->wInitTime + numMoves * g->wIncrement);
+ if ((g->type != TYPE_UNTIMED) && (g->wInitTime == 0))
+ max +=10 * numPlayers; /* 0 x start with ten secs */
+
+ } else if (numPlayers == 2) {
+ max = 60 * (g->wInitTime + g->bInitTime)
+ + numMoves * (g->wIncrement + g->bIncrement);
+ if ((g->type != TYPE_UNTIMED) && (g->wInitTime == 0))
+ max +=10; /* 0 x start with ten secs */
+ if ((g->type != TYPE_UNTIMED) && (g->bInitTime == 0))
+ max +=10; /* 0 x start with ten secs */
+
+ } else {
+ max = 60 * g->bInitTime + numMoves * g->bIncrement;
+ if ((g->type != TYPE_UNTIMED) && (g->bInitTime == 0))
+ max +=10; /* 0 x start with ten secs */
+ }
+
+ return max;
+}
+
+
+/* The black player in game *g has been challenged. S/he has a list
+ of formulas, and we're checking the one given by the index clause
+ (MAX_FORMULA denotes the actual formula; if clause is smaller,
+ we're looking at one of the user-defined formulas). We're at
+ position *i in the formula. If we find a legitimate variable there
+ and eval is 1, VarToToken puts its value in *tok; if eval is 0,
+ just move past the variable. Returns 1 or 0, depending on whether
+ a legitimate variable was found.
+*/
+int VarToToken (game *g, int clause, char *string, int *i, int *tok, int eval)
+{
+ player *me = &parray[g->black];
+ player *you = &parray[g->white];
+ int index=0, c;
+ double dummy_sterr;
+
+ /* We list possible variables with the longest names first. */
+ if (MoveIndexPastString(string, i, "registered")) *tok=you->registered;
+ else if (MoveIndexPastString(string, i, "ratingdiff"))
+ *tok = GetRating(you, g->type) - GetRating(me, g->type);
+ else if (MoveIndexPastString(string, i, "assessloss"))
+ {
+ if (g->rated)
+ rating_sterr_delta(g->black, g->white, g->type,
+ time(0), RESULT_LOSS, tok, &dummy_sterr);
+ else *tok = 0;
+ }
+ else if (MoveIndexPastString(string, i, "assessdraw"))
+ {
+ if (g->rated)
+ rating_sterr_delta(g->black, g->white, g->type,
+ time(0), RESULT_DRAW, tok, &dummy_sterr);
+ else *tok = 0;
+ }
+ else if (MoveIndexPastString(string, i, "assesswin"))
+ {
+ if (g->rated)
+ rating_sterr_delta(g->black, g->white, g->type,
+ time(0), RESULT_WIN, tok, &dummy_sterr);
+ else *tok = 0;
+ }
+ else if (MoveIndexPastString(string, i, "mymaxtime"))
+ {
+ if (GetNumberInsideParens(g, clause, i, tok, eval) != ERR_NONE)
+ return (0);
+ *tok = Maxtime (g, *tok, 1);
+ }
+#ifdef TIMESEAL
+ else if (MoveIndexPastString(string, i, "timeseal"))
+ *tok = con[you->socket].timeseal;
+#endif
+ else if (MoveIndexPastString(string, i, "myrating"))
+ *tok = GetRating(me, g->type);
+ else if (MoveIndexPastString(string, i, "computer"))
+ *tok = in_list(-1, L_COMPUTER, you->name);
+ else if (MoveIndexPastString(string, i, "standard"))
+ *tok = (g->type == TYPE_STAND);
+ else if (MoveIndexPastString(string, i, "private"))
+ *tok = you->private;
+ else if (MoveIndexPastString(string, i, "maxtime"))
+ {
+ if (GetNumberInsideParens(g, clause, i, tok, eval) != ERR_NONE)
+ return (0);
+ *tok = Maxtime (g, *tok, 2);
+ }
+ else if (MoveIndexPastString(string, i, "abuser"))
+ *tok = in_list(-1, L_ABUSER, you->name);
+ else if (MoveIndexPastString(string, i, "rating"))
+ *tok = GetRating(you, g->type);
+ else if (MoveIndexPastString(string, i, "rated")) *tok=g->rated;
+ else if (MoveIndexPastString(string, i, "blitz")) *tok = (g->type == TYPE_BLITZ);
+ else if (MoveIndexPastString(string, i, "wild")) *tok = (g->type == TYPE_WILD);
+ else if (MoveIndexPastString(string, i, "lightning")) *tok = (g->type == TYPE_LIGHT);
+ else if (MoveIndexPastString(string, i, "nonstandard")) *tok = (g->type == TYPE_NONSTANDARD);
+ else if (MoveIndexPastString(string, i, "untimed")) *tok = (g->type == TYPE_UNTIMED);
+ else if (MoveIndexPastString(string, i, "time")) *tok=g->wInitTime;
+ else if (MoveIndexPastString(string, i, "inc")) *tok=g->wIncrement;
+ else if (tolower(string[*i])=='f' && isdigit(string[*i+1]) &&
+ (c = (string[*i+1]-'1')) >= 0 && clause > c)
+ {
+ *i += 2;
+ return (!CheckFormula (g, c, &index, OPTYPE_NONE, tok, eval));
+ }
+ else return (0);
+ return (1);
+} /* end of function VarToToken. */
+
+/* ScanForOp checks for an operator at position *i in string[]. */
+int ScanForOp (char *string, int *i)
+{
+ while (string[*i] != '\0' && isspace(string[*i])) (*i)++;
+
+ if (string[*i] == '\0') return (OP_NONE);
+ if (string[*i] == '#') return (OP_NONE);
+ if (string[*i] == ')') return (OP_RTPAREN);
+
+ /* Two char operators and longer first. */
+ if (MoveIndexPastString(string, i, "and")) return (OP_AND);
+ if (MoveIndexPastString(string, i, "or")) return (OP_OR);
+ if (MoveIndexPastString(string, i, "||")) return (OP_OR);
+ if (MoveIndexPastString(string, i, "&&")) return (OP_AND);
+ if (MoveIndexPastString(string, i, "==")) return (OP_EQ);
+ if (MoveIndexPastString(string, i, "!=")) return (OP_NEQ);
+ if (MoveIndexPastString(string, i, "<>")) return (OP_NEQ);
+ if (MoveIndexPastString(string, i, ">=")) return (OP_GE);
+ if (MoveIndexPastString(string, i, "=>")) return (OP_GE);
+ if (MoveIndexPastString(string, i, "<=")) return (OP_LE);
+ if (MoveIndexPastString(string, i, "=<")) return (OP_LE);
+
+ /* One char operators now. */
+ if (MoveIndexPastString(string, i, "|")) return (OP_OR);
+ if (MoveIndexPastString(string, i, "&")) return (OP_AND);
+ if (MoveIndexPastString(string, i, ">")) return (OP_GT);
+ if (MoveIndexPastString(string, i, "<")) return (OP_LT);
+ if (MoveIndexPastString(string, i, "=")) return (OP_EQ);
+ if (MoveIndexPastString(string, i, "+")) return (OP_PLUS);
+ if (MoveIndexPastString(string, i, "-")) return (OP_MINUS);
+ if (MoveIndexPastString(string, i, "*")) return (OP_MULT);
+ if (MoveIndexPastString(string, i, "/")) return (OP_DIV);
+ return (OP_BAD);
+} /* end of function ScanForOp. */
+
+/* OpType returns the precedence of the operator op. */
+int OpType (int op)
+{
+ switch (op)
+ {
+ case OP_BAD: return (OPTYPE_BAD);
+ case OP_NONE: return (OPTYPE_NONE);
+ case OP_RTPAREN: return (OPTYPE_RPAREN);
+ case OP_OR: return (OPTYPE_OR);
+ case OP_AND: return (OPTYPE_AND);
+ case OP_EQ: case OP_NEQ: return (OPTYPE_COMPEQ);
+ case OP_GT: case OP_GE: case OP_LT: case OP_LE: return (OPTYPE_COMPGL);
+ case OP_PLUS: case OP_MINUS: return (OPTYPE_ADD);
+ case OP_MULT: case OP_DIV: return (OPTYPE_MULT);
+ case OP_NEGATE: case OP_NOT: return (OPTYPE_UNARY);
+ default: return (OPTYPE_BAD);
+ }
+} /* end of function OpType. */
+
+/* In EvalBinaryOp, *left is the left operand; and op is the
+ current operator. *g and clause specify which formula string to
+ look at (we're checking parray[g->black].formulaLines[clause]),
+ and *i tells us where we are in the string. We look for a right
+ operand from position *i in the string, and place the expression
+ (*left op right) in *left. For example, if *left=6, op =
+ OP_MULT, and we pull off right = 4, we replace *left with
+ 6*4=24. Returns 0 if no error; otherwise indicates the error.
+*/
+int EvalBinaryOp (int *left, int op, game *g, int clause, int *i)
+{
+ int right, ret;
+ if ((op==OP_OR) && (*left != 0)) /* Nothing to decide. */
+ {
+ *left = 1;
+ return (CheckFormula (g, clause, i, OpType(op), &right, 0));
+ }
+ else if ((op==OP_AND) && (*left == 0)) /* Nothing to decide. */
+ return (CheckFormula (g, clause, i, OpType(op), &right, 0));
+
+ else {
+ ret = CheckFormula (g, clause, i, OpType(op), &right, 1);
+ if (ret != ERR_NONE) return (ret);
+ }
+ switch (op)
+ {
+ default: case OP_BAD: return (ERR_BADOP);
+ case OP_NONE: case OP_RTPAREN: return (ERR_NONE);
+ case OP_OR: *left = (*left || right); return (ERR_NONE);
+ case OP_AND: *left = (*left && right); return (ERR_NONE);
+ case OP_EQ: *left = (*left == right); return (ERR_NONE);
+ case OP_NEQ: *left = (*left != right); return (ERR_NONE);
+ case OP_GT: *left = (*left > right); return (ERR_NONE);
+ case OP_GE: *left = (*left >= right); return (ERR_NONE);
+ case OP_LT: *left = (*left < right); return (ERR_NONE);
+ case OP_LE: *left = (*left <= right); return (ERR_NONE);
+ case OP_PLUS: *left += right; return (ERR_NONE);
+ case OP_MINUS: *left -= right; return (ERR_NONE);
+ case OP_MULT: *left *= right; return (ERR_NONE);
+ case OP_DIV:
+ if (right != 0)
+ {
+ *left /= right;
+ return (ERR_NONE);
+ }
+ else
+ {
+ pprintf(g->black, "Dividing by %lf instead or zero in formula.\n",
+FUDGE_FACTOR);
+ *left /= FUDGE_FACTOR;
+ return (ERR_NONE);
+ }
+ }
+} /* end of function EvalBinaryOp. */
+
+/* If eval is 1, ScanForNumber evaluates the number at position *i
+ in the formula given by *g and clause, and place this value in
+ *token. op_type is the precedence of the operator preceding the
+ *i'th position. If we come to an operator of higher precedence,
+ we must keep going before we can leave this function. If eval
+ is 0, just move past the number we would evaluate. Returns 0 if
+ no error; otherwise return code indicates the error.
+*/
+int ScanForNumber (game *g, int clause, int *i, int op_type,
+ int *token, int eval)
+{
+ char *string = GetPlayersFormula (&parray[g->black], clause);
+ char c;
+ int ret;
+
+ while ((string[*i] != '\0') && (isspace(string[*i]))) (*i)++;
+ switch (c = string[*i])
+ {
+ case '\0': case '#':
+ if (op_type != OPTYPE_NONE) return (ERR_EOF);
+ else *token=1;
+ return (ERR_NONE);
+
+ case ')':
+ if (op_type != OPTYPE_PAREN) return (ERR_PAREN);
+ else *token=1;
+ return(ERR_NONE);
+
+ case '(': return GetNumberInsideParens(g,clause,i,token,eval);
+
+ case '-': case '!':
+ ++(*i);
+ if (c==string[*i]) return(ERR_UNARY);
+ ret = ScanForNumber(g,clause,i,OPTYPE_UNARY,token,eval);
+ if (ret != ERR_NONE)
+ return (ret);
+ if (c == '-') *token = -(*token);
+ else if (c == '!') *token = !(*token);
+ return (ERR_NONE);
+
+ default:
+ if (isdigit(string[*i]))
+ {
+ *token = 0;
+
+ do *token = 10 * (*token) + string[(*i)++] - '0';
+ while (isdigit(string[*i]));
+
+ while (string[*i] != '\0' && isspace(string[*i])) (*i)++;
+ if (MoveIndexPastString (string, i, "minutes"))
+ *token *= 60;
+ return (ERR_NONE);
+ }
+ else if (isalpha(string[*i]))
+ {
+ if (!VarToToken (g, clause, string, i, token, eval))
+ return (ERR_BADVAR);
+ return(ERR_NONE);
+ }
+ else return (ERR_NONESENSE);
+ }
+} /* end of function ScanForNumber. */
+
+/* If eval is 1, CheckFormula looks for the next token in the
+ formula given by *g, clause, and *i; usually this is the right
+ side of an expression whose operator has precedence OpType; if
+ eval is 0, just go to the end of an expression. Return 0 if no
+ error; otherwise, return error type.
+*/
+int CheckFormula (game *g, int clause, int *i, int op_type,
+ int *result, int eval)
+{
+ int token, ret, nextOp, lastPos;
+ char *string = GetPlayersFormula (&parray[g->black], clause);
+
+ if (string == NULL)
+ {
+ *result = 1;
+ return (ERR_NONE);
+ }
+ ret = ScanForNumber (g, clause, i, op_type, &token, eval);
+ if (ret != ERR_NONE)
+ return (ret);
+ lastPos = *i;
+ nextOp = ScanForOp (string, i);
+ while (OpType(nextOp) > op_type) /* higher precedence. */
+ {
+ if (nextOp==OP_RTPAREN) return (ERR_PAREN);
+ if (!eval)
+ ret = CheckFormula(g, clause, i, OpType(nextOp), &token, 0);
+ else ret = EvalBinaryOp (&token, nextOp, g, clause, i);
+ if (ret != ERR_NONE) return (ret);
+ lastPos = *i;
+ nextOp = ScanForOp (string, i);
+ }
+ if (nextOp == OP_BAD) return(ERR_BADOP);
+ *result = token;
+
+ /* move back unless we're at the end or at a right paren, in which
+ case we never went forward. */
+ if (nextOp != OP_NONE && nextOp != OP_RTPAREN) *i=lastPos;
+ return (ERR_NONE);
+} /* end of function CheckFormula. */
+
+/* which clauses are relevant for a player's formula. */
+PRIVATE int ChooseClauses(player *who, char *formula)
+{
+ int i, which, ret=0;
+
+ if (formula == NULL)
+ return ret;
+ for (i=0; formula[i] != '\0' && formula[i] != '#'; i++) {
+ if (formula[i] != 'f' || (i > 0 && isalnum(formula[i-1]))
+ || !isdigit(formula[i+1]))
+ continue;
+ sscanf(&formula[i], "f%d", &which);
+ ret |= (1 << (which - 1));
+ }
+ /* now scan clauses found as part of the formula. */
+ for (i = MAX_FORMULA - 1; i >= 0; i--) {
+ if (ret & (1 << i)) {
+ ret |= ChooseClauses(who, who->formulaLines[i]);
+ }
+ }
+ return ret;
+} /* end of function ChooseClauses. */
+
+void ExplainFormula (game *g, textlist **clauses)
+{
+ int i, which, dummy_index, value;
+ char txt[20];
+ player *challenged = &parray[g->black];
+ textlist **Cur = clauses;
+
+ which = ChooseClauses(challenged, challenged->formula);
+
+ for (i = 0; i < MAX_FORMULA; i++) {
+ if ((which & (1 << i)) == 0)
+ continue;
+ dummy_index = 0;
+ CheckFormula (g, i, &dummy_index, OPTYPE_NONE, &value, 1);
+ sprintf(txt, "%d", value);
+ SaveTextListEntry (Cur, txt, i);
+ Cur = &(*Cur)->next;
+ }
+}
+
+#if 0
+void ExplainFormula (game *g, textlist *eval)
+{
+ int i, newPos, value;
+ char Head[MAX_STRING_LENGTH],
+ Tail[MAX_STRING_LENGTH];
+
+ strcpy (strRet, GetPlayersFormula(&parray[g->black], clause));
+ for (i=0; strRet[i] != '\0'; i++)
+ {
+ if (strRet[i] == '#')
+ {
+ strRet[i] = '\0';
+ break;
+ }
+ if (!isalpha(strRet[i])) continue;
+ newPos = i;
+ if (!VarToToken(g, clause, strRet, &newPos, &value, 1))
+ i = newPos;
+ else
+ {
+ strcpy (Head, strRet);
+ strcpy (Tail, strRet + newPos);
+ Head[i] = '\0';
+
+ sprintf(strRet, "%s%d%s", Head, value, Tail);
+ while (isalpha(strRet[i])) i++;
+ }
+ }
+}
+#endif
+
+/* GameMatchesFormula converts parameters to a game structure
+ and passes a pointer to this game to CheckFormula for
+ evaluation. It returns the evaluated formula.
+*/
+PUBLIC int GameMatchesFormula (int w, int b, int wTime, int wInc, int bTime,
+ int bInc, int rated, int gametype, textlist **clauseList)
+{
+ game g;
+ int index=0, ret;
+
+ g.white = w; g.black = b;
+ g.wInitTime = wTime; g.bInitTime = bTime;
+ g.wIncrement = wInc; g.bIncrement = bInc;
+ g.rated = rated;
+ g.type = gametype;
+
+ if (CheckFormula(&g, MAX_FORMULA, &index, OPTYPE_NONE, &ret, 1) != ERR_NONE)
+ return (0);
+ if (ret == 0) ExplainFormula (&g, clauseList);
+ return (ret);
+} /* end of function GameMatchesFormula. */
+
+/* SetValidFormula sets a clause of player p and creates a game structure
+ to check whether that new formula is legitimate. If so, return 1;
+ otherwise, reset the formula and return 0.
+*/
+int SetValidFormula (int p, int clause, char *string)
+{
+ game g;
+ int index=0, ret, err=ERR_NONE;
+ char *Old=NULL, **Cur;
+ player *me = &parray[p];
+
+ if (clause==MAX_FORMULA)
+ Cur = &me->formula;
+ else
+ Cur = &me->formulaLines[clause];
+
+ Old = *Cur;
+
+ if (string != NULL) {
+ string = eatwhite(string);
+ *Cur = (*string != '\0' ? strdup (string) : NULL);
+ }
+ else *Cur = NULL;
+
+ if (*Cur==NULL) {
+ if (Old != NULL) rfree(Old);
+ return 1;
+ }
+
+ g.white = g.black = p;
+ g.wInitTime = g.bInitTime = me->d_time;
+ g.wIncrement = g.bIncrement = me->d_inc;
+ g.rated = me->rated;
+ g.type = TYPE_BLITZ;
+ err = CheckFormula (&g, clause, &index, OPTYPE_NONE, &ret, 0);
+
+ if (err != ERR_NONE) {
+ /* Bad formula; reset it. */
+ rfree(*Cur);
+ *Cur = Old;
+ } else {
+ if (Old != NULL) rfree(Old);
+ }
+ return (err == ERR_NONE);
+}
+
+PUBLIC void ShowClauses (int p, int p1, textlist *clauses)
+{
+ textlist *Cur;
+
+ if (clauses != NULL)
+ pprintf(p, "\n");
+ for (Cur = clauses; Cur != NULL; Cur = Cur->next) {
+ pprintf(p, "f%d=%s: %s\n", Cur->index + 1, Cur->text,
+ parray[p1].formulaLines[Cur->index]);
+ }
+}
blob - /dev/null
blob + 17417c57af817a3b208ad3c2c0da781e38d5a989 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/formula.h
+#ifndef FORMULA_H
+#define FORMULA_H
+
+#define OP_BAD -1
+#include "playerdb.h"
+#include "gamedb.h"
+
+#define OP_NONE 0
+#define OP_RTPAREN 1
+#define OP_OR 2
+#define OP_AND 3
+#define OP_EQ 4
+#define OP_NEQ 5
+#define OP_GT 6
+#define OP_GE 7
+#define OP_LT 8
+#define OP_LE 9
+#define OP_PLUS 10
+#define OP_MINUS 11
+#define OP_MULT 12
+#define OP_DIV 13
+#define OP_NEGATE 14
+#define OP_NOT 15
+
+#define OPTYPE_BAD 0
+#define OPTYPE_NONE 1
+#define OPTYPE_RPAREN 2
+#define OPTYPE_PAREN 3
+#define OPTYPE_OR 4
+#define OPTYPE_AND 5
+#define OPTYPE_COMPEQ 6
+#define OPTYPE_COMPGL 7
+#define OPTYPE_ADD 8
+#define OPTYPE_MULT 9
+#define OPTYPE_UNARY 10
+
+#define ERR_NONE 0
+#define ERR_EOF 1
+#define ERR_UNARY 2
+#define ERR_BADCHAR 3
+#define ERR_BADVAR 4
+#define ERR_BADOP 5
+#define ERR_NONESENSE 6
+#define ERR_DIVBYZERO 7
+#define ERR_PAREN 8
+
+#define FUDGE_FACTOR 1e-3
+
+extern int GetRating (player *, int);
+extern int GameMatchesFormula (int, int, int, int, int, int, int, int, textlist **);
+extern int CheckFormula (game *, int, int *, int, int *, int);
+extern void ShowClauses (int, int, textlist *);
+
+#endif
+
blob - /dev/null
blob + 4ad10c61f94d22e56a2e75943f756d05f5649d8d (mode 644)
Binary files /dev/null and FICS.DIST/FICS/formula.o differ
blob - /dev/null
blob + 03c677d36def8d365f86e2381aa3f90dedb9678c (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/gamedb.c
+/* gamedb.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "gamedb.h"
+#include "playerdb.h"
+#include "gameproc.h"
+#include "command.h"
+#include "utils.h"
+#include "rmalloc.h"
+#include "eco.h"
+#include "network.h"
+
+PUBLIC game *garray = NULL;
+PUBLIC int g_num = 0;
+
+PRIVATE int get_empty_slot()
+/* this method is awful! how about allocation as we need it and freeing
+ afterwards! */
+{
+ int i;
+
+ for (i = 0; i < g_num; i++) {
+ if (garray[i].status == GAME_EMPTY)
+ return i;
+ }
+ g_num++;
+ if (!garray) {
+ garray = (game *) rmalloc(sizeof(game) * g_num);
+ } else {
+ garray = (game *) rrealloc(garray, sizeof(game) * g_num);
+ } /* yeah great, bet this causes lag! - DAV*/
+ garray[g_num - 1].status = GAME_EMPTY;
+ return g_num - 1;
+}
+
+PUBLIC int game_new()
+{
+ int new = get_empty_slot();
+ game_zero(new);
+ return new;
+}
+
+PUBLIC int game_zero(int g)
+{
+ garray[g].white = -1;
+ garray[g].black = -1;
+/* garray[g].old_white = -1;
+ garray[g].old_black = -1;
+*/
+ garray[g].status = GAME_NEW;
+ garray[g].link = -1;
+ garray[g].rated = 0;
+ garray[g].private = 0;
+ garray[g].result = END_NOTENDED;
+ garray[g].type = TYPE_UNTIMED;
+ garray[g].passes = 0;
+ board_init(&garray[g].game_state, NULL, NULL);
+ garray[g].game_state.gameNum = g;
+ garray[g].numHalfMoves = 0;
+ garray[g].moveListSize = 0;
+ garray[g].moveList = NULL;
+ garray[g].examMoveListSize = 0;
+ garray[g].examMoveList = NULL;
+ garray[g].wInitTime = 300; /* 5 minutes */
+ garray[g].wIncrement = 0;
+ garray[g].bInitTime = 300; /* 5 minutes */
+ garray[g].bIncrement = 0;
+#ifdef TIMESEAL
+ garray[g].flag_pending = FLAG_NONE;
+ garray[g].flag_check_time = 0L;
+#endif
+ garray[g].white_name[0] = '\0';
+ garray[g].black_name[0] = '\0';
+ garray[g].white_rating = 0;
+ garray[g].black_rating = 0;
+ garray[g].revertHalfMove = 0;
+ return 0;
+}
+
+PUBLIC int game_free(int g)
+{
+ if (garray[g].moveListSize)
+ rfree(garray[g].moveList);
+ if (garray[g].examMoveListSize)
+ rfree(garray[g].examMoveList);
+ garray[g].moveListSize = 0;
+ garray[g].examMoveListSize = 0;
+ return 0;
+}
+
+PUBLIC int game_clear(int g)
+{
+ game_free(g);
+ game_zero(g);
+ return 0;
+}
+
+PUBLIC int game_remove(int g)
+{
+ /* Should remove game from players observation list */
+ game_clear(g);
+ garray[g].status = GAME_EMPTY;
+ return 0;
+}
+
+/* old moves not stored now - uses smoves */
+PUBLIC int game_finish(int g)
+{
+ player_game_ended(g); /* Alert playerdb that game ended */
+/* NewOldGame(g); */
+/* game_free(g) */
+ game_remove(g);
+ return 0;
+}
+
+#if 0
+PUBLIC void PosToBoardList (int g)
+{
+ if (garray[g].numHalfMoves >= garray[g].boardListSize) {
+ garray[g].boardListSize += 50;
+ if (garray[g].boardListSize <= 50)
+ garray[g].boardList =
+ (boardList_t *) rmalloc(garray[g].boardListSize * sizeof(boardList_t));
+ else
+ garray[g].boardList = (boardList_t *) rrealloc (garray[g].boardList,
+ garray[g].boardListSize * sizeof(boardList_t));
+ }
+ if (garray[g].boardList != NULL)
+ strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g));
+ else
+ fprintf(stderr, "Board List could not be allocated for game %d.\n", g+1);
+}
+#endif
+
+PUBLIC void MakeFENpos (int g, char *FEN)
+{
+ strcpy(FEN, boardToFEN(g));
+}
+
+PUBLIC char *game_time_str(int wt, int winc, int bt, int binc)
+{
+ static char tstr[50];
+
+ if ((!wt) && (!winc)) { /* Untimed */
+ strcpy(tstr, "");
+ return tstr;
+ }
+ if ((wt == bt) && (winc == binc)) {
+ sprintf(tstr, " %d %d", wt, winc);
+ } else {
+ sprintf(tstr, " %d %d : %d %d", wt, winc, bt, binc);
+ }
+ return tstr;
+}
+
+PUBLIC char *bstr[] = {"untimed", "blitz", "standard", "non-standard", "wild", "lightning", "bughouse"};
+PUBLIC char *rstr[] = {"unrated", "rated"};
+
+PUBLIC char *game_str(int rated, int wt, int winc, int bt, int binc,
+ char *cat, char *board)
+{
+ static char tstr[200];
+
+ if (cat && cat[0] && board && board[0] &&
+ (strcmp(cat, "standard") || strcmp(board, "standard"))) {
+ sprintf(tstr, "%s %s%s Loaded from %s/%s",
+ rstr[rated],
+ bstr[game_isblitz(wt / 60, winc, bt / 60, binc, cat, board)],
+ game_time_str(wt / 60, winc, bt / 60, binc),
+ cat, board);
+ } else {
+ sprintf(tstr, "%s %s%s",
+ rstr[rated],
+ bstr[game_isblitz(wt / 60, winc, bt / 60, binc, cat, board)],
+ game_time_str(wt / 60, winc, bt / 60, binc));
+ }
+ return tstr;
+}
+
+PUBLIC int game_isblitz(int wt, int winc, int bt, int binc,
+ char *cat, char *board)
+{
+ int total;
+
+ if (cat && cat[0] && board && board[0] && (!strcmp(cat, "wild")))
+ return TYPE_WILD;
+ if (cat && cat[0] && board && board[0] &&
+ (strcmp(cat, "standard") || strcmp(board, "standard")))
+ return TYPE_NONSTANDARD;
+ if (((wt == 0) && (winc == 0)) || ((bt == 0) && (binc == 0)))
+ /* nonsense if one is timed and one is not */
+ return TYPE_UNTIMED;
+ if ((wt != bt) || (winc != binc))
+ return TYPE_NONSTANDARD;
+ total = wt * 60 + winc * 40;
+ if (total < 180) /* 3 minute */
+ return TYPE_LIGHT;
+ if (total >= 900) /* 15 minutes */
+ return TYPE_STAND;
+ else
+ return TYPE_BLITZ;
+}
+
+PUBLIC void send_board_to(int g, int p)
+{
+ char *b;
+ int side;
+ int relation;
+
+/* since we know g and p, figure out our relationship to this game */
+
+ side = WHITE;
+ if (garray[g].status == GAME_EXAMINE) {
+ if (parray[p].game == g) {
+ relation = 2;
+ } else {
+ relation = -2;
+ }
+ } else {
+ if (parray[p].game == g) {
+ side = parray[p].side;
+ relation = ((side == garray[g].game_state.onMove) ? 1 : -1);
+ } else {
+ relation = 0;
+ }
+ }
+
+ if (parray[p].flip) { /* flip board? */
+ if (side == WHITE)
+ side = BLACK;
+ else
+ side = WHITE;
+ }
+ game_update_time(g);
+ b = board_to_string(garray[g].white_name,
+ garray[g].black_name,
+ garray[g].wTime,
+ garray[g].bTime,
+ &garray[g].game_state,
+ (garray[g].status == GAME_EXAMINE) ?
+ garray[g].examMoveList : garray[g].moveList,
+ parray[p].style,
+ side, relation, p);
+
+#ifdef TIMESEAL
+
+ if (con[parray[p].socket].timeseal) {
+ if (parray[p].bell) {
+ pprintf_noformat(p, "\007\n[G]\n%s", b);
+ } else {
+ pprintf_noformat(p, "\n[G]\n%s", b);
+ }
+ } else {
+ if (parray[p].bell) {
+ pprintf_noformat(p, "\007\n%s", b);
+ } else {
+ pprintf_noformat(p, "\n%s", b);
+ }
+ }
+
+#else
+
+ if (parray[p].bell) {
+ pprintf_noformat(p, "\007\n%s", b);
+ } else {
+ pprintf_noformat(p, "\n%s", b);
+ }
+
+#endif
+
+ if (p != commanding_player) {
+ pprintf(p, "%s", parray[p].prompt);
+ }
+}
+
+PUBLIC void send_boards(int g)
+{
+ int p;
+ simul_info_t *simInfo = &parray[garray[g].white].simul_info;
+
+ if (simInfo->numBoards == 0 || simInfo->boards[simInfo->onBoard] == g)
+ for (p = 0; p < p_num; p++) {
+ if (parray[p].status == PLAYER_EMPTY)
+ continue;
+ if (player_is_observe(p, g) || (parray[p].game == g))
+ send_board_to(g, p);
+ }
+}
+
+PUBLIC void game_update_time(int g)
+{
+ unsigned now, timesince;
+
+ if (garray[g].clockStopped)
+ return;
+ if (garray[g].type == TYPE_UNTIMED)
+ return;
+ now = tenth_secs();
+ timesince = now - garray[g].lastDecTime;
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime -= timesince;
+ } else {
+ garray[g].bTime -= timesince;
+ }
+ garray[g].lastDecTime = now;
+}
+
+PUBLIC void game_update_times()
+{
+ int g;
+
+ for (g = 0; g < g_num; g++) {
+ if (garray[g].status != GAME_ACTIVE)
+ continue;
+ if (garray[g].clockStopped)
+ continue;
+ game_update_time(g);
+ }
+}
+
+#if 0 /* oldgame is obsolete - games are stored in history */
+PRIVATE int oldGameArray[MAXOLDGAMES];
+PRIVATE int numOldGames = 0;
+
+PRIVATE int RemoveOldGame(int g)
+{
+ int i;
+
+ for (i = 0; i < numOldGames; i++) {
+ if (oldGameArray[i] == g)
+ break;
+ }
+ if (i == numOldGames)
+ return -1; /* Not found! */
+ for (; i < numOldGames - 1; i++)
+ oldGameArray[i] = oldGameArray[i + 1];
+ numOldGames--;
+ game_remove(g);
+ return 0;
+}
+
+PRIVATE int AddOldGame(int g)
+{
+ if (numOldGames == MAXOLDGAMES) /* Remove the oldest */
+ RemoveOldGame(oldGameArray[0]);
+ oldGameArray[numOldGames] = g;
+ numOldGames++;
+ return 0;
+}
+
+PUBLIC int FindOldGameFor(int p)
+{
+ int i;
+
+ if (p == -1)
+ return numOldGames - 1;
+ for (i = numOldGames - 1; i >= 0; i--) {
+ if (garray[oldGameArray[i]].old_white == p)
+ return oldGameArray[i];
+ if (garray[oldGameArray[i]].old_black == p)
+ return oldGameArray[i];
+ }
+ return -1;
+}
+
+/* This just removes the game if both players have new-old games */
+PUBLIC int RemoveOldGamesForPlayer(int p)
+{
+ int g;
+
+ g = FindOldGameFor(p);
+ if (g < 0)
+ return 0;
+ if (garray[g].old_white == p)
+ garray[g].old_white = -1;
+ if (garray[g].old_black == p)
+ garray[g].old_black = -1;
+ if ((garray[g].old_white == -1) && (garray[g].old_black == -1)) {
+ RemoveOldGame(g);
+ }
+ return 0;
+}
+
+/* This recycles any old games for players who disconnect */
+PUBLIC int ReallyRemoveOldGamesForPlayer(int p)
+{
+ int g;
+
+ g = FindOldGameFor(p);
+ if (g < 0)
+ return 0;
+ RemoveOldGame(g);
+ return 0;
+}
+
+PUBLIC int NewOldGame(int g)
+{
+ RemoveOldGamesForPlayer(garray[g].white);
+ RemoveOldGamesForPlayer(garray[g].black);
+ garray[g].old_white = garray[g].white;
+ garray[g].old_black = garray[g].black;
+ garray[g].status = GAME_STORED;
+ AddOldGame(g);
+ return 0;
+}
+#endif
+
+PUBLIC char *EndString(int g, int personal)
+{
+/* personal 0 == White checkmated; personal 1 == loon checkmated */
+
+ static char endstr[200];
+ char *blackguy, *whiteguy;
+ static char blackstr[] = "Black";
+ static char whitestr[] = "White";
+
+ blackguy = (personal ? garray[g].black_name : blackstr);
+ whiteguy = (personal ? garray[g].white_name : whitestr);
+
+ switch (garray[g].result) {
+ case END_CHECKMATE:
+ sprintf(endstr, "%s checkmated",
+ garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_RESIGN:
+ sprintf(endstr, "%s resigned",
+ garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_FLAG:
+ sprintf(endstr, "%s ran out of time",
+ garray[g].winner == WHITE ? blackguy : whiteguy);
+ break;
+ case END_AGREEDDRAW:
+ sprintf(endstr, "Game drawn by mutual agreement");
+ break;
+ case END_BOTHFLAG:
+ sprintf(endstr, "Game drawn because both players ran out of time");
+ break;
+ case END_REPETITION:
+ sprintf(endstr, "Game drawn by repetition");
+ break;
+ case END_50MOVERULE:
+ sprintf(endstr, "Draw by the 50 move rule");
+ break;
+ case END_ADJOURN:
+ sprintf(endstr, "Game adjourned by mutual agreement");
+ break;
+ case END_LOSTCONNECTION:
+ sprintf(endstr, "%s lost connection, game adjourned",
+ garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_ABORT:
+ sprintf(endstr, "Game aborted by mutual agreement");
+ break;
+ case END_STALEMATE:
+ sprintf(endstr, "Stalemate.");
+ break;
+ case END_NOTENDED:
+ sprintf(endstr, "Still in progress");
+ break;
+ case END_COURTESY:
+ sprintf(endstr, "Game courtesyaborted by %s",
+ garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_COURTESYADJOURN:
+ sprintf(endstr, "Game courtesyadjourned by %s",
+ garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_NOMATERIAL:
+ sprintf(endstr, "Game drawn because neither player has mating material");
+ break;
+ case END_FLAGNOMATERIAL:
+ sprintf(endstr, "%s ran out of time and %s has no material to mate",
+ garray[g].winner == WHITE ? blackguy : whiteguy,
+ garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_ADJDRAW:
+ sprintf(endstr, "Game drawn by adjudication");
+ break;
+ case END_ADJWIN:
+ sprintf(endstr, "%s wins by adjudication",
+ garray[g].winner == WHITE ? whiteguy : blackguy);
+ break;
+ case END_ADJABORT:
+ sprintf(endstr, "Game aborted by adjudication");
+ break;
+ default:
+ sprintf(endstr, "???????");
+ break;
+ }
+
+ return (endstr);
+}
+
+PUBLIC char *EndSym(int g)
+{
+ static char *symbols[] = {"1-0", "0-1", "1/2-1/2", "*"};
+
+ switch (garray[g].result) {
+ case END_CHECKMATE:
+ case END_RESIGN:
+ case END_FLAG:
+ case END_ADJWIN:
+ return ((garray[g].winner == WHITE) ? symbols[0] : symbols[1]);
+ break;
+ case END_AGREEDDRAW:
+ case END_BOTHFLAG:
+ case END_REPETITION:
+ case END_50MOVERULE:
+ case END_STALEMATE:
+ case END_NOMATERIAL:
+ case END_FLAGNOMATERIAL:
+ case END_ADJDRAW:
+ return (symbols[2]);
+ break;
+ }
+
+ return (symbols[3]);
+}
+
+/* This should be enough to hold any game up to at least 250 moves
+ * If we overwrite this, the server will crash.
+ */
+#define GAME_STRING_LEN 16000
+PRIVATE char gameString[GAME_STRING_LEN];
+PUBLIC char *movesToString(int g, int pgn)
+{
+ char tmp[160];
+ int wr, br;
+ int i, col;
+ unsigned curTime;
+ char *serv_loc = SERVER_LOCATION;
+ char *serv_name = SERVER_NAME;
+
+ wr = garray[g].white_rating;
+ br = garray[g].black_rating;
+
+
+ curTime = untenths(garray[g].timeOfStart);
+
+ if (pgn) {
+ sprintf(gameString,
+ "\n[Event \"%s %s %s game\"]\n"
+ "[Site \"%s, %s\"]\n",
+ serv_name,rstr[garray[g].rated], bstr[garray[g].type],serv_name,serv_loc);
+ strftime(tmp, sizeof(tmp),
+ "[Date \"%Y.%m.%d\"]\n"
+ "[Time \"%H:%M:%S\"]\n",
+ localtime((time_t *) &curTime));
+ strcat(gameString, tmp);
+ sprintf(tmp,
+ "[Round \"-\"]\n"
+ "[White \"%s\"]\n"
+ "[Black \"%s\"]\n"
+ "[WhiteElo \"%d\"]\n"
+ "[BlackElo \"%d\"]\n",
+ garray[g].white_name, garray[g].black_name, wr, br);
+ strcat(gameString, tmp);
+ sprintf(tmp,
+ "[TimeControl \"%d+%d\"]\n"
+ "[Mode \"ICS\"]\n"
+ "[Result \"%s\"]\n\n",
+ garray[g].wInitTime / 10, garray[g].wIncrement / 10, EndSym(g));
+ strcat(gameString, tmp);
+
+ col = 0;
+ for (i = 0; i < garray[g].numHalfMoves; i++) {
+ if (!(i % 2)) {
+ if ((col += sprintf(tmp, "%d. ", i / 2 + 1)) > 70) {
+ strcat(gameString, "\n");
+ col = 0;
+ }
+ strcat(gameString, tmp);
+ }
+ if ((col += sprintf(tmp, "%s ", (garray[g].status == GAME_EXAMINE) ? garray[g].examMoveList[i].algString : garray[g].moveList[i].algString)) > 70) {
+ strcat(gameString, "\n");
+ col = 0;
+ }
+ strcat(gameString, tmp);
+ }
+ strcat(gameString, "\n");
+
+ } else {
+
+ sprintf(gameString, "\n%s ", garray[g].white_name);
+ if (wr > 0) {
+ sprintf(tmp, "(%d) ", wr);
+ } else {
+ sprintf(tmp, "(UNR) ");
+ }
+ strcat(gameString, tmp);
+ sprintf(tmp, "vs. %s ", garray[g].black_name);
+ strcat(gameString, tmp);
+ if (br > 0) {
+ sprintf(tmp, "(%d) ", br);
+ } else {
+ sprintf(tmp, "(UNR) ");
+ }
+ strcat(gameString, tmp);
+ strcat(gameString, "--- ");
+ strcat(gameString, (char*) (localtime((time_t *) &curTime)));
+ if (garray[g].rated) {
+ strcat(gameString, "\nRated ");
+ } else {
+ strcat(gameString, "\nUnrated ");
+ }
+ if (garray[g].type == TYPE_BLITZ) {
+ strcat(gameString, "Blitz ");
+ } else if (garray[g].type == TYPE_LIGHT) {
+ strcat(gameString, "Lighting ");
+ } else if (garray[g].type == TYPE_BUGHOUSE) {
+ strcat(gameString, "Bughouse ");
+ } else if (garray[g].type == TYPE_STAND) {
+ strcat(gameString, "Standard ");
+ } else if (garray[g].type == TYPE_WILD) {
+ strcat(gameString, "Wild ");
+ } else if (garray[g].type == TYPE_NONSTANDARD) {
+ strcat(gameString, "Non-standard ");
+ } else {
+ strcat(gameString, "Untimed ");
+ }
+ strcat(gameString, "match, initial time: ");
+ if ((garray[g].bInitTime != garray[g].wInitTime) || (garray[g].wIncrement != garray[g].bIncrement)) { /* different starting times */
+ sprintf(tmp, "%d minutes, increment: %d seconds AND %d minutes, increment: %d seconds.\n\n", garray[g].wInitTime / 600, garray[g].wIncrement / 10, garray[g].bInitTime / 600, garray[g].bIncrement / 10);
+ } else {
+ sprintf(tmp, "%d minutes, increment: %d seconds.\n\n", garray[g].wInitTime / 600, garray[g].wIncrement / 10);
+ }
+ strcat(gameString, tmp);
+ sprintf(tmp, "Move %-19s%-19s\n", garray[g].white_name, garray[g].black_name);
+ strcat(gameString, tmp);
+ strcat(gameString, "---- ---------------- ----------------\n");
+
+ for (i = 0; i < garray[g].numHalfMoves; i += 2) {
+ if (i + 1 < garray[g].numHalfMoves) {
+ sprintf(tmp, "%3d. %-16s ", i / 2 + 1,
+ (garray[g].status == GAME_EXAMINE) ?
+ move_and_time(&garray[g].examMoveList[i]) :
+ move_and_time(&garray[g].moveList[i]));
+ strcat(gameString, tmp);
+ sprintf(tmp, "%-16s\n",
+ (garray[g].status == GAME_EXAMINE) ?
+ move_and_time(&garray[g].examMoveList[i + 1]) :
+ move_and_time(&garray[g].moveList[i + 1]));
+ } else {
+ sprintf(tmp, "%3d. %-16s\n", i / 2 + 1,
+ (garray[g].status == GAME_EXAMINE) ?
+ move_and_time(&garray[g].examMoveList[i]) :
+ move_and_time(&garray[g].moveList[i]));
+ }
+ strcat(gameString, tmp);
+ if (strlen(gameString) > GAME_STRING_LEN - 100) { /* Bug out if getting
+ close to filling this
+ string */
+ return gameString;
+ }
+ }
+
+ strcat(gameString, " ");
+ }
+
+ sprintf(tmp, "{%s} %s\n", EndString(g, 0), EndSym(g));
+ strcat(gameString, tmp);
+
+ return gameString;
+}
+
+PUBLIC void game_disconnect(int g, int p)
+{
+ game_ended(g, (garray[g].white == p) ? WHITE : BLACK, END_LOSTCONNECTION);
+}
+
+PUBLIC int CharToPiece(char c)
+{
+ switch (c) {
+ case 'P':return W_PAWN;
+ case 'p':
+ return B_PAWN;
+ case 'N':
+ return W_KNIGHT;
+ case 'n':
+ return B_KNIGHT;
+ case 'B':
+ return W_BISHOP;
+ case 'b':
+ return B_BISHOP;
+ case 'R':
+ return W_ROOK;
+ case 'r':
+ return B_ROOK;
+ case 'Q':
+ return W_QUEEN;
+ case 'q':
+ return B_QUEEN;
+ case 'K':
+ return W_KING;
+ case 'k':
+ return B_KING;
+ default:
+ return NOPIECE;
+ }
+}
+
+PUBLIC int PieceToChar(int piece)
+{
+ switch (piece) {
+ case W_PAWN:return 'P';
+ case B_PAWN:
+ return 'p';
+ case W_KNIGHT:
+ return 'N';
+ case B_KNIGHT:
+ return 'n';
+ case W_BISHOP:
+ return 'B';
+ case B_BISHOP:
+ return 'b';
+ case W_ROOK:
+ return 'R';
+ case B_ROOK:
+ return 'r';
+ case W_QUEEN:
+ return 'Q';
+ case B_QUEEN:
+ return 'q';
+ case W_KING:
+ return 'K';
+ case B_KING:
+ return 'k';
+ default:
+ return ' ';
+ }
+}
+
+/* One line has everything on it */
+PRIVATE int WriteMoves(FILE * fp, move_t *m)
+{
+ unsigned long MoveInfo = (m->color == BLACK);
+ int piece, castle;
+ int useFile = 0, useRank = 0, check = 0;
+ int i;
+
+ castle = (m->moveString[0] == 'o');
+ if (castle)
+ piece = KING;
+ else
+ piece = piecetype(CharToPiece(m->moveString[0]));
+
+ MoveInfo = (MoveInfo <<= 3) | piece;
+ MoveInfo = (MoveInfo <<= 3) | m->fromFile;
+ MoveInfo = (MoveInfo <<= 3) | m->fromRank;
+ MoveInfo = (MoveInfo <<= 3) | m->toFile;
+ MoveInfo = (MoveInfo <<= 3) | m->toRank;
+ MoveInfo = (MoveInfo <<= 3) | (m->pieceCaptured & 7);
+ MoveInfo = (MoveInfo <<= 3) | (m->piecePromotionTo & 7);
+ MoveInfo = (MoveInfo <<= 1) | (m->enPassant != 0);
+
+ /* Are we using from-file or from-rank in algString? */
+ i = strlen(m->algString) - 1;
+ if (m->algString[i] == '+') {
+ check = 1;
+ i--;
+ }
+ if (piece != PAWN && !castle) {
+ i -= 2;
+ if (i < 0)
+ return -1;
+ if (m->algString[i] == 'x')
+ i--;
+ if (i < 0)
+ return -1;
+ if (isdigit(m->algString[i])) {
+ useRank = 2;
+ i--;
+ }
+ if (i < 0)
+ return -1;
+ useFile = (islower(m->algString[i]) ? 4 : 0);
+ }
+ MoveInfo = (MoveInfo << 3) | useFile | useRank | check;
+ fprintf(fp, "%lx %x %x\n", MoveInfo, m->tookTime, m->atTime);
+
+#if 0
+ fprintf(fp, "%d %d %d %d %d %d %d %d %d \"%s\" \"%s\" %u %u\n",
+ m->color, m->fromFile, m->fromRank, m->toFile, m->toRank,
+ m->pieceCaptured, m->piecePromotionTo, m->enPassant, m->doublePawn,
+ m->moveString, m->algString, m->atTime, m->tookTime);
+#endif
+ return 0;
+}
+
+PRIVATE int ReadMove(FILE * fp, move_t *m)
+{
+ char line[MAX_GLINE_SIZE];
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ if (sscanf(line, "%d %d %d %d %d %d %d %d %d \"%[^\"]\" \"%[^\"]\" %u %u\n",
+ &m->color, &m->fromFile, &m->fromRank, &m->toFile, &m->toRank,
+ &m->pieceCaptured, &m->piecePromotionTo, &m->enPassant, &m->doublePawn,
+ m->moveString, m->algString, &m->atTime, &m->tookTime) != 13)
+ return -1;
+ return 0;
+}
+
+PRIVATE void WriteGameState(FILE * fp, game_state_t *gs)
+{
+ int i, j;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ fprintf(fp, "%c", PieceToChar(gs->board[i][j]));
+ }
+ fprintf(fp, "%d %d %d %d %d %d",
+ gs->wkmoved, gs->wqrmoved, gs->wkrmoved,
+ gs->bkmoved, gs->bqrmoved, gs->bkrmoved);
+ for (i = 0; i < 8; i++)
+ fprintf(fp, " %d %d", gs->ep_possible[0][i], gs->ep_possible[1][i]);
+ fprintf(fp, " %d %d %d\n", gs->lastIrreversable, gs->onMove, gs->moveNum);
+}
+
+PRIVATE int ReadGameState(FILE * fp, game_state_t *gs, int version)
+{
+ int i, j;
+ char pieceChar;
+ int wkmoved, wqrmoved, wkrmoved, bkmoved, bqrmoved, bkrmoved;
+
+ if (version == 0) {
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++)
+ if (fscanf(fp, "%d ", &gs->board[i][j]) != 1)
+ return -1;
+ } else {
+ getc(fp); /* Skip past a newline. */
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ pieceChar = getc(fp);
+ gs->board[i][j] = CharToPiece(pieceChar);
+ }
+ }
+ if (fscanf(fp, "%d %d %d %d %d %d",
+ &wkmoved, &wqrmoved, &wkrmoved,
+ &bkmoved, &bqrmoved, &bkrmoved) != 6)
+ return -1;
+ gs->wkmoved = wkmoved;
+ gs->wqrmoved = wqrmoved;
+ gs->wkrmoved = wkrmoved;
+ gs->bkmoved = bkmoved;
+ gs->bqrmoved = bqrmoved;
+ gs->bkrmoved = bkrmoved;
+ for (i = 0; i < 8; i++)
+ if (fscanf(fp, " %d %d", &gs->ep_possible[0][i], &gs->ep_possible[1][i]) != 2)
+ return -1;
+ if (fscanf(fp, " %d %d %d\n", &gs->lastIrreversable, &gs->onMove, &gs->moveNum) != 3)
+ return -1;
+ return 0;
+}
+
+PUBLIC int got_attr_value(int g, char *attr, char *value, FILE * fp, char *file)
+{
+ int i;
+
+ if (!strcmp(attr, "w_init:")) {
+ garray[g].wInitTime = atoi(value);
+ } else if (!strcmp(attr, "w_inc:")) {
+ garray[g].wIncrement = atoi(value);
+ } else if (!strcmp(attr, "b_init:")) {
+ garray[g].bInitTime = atoi(value);
+ } else if (!strcmp(attr, "b_inc:")) {
+ garray[g].bIncrement = atoi(value);
+ } else if (!strcmp(attr, "white_name:")) {
+ strcpy(garray[g].white_name, value);
+ } else if (!strcmp(attr, "black_name:")) {
+ strcpy(garray[g].black_name, value);
+ } else if (!strcmp(attr, "white_rating:")) {
+ garray[g].white_rating = atoi(value);
+ } else if (!strcmp(attr, "black_rating:")) {
+ garray[g].black_rating = atoi(value);
+ } else if (!strcmp(attr, "result:")) {
+ garray[g].result = atoi(value);
+ } else if (!strcmp(attr, "timestart:")) {
+ garray[g].timeOfStart = atoi(value);
+ } else if (!strcmp(attr, "w_time:")) {
+ garray[g].wTime = atoi(value);
+ } else if (!strcmp(attr, "b_time:")) {
+ garray[g].bTime = atoi(value);
+ } else if (!strcmp(attr, "clockstopped:")) {
+ garray[g].clockStopped = atoi(value);
+ } else if (!strcmp(attr, "rated:")) {
+ garray[g].rated = atoi(value);
+ } else if (!strcmp(attr, "private:")) {
+ garray[g].private = atoi(value);
+ } else if (!strcmp(attr, "type:")) {
+ garray[g].type = atoi(value);
+ } else if (!strcmp(attr, "halfmoves:")) {
+ garray[g].numHalfMoves = atoi(value);
+ if (garray[g].numHalfMoves == 0)
+ return 0;
+ garray[g].moveListSize = garray[g].numHalfMoves;
+ garray[g].moveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].moveListSize);
+ for (i = 0; i < garray[g].numHalfMoves; i++) {
+ if (ReadMove(fp, &garray[g].moveList[i])) {
+ fprintf(stderr, "FICS: Trouble reading moves from %s.\n", file);
+ return -1;
+ }
+ }
+ } else if (!strcmp(attr, "gamestate:")) { /* Value meaningless */
+ if (garray[g].status != GAME_EXAMINE &&
+ ReadGameState(fp, &garray[g].game_state, 0)) {
+ fprintf(stderr, "FICS: Trouble reading game state from %s.\n", file);
+ return -1;
+ }
+ } else {
+ fprintf(stderr, "FICS: Error bad attribute >%s< from file %s\n", attr, file);
+ }
+ return 0;
+}
+
+void ReadOneV1Move(FILE * fp, move_t *m)
+{
+ int i;
+ char PieceChar;
+ int useFile, useRank, check, piece;
+ unsigned long MoveInfo;
+
+ fscanf(fp, "%lx %x %x", &MoveInfo, &m->tookTime, &m->atTime);
+ check = MoveInfo & 1;
+ useRank = MoveInfo & 2;
+ useFile = MoveInfo & 4;
+ MoveInfo >>= 3;
+ m->enPassant = MoveInfo & 1; /* may have to negate later. */
+ MoveInfo >>= 1;
+ m->piecePromotionTo = MoveInfo & 7; /* may have to change color. */
+ MoveInfo >>= 3;
+ m->pieceCaptured = MoveInfo & 7; /* may have to change color. */
+ MoveInfo >>= 3;
+ m->toRank = MoveInfo & 7;
+ MoveInfo >>= 3;
+ m->toFile = MoveInfo & 7;
+ MoveInfo >>= 3;
+ m->fromRank = MoveInfo & 7;
+ MoveInfo >>= 3;
+ m->fromFile = MoveInfo & 7;
+ MoveInfo >>= 3;
+ piece = MoveInfo & 7;
+ m->color = (MoveInfo & 8) ? BLACK : WHITE;
+ if (m->pieceCaptured != NOPIECE) {
+ if (m->color == BLACK)
+ m->pieceCaptured |= WHITE;
+ else
+ m->pieceCaptured |= BLACK;
+ }
+ if (piece == PAWN) {
+ PieceChar = 'P';
+ if ((m->toRank == 3 && m->fromRank == 1)
+ || (m->toRank == 4 && m->fromRank == 6))
+ m->doublePawn = m->toFile;
+ else
+ m->doublePawn = -1;
+ if (m->pieceCaptured)
+ sprintf(m->algString, "%cx%c%d", 'a' + m->fromFile,
+ 'a' + m->toFile, m->toRank + 1);
+ else
+ sprintf(m->algString, "%c%d", 'a' + m->toFile, m->toRank + 1);
+ if (m->piecePromotionTo != 0) {
+ if (m->piecePromotionTo == KNIGHT)
+ strcat(m->algString, "=N");
+ else if (m->piecePromotionTo == BISHOP)
+ strcat(m->algString, "=B");
+ else if (m->piecePromotionTo == ROOK)
+ strcat(m->algString, "=R");
+ else if (m->piecePromotionTo == QUEEN)
+ strcat(m->algString, "=Q");
+ m->piecePromotionTo |= m->color;
+ }
+ if (m->enPassant)
+ m->enPassant = m->toFile - m->fromFile;
+ } else {
+ m->doublePawn = -1;
+ PieceChar = PieceToChar(piecetype(piece) | WHITE);
+ if (PieceChar == 'K' && m->fromFile == 4 && m->toFile == 6) {
+ strcpy(m->algString, "O-O");
+ strcpy(m->moveString, "o-o");
+ } else if (PieceChar == 'K' && m->fromFile == 4 && m->toFile == 2) {
+ strcpy(m->algString, "O-O-O");
+ strcpy(m->moveString, "o-o-o");
+ } else {
+ i = 0;
+ m->algString[i++] = PieceChar;
+ if (useFile)
+ m->algString[i++] = 'a' + m->fromFile;
+ if (useRank)
+ m->algString[i++] = '1' + m->fromRank;
+ if (m->pieceCaptured != 0)
+ m->algString[i++] = 'x';
+ m->algString[i++] = 'a' + m->toFile;
+ m->algString[i++] = '1' + m->toRank;
+ m->algString[i] = '\0';
+ }
+ }
+ if (m->algString[0] != 'O')
+ sprintf(m->moveString, "%c/%c%d-%c%d", PieceChar, 'a' + m->fromFile,
+ m->fromRank + 1, 'a' + m->toFile, m->toRank + 1);
+ if (check)
+ strcat(m->algString, "+");
+}
+
+int ReadV1Moves(game *g, FILE * fp)
+{
+ int i;
+
+ g->moveListSize = g->numHalfMoves;
+ g->moveList = (move_t *) rmalloc(sizeof(move_t) * g->moveListSize);
+ for (i = 0; i < g->numHalfMoves; i++) {
+ ReadOneV1Move(fp, &g->moveList[i]);
+ }
+ return 0;
+}
+
+int ReadV1GameFmt(game *g, FILE * fp, char *file, int version)
+{
+ fscanf(fp, "%s %s", g->white_name, g->black_name);
+ fscanf(fp, "%d %d", &g->white_rating, &g->black_rating);
+ fscanf(fp, "%d %d %d %d", &g->wInitTime, &g->wIncrement,
+ &g->bInitTime, &g->bIncrement);
+ if ((version < 3) && (!(g->bInitTime)))
+ g->bInitTime = g->wInitTime;
+ /*PRE-V3 assumed bInitTime was 0 if balanced clocks*/
+ fscanf(fp, "%lx", &g->timeOfStart);
+ fscanf(fp, "%d %d", &g->wTime, &g->bTime);
+
+/* fixing an (apparently) old bug: winner not saved */
+ if (version > 1)
+ fscanf(fp, "%d %d", &g->result, &g->winner);
+ else
+ fscanf(fp, "%d", &g->result);
+
+ fscanf(fp, "%d %d %d %d", &g->private, &g->type,
+ &g->rated, &g->clockStopped);
+ fscanf(fp, "%d", &g->numHalfMoves);
+ ReadV1Moves(g, fp);
+ if (g->status != GAME_EXAMINE
+ && ReadGameState(fp, &g->game_state, version)) {
+ fprintf(stderr, "FICS: Trouble reading game state from %s.\n", file);
+ return -1;
+ }
+ return 0;
+}
+
+PUBLIC int ReadGameAttrs(FILE * fp, char *fname, int g)
+{
+ int len;
+ int version = 0;
+ char *attr, *value;
+ char line[MAX_GLINE_SIZE];
+
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+
+ if (line[0] == 'v') {
+ sscanf(line, "%*c %d", &version);
+ }
+ if (version > 0) {
+ ReadV1GameFmt(&garray[g], fp, fname, version);
+ }
+ /* Read the game file here */
+ else
+ do {
+ if ((len = strlen(line)) <= 1) {
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ continue;
+ }
+ line[len - 1] = '\0';
+ attr = eatwhite(line);
+ if (attr[0] == '#')
+ continue; /* Comment */
+ value = eatword(attr);
+ if (!*value) {
+ fprintf(stderr, "FICS: Error reading file %s\n", fname);
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ continue;
+ }
+ *value = '\0';
+ value++;
+ value = eatwhite(value);
+ if (!*value) {
+ fprintf(stderr, "FICS: Error reading file %s\n", fname);
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ continue;
+ }
+ stolower(attr);
+ if (got_attr_value(g, attr, value, fp, fname)) {
+ return -1;
+ }
+ fgets(line, MAX_GLINE_SIZE - 1, fp);
+ } while (!feof(fp));
+ if (!(garray[g].bInitTime))
+ garray[g].bInitTime = garray[g].wInitTime;
+ return 0;
+}
+
+PUBLIC int game_read(int g, int wp, int bp)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+
+ garray[g].white = wp;
+ garray[g].black = bp;
+/* garray[g].old_white = -1;
+ garray[g].old_black = -1;
+*/
+ garray[g].moveListSize = 0;
+ garray[g].game_state.gameNum = g;
+ strcpy(garray[g].white_name, parray[wp].name);
+ strcpy(garray[g].black_name, parray[bp].name);
+ if (garray[g].type == TYPE_BLITZ) {
+ garray[g].white_rating = parray[wp].b_stats.rating;
+ garray[g].black_rating = parray[bp].b_stats.rating;
+ } else if (garray[g].type == TYPE_WILD) {
+ garray[g].white_rating = parray[wp].w_stats.rating;
+ garray[g].black_rating = parray[bp].w_stats.rating;
+ } else if (garray[g].type == TYPE_LIGHT) {
+ garray[g].white_rating = parray[wp].l_stats.rating;
+ garray[g].black_rating = parray[bp].l_stats.rating;
+ } else if (garray[g].type == TYPE_BUGHOUSE) {
+ garray[g].white_rating = parray[wp].bug_stats.rating;
+ garray[g].black_rating = parray[bp].bug_stats.rating;
+ } else {
+ garray[g].white_rating = parray[wp].s_stats.rating;
+ garray[g].black_rating = parray[bp].s_stats.rating;
+ }
+ sprintf(fname, "%s/%c/%s-%s", adj_dir, parray[wp].login[0],
+ parray[wp].login, parray[bp].login);
+ fp = fopen(fname, "r");
+ if (!fp) {
+ return -1;
+ }
+ if (ReadGameAttrs(fp, fname, g) < 0) {
+ fclose(fp);
+ return -1;
+ }
+ fclose(fp);
+
+ if (garray[g].result == END_ADJOURN
+ || garray[g].result == END_COURTESYADJOURN)
+ garray[g].result = END_NOTENDED;
+ garray[g].status = GAME_ACTIVE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ /* Need to do notification and pending cleanup */
+ return 0;
+}
+
+PUBLIC int game_delete(int wp, int bp)
+{
+ char fname[MAX_FILENAME_SIZE];
+ char lname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s-%s", adj_dir, parray[wp].login[0],
+ parray[wp].login, parray[bp].login);
+ sprintf(lname, "%s/%c/%s-%s", adj_dir, parray[bp].login[0],
+ parray[wp].login, parray[bp].login);
+ unlink(fname);
+ unlink(lname);
+ return 0;
+}
+
+void WriteGameFile(FILE * fp, int g)
+{
+ int i;
+ game *gg = &garray[g];
+ player *wp = &parray[gg->white], *bp = &parray[gg->black];
+
+ fprintf(fp, "v %d\n", GAMEFILE_VERSION);
+ fprintf(fp, "%s %s\n", wp->name, bp->name);
+ fprintf(fp, "%d %d\n", gg->white_rating, gg->black_rating);
+ fprintf(fp, "%d %d %d %d\n", gg->wInitTime, gg->wIncrement,
+ gg->bInitTime, gg->bIncrement);
+ fprintf(fp, "%lx\n", gg->timeOfStart);
+/* fprintf(fp, "%d %d\n", gg->wTime, gg->bTime); */
+#ifdef TIMESEAL
+ fprintf(fp, "%d %d\n",
+ (con[wp->socket].timeseal ? gg->wRealTime/100 : gg->wTime),
+ (con[bp->socket].timeseal ? gg->bRealTime/100 : gg->bTime));
+#endif
+ fprintf(fp, "%d %d\n", gg->result, gg->winner);
+ fprintf(fp, "%d %d %d %d\n", gg->private, gg->type,
+ gg->rated, gg->clockStopped);
+ fprintf(fp, "%d\n", gg->numHalfMoves);
+ for (i = 0; i < garray[g].numHalfMoves; i++) {
+ WriteMoves(fp, &garray[g].moveList[i]);
+ }
+ WriteGameState(fp, &garray[g].game_state);
+}
+
+PUBLIC int game_save(int g)
+{
+ FILE *fp;
+ player *wp, *bp;
+ game *gg = &garray[g];
+ char fname[MAX_FILENAME_SIZE];
+ char lname[MAX_FILENAME_SIZE];
+
+ wp = &parray[gg->white];
+ bp = &parray[gg->black];
+ sprintf(fname, "%s/%c/%s-%s", adj_dir, wp->login[0],
+ wp->login, bp->login);
+ sprintf(lname, "%s/%c/%s-%s", adj_dir, bp->login[0],
+ wp->login, bp->login);
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Problem opening file %s for write\n", fname);
+ return -1;
+ }
+ WriteGameFile(fp, g);
+#if 0
+ fprintf(fp, "W_Init: %d\n", garray[g].wInitTime);
+ fprintf(fp, "W_Inc: %d\n", garray[g].wIncrement);
+ fprintf(fp, "B_Init: %d\n", garray[g].bInitTime);
+ fprintf(fp, "B_Inc: %d\n", garray[g].bIncrement);
+ fprintf(fp, "white_name: %s\n", wp->name);
+ fprintf(fp, "black_name: %s\n", bp->name);
+ fprintf(fp, "white_rating: %d\n", garray[g].white_rating);
+ fprintf(fp, "black_rating: %d\n", garray[g].black_rating);
+ fprintf(fp, "result: %d\n", garray[g].result);
+ fprintf(fp, "TimeStart: %d\n", (int) garray[g].timeOfStart);
+ fprintf(fp, "W_Time: %d\n", garray[g].wTime);
+ fprintf(fp, "B_Time: %d\n", garray[g].bTime);
+ fprintf(fp, "ClockStopped: %d\n", garray[g].clockStopped);
+ fprintf(fp, "Rated: %d\n", garray[g].rated);
+ fprintf(fp, "Private: %d\n", garray[g].private);
+ fprintf(fp, "Type: %d\n", garray[g].type);
+ fprintf(fp, "HalfMoves: %d\n", garray[g].numHalfMoves);
+ for (i = 0; i < garray[g].numHalfMoves; i++) {
+ WriteMoves(fp, &garray[g].moveList[i]);
+ }
+ fprintf(fp, "GameState: IsNext\n");
+ WriteGameState(fp, &garray[g].game_state);
+#endif
+ fclose(fp);
+ /* Create link for easier stored game finding */
+ if (bp->login[0] != wp->login[0])
+ link(fname, lname);
+ return 0;
+}
+
+#if 0
+PRIVATE int history_game_save(int g, char *fname)
+{
+ FILE *fp;
+ int wp, bp;
+ int i;
+
+ wp = garray[g].white;
+ bp = garray[g].black;
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Problem openning file %s for write\n", fname);
+ return -1;
+ }
+ fprintf(fp, "W_Init: %d\n", garray[g].wInitTime);
+ fprintf(fp, "W_Inc: %d\n", garray[g].wIncrement);
+ fprintf(fp, "B_Init: %d\n", garray[g].bInitTime);
+ fprintf(fp, "B_Inc: %d\n", garray[g].bIncrement);
+ fprintf(fp, "TimeStart: %d\n", (int) garray[g].timeOfStart);
+ fprintf(fp, "W_Time: %d\n", garray[g].wTime);
+ fprintf(fp, "B_Time: %d\n", garray[g].bTime);
+ fprintf(fp, "ClockStopped: %d\n", garray[g].clockStopped);
+ fprintf(fp, "Rated: %d\n", garray[g].rated);
+ fprintf(fp, "Private: %d\n", garray[g].private);
+ fprintf(fp, "Type: %d\n", garray[g].type);
+ fprintf(fp, "HalfMoves: %d\n", garray[g].numHalfMoves);
+ for (i = 0; i < garray[g].numHalfMoves; i++) {
+ WriteMoves(fp, &garray[g].moveList[i]);
+ }
+ fprintf(fp, "GameState: IsNext\n");
+ WriteGameState(fp, &garray[g].game_state);
+ fclose(fp);
+ return 0;
+}
+#endif
+
+PRIVATE long OldestHistGame(char *login)
+{
+ FILE *fp;
+ char pFile[MAX_FILENAME_SIZE];
+ long when;
+
+ sprintf(pFile, "%s/player_data/%c/%s.%s", stats_dir,
+ login[0], login, STATS_GAMES);
+ fp = fopen(pFile, "r");
+
+ if (fp == NULL) {
+ sprintf(pFile, "%s/player_data/%c/.rem.%s.%s", stats_dir,
+ login[0], login, STATS_GAMES);
+ fp = fopen(pFile, "r");
+ }
+ if (fp != NULL) {
+ fscanf(fp, "%*d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %*s %*s %ld",
+ &when);
+ fclose(fp);
+ return when;
+ } else
+ return 0L;
+}
+
+PRIVATE void RemoveHistGame(char *file, int maxlines)
+{
+ FILE *fp;
+ char GameFile[MAX_FILENAME_SIZE];
+ char Opponent[MAX_LOGIN_NAME];
+ char line[MAX_LINE_SIZE];
+ long When, oppWhen;
+ int count = 0;
+
+ fp = fopen(file, "r");
+ if (fp == NULL)
+ return;
+
+ fgets(line, MAX_LINE_SIZE - 1, fp);
+ sscanf(line, "%*d %*c %*d %*c %*d %s %*s %*d %*d %*d %*d %*s %*s %ld",
+ Opponent, &When);
+ count++;
+
+ while (!feof(fp)) {
+ fgets(line, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp))
+ count++;
+ }
+ fclose(fp);
+
+ stolower(Opponent);
+ if (count > maxlines) {
+ truncate_file(file, maxlines);
+
+ oppWhen = OldestHistGame(Opponent);
+ if (oppWhen > When || oppWhen <= 0L) {
+ sprintf(GameFile, "%s/%ld/%ld", hist_dir, When % 100, When);
+ unlink(GameFile);
+ }
+ }
+}
+
+PUBLIC void RemHist(char *who)
+{
+ FILE *fp;
+ char fName[MAX_FILENAME_SIZE];
+ char Opp[MAX_LOGIN_NAME];
+ long When, oppWhen;
+
+ sprintf(fName, "%s/player_data/%c/%s.%s", stats_dir,
+ who[0], who, STATS_GAMES);
+ fp = fopen(fName, "r");
+ if (fp != NULL) {
+ while (!feof(fp)) {
+ fscanf(fp, "%*d %*c %*d %*c %*d %s %*s %*d %*d %*d %*d %*s %*s %ld",
+ Opp, &When);
+ stolower(Opp);
+ oppWhen = OldestHistGame(Opp);
+ if (oppWhen > When || oppWhen <= 0L) {
+ sprintf(fName, "%s/%ld/%ld", hist_dir, When % 100, When);
+ unlink(fName);
+ }
+ }
+ }
+}
+
+PRIVATE void write_g_out(int g, char *file, int maxlines, int isDraw,
+ char *EndSymbol, char *name, time_t *now)
+{
+ FILE *fp;
+ int wp, bp;
+ int wr, br;
+ char type[4];
+ char tmp[2048];
+ char *ptmp = tmp;
+ char cResult;
+ int count = -1;
+ char *goteco;
+
+ wp = garray[g].white;
+ bp = garray[g].black;
+
+ if (garray[g].private) {
+ type[0] = 'p';
+ } else {
+ type[0] = ' ';
+ }
+ if (garray[g].type == TYPE_BLITZ) {
+ wr = parray[wp].b_stats.rating;
+ br = parray[bp].b_stats.rating;
+ type[1] = 'b';
+ } else if (garray[g].type == TYPE_WILD) {
+ wr = parray[wp].w_stats.rating;
+ br = parray[bp].w_stats.rating;
+ type[1] = 'w';
+ } else if (garray[g].type == TYPE_STAND) {
+ wr = parray[wp].s_stats.rating;
+ br = parray[bp].s_stats.rating;
+ type[1] = 's';
+ } else if (garray[g].type == TYPE_LIGHT) {
+ wr = parray[wp].l_stats.rating;
+ br = parray[bp].l_stats.rating;
+ type[1] = 'l';
+ } else if (garray[g].type == TYPE_BUGHOUSE) {
+ wr = parray[wp].bug_stats.rating;
+ br = parray[bp].bug_stats.rating;
+ type[1] = 'd';
+ } else {
+ wr = 0;
+ br = 0;
+ if (garray[g].type == TYPE_NONSTANDARD)
+ type[1] = 'n';
+ else
+ type[1] = 'u';
+ }
+ if (garray[g].rated) {
+ type[2] = 'r';
+ } else {
+ type[2] = 'u';
+ }
+ type[3] = '\0';
+
+ fp = fopen(file, "r");
+ if (fp) {
+ while (!feof(fp))
+ fgets(tmp, 1024, fp);
+ sscanf(ptmp, "%d", &count);
+ fclose(fp);
+ }
+ count = (count + 1) % 100;
+
+ fp = fopen(file, "a");
+ if (!fp)
+ return;
+
+ goteco = getECO(g);
+
+/* Counter Result MyRating MyColor OppRating OppName [pbr 2 12 2 12] ECO End Date */
+ if (name == parray[wp].name) {
+ if (isDraw)
+ cResult = '=';
+ else if (garray[g].winner == WHITE)
+ cResult = '+';
+ else
+ cResult = '-';
+
+ fprintf(fp, "%d %c %d W %d %s %s %d %d %d %d %s %s %ld\n",
+ count, cResult, wr, br, parray[bp].name, type,
+ garray[g].wInitTime, garray[g].wIncrement,
+ garray[g].bInitTime, garray[g].bIncrement,
+ goteco,
+ EndSymbol,
+ (long) *now);
+ } else {
+ if (isDraw)
+ cResult = '=';
+ else if (garray[g].winner == BLACK)
+ cResult = '+';
+ else
+ cResult = '-';
+
+ fprintf(fp, "%d %c %d B %d %s %s %d %d %d %d %s %s %ld\n",
+ count, cResult, br, wr, parray[wp].name, type,
+ garray[g].wInitTime, garray[g].wIncrement,
+ garray[g].bInitTime, garray[g].bIncrement,
+ goteco,
+ EndSymbol,
+ (long) *now);
+ }
+ fclose(fp);
+
+ RemoveHistGame(file, maxlines);
+/*
+ if ((name == parray[wp].name) && (parray[wp].registered)) {
+ sprintf(tmp, "%s/%c/%s.%d", adj_dir, parray[wp].login[0], parray[wp].login, count);
+ history_game_save(g, tmp);
+ }
+ if ((name == parray[bp].name) && (parray[bp].registered)) {
+ sprintf(tmp, "%s/%c/%s.%d", adj_dir, parray[bp].login[0], parray[bp].login, count);
+ history_game_save(g, tmp);
+ }
+*/
+}
+
+/* Find from_spot in journal list - return 0 if corrupted */
+
+PUBLIC int journal_get_info(int p,char from_spot,char* WhiteName, int* WhiteRating,
+ char* BlackName, int* BlackRating, char* type,int* t,int* i,char* eco,
+ char* ending,char* result, char *fname)
+{
+ char count;
+ FILE *fp;
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ fprintf (stderr, "Corrupt journal file! %s\n",fname);
+ pprintf (p, "The journal file is corrupt! See an admin.\n");
+ return 0;
+ }
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &count,
+ WhiteName,
+ &(*WhiteRating),
+ BlackName,
+ &(*BlackRating),
+ type,
+ &(*t), &(*i),
+ eco,
+ ending,
+ result) != 11) {
+ fprintf(stderr, "FICS: Error in journal info format. %s\n", fname);
+ pprintf(p, "The journal file is corrupt! Error in internal format.\n");
+ fclose(fp);
+ return 0;
+ }
+ if (tolower(count) == from_spot) {
+ fclose(fp);
+ return 1;
+ }
+ }
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC void addjournalitem(int p,char count2,char* WhiteName2, int WhiteRating2,
+ char* BlackName2, int BlackRating2, char* type2,int t2,int i2,char* eco2,
+ char* ending2,char* result2, char* fname)
+
+{
+ int WhiteRating, BlackRating;
+ int t, i;
+ char WhiteName[MAX_LOGIN_NAME + 1];
+ char BlackName[MAX_LOGIN_NAME + 1];
+ char type[100];
+ char eco[100];
+ char ending[100];
+ char count;
+ char result[100];
+ int have_output=0;
+ char fname2[MAX_FILENAME_SIZE];
+
+ FILE *fp;
+ FILE *fp2;
+
+ strcpy (fname2,fname);
+ strcat (fname2,".w");
+ fp2 = fopen(fname2, "w");
+ if (!fp2) {
+ fprintf(stderr, "FICS: Problem opening file %s for write\n", fname);
+ pprintf (p, "Couldn't update journal! Report this to an admin.\n");
+ return;
+ }
+ fp = fopen(fname, "r");
+ if (!fp) { /* Empty? */
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ count2, WhiteName2, WhiteRating2, BlackName2, BlackRating2,
+ type2, t2, i2, eco2, ending2,
+ result2);
+ fclose (fp2);
+ rename (fname2, fname);
+ return;
+ } else {
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &count,
+ WhiteName,
+ &WhiteRating,
+ BlackName,
+ &BlackRating,
+ type,
+ &t, &i,
+ eco,
+ ending,
+ result) != 11) {
+ fprintf(stderr, "FICS: Error in journal info format - aborting. %s\n", fname);
+ fclose(fp);
+ fclose(fp2);
+ return;
+ }
+ if ((count >= count2) && (!have_output)) {
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ count2,
+ WhiteName2,
+ WhiteRating2,
+ BlackName2,
+ BlackRating2,
+ type2,
+ t2, i2,
+ eco2,
+ ending2,
+ result2);
+ have_output = 1;
+ }
+ if (count != count2) {
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ count,
+ WhiteName,
+ WhiteRating,
+ BlackName,
+ BlackRating,
+ type,
+ t, i,
+ eco,
+ ending,
+ result);
+ }
+ }
+ if (!have_output) { /* Haven't written yet */
+ fprintf(fp2, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ count2,
+ WhiteName2,
+ WhiteRating2,
+ BlackName2,
+ BlackRating2,
+ type2,
+ t2, i2,
+ eco2,
+ ending2,
+ result2);
+ }
+ }
+ fclose(fp);
+ fclose(fp2);
+ rename(fname2, fname);
+ return;
+}
+
+PUBLIC int pjournal(int p, int p1, char *fname)
+{
+ FILE *fp;
+ int WhiteRating, BlackRating;
+ int t, i;
+ char WhiteName[MAX_LOGIN_NAME + 1];
+ char BlackName[MAX_LOGIN_NAME + 1];
+ char type[100];
+ char eco[100];
+ char ending[100];
+ char count;
+ char result[100];
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no journal information available.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Journal for %s:\n", parray[p1].name);
+ pprintf(p, " White Rating Black Rating Type ECO End Result\n");
+ while (!feof(fp)) {
+ if (fscanf(fp, "%c %s %d %s %d %s %d %d %s %s %s\n",
+ &count,
+ WhiteName,
+ &WhiteRating,
+ BlackName,
+ &BlackRating,
+ type,
+ &t, &i,
+ eco,
+ ending,
+ result) != 11) {
+ fprintf(stderr, "FICS: Error in journal info format. %s\n", fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ WhiteName[13] = '\0'; /* only first 13 chars in name */
+ BlackName[13] = '\0';
+ pprintf(p, "%c: %-13s %4d %-13s %4d [%3s%3d%4d] %s %3s %-7s\n",
+ count, WhiteName, WhiteRating,
+ BlackName, BlackRating,
+ type, t / 600, i / 10, eco, ending,
+ result);
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+PUBLIC int pgames(int p, int p1, char *fname)
+{
+ FILE *fp;
+ time_t t;
+ int MyRating, OppRating;
+ int wt, wi, bt, bi;
+ char OppName[MAX_LOGIN_NAME + 1];
+ char type[100];
+ char eco[100];
+ char ending[100];
+ char MyColor[2];
+ int count;
+ char result[2];
+
+ fp = fopen(fname, "r");
+ if (!fp) {
+ pprintf(p, "Sorry, no game information available.\n");
+ return COM_OK;
+ }
+ pprintf(p, "History for %s:\n", parray[p1].name);
+ pprintf(p, " Opponent Type ECO End Date\n");
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %s %d %s %s %d %d %d %d %s %s %ld\n",
+ &count,
+ result,
+ &MyRating,
+ MyColor,
+ &OppRating,
+ OppName,
+ type,
+ &wt, &wi,
+ &bt, &bi,
+ eco,
+ ending,
+ (long *) &t) != 14) {
+ fprintf(stderr, "FICS: Error in games info format. %s\n", fname);
+ fclose(fp);
+ return COM_OK;
+ }
+ OppName[13] = '\0'; /* only first 13 chars in name */
+ pprintf(p, "%2d: %s %4d %s %4d %-13s [%3s%3d%4d] %s %3s %s",
+ count, result, MyRating, MyColor,
+ OppRating, OppName,
+ type, wt / 600, wi / 10, eco, ending,
+ ctime(&t));
+ }
+ fclose(fp);
+ return COM_OK;
+}
+
+PUBLIC void game_write_complete(int g, int isDraw, char *EndSymbol)
+{
+ char fname[MAX_FILENAME_SIZE];
+ int wp = garray[g].white, bp = garray[g].black;
+ time_t now = time(NULL);
+ int fd;
+ FILE *fp;
+
+ do {
+ sprintf(fname, "%s/%ld/%ld", hist_dir, (long) now % 100, (long) now);
+ fd = open(fname, O_WRONLY | O_CREAT | O_EXCL, 0644);
+ if (fd == EEXIST)
+ now++;
+ } while (fd == EEXIST);
+
+ if (fd >= 0) {
+ fp = fdopen(fd, "w");
+ if (fp != NULL)
+ WriteGameFile(fp, g);
+ else
+ fprintf(stderr, "Trouble writing history file %s", fname);
+ fclose(fp);
+ close(fd);
+ }
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[wp].login[0], parray[wp].login, STATS_GAMES);
+ write_g_out(g, fname, 10, isDraw, EndSymbol, parray[wp].name, &now);
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[bp].login[0], parray[bp].login, STATS_GAMES);
+ write_g_out(g, fname, 10, isDraw, EndSymbol, parray[bp].name, &now);
+}
+
+PUBLIC int game_count(void)
+{
+ int g, count = 0;
+
+ for (g = 0; g < g_num; g++) {
+ if ((garray[g].status == GAME_ACTIVE) || (garray[g].status == GAME_EXAMINE))
+ count++;
+ }
+ if (count > game_high)
+ game_high = count;
+ return count;
+}
+
blob - /dev/null
blob + a7f027cfeba9d4fcdcbde246394c5a684d860755 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/gamedb.h
+/* gamedb.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _GAMEDB_H
+#define _GAMEDB_H
+
+#include <time.h>
+#include "board.h"
+
+extern char *bstr[];
+extern char *rstr[];
+
+#define GAMEFILE_VERSION 3
+#define MAX_GLINE_SIZE 1024
+
+#define REL_GAME 0
+#define REL_SPOS 1
+#define REL_REFRESH 2
+#define REL_EXAMINE 3
+
+#define GAME_EMPTY 0
+#define GAME_NEW 1
+#define GAME_ACTIVE 2
+#define GAME_EXAMINE 3 /* examine is now 3 */
+
+/*
+#define GAME_STORED 3
+#define GAME_EXAMINE 4
+*/
+
+#define TYPE_UNTIMED 0
+#define TYPE_BLITZ 1
+#define TYPE_STAND 2
+#define TYPE_NONSTANDARD 3
+#define TYPE_WILD 4
+#define TYPE_LIGHT 5
+#define TYPE_BUGHOUSE 6
+
+#ifdef TIMESEAL
+#define FLAG_CHECKING -1
+#define FLAG_NONE 0
+#define FLAG_CALLED 1
+#define FLAG_ABORT 2
+#endif
+
+#define END_CHECKMATE 0
+#define END_RESIGN 1
+#define END_FLAG 2
+#define END_AGREEDDRAW 3
+#define END_REPETITION 4
+#define END_50MOVERULE 5
+#define END_ADJOURN 6
+#define END_LOSTCONNECTION 7
+#define END_ABORT 8
+#define END_STALEMATE 9
+#define END_NOTENDED 10
+#define END_COURTESY 11
+#define END_BOTHFLAG 12
+#define END_NOMATERIAL 13
+#define END_FLAGNOMATERIAL 14
+#define END_ADJDRAW 15
+#define END_ADJWIN 16
+#define END_ADJABORT 17
+#define END_COURTESYADJOURN 18
+
+#if 0
+typedef unsigned char boardList_t[74];
+#endif
+
+typedef struct _game {
+ /* Saved in the game file */
+ int wInitTime, wIncrement;
+ int bInitTime, bIncrement;
+ time_t timeOfStart;
+#ifdef TIMESEAL
+ int wLastRealTime;
+ int wRealTime;
+ int wTimeWhenReceivedMove;
+ int wTimeWhenMoved;
+ int bLastRealTime;
+ int bRealTime;
+ int bTimeWhenReceivedMove;
+ int bTimeWhenMoved;
+ int flag_pending;
+ unsigned long flag_check_time;
+#endif
+ int wTime;
+ int bTime;
+ int clockStopped;
+ int rated;
+ int private;
+ int type;
+ int passes; /* For simul's */
+ int numHalfMoves;
+ move_t *moveList; /* primary movelist */
+ unsigned char FENstartPos[74]; /* Save the starting position. */
+ game_state_t game_state;
+/* This is now in moveList, and FENstartPos. -- hersco */
+/*
+ int boardListSize;
+ boardList_t *boardList;
+ boardList_t boardList[500];
+*/
+ char white_name[18]; /* to hold the playername even after he disconnects */
+ char black_name[18];
+ int white_rating;
+ int black_rating;
+
+ /* Not saved in game file */
+ int revertHalfMove;
+ int totalHalfMoves;
+ int white;
+ int black;
+ /* int old_white; */ /* Contains the old game player number */
+ /* int old_black; */ /* Contains the old game player number */
+ int link;
+ int status;
+ int moveListSize; /* Total allocated in *moveList */
+ int examHalfMoves;
+ move_t *examMoveList; /* extra movelist for examine */
+ int examMoveListSize;
+
+ unsigned startTime; /* The relative time the game started */
+ unsigned lastMoveTime; /* Last time a move was made */
+ unsigned lastDecTime; /* Last time a players clock was decremented */
+
+ int result;
+ int winner;
+
+} game;
+
+extern game *garray;
+extern int g_num;
+
+extern int game_new(void);
+extern int game_zero(int);
+extern int game_free(int);
+extern int game_clear(int);
+extern int game_remove(int);
+extern int game_finish(int);
+extern void MakeFENpos (int, char *);
+
+extern char *game_time_str(int, int, int, int);
+extern char *game_str(int, int, int, int, int, char *, char *);
+extern int game_isblitz(int, int, int, int, char *, char *);
+
+extern void send_board_to(int, int);
+extern void send_boards(int);
+extern void game_update_time(int);
+extern void game_update_times(void);
+
+/* #define MAXOLDGAMES 50
+
+extern int FindOldGameFor(int);
+extern int RemoveOldGamesForPlayer(int);
+extern int ReallyRemoveOldGamesForPlayer(int);
+extern int NewOldGame(int);
+Kill this oldgame rubbish - wastes memory - DAV */
+
+extern char *movesToString(int, int);
+extern char *EndSym(int);
+extern char *EndString(int, int);
+
+extern void game_disconnect(int, int);
+
+extern int CharToPiece(char);
+extern int PieceToChar(int);
+extern int got_attr_value();
+extern int ReadGameAttrs();
+extern int game_read(int, int, int);
+extern int game_delete(int, int);
+extern int game_save(int);
+extern void RemHist (char *);
+
+extern int journal_get_info(int,char,char*,int*,
+ char*,int*,char*,int*,int*,char*,
+ char*,char*,char*);
+extern void addjournalitem(int,char,char*,int,char*,int,char*,int,int,
+ char*, char*, char* ,char*);
+extern int pgames(int, int, char *);
+extern int pjournal(int, int, char *);
+extern void game_write_complete(int, int, char *);
+extern int game_count(void);
+
+/* extern time_t time(); */
+
+#endif
+
blob - /dev/null
blob + 1aa7506f0ea1f4304fb4939f09aa58e91a11f6b2 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/gamedb.o differ
blob - /dev/null
blob + cf07200be94a12f21a48154cca9ed6ac5ff81192 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/gameproc.c
+/* gameproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ Dave Herscovici 95/11/26 Split into two files;
+ Second is obsproc.c.
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "command.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "movecheck.h"
+#include "utils.h"
+#include "ratings.h"
+#include "rmalloc.h"
+#include "comproc.h"
+#include "matchproc.h"
+#include "eco.h"
+#include "network.h"
+#include "lists.h"
+/* #include "hostinfo.h" */
+
+PUBLIC void game_ended(int g, int winner, int why)
+{
+ char outstr[200];
+ char tmp[200];
+ int p;
+ int gl = garray[g].link;
+ int rate_change = 0;
+ int isDraw = 0;
+ int whiteResult;
+ char winSymbol[10];
+ char EndSymbol[10];
+ char *NameOfWinner, *NameOfLoser;
+ int beingplayed = 0; /* i.e. it wasn't loaded for adjudication */
+
+ beingplayed = (parray[garray[g].black].game == g);
+
+ sprintf(outstr, "\n{Game %d (%s vs. %s) ", g + 1,
+ parray[garray[g].white].name,
+ parray[garray[g].black].name);
+ garray[g].result = why;
+ garray[g].winner = winner;
+ if (winner == WHITE) {
+ whiteResult = RESULT_WIN;
+ strcpy(winSymbol, "1-0");
+ NameOfWinner = parray[garray[g].white].name;
+ NameOfLoser = parray[garray[g].black].name;
+ } else {
+ whiteResult = RESULT_LOSS;
+ strcpy(winSymbol, "0-1");
+ NameOfWinner = parray[garray[g].black].name;
+ NameOfLoser = parray[garray[g].white].name;
+ }
+ switch (why) {
+ case END_CHECKMATE:
+ sprintf(tmp, "%s checkmated} %s\n", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Mat");
+ rate_change = 1;
+ break;
+ case END_RESIGN:
+ sprintf(tmp, "%s resigns} %s\n", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Res");
+ rate_change = 1;
+ break;
+ case END_FLAG:
+ sprintf(tmp, "%s forfeits on time} %s\n", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Fla");
+ rate_change = 1;
+ break;
+ case END_STALEMATE:
+ sprintf(tmp, "Game drawn by stalemate} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Sta");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_AGREEDDRAW:
+ sprintf(tmp, "Game drawn by mutual agreement} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Agr");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_BOTHFLAG:
+ sprintf(tmp, "Game drawn because both players ran out of time} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Fla");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_REPETITION:
+ sprintf(tmp, "Game drawn by repetition} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Rep");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_50MOVERULE:
+ sprintf(tmp, "Game drawn by the 50 move rule} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "50");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJOURN:
+ if (gl >= 0) {
+ sprintf(tmp, "Bughouse game aborted.} *\n");
+ whiteResult = RESULT_ABORT;
+ } else {
+ sprintf(tmp, "Game adjourned by mutual agreement} *\n");
+ game_save(g);
+ }
+ break;
+ case END_LOSTCONNECTION:
+ sprintf(tmp, "%s lost connection; game ", NameOfWinner);
+ if (parray[garray[g].white].registered && parray[garray[g].black].registered
+ && gl < 0) {
+ sprintf(tmp, "adjourned} *\n");
+ game_save(g);
+ } else
+ sprintf(tmp, "aborted} *\n");
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_ABORT:
+ sprintf(tmp, "Game aborted by mutual agreement} *\n");
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_COURTESY:
+ sprintf(tmp, "Game courtesyaborted by %s} *\n", NameOfWinner);
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_COURTESYADJOURN:
+ if (gl >= 0) {
+ sprintf(tmp, "Bughouse game courtesyaborted by %s.} *\n", NameOfWinner);
+ whiteResult = RESULT_ABORT;
+ } else {
+ sprintf(tmp, "Game courtesyadjourned by %s} *\n", NameOfWinner);
+ game_save(g);
+ }
+ break;
+ case END_NOMATERIAL:
+ /* Draw by insufficient material (e.g., lone K vs. lone K) */
+ sprintf(tmp, "Neither player has mating material} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "NM ");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_FLAGNOMATERIAL:
+ sprintf(tmp, "%s ran out of time and %s has no material to mate} 1/2-1/2\n",
+ NameOfLoser, NameOfWinner);
+ isDraw = 1;
+ strcpy(EndSymbol, "TM ");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJWIN:
+ sprintf(tmp, "%s wins by adjudication} %s\n", NameOfWinner, winSymbol);
+ strcpy(EndSymbol, "Adj");
+ rate_change = 1;
+ break;
+ case END_ADJDRAW:
+ sprintf(tmp, "Game drawn by adjudication} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Adj");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJABORT:
+ sprintf(tmp, "Game aborted by adjudication} *\n");
+ whiteResult = RESULT_ABORT;
+ break;
+ default:
+ sprintf(tmp, "Hmm, the game ended and I don't know why} *\n");
+ break;
+ }
+ strcat(outstr, tmp);
+ if (beingplayed) {
+ pprintf_noformat(garray[g].white, outstr);
+ pprintf_noformat(garray[g].black, outstr);
+ if (parray[garray[g].white].bell)
+ pprintf (garray[g].white, "\007");
+ if (parray[garray[g].black].bell)
+ pprintf (garray[g].black, "\007");
+
+ garray[g].link = -1; /*IanO: avoids recursion */
+ if (gl >= 0 && garray[gl].link >= 0) {
+ pprintf_noformat(garray[gl].white, outstr);
+ pprintf_noformat(garray[gl].black, outstr);
+ game_ended(gl, CToggle(winner), why);
+ }
+
+ for (p = 0; p < p_num; p++) {
+ if ((p == garray[g].white) || (p == garray[g].black))
+ continue;
+ if (parray[p].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p].i_game && !player_is_observe(p, g))
+ continue;
+ pprintf_noformat(p, outstr);
+/* if (parray[p].bell)
+ pprintf (p, "\007"); removed - caused annoyance */
+ pprintf_prompt(p, "");
+ }
+ }
+ if ((garray[g].rated) && (rate_change)) {
+ /* Adjust ratings */
+ rating_update(g);
+#if 0
+ if (parray[garray[g].white].network_player &&
+ parray[garray[g].black].network_player) {
+ if (MailGameResult) { /* Send to ratings server */
+ if (isDraw) {
+ /* hostinfo_mailresults(garray[g].type == TYPE_BLITZ ? "blitz" :
+ garray[g].type == TYPE_WILD ? "wild " : "stand", "
+ parray[garray[g].white].name, parray[garray[g].black].name,
+ "draw"); */
+ } else {
+/* hostinfo_mailresults(garray[g].type == TYPE_BLITZ ? "blitz" : garray[g].type == TYPE_WILD ? "wild " : "stand",
+ parray[garray[g].white].name,
+ parray[garray[g].black].name,
+ (winner == WHITE) ? parray[garray[g].white].name :
+ parray[garray[g].black].name); */
+ }
+ }
+ }
+#endif
+
+ } else {
+ if (beingplayed) {
+ pprintf(garray[g].white, "No ratings adjustment done.\n");
+ pprintf(garray[g].black, "No ratings adjustment done.\n");
+ }
+ }
+ if (rate_change && gl < 0)
+ game_write_complete(g, isDraw, EndSymbol);
+ /* Mail off the moves */
+ if (parray[garray[g].white].automail) {
+ pcommand(garray[g].white, "mailmoves");
+ }
+ if (parray[garray[g].black].automail) {
+ pcommand(garray[g].black, "mailmoves");
+ }
+ parray[garray[g].white].num_white++;
+ parray[garray[g].white].lastColor = WHITE;
+ parray[garray[g].black].num_black++;
+ parray[garray[g].black].lastColor = BLACK;
+ parray[garray[g].white].last_opponent = garray[g].black;
+ parray[garray[g].black].last_opponent = garray[g].white;
+ if (beingplayed) {
+ parray[garray[g].white].game = -1;
+ parray[garray[g].black].game = -1;
+ parray[garray[g].white].opponent = -1;
+ parray[garray[g].black].opponent = -1;
+ if (garray[g].white != commanding_player)
+ pprintf_prompt(garray[g].white, "");
+ if (garray[g].black != commanding_player)
+ pprintf_prompt(garray[g].black, "");
+ if (parray[garray[g].white].simul_info.numBoards) {
+ player_simul_over(garray[g].white, g, whiteResult);
+ }
+ }
+ game_finish(g);
+}
+
+PRIVATE int was_promoted(game *g, int f, int r)
+{
+#define BUGHOUSE_PAWN_REVERT 1
+#ifdef BUGHOUSE_PAWN_REVERT
+ int i;
+
+ for (i = g->numHalfMoves-2; i > 0; i -= 2) {
+ if (g->moveList[i].toFile == f && g->moveList[i].toRank == r) {
+ if (g->moveList[i].piecePromotionTo)
+ return 1;
+ if (g->moveList[i].fromFile == ALG_DROP)
+ return 0;
+ f = g->moveList[i].fromFile;
+ r = g->moveList[i].fromRank;
+ }
+ }
+#endif
+ return 0;
+}
+
+PUBLIC int pIsPlaying (int p)
+{
+ int g = parray[p].game;
+ int p1 = parray[p].opponent;
+
+ if (g < 0 || garray[g].status == GAME_EXAMINE) {
+ pprintf (p, "You are not playing a game.\n");
+ return 0;
+ } else if (garray[g].white != p && garray[g].black != p) {
+ /* oh oh; big bad game bug. */
+ fprintf (stderr, "BUG: Player %s playing game %d according to parray,"
+ "\n but not according to garray.\n", parray[p].name, g+1);
+ pprintf (p, "Disconnecting you from game number %d.\n", g+1);
+ parray[p].game = -1;
+ if (p1 >= 0 && parray[p1].game == g
+ && garray[g].white != p1 && garray[g].black != p1) {
+ pprintf (p1, "Disconnecting you from game number %d.\n", g+1);
+ parray[p1].game = -1;
+ }
+ return 0;
+ }
+ else return 1;
+}
+
+PUBLIC void process_move(int p, char *command)
+{
+ int g;
+ move_t move;
+ int result;
+ unsigned now;
+ int len; /* loon: for lame promotion hack */
+ int i;
+
+ if (parray[p].game < 0) {
+ pprintf(p, "You are not playing or examining a game.\n");
+ return;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ g = parray[p].game;
+
+ if (garray[g].status != GAME_EXAMINE) {
+ if (!pIsPlaying) return;
+
+ if (parray[p].side != garray[g].game_state.onMove) {
+ pprintf(p, "It is not your move.\n");
+ return;
+ }
+ if (garray[g].clockStopped) {
+ pprintf(p, "Game clock is paused, use \"unpause\" to resume.\n");
+ return;
+ }
+ }
+ if ((len = strlen(command)) > 1) {
+ if (command[len - 2] == '=') {
+ switch (tolower(command[strlen(command) - 1])) {
+ case 'n':
+ parray[p].promote = KNIGHT;
+ break;
+ case 'b':
+ parray[p].promote = BISHOP;
+ break;
+ case 'r':
+ parray[p].promote = ROOK;
+ break;
+ case 'q':
+ parray[p].promote = QUEEN;
+ break;
+ default:
+ pprintf(p, "Don't understand that move.\n");
+ return;
+ break;
+ }
+ }
+ }
+ switch (parse_move(command, &garray[g].game_state, &move, parray[p].promote)) {
+ case MOVE_ILLEGAL:
+ pprintf(p, "Illegal move.\n");
+ return;
+ break;
+ case MOVE_AMBIGUOUS:
+ pprintf(p, "Ambiguous move.\n");
+ return;
+ break;
+ default:
+ break;
+ }
+
+ if (garray[g].status == GAME_EXAMINE) {
+ garray[g].numHalfMoves++;
+ if (garray[g].numHalfMoves > garray[g].examMoveListSize) {
+ garray[g].examMoveListSize += 20; /* Allocate 20 moves at a time */
+ if (!garray[g].examMoveList) {
+ garray[g].examMoveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].examMoveListSize);
+ } else {
+ garray[g].examMoveList = (move_t *) rrealloc(garray[g].examMoveList, sizeof(move_t) * garray[g].examMoveListSize);
+ }
+ }
+ result = execute_move(&garray[g].game_state, &move, 1);
+ move.atTime = now;
+ move.tookTime = 0;
+ MakeFENpos(g, move.FENpos);
+ garray[g].examMoveList[garray[g].numHalfMoves - 1] = move;
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+
+ } else { /* real game */
+ i = parray[p].opponent;
+ if (parray[i].simul_info.numBoards &&
+ (parray[i].simul_info.boards[parray[i].simul_info.onBoard] != g)) {
+ pprintf(p, "It isn't your turn: wait until the simul giver is at your board.\n");
+ return;
+ }
+#ifdef TIMESEAL
+
+ if (con[parray[p].socket].timeseal) { /* does he use timeseal? */
+ if (parray[p].side == WHITE) {
+ garray[g].wLastRealTime = garray[g].wRealTime;
+ garray[g].wTimeWhenMoved = con[parray[p].socket].time;
+ if (((garray[g].wTimeWhenMoved - garray[g].wTimeWhenReceivedMove) < 0) ||
+ (garray[g].wTimeWhenReceivedMove == 0)) {
+ /* might seem weird - but could be caused by a person moving BEFORE
+ he receives the board pos (this is possible due to lag) but it's
+ safe to say he moved in 0 secs :-) */
+ garray[g].wTimeWhenReceivedMove = garray[g].wTimeWhenMoved;
+ } else {
+ garray[g].wRealTime -= garray[g].wTimeWhenMoved - garray[g].wTimeWhenReceivedMove;
+ }
+ } else if (parray[p].side == BLACK) {
+ garray[g].bLastRealTime = garray[g].bRealTime;
+ garray[g].bTimeWhenMoved = con[parray[p].socket].time;
+ if (((garray[g].bTimeWhenMoved - garray[g].bTimeWhenReceivedMove) < 0) ||
+ (garray[g].bTimeWhenReceivedMove == 0)) {
+ /* might seem weird - but could be caused by a person moving BEFORE
+ he receives the board pos (this is possible due to lag) but it's
+ safe to say he moved in 0 secs :-) */
+ garray[g].bTimeWhenReceivedMove = garray[g].bTimeWhenMoved;
+ } else {
+ garray[g].bRealTime -= garray[g].bTimeWhenMoved - garray[g].bTimeWhenReceivedMove;
+ }
+ }
+ }
+ /* we need to reset the opp's time for receiving the board since the
+ timeseal decoder only alters the time if it's 0 Otherwise the time
+ would be changed if the player did a refresh which would screw up
+ the timings */
+ if (parray[p].side == WHITE) {
+ garray[g].bTimeWhenReceivedMove = 0;
+ } else {
+ garray[g].wTimeWhenReceivedMove = 0;
+ }
+
+#endif
+
+ game_update_time(g);
+
+ /* maybe add autoflag here in the future? */
+
+#ifdef TIMESEAL
+
+ if (con[parray[p].socket].timeseal) { /* does he use timeseal? */
+ if (parray[p].side == WHITE) {
+ garray[g].wRealTime += garray[g].wIncrement * 100;
+ garray[g].wTime = garray[g].wRealTime / 100; /* remember to conv to
+ tenth secs */
+ } else if (parray[p].side == BLACK) {
+ garray[g].bRealTime += garray[g].bIncrement * 100; /* conv to ms */
+ garray[g].bTime = garray[g].bRealTime / 100; /* remember to conv to
+ tenth secs */
+ }
+ } else {
+ if (garray[g].game_state.onMove == BLACK) {
+ garray[g].bTime += garray[g].bIncrement;
+ }
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += garray[g].wIncrement;
+ }
+ }
+
+#else
+
+ if (garray[g].game_state.onMove == BLACK) {
+ garray[g].bTime += garray[g].bIncrement;
+ }
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += garray[g].wIncrement;
+ }
+#endif
+
+ /* Do the move */
+ garray[g].numHalfMoves++;
+ if (garray[g].numHalfMoves > garray[g].moveListSize) {
+ garray[g].moveListSize += 20; /* Allocate 20 moves at a time */
+ if (!garray[g].moveList) {
+ garray[g].moveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].moveListSize);
+ } else {
+ garray[g].moveList = (move_t *) rrealloc(garray[g].moveList, sizeof(move_t) * garray[g].moveListSize);
+ }
+ }
+ result = execute_move(&garray[g].game_state, &move, 1);
+ if (result == MOVE_OK && garray[g].link >= 0 && move.pieceCaptured != NOPIECE) {
+ /* transfer captured piece to partner */
+ /* check if piece reverts to a pawn */
+ if (was_promoted(&garray[g], move.toFile, move.toRank))
+ update_holding(garray[g].link, colorval(move.pieceCaptured) | PAWN);
+ else
+ update_holding(garray[g].link, move.pieceCaptured);
+ }
+ now = tenth_secs();
+ move.atTime = now;
+ if (garray[g].numHalfMoves > 1) {
+ move.tookTime = move.atTime - garray[g].lastMoveTime;
+ } else {
+ move.tookTime = move.atTime - garray[g].startTime;
+ }
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+
+#ifdef TIMESEAL
+
+ if (con[parray[p].socket].timeseal) { /* does he use timeseal? */
+ if (parray[p].side == WHITE) {
+ move.tookTime = (garray[parray[p].game].wTimeWhenMoved -
+ garray[parray[p].game].wTimeWhenReceivedMove) / 100;
+ } else {
+ move.tookTime = (garray[parray[p].game].bTimeWhenMoved -
+ garray[parray[p].game].bTimeWhenReceivedMove) / 100;
+ }
+ }
+#endif
+
+ MakeFENpos(g, move.FENpos);
+ garray[g].moveList[garray[g].numHalfMoves - 1] = move;
+ }
+
+ send_boards(g);
+
+ if (result == MOVE_ILLEGAL) {
+ pprintf(p, "Internal error, illegal move accepted!\n");
+ }
+ if ((result == MOVE_OK) && (garray[g].status == GAME_EXAMINE)) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf_prompt(p1, "%s moves: %s\n", parray[p].name, move.algString);
+ }
+ }
+ }
+ if (result == MOVE_CHECKMATE) {
+ if (garray[g].status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s has been checkmated.\n",
+ (CToggle(garray[g].game_state.onMove) == BLACK) ? "White" : "Black");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(garray[g].game_state.onMove), END_CHECKMATE);
+ }
+ }
+ if (result == MOVE_STALEMATE) {
+ if (garray[g].status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "Stalemate.\n");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(garray[g].game_state.onMove), END_STALEMATE);
+ }
+ }
+ if (result == MOVE_NOMATERIAL) {
+ if (garray[g].status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "No mating material.\n");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(garray[g].game_state.onMove), END_NOMATERIAL);
+ }
+ }
+}
+
+PUBLIC int com_resign(int p, param_list param)
+{
+ int g, o, oconnected;
+
+ if (param[0].type == TYPE_NULL) {
+ g = parray[p].game;
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ } else {
+ player_decline_offers(p, -1, -1);
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_RESIGN);
+ }
+ } else if (FindPlayer(p, param[0].val.word, &o, &oconnected)) {
+ g = game_new();
+ if (game_read(g, p, o) < 0) {
+ if (game_read(g, o, p) < 0) {
+ pprintf(p, "You have no stored game with %s\n", parray[o].name);
+ if (!oconnected)
+ player_remove(o);
+ return COM_OK;
+ } else {
+ garray[g].white = o;
+ garray[g].black = p;
+ }
+ } else {
+ garray[g].white = p;
+ garray[g].black = o;
+ }
+ pprintf(p, "You resign your stored game with %s\n", parray[o].name);
+ game_delete(garray[g].white, garray[g].black);
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_RESIGN);
+ pcommand(p, "message %s I have resigned our stored game \"%s vs. %s.\"",
+ parray[o].name,
+ parray[garray[g].white].name,
+ parray[garray[g].black].name);
+ if (!oconnected)
+ player_remove(o);
+ }
+ return COM_OK;
+}
+
+int Check50MoveRule (int p, int g)
+{
+ int num_reversible = garray[g].numHalfMoves;
+
+ if (garray[g].game_state.lastIrreversable >= 0) {
+ num_reversible -= garray[g].game_state.lastIrreversable;
+ }
+ if (num_reversible > 99) {
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_50MOVERULE);
+ return 1;
+ }
+ return 0;
+}
+
+char *GetFENpos (int g, int half_move)
+{
+ if (half_move < 0)
+ return garray[g].FENstartPos;
+ else return garray[g].moveList[half_move].FENpos;
+}
+
+int CheckRepetition (int p, int g)
+{
+ int move_num;
+ int flag1 = 1, flag2 = 1;
+ char *pos1 = GetFENpos (g, garray[g].numHalfMoves - 1);
+ char *pos2 = GetFENpos (g, garray[g].numHalfMoves);
+ char *pos;
+
+ if (garray[g].numHalfMoves < 8) /* can't have three repeats any quicker. */
+ return 0;
+
+ for (move_num = garray[g].game_state.lastIrreversable;
+ move_num < garray[g].numHalfMoves - 1; move_num++) {
+ pos = GetFENpos (g, move_num);
+ if (strlen(pos1) == strlen(pos) && !strcmp(pos1, pos))
+ flag1++;
+ if (strlen(pos2) == strlen(pos) && !strcmp(pos2, pos))
+ flag2++;
+ }
+ if (flag1 >= 3 || flag2 >= 3) {
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_DRAW) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_DRAW);
+ player_decline_offers(p, -1, -1);
+ }
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_REPETITION);
+ return 1;
+ }
+ else return 0;
+}
+
+PUBLIC int com_draw(int p, param_list param)
+{
+ int p1, g = parray[p].game;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ if (Check50MoveRule (p, g) || CheckRepetition(p, g)) {
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] !=
+ g) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_DRAW) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_DRAW);
+ player_decline_offers(p, -1, -1);
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_AGREEDDRAW);
+ } else {
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " offers you a draw.\n");
+ pprintf(p, "Draw request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_DRAW, 0);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_pause(int p, param_list param)
+{
+ int g;
+ int now;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (garray[g].wTime == 0) {
+ pprintf(p, "You can't pause untimed games.\n");
+ return COM_OK;
+ }
+ if (garray[g].clockStopped) {
+ pprintf(p, "Game is already paused, use \"unpause\" to resume.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_PAUSE) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_PAUSE);
+ garray[g].clockStopped = 1;
+ /* Roll back the time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ pprintf_prompt(parray[p].opponent, "\n%s accepted pause. Game clock paused.\n",
+ parray[p].name);
+ pprintf(p, "Game clock paused.\n");
+ } else {
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " requests to pause the game.\n");
+ pprintf(p, "Pause request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_PAUSE, 0);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unpause(int p, param_list param)
+{
+ int now;
+ int g;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (!garray[g].clockStopped) {
+ pprintf(p, "Game is not paused.\n");
+ return COM_OK;
+ }
+ garray[g].clockStopped = 0;
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ pprintf(p, "Game clock resumed.\n");
+ pprintf_prompt(parray[p].opponent, "\nGame clock resumed.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_abort(int p, param_list param)
+{
+ int p1, g, myColor, yourColor, myGTime, yourGTime;
+ int courtesyOK = 1;
+
+ ASSERT(param[0].type == TYPE_NULL);
+
+ g = parray[p].game;
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ p1 = parray[p].opponent;
+ if (p == garray[g].white) {
+ myColor = WHITE;
+ yourColor = BLACK;
+ myGTime = garray[g].wTime;
+ yourGTime = garray[g].bTime;
+ } else {
+ myColor = BLACK;
+ yourColor = WHITE;
+ myGTime = garray[g].bTime;
+ yourGTime = garray[g].wTime;
+ }
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != g) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, p1, PEND_ABORT) >= 0) {
+ player_remove_request(p1, p, PEND_ABORT);
+ player_decline_offers(p, -1, -1);
+ game_ended(g, yourColor, END_ABORT);
+ } else {
+ game_update_time(g);
+
+#ifdef TIMESEAL
+ if (con[parray[p].socket].timeseal
+ && garray[g].game_state.onMove == myColor
+ && garray[g].flag_pending == FLAG_ABORT) {
+ /* It's my move, opponent has asked for abort; I lagged out,
+ my timeseal prevented courtesyabort, and I sent an abort
+ request before acknowledging (and processing) my opponent's
+ courtesyabort. OK, let's abort already :-). */
+ player_decline_offers(p, -1, -1);
+ game_ended(g, yourColor, END_ABORT);
+ }
+
+ if (con[parray[p1].socket].timeseal) { /* opp uses timeseal? */
+
+ int yourRealTime = (myColor == WHITE ? garray[g].bRealTime
+ : garray[g].wRealTime);
+ if (myGTime > 0 && yourGTime <= 0 && yourRealTime > 0) {
+ /* Override courtesyabort; opponent still has time. Check for lag. */
+ courtesyOK = 0;
+
+ if (garray[g].game_state.onMove != myColor
+ && garray[g].flag_pending != FLAG_CHECKING) {
+ /* Opponent may be lagging; let's ask. */
+ garray[g].flag_pending = FLAG_ABORT;
+ garray[g].flag_check_time = time(0);
+ pprintf(p, "Opponent has timeseal; trying to courtesyabort.\n");
+ pprintf(p1, "\n[G]\n");
+ return COM_OK;
+ }
+ }
+ }
+#endif
+
+ if (myGTime > 0 && yourGTime <= 0 && courtesyOK) {
+ /* player wants to abort + opponent is out of time = courtesyabort */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been aborted.");
+ pprintf(p1, "Your opponent has aborted the game rather than calling your flag.");
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_COURTESY);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf(p1, " would like to abort the game; ");
+ pprintf_prompt(p1, "type \"abort\" to accept.\n");
+ pprintf(p, "Abort request sent.\n");
+ player_add_request(p, p1, PEND_ABORT, 0);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_courtesyabort(int p, param_list param)
+{
+ pprintf(p, "Courtesyabort is obsolete; use \"abort\" instead.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_courtesyadjourn(int p, param_list param)
+{
+ pprintf(p, "Use \"adjourn\" to courtesyadjourn a game.\n");
+ return COM_OK;
+}
+
+PRIVATE int player_has_mating_material(game_state_t *gs, int color)
+{
+ int i, j;
+ int piece;
+ int minor_pieces = 0;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ piece = gs->board[i][j];
+ switch (piecetype(piece)) {
+ case BISHOP:
+ case KNIGHT:
+ if (iscolor(piece, color))
+ minor_pieces++;
+ break;
+ case KING:
+ case NOPIECE:
+ break;
+ default:
+ if (iscolor(piece, color))
+ return 1;
+ }
+ }
+ return ((minor_pieces > 1) ? 1 : 0);
+}
+
+PUBLIC int com_flag(int p, param_list param)
+{
+ int g;
+ int myColor;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ g = parray[p].game;
+ myColor = (p == garray[g].white ? WHITE : BLACK);
+ if (garray[g].type == TYPE_UNTIMED) {
+ pprintf(p, "You can't flag an untimed game.\n");
+ return COM_OK;
+ }
+ if (garray[g].numHalfMoves < 2) {
+ pprintf(p, "You cannot flag before both players have moved.\nUse abort instead.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+
+#ifdef TIMESEAL
+
+ {
+ int myTime, yourTime, opp = parray[p].opponent, serverTime;
+
+ if (con[parray[p].socket].timeseal) { /* does caller use timeseal? */
+ myTime = (myColor == WHITE ? garray[g].wRealTime
+ : garray[g].bRealTime);
+ } else {
+ myTime = (myColor == WHITE ? garray[g].wTime : garray[g].bTime);
+ }
+ serverTime = (myColor == WHITE ? garray[g].bTime : garray[g].wTime);
+
+ if (con[parray[opp].socket].timeseal) { /* opp uses timeseal? */
+ yourTime = (myColor == WHITE ? garray[g].bRealTime
+ : garray[g].wRealTime);
+ } else {
+ yourTime = serverTime;
+ }
+
+ /* the clocks to compare are now in myTime and yourTime */
+
+ if ((myTime <= 0) && (yourTime <= 0)) {
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_BOTHFLAG);
+ return COM_OK;
+ }
+ if (yourTime > 0) {
+ /* Opponent still has time, but if that's only because s/he
+ * may be lagging, we should ask for an acknowledgement and then
+ * try to call the flag. */
+
+ if (serverTime <= 0 && garray[g].game_state.onMove != myColor
+ && garray[g].flag_pending != FLAG_CHECKING) {
+
+ /* server time thinks opponent is down, but RealTIme disagrees.
+ * ask client to acknowledge it's alive. */
+
+ garray[g].flag_pending = FLAG_CALLED;
+ garray[g].flag_check_time = time(0);
+ pprintf(p, "Opponent has timeseal; checking if (s)he's lagging.\n");
+ pprintf (opp, "\n[G]\n");
+ return COM_OK;
+ }
+
+ /* if we're here, it means one of:
+ * 1. the server agrees opponent has time, whether lagging or not.
+ * 2. opp. has timeseal (if yourTime != serverTime), had time left
+ * after the last move (yourTime > 0), and it's still your move.
+ * 3. we're currently checking a flag call after having receiving
+ * acknowledgement from the other timeseal (and would have reset
+ * yourTime if the flag were down). */
+
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ }
+
+#else
+
+ if ((garray[g].wTime <= 0) && (garray[g].bTime <= 0)) {
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_BOTHFLAG);
+ return COM_OK;
+ }
+ if (myColor == WHITE) {
+ if (garray[g].bTime > 0) {
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ } else {
+ if (garray[g].wTime > 0) {
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ }
+
+#endif
+
+ player_decline_offers(p, -1, -1);
+ if (player_has_mating_material(&garray[g].game_state, myColor))
+ game_ended(g, myColor, END_FLAG);
+ else
+ game_ended(g, myColor, END_FLAGNOMATERIAL);
+ return COM_OK;
+}
+
+PUBLIC int com_adjourn(int p, param_list param)
+{
+ int p1, g, myColor, yourColor;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if (!pIsPlaying(p))
+ return COM_OK;
+
+ p1 = parray[p].opponent;
+ g = parray[p].game;
+ if (!(parray[p].registered && parray[p1].registered)) {
+ pprintf(p, "Both players must be registered to adjorn a game. Use \"abort\".\n");
+ return COM_OK;
+ }
+ if (garray[g].link >= 0) {
+ pprintf(p, "Bughouse games cannot be adjourned.\n");
+ return COM_OK;
+ }
+ myColor = (p == garray[g].white ? WHITE : BLACK);
+ yourColor = (myColor == WHITE ? BLACK : WHITE);
+
+ if (player_find_pendfrom(p, p1, PEND_ADJOURN) >= 0) {
+ player_remove_request(p1, p, PEND_ADJOURN);
+ player_decline_offers(p, -1, -1);
+ game_ended(parray[p].game, yourColor, END_ADJOURN);
+ } else {
+ game_update_time(g);
+ if (((myColor == WHITE) && (garray[g].wTime > 0) && (garray[g].bTime <= 0))
+ || ((myColor == BLACK) && (garray[g].bTime > 0) && (garray[g].wTime <= 0))) {
+/* player wants to adjourn + opponent is out of time = courtesyadjourn */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been adjourned.");
+ pprintf(p1, "Your opponent has adjourned the game rather than calling your flag.");
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_COURTESYADJOURN);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf(p1, " would like to adjourn the game; ");
+ pprintf_prompt(p1, "type \"adjourn\" to accept.\n");
+ pprintf(p, "Adjourn request sent.\n");
+ player_add_request(p, p1, PEND_ADJOURN, 0);
+ }
+ }
+ return COM_OK;
+}
+#if 0 /* this might as well die now */
+PUBLIC int com_load(int p, param_list param)
+{
+ pprintf(p, "Obsolete command, please use match <opponent>.\n");
+ return COM_OK;
+}
+#endif
+
+PUBLIC int com_takeback(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int from;
+ int g, i;
+ int p1;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] !=
+ parray[p].game) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (garray[g].link >= 0) {
+ pprintf(p, "Takeback not implemented for bughouse games yet.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if ((from = player_find_pendfrom(p, parray[p].opponent, PEND_TAKEBACK)) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_TAKEBACK);
+ if (parray[p].p_from_list[from].param1 == nHalfMoves) {
+ /* Doing the takeback */
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ for (i = 0; i < nHalfMoves; i++) {
+ if (backup_move(g, REL_GAME) != MOVE_OK) {
+ pprintf(garray[g].white, "Can only backup %d moves\n", i);
+ pprintf(garray[g].black, "Can only backup %d moves\n", i);
+ break;
+ }
+ }
+
+#ifdef TIMESEAL
+
+ garray[g].wTimeWhenReceivedMove = 0;
+ garray[g].bTimeWhenReceivedMove = 0;
+
+#endif
+
+ send_boards(g);
+ } else {
+ if (garray[g].numHalfMoves < nHalfMoves) {
+ pprintf(p, "There are only %d half moves in your game.\n", garray[g].numHalfMoves);
+ pprintf_prompt(parray[p].opponent, "\n%s has declined the takeback request.\n", parray[p].name, nHalfMoves);
+ return COM_OK;
+ }
+ pprintf(p, "You disagree on the number of half-moves to takeback.\n");
+ pprintf(p, "Alternate takeback request sent.\n");
+ pprintf_prompt(parray[p].opponent, "\n%s proposes a different number (%d) of half-move(s).\n", parray[p].name, nHalfMoves);
+ player_add_request(p, parray[p].opponent, PEND_TAKEBACK, nHalfMoves);
+ }
+ } else {
+ if (garray[g].numHalfMoves < nHalfMoves) {
+ pprintf(p, "There are only %d half moves in your game.\n", garray[g].numHalfMoves);
+ return COM_OK;
+ }
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " would like to take back %d half move(s).\n",
+ nHalfMoves);
+ pprintf(p, "Takeback request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_TAKEBACK, nHalfMoves);
+ }
+ return COM_OK;
+}
+
+
+PUBLIC int com_switch(int p, param_list param)
+{
+ int g = parray[p].game;
+ int tmp, now;
+ int p1;
+ char *strTmp;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != g) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if (garray[g].link >= 0) {
+ pprintf(p, "Switch not implemented for bughouse games.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_SWITCH) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_SWITCH);
+ /* Doing the switch */
+ player_decline_offers(p, -1, -PEND_SIMUL);
+
+ tmp = garray[g].white;
+ garray[g].white = garray[g].black;
+ garray[g].black = tmp;
+ parray[p].side = (parray[p].side == WHITE) ? BLACK : WHITE;
+ strTmp = strdup(garray[g].white_name);
+ strcpy(garray[g].white_name, garray[g].black_name);
+ strcpy(garray[g].black_name, strTmp);
+ strfree(strTmp);
+
+ parray[parray[p].opponent].side =
+ (parray[parray[p].opponent].side == WHITE) ? BLACK : WHITE;
+ /* Roll back the time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+ }
+ if (garray[g].rated && garray[g].numHalfMoves > 0) {
+ pprintf(p, "You cannot switch sides once a rated game is underway.\n");
+ return COM_OK;
+ }
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " would like to switch sides.\nType \"accept\" to switch sides, or \"decline\" to refuse.\n");
+ pprintf(p, "Switch request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_SWITCH, 0);
+ return COM_OK;
+}
+
+PUBLIC int com_time(int p, param_list param)
+{
+ int p1, g;
+
+ if (param[0].type == TYPE_NULL) {
+ g = parray[p].game;
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= g_num) || (garray[g].status != GAME_ACTIVE)) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+ pprintf(p, "White (%s) : %d mins, %d secs\n",
+ parray[garray[g].white].name,
+ garray[g].wTime / 600,
+ (garray[g].wTime - ((garray[g].wTime / 600) * 600)) / 10);
+ pprintf(p, "Black (%s) : %d mins, %d secs\n",
+ parray[garray[g].black].name,
+ garray[g].bTime / 600,
+ (garray[g].bTime - ((garray[g].bTime / 600) * 600)) / 10);
+ return COM_OK;
+}
+
+PUBLIC int com_boards(int p, param_list param)
+{
+ char *category = NULL;
+ char dname[MAX_FILENAME_SIZE];
+ DIR *dirp;
+#ifdef USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+
+ if (param[0].type == TYPE_WORD)
+ category = param[0].val.word;
+ if (category) {
+ pprintf(p, "Boards Available For Category %s:\n", category);
+ sprintf(dname, "%s/%s", board_dir, category);
+ } else {
+ pprintf(p, "Categories Available:\n");
+ sprintf(dname, "%s", board_dir);
+ }
+ dirp = opendir(dname);
+ if (!dirp) {
+ pprintf(p, "No such category %s, try \"boards\".\n", category);
+ return COM_OK;
+ }
+
+/* YUK! what a mess, how about printing an ordered directory? - DAV*/
+
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (!strcmp(dp->d_name, "."))
+ continue;
+ if (!strcmp(dp->d_name, ".."))
+ continue;
+ pprintf(p, "%s\n", dp->d_name);
+ }
+ closedir(dirp);
+ return COM_OK;
+}
+
+PUBLIC int com_simmatch(int p, param_list param)
+{
+ int p1, g, adjourned;
+ int num;
+ char tmp[100];
+
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are still examining a game.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You can't simmatch yourself!\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, p1, PEND_SIMUL) >= 0) {
+ player_remove_request(p, p1, PEND_MATCH);
+ player_remove_request(p1, p, PEND_MATCH);
+ player_remove_request(p, p1, PEND_SIMUL);
+ player_remove_request(p1, p, PEND_SIMUL);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+ player_decline_offers(p1, -1, PEND_SIMUL);
+ player_withdraw_offers(p1, -1, PEND_SIMUL);
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_decline_offers(p1, -1, PEND_MATCH);
+ player_withdraw_offers(p1, -1, PEND_MATCH);
+ player_decline_offers(p, -1, PEND_PARTNER);
+ player_withdraw_offers(p, -1, PEND_PARTNER);
+ player_decline_offers(p1, -1, PEND_PARTNER);
+ player_withdraw_offers(p1, -1, PEND_PARTNER);
+
+ /* Accepting Simul ! */
+
+ if (parray[p].simul_info.numBoards >= MAX_SIMUL) {
+ pprintf(p, "You are already playing the maximum of %d boards.\n", MAX_SIMUL);
+ pprintf(p1, "Simul request removed, boards filled.\n");
+ return COM_OK;
+ }
+ unobserveAll(p); /* stop observing when match starts */
+ unobserveAll(p1);
+
+ g = game_new();
+ adjourned = 0;
+ if (game_read(g, p, p1) >= 0)
+ adjourned = 1;
+ if (!adjourned) { /* no adjourned game, so begin a new game */
+ game_remove(g);
+
+ if (create_new_match(p, p1, 0, 0, 0, 0, 0, "standard", "standard", 1)) {
+ pprintf(p, "There was a problem creating the new match.\n");
+ pprintf_prompt(p1, "There was a problem creating the new match.\n");
+ return COM_OK;
+ }
+ } else { /* resume adjourned game */
+ game_delete(p, p1);
+
+ sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s simul.}\n", g + 1, parray[p].name, parray[p1].name, rstr[garray[g].rated], bstr[garray[g].type]);
+ pprintf(p, tmp);
+ pprintf(p1, tmp);
+
+ garray[g].white = p;
+ garray[g].black = p1;
+ garray[g].status = GAME_ACTIVE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ parray[p].game = g;
+ parray[p].opponent = p1;
+ parray[p].side = WHITE;
+ parray[p1].game = g;
+ parray[p1].opponent = p;
+ parray[p1].side = BLACK;
+ send_boards(g);
+ }
+
+ num = parray[p].simul_info.numBoards;
+ parray[p].simul_info.results[num] = -1;
+ parray[p].simul_info.boards[num] = parray[p].game;
+ parray[p].simul_info.numBoards++;
+ if (parray[p].simul_info.numBoards > 1 &&
+ parray[p].simul_info.onBoard >= 0)
+ player_goto_board(p, parray[p].simul_info.onBoard);
+ else
+ parray[p].simul_info.onBoard = 0;
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, -1, PEND_SIMUL) >= 0) {
+ pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards) {
+ pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >=0) {
+ pprintf(p, "You are already playing a game.\n");
+ return COM_OK;
+ }
+ if (!parray[p1].sopen) {
+ pprintf_highlight(p, "%s", parray[p1].name);
+ pprintf(p, " is not open to receiving simul requests.\n");
+ return COM_OK;
+ }
+ if (parray[p1].simul_info.numBoards >= MAX_SIMUL) {
+ pprintf_highlight(p, "%s", parray[p1].name);
+ pprintf(p, " is already playing the maximum of %d boards.\n", MAX_SIMUL);
+ return COM_OK;
+ }
+/* loon: checking for some crazy situations we can't allow :) */
+
+ if ((parray[p1].game >=0) &&(parray[p1].simul_info.numBoards == 0)) {
+ pprintf_highlight(p, "%s", parray[p1].name);
+ if (parray[garray[parray[p1].game].white].simul_info.numBoards) {
+ pprintf(p, " is playing in ");
+ pprintf_highlight(p, "%s", parray[parray[p1].opponent].name);
+ pprintf(p, "'s simul, and can't accept.\n");
+ } else {
+ pprintf(p, " can't begin a simul while playing a non-simul game.\n");
+ }
+ return COM_OK;
+ }
+/* loon: this was (p, p1, PEND_SIMUL) but player_add_request needs 4 args...
+if 0 is the incorrect 4th arg, please fix :) */
+
+ g = game_new(); /* Check if an adjourned untimed game */
+ adjourned = ((game_read(g, p, p1) < 0) && (game_read(g, p1, p) < 0)) ? 0 : 1;
+ if (adjourned) {
+ if (!(garray[g].type == TYPE_UNTIMED))
+ adjourned = 0;
+ }
+ game_remove(g);
+
+ if (player_add_request(p, p1, PEND_SIMUL, 0)) {
+ pprintf(p, "Maximum number of pending actions reached. Your request was not sent.\nTry again later.\n");
+ return COM_OK;
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ if (adjourned) {
+ pprintf_prompt(p1, " requests to continue an adjourned simul game.\n");
+ pprintf(p, "Request to resume simul sent. Adjourned game found.\n");
+ } else {
+ pprintf_prompt(p1, " requests to join a simul match with you.\n");
+ pprintf(p, "Simul match request sent.\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_goboard(int p, param_list param)
+{
+ int on, g, p1;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You can't goboard yourself!\n");
+ return COM_OK;
+ }
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ if (p1 == garray[g].black) {
+ pprintf(p, "You are already at that board!\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ if (player_goto_simulgame_bynum(p, parray[p1].game) !=-1) {
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " has moved away from your board.\n");
+ }
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+PUBLIC int com_gonum(int p, param_list param)
+{
+ int on, g, gamenum;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ gamenum = param[0].val.integer - 1;
+ if (gamenum < 0)
+ gamenum = 0;
+ if (on == gamenum) {
+ pprintf(p, "You are already at that board!\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ if (player_goto_simulgame_bynum(p, gamenum) != -1) {
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " has moved away from your board.\n");
+ }
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+PUBLIC int com_simnext(int p, param_list param)
+{
+ int on, g;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " is moving away from your board.\n");
+ player_goto_next_board(p);
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+
+PUBLIC int com_simprev(int p, param_list param)
+{
+ int on, g;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " is moving back to the previous board.\n");
+ }
+ player_goto_prev_board(p);
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+PUBLIC int com_simgames(int p, param_list param)
+{
+ int p1 = p;
+
+ if (param[0].type == TYPE_WORD) {
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "No player named %s is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ if (p1 == p)
+ pprintf(p, "You are playing %d simultaneous games.\n",
+ player_num_active_boards(p1));
+ else
+ pprintf(p, "%s is playing %d simultaneous games.\n", parray[p1].name,
+ player_num_active_boards(p1));
+ return COM_OK;
+}
+
+PUBLIC int com_simpass(int p, param_list param)
+{
+ int g, p1, on;
+
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ g = parray[p].game;
+ p1 = garray[g].white;
+ if (!parray[p1].simul_info.numBoards) {
+ pprintf(p, "You are not participating in a simul.\n");
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You are the simul holder and cannot pass!\n");
+ return COM_OK;
+ }
+ if (player_num_active_boards(p1) == 1) {
+ pprintf(p, "This is the only game, so passing is futile.\n");
+ return COM_OK;
+ }
+ on = parray[p1].simul_info.onBoard;
+ if (parray[p1].simul_info.boards[on] != g) {
+ pprintf(p, "You cannot pass until the simul holder arrives!\n");
+ return COM_OK;
+ }
+ if (garray[g].passes >= MAX_SIMPASS) {
+ if (parray[p].bell)
+ pprintf(p, "\a");
+ pprintf(p, "You have reached your maximum of %d pass(es).\n", MAX_SIMPASS);
+ pprintf(p, "Please move IMMEDIATELY!\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " tried to pass, but is out of passes.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+
+ garray[g].passes++;
+ pprintf(p, "You have passed and have %d pass(es) left.\n",
+ (MAX_SIMPASS - garray[g].passes));
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " has decided to pass and has %d pass(es) left.\n",
+ (MAX_SIMPASS - garray[g].passes));
+ player_goto_next_board(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_simabort(int p, param_list param)
+{
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ game_ended(parray[p].simul_info.boards[parray[p].simul_info.onBoard],
+ WHITE, END_ABORT);
+ return COM_OK;
+}
+
+PUBLIC int com_simallabort(int p, param_list param)
+{
+ int i;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ for (i = 0; i < parray[p].simul_info.numBoards; i++) {
+ if (parray[p].simul_info.boards[i] >= 0) {
+ game_ended(parray[p].simul_info.boards[i],
+ WHITE, END_ABORT);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_simadjourn(int p, param_list param)
+{
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ game_ended(parray[p].simul_info.boards[parray[p].simul_info.onBoard],
+ WHITE, END_ADJOURN);
+ return COM_OK;
+}
+
+PUBLIC int com_simalladjourn(int p, param_list param)
+{
+ int i;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ for (i = 0; i < parray[p].simul_info.numBoards; i++) {
+ if (parray[p].simul_info.boards[i] >= 0) {
+ game_ended(parray[p].simul_info.boards[i],
+ WHITE, END_ADJOURN);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_moretime(int p, param_list param)
+{
+ int g, increment;
+
+ ASSERT(param[0].type == TYPE_INT);
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You cannot use moretime in an examined game.\n");
+ return COM_OK;
+ }
+ increment = param[0].val.integer;
+ if (increment <= 0) {
+ pprintf(p, "Moretime requires an integer value greater than zero.\n");
+ return COM_OK;
+ }
+ if (!pIsPlaying(p)) {
+ return COM_OK;
+ }
+ if (increment > 600) {
+ pprintf(p, "Moretime has a maximum limit of 600 seconds.\n");
+ increment = 600;
+ }
+ g = parray[p].game;
+ if (garray[g].white == p) {
+ garray[g].bTime += increment * 10;
+#ifdef TIMESEAL
+ garray[g].bRealTime += increment * 10 * 100;
+#endif
+ pprintf(p, "%d seconds were added to your opponents clock\n",
+ increment);
+ pprintf_prompt(parray[p].opponent,
+ "\nYour opponent has added %d seconds to your clock.\n",
+ increment);
+ }
+ if (garray[g].black == p) {
+ garray[g].wTime += increment * 10;;
+#ifdef TIMESEAL
+ garray[g].wRealTime += increment * 10 * 100;
+#endif
+ pprintf(p, "%d seconds were added to your opponents clock\n",
+ increment);
+ pprintf_prompt(parray[p].opponent,
+ "\nYour opponent has added %d seconds to your clock.\n",
+ increment);
+ }
+ return COM_OK;
+}
+
blob - /dev/null
blob + 832f5c9940c80f27d6007d7c93da70bcc866e909 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/gameproc.c.orig
+/* gameproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "command.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "movecheck.h"
+#include "utils.h"
+#include "ratings.h"
+#include "rmalloc.h"
+#include "comproc.h"
+#include "matchproc.h"
+#include "formula.h"
+#include "eco.h"
+#include "network.h"
+/* #include "hostinfo.h" */
+
+PUBLIC void game_ended(int g, int winner, int why)
+{
+ char outstr[200];
+ char tmp[200];
+ int p;
+ int rate_change = 0;
+ int isDraw = 0;
+ int whiteResult;
+ char winSymbol[10];
+ char EndSymbol[10];
+ char *NameOfWinner, *NameOfLoser;
+ int beingplayed = 0; /* i.e. it wasn't loaded for adjudication */
+
+ beingplayed = (parray[garray[g].black].game == g);
+
+ sprintf(outstr, "\n{Game %d (%s vs. %s) ", g + 1,
+ parray[garray[g].white].name,
+ parray[garray[g].black].name);
+ garray[g].result = why;
+ garray[g].winner = winner;
+ if (winner == WHITE) {
+ whiteResult = RESULT_WIN;
+ strcpy(winSymbol, "1-0");
+ NameOfWinner = parray[garray[g].white].name;
+ NameOfLoser = parray[garray[g].black].name;
+ } else {
+ whiteResult = RESULT_LOSS;
+ strcpy(winSymbol, "0-1");
+ NameOfWinner = parray[garray[g].black].name;
+ NameOfLoser = parray[garray[g].white].name;
+ }
+ switch (why) {
+ case END_CHECKMATE:
+ sprintf(tmp, "%s checkmated} %s\n", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Mat");
+ rate_change = 1;
+ break;
+ case END_RESIGN:
+ sprintf(tmp, "%s resigns} %s\n", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Res");
+ rate_change = 1;
+ break;
+ case END_FLAG:
+ sprintf(tmp, "%s forfeits on time} %s\n", NameOfLoser, winSymbol);
+ strcpy(EndSymbol, "Fla");
+ rate_change = 1;
+ break;
+ case END_STALEMATE:
+ sprintf(tmp, "Game drawn by stalemate} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Sta");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_AGREEDDRAW:
+ sprintf(tmp, "Game drawn by mutual agreement} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Agr");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_BOTHFLAG:
+ sprintf(tmp, "Game drawn because both players ran out of time} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Fla");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_REPETITION:
+ sprintf(tmp, "Game drawn by repetition} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Rep");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_50MOVERULE:
+ sprintf(tmp, "Game drawn by the 50 move rule} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "50");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJOURN:
+ sprintf(tmp, "Game adjourned by mutual agreement} *\n");
+ game_save(g);
+ break;
+ case END_LOSTCONNECTION:
+ sprintf(tmp, "%s lost connection; game ", NameOfWinner);
+ if (parray[garray[g].white].registered && parray[garray[g].black].registered) {
+ sprintf(tmp, "adjourned} *\n");
+ game_save(g);
+ } else
+ sprintf(tmp, "aborted} *\n");
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_ABORT:
+ sprintf(tmp, "Game aborted by mutual agreement} *\n");
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_COURTESY:
+ sprintf(tmp, "Game courtesyaborted by %s} *\n", NameOfWinner);
+ whiteResult = RESULT_ABORT;
+ break;
+ case END_COURTESYADJOURN:
+ sprintf(tmp, "Game courtesyadjourned by %s} *\n", NameOfWinner);
+ game_save(g);
+ break;
+ case END_NOMATERIAL:
+ /* Draw by insufficient material (e.g., lone K vs. lone K) */
+ sprintf(tmp, "Neither player has mating material} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "NM ");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_FLAGNOMATERIAL:
+ sprintf(tmp, "%s ran out of time and %s has no material to mate} 1/2-1/2\n",
+ NameOfLoser, NameOfWinner);
+ isDraw = 1;
+ strcpy(EndSymbol, "TM ");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJWIN:
+ sprintf(tmp, "%s wins by adjudication} %s\n", NameOfWinner, winSymbol);
+ strcpy(EndSymbol, "Adj");
+ rate_change = 1;
+ break;
+ case END_ADJDRAW:
+ sprintf(tmp, "Game drawn by adjudication} 1/2-1/2\n");
+ isDraw = 1;
+ strcpy(EndSymbol, "Adj");
+ rate_change = 1;
+ whiteResult = RESULT_DRAW;
+ break;
+ case END_ADJABORT:
+ sprintf(tmp, "Game aborted by adjudication} *\n");
+ whiteResult = RESULT_ABORT;
+ break;
+ default:
+ sprintf(tmp, "Hmm, the game ended and I don't know why} *\n");
+ break;
+ }
+ strcat(outstr, tmp);
+ if (beingplayed) {
+ pprintf_noformat(garray[g].white, outstr);
+ pprintf_noformat(garray[g].black, outstr);
+
+ for (p = 0; p < p_num; p++) {
+ if ((p == garray[g].white) || (p == garray[g].black))
+ continue;
+ if (parray[p].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p].i_game && !player_is_observe(p, g))
+ continue;
+ pprintf_noformat(p, outstr);
+ pprintf_prompt(p, "");
+ }
+ }
+ if ((garray[g].rated) && (rate_change)) {
+ /* Adjust ratings */
+ rating_update(g);
+ if (parray[garray[g].white].network_player &&
+ parray[garray[g].black].network_player) {
+ if (MailGameResult) { /* Send to ratings server */
+ if (isDraw) {
+ /* hostinfo_mailresults(garray[g].type == TYPE_BLITZ ? "blitz" :
+ garray[g].type == TYPE_WILD ? "wild " : "stand", "
+ parray[garray[g].white].name, parray[garray[g].black].name,
+ "draw"); */
+ } else {
+/* hostinfo_mailresults(garray[g].type == TYPE_BLITZ ? "blitz" : garray[g].type == TYPE_WILD ? "wild " : "stand",
+ parray[garray[g].white].name,
+ parray[garray[g].black].name,
+ (winner == WHITE) ? parray[garray[g].white].name :
+ parray[garray[g].black].name); */
+ }
+ }
+ }
+ } else {
+ if (beingplayed) {
+ pprintf(garray[g].white, "No ratings adjustment done.\n");
+ pprintf(garray[g].black, "No ratings adjustment done.\n");
+ }
+ }
+ if (rate_change)
+ game_write_complete(g, isDraw, EndSymbol);
+ /* Mail off the moves */
+ if (parray[garray[g].white].automail) {
+ pcommand(garray[g].white, "mailmoves");
+ }
+ if (parray[garray[g].black].automail) {
+ pcommand(garray[g].black, "mailmoves");
+ }
+ parray[garray[g].white].num_white++;
+ parray[garray[g].white].lastColor = WHITE;
+ parray[garray[g].black].num_black++;
+ parray[garray[g].black].lastColor = BLACK;
+ parray[garray[g].white].last_opponent = garray[g].black;
+ parray[garray[g].black].last_opponent = garray[g].white;
+ if (beingplayed) {
+ parray[garray[g].white].game = -1;
+ parray[garray[g].black].game = -1;
+ parray[garray[g].white].opponent = -1;
+ parray[garray[g].black].opponent = -1;
+ if (garray[g].white != commanding_player)
+ pprintf_prompt(garray[g].white, "");
+ if (garray[g].black != commanding_player)
+ pprintf_prompt(garray[g].black, "");
+ if (parray[garray[g].white].simul_info.numBoards) {
+ player_simul_over(garray[g].white, g, whiteResult);
+ }
+ }
+ game_finish(g);
+}
+
+PUBLIC void process_move(int p, char *command)
+{
+ int g;
+ move_t move;
+ int result;
+ unsigned now;
+ int len; /* loon: for lame promotion hack */
+ int i;
+
+ if (parray[p].game <0) {
+ pprintf(p, "You are not playing a game.\n");
+ return;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ g = parray[p].game;
+
+ if (garray[g].status != GAME_EXAMINE) {
+ if (parray[p].side != garray[g].game_state.onMove) {
+ pprintf(p, "It is not your move.\n");
+ return;
+ }
+ if (garray[g].clockStopped) {
+ pprintf(p, "Game clock is paused, use \"unpause\" to resume.\n");
+ return;
+ }
+ }
+ if ((len = strlen(command)) > 1) {
+ if (command[len - 2] == '=') {
+ switch (tolower(command[strlen(command) - 1])) {
+ case 'n':
+ parray[p].promote = KNIGHT;
+ break;
+ case 'b':
+ parray[p].promote = BISHOP;
+ break;
+ case 'r':
+ parray[p].promote = ROOK;
+ break;
+ case 'q':
+ parray[p].promote = QUEEN;
+ break;
+ default:
+ pprintf(p, "Don't understand that move.\n");
+ return;
+ break;
+ }
+ }
+ }
+ switch (parse_move(command, &garray[g].game_state, &move, parray[p].promote)) {
+ case MOVE_ILLEGAL:
+ pprintf(p, "Illegal move.\n");
+ return;
+ break;
+ case MOVE_AMBIGUOUS:
+ pprintf(p, "Ambiguous move.\n");
+ return;
+ break;
+ default:
+ break;
+ }
+
+ if (garray[g].status == GAME_EXAMINE) {
+ garray[g].numHalfMoves++;
+ if (garray[g].numHalfMoves > garray[g].examMoveListSize) {
+ garray[g].examMoveListSize += 20; /* Allocate 20 moves at a time */
+ if (!garray[g].examMoveList) {
+ garray[g].examMoveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].examMoveListSize);
+ } else {
+ garray[g].examMoveList = (move_t *) rrealloc(garray[g].examMoveList, sizeof(move_t) * garray[g].examMoveListSize);
+ }
+ }
+ result = execute_move(&garray[g].game_state, &move, 1);
+ move.atTime = now;
+ move.tookTime = 0;
+ garray[g].examMoveList[garray[g].numHalfMoves - 1] = move;
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+
+ } else { /* real game */
+ i = parray[p].opponent;
+ if (parray[i].simul_info.numBoards &&
+ (parray[i].simul_info.boards[parray[i].simul_info.onBoard] != g)) {
+ pprintf(p, "It isn't your turn: wait until the simul giver is at your board.\n");
+ return;
+ }
+#ifdef TIMESEAL
+
+
+ if (con[parray[p].socket].timeseal) { /* does he use timeseal? */
+ if (parray[p].side == WHITE) {
+ garray[g].wLastRealTime = garray[g].wRealTime;
+ garray[g].wTimeWhenMoved = con[parray[p].socket].time;
+ if (((garray[g].wTimeWhenMoved - garray[g].wTimeWhenReceivedMove) < 0) ||
+ (garray[g].wTimeWhenReceivedMove == 0)) {
+ /* might seem weird - but could be caused by a person moving BEFORE
+ he receives the board pos (this is possible due to lag) but it's
+ safe to say he moved in 0 secs :-) */
+ garray[g].wTimeWhenReceivedMove = garray[g].wTimeWhenMoved;
+ } else {
+ garray[g].wRealTime -= garray[g].wTimeWhenMoved - garray[g].wTimeWhenReceivedMove;
+ }
+ } else if (parray[p].side == BLACK) {
+ garray[g].bLastRealTime = garray[g].bRealTime;
+ garray[g].bTimeWhenMoved = con[parray[p].socket].time;
+ if (((garray[g].bTimeWhenMoved - garray[g].bTimeWhenReceivedMove) < 0) ||
+ (garray[g].bTimeWhenReceivedMove == 0)) {
+ /* might seem weird - but could be caused by a person moving BEFORE
+ he receives the board pos (this is possible due to lag) but it's
+ safe to say he moved in 0 secs :-) */
+ garray[g].bTimeWhenReceivedMove = garray[g].bTimeWhenMoved;
+ } else {
+ garray[g].bRealTime -= garray[g].bTimeWhenMoved - garray[g].bTimeWhenReceivedMove;
+ }
+ }
+ }
+ if (parray[p].side == WHITE) {
+ /* we need to reset the opp's time for receiving the board since the
+ timeseal decoder only alters the time if it's 0 Otherwise the time
+ would be changed if the player did a refresh which would screw up
+ the timings */
+ garray[g].bTimeWhenReceivedMove = 0;
+ } else {
+ /* we need to reset the opp's time for receiving the board since the
+ timeseal decoder only alters the time if it's 0 Otherwise the time
+ would be changed if the player did a refresh which would screw up
+ the timings */
+ garray[g].wTimeWhenReceivedMove = 0;
+ }
+
+#endif
+
+ game_update_time(g);
+
+ /* maybe add autoflag here in the future? */
+
+#ifdef TIMESEAL
+
+ if (con[parray[p].socket].timeseal) { /* does he use timeseal? */
+ if (parray[p].side == WHITE) {
+ garray[g].wRealTime += garray[g].wIncrement * 100;
+ garray[g].wTime = garray[g].wRealTime / 100; /* remember to conv to
+ tenth secs */
+ } else if (parray[p].side == BLACK) {
+ garray[g].bRealTime += garray[g].bIncrement * 100; /* conv to ms */
+ garray[g].bTime = garray[g].bRealTime / 100; /* remember to conv to
+ tenth secs */
+ }
+ } else {
+ if (garray[g].game_state.onMove == BLACK) {
+ garray[g].bTime += garray[g].bIncrement;
+ }
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += garray[g].wIncrement;
+ }
+ }
+
+#else
+
+ if (garray[g].game_state.onMove == BLACK) {
+ garray[g].bTime += garray[g].bIncrement;
+ }
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += garray[g].wIncrement;
+ }
+#endif
+
+ /* Do the move */
+ garray[g].numHalfMoves++;
+ if (garray[g].numHalfMoves > garray[g].moveListSize) {
+ garray[g].moveListSize += 20; /* Allocate 20 moves at a time */
+ if (!garray[g].moveList) {
+ garray[g].moveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].moveListSize);
+ } else {
+ garray[g].moveList = (move_t *) rrealloc(garray[g].moveList, sizeof(move_t) * garray[g].moveListSize);
+ }
+ }
+ result = execute_move(&garray[g].game_state, &move, 1);
+ now = tenth_secs();
+ move.atTime = now;
+ if (garray[g].numHalfMoves > 1) {
+ move.tookTime = move.atTime - garray[g].lastMoveTime;
+ } else {
+ move.tookTime = move.atTime - garray[g].startTime;
+ }
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+
+#ifdef TIMESEAL
+
+ if (con[parray[p].socket].timeseal) { /* does he use timeseal? */
+ if (parray[p].side == WHITE) {
+ move.tookTime = (garray[parray[p].game].wTimeWhenMoved -
+ garray[parray[p].game].wTimeWhenReceivedMove) / 100;
+ } else {
+ move.tookTime = (garray[parray[p].game].bTimeWhenMoved -
+ garray[parray[p].game].bTimeWhenReceivedMove) / 100;
+ }
+ }
+#endif
+
+ garray[g].moveList[garray[g].numHalfMoves - 1] = move;
+ }
+
+ send_boards(g);
+
+ strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g));
+
+ if (result == MOVE_ILLEGAL) {
+ pprintf(p, "Internal error, illegal move accepted!\n");
+ }
+ if ((result == MOVE_OK) && (garray[g].status == GAME_EXAMINE)) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf_prompt(p1, "%s moves: %s\n", parray[p].name, move.algString);
+ }
+ }
+ }
+ if (result == MOVE_CHECKMATE) {
+ if (garray[g].status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s has been checkmated.\n",
+ (CToggle(garray[g].game_state.onMove) == BLACK) ? "White" : "Black");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(garray[g].game_state.onMove), END_CHECKMATE);
+ }
+ }
+ if (result == MOVE_STALEMATE) {
+ if (garray[g].status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "Stalemate.\n");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(garray[g].game_state.onMove), END_STALEMATE);
+ }
+ }
+ if (result == MOVE_NOMATERIAL) {
+ if (garray[g].status == GAME_EXAMINE) {
+ int p1;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "No mating material.\n");
+ }
+ }
+ } else {
+ game_ended(g, CToggle(garray[g].game_state.onMove), END_NOMATERIAL);
+ }
+ }
+}
+
+int GameNumFromParam(int p, int *p1, parameter *param)
+{
+ if (param->type == TYPE_WORD) {
+ *p1 = player_find_part_login(param->val.word);
+ if (*p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param->val.word);
+ return -1;
+ }
+ if (parray[*p1].game <0)
+ pprintf(p, "%s is not playing a game.\n", parray[*p1].name);
+ return parray[*p1].game;
+ } else { /* Must be an integer */
+ *p1 = -1;
+ if (param->val.integer <= 0)
+ pprintf(p, "%d is not a valid game number.\n", param->val.integer);
+ return param->val.integer - 1;
+ }
+}
+
+PUBLIC int com_resign(int p, param_list param)
+{
+ int g, o, oconnected, confused = 0;
+
+ if (param[0].type == TYPE_NULL) {
+ g = parray[p].game;
+ if ((g < 0) || (garray[g].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ } else {
+ player_decline_offers(p, -1, -1);
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_RESIGN);
+ }
+ } else if (FindPlayer(p, ¶m[0], &o, &oconnected)) {
+ g = game_new();
+ if (game_read(g, p, o) < 0) {
+ if (game_read(g, o, p) < 0) {
+ confused = 1;
+ pprintf(p, "You have no stored game with %s\n", parray[o].name);
+ } else {
+ garray[g].white = o;
+ garray[g].black = p;
+ }
+ } else {
+ garray[g].white = p;
+ garray[g].black = o;
+ }
+ if (!confused) {
+ pprintf(p, "You resign your stored game with %s\n", parray[o].name);
+ game_delete(garray[g].white, garray[g].black);
+ game_ended(g, (garray[g].white == p) ? BLACK : WHITE, END_RESIGN);
+ pcommand(p, "message %s I have resigned our stored game \"%s vs. %s.\"",
+ parray[o].name,
+ parray[garray[g].white].name,
+ parray[garray[g].black].name);
+ if (!oconnected)
+ player_remove(o);
+ }
+ }
+ return COM_OK;
+}
+
+/*
+PUBLIC int com_resign(int p, param_list param)
+{
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((parray[p].game <0) || (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -1);
+ game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_RESIGN);
+ return COM_OK;
+}
+*/
+
+PUBLIC int com_draw(int p, param_list param)
+{
+ int p1;
+ int move_num = 0;
+ int i = 0, flag = 0;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ if (garray[parray[p].game].numHalfMoves - ((garray[parray[p].game].game_state.lastIrreversable == -1) ? 0 : garray[parray[p].game].game_state.lastIrreversable) > 99) {
+ game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_50MOVERULE);
+ return COM_OK;
+ }
+ if (garray[parray[p].game].game_state.lastIrreversable != -1)
+ move_num = garray[parray[p].game].game_state.lastIrreversable;
+
+ for (i = (garray[parray[p].game].numHalfMoves - 1); i <= garray[parray[p].game].numHalfMoves; i++) {
+ flag = 0;
+ if (garray[parray[p].game].game_state.lastIrreversable != -1)
+ move_num = garray[parray[p].game].game_state.lastIrreversable;
+ for (; move_num <= garray[parray[p].game].numHalfMoves; move_num++) {
+ if ((strlen(garray[parray[p].game].boardList[move_num])) !=
+ (strlen(garray[parray[p].game].boardList[i])))
+ continue;
+
+ if (!strcmp(garray[parray[p].game].boardList[move_num],
+ garray[parray[p].game].boardList[i]))
+ flag++;
+ }
+ if (flag >= 3) {
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_DRAW) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_DRAW);
+ player_decline_offers(p, -1, -1);
+ }
+ game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_REPETITION);
+ return COM_OK;
+ }
+ }
+
+ p1 = parray[p].opponent;
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] !=
+ parray[p].game) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_DRAW) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_DRAW);
+ player_decline_offers(p, -1, -1);
+ game_ended(parray[p].game, (garray[parray[p].game].white == p) ? BLACK : WHITE, END_AGREEDDRAW);
+ } else {
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " offers you a draw.\n");
+ pprintf(p, "Draw request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_DRAW, 0);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_pause(int p, param_list param)
+{
+ int g;
+ int now;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (garray[g].wTime == 0) {
+ pprintf(p, "You can't pause untimed games.\n");
+ return COM_OK;
+ }
+ if (garray[g].clockStopped) {
+ pprintf(p, "Game is already paused, use \"unpause\" to resume.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_PAUSE) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_PAUSE);
+ garray[g].clockStopped = 1;
+ /* Roll back the time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ pprintf_prompt(parray[p].opponent, "\n%s accepted pause. Game clock paused.\n",
+ parray[p].name);
+ pprintf(p, "Game clock paused.\n");
+ } else {
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " requests to pause the game.\n");
+ pprintf(p, "Pause request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_PAUSE, 0);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unpause(int p, param_list param)
+{
+ int now;
+ int g;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (!garray[g].clockStopped) {
+ pprintf(p, "Game is not paused.\n");
+ return COM_OK;
+ }
+ garray[g].clockStopped = 0;
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ pprintf(p, "Game clock resumed.\n");
+ pprintf_prompt(parray[p].opponent, "\nGame clock resumed.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_abort(int p, param_list param)
+{
+ int p1, g, myColor, yourColor;
+
+ ASSERT(param[0].type == TYPE_NULL);
+
+ g = parray[p].game;
+ if ((g < 0) || (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ myColor = (p == garray[g].white ? WHITE : BLACK);
+ yourColor = (myColor == WHITE ? BLACK : WHITE);
+
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != g) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, p1, PEND_ABORT) >= 0) {
+ player_remove_request(p1, p, PEND_ABORT);
+ player_decline_offers(p, -1, -1);
+ game_ended(g, yourColor, END_ABORT);
+ } else {
+ game_update_time(g);
+
+#ifdef TIMESEAL
+
+ if (con[parray[parray[p].opponent].socket].timeseal) { /* opp uses timeseal? */
+
+ /* If opponent has timeseal - we have no use for courtesyabort since
+ courtesyabort was used when opponent lagged out of time which cannot
+ happen with timeseal - only courtesyadjourn should be possible.
+ Thus: the request can only be for a normal abort of the game. */
+
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " would like to abort the game.\n");
+ pprintf(p, "Abort request sent.\n");
+ player_add_request(p, p1, PEND_ABORT, 0);
+ } else {
+ if ((myColor == WHITE && garray[g].wTime > 0 && garray[g].bTime <= 0)
+ || (myColor == BLACK && garray[g].bTime > 0 && garray[g].wTime <= 0)) {
+ /* player wants to abort + opponent is out of time = courtesyabort */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been aborted.");
+ pprintf(p1, "Your opponent has aborted the game rather than calling your flag.");
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_COURTESY);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " would like to abort the game.\n");
+ pprintf(p, "Abort request sent.\n");
+ player_add_request(p, p1, PEND_ABORT, 0);
+ }
+ }
+
+#else
+
+ if ((myColor == WHITE && garray[g].wTime > 0 && garray[g].bTime <= 0)
+ || (myColor == BLACK && garray[g].bTime > 0 && garray[g].wTime <= 0)) {
+ /* player wants to abort + opponent is out of time = courtesyabort */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been aborted.");
+ pprintf(p1, "Your opponent has aborted the game rather than calling your flag.");
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_COURTESY);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf(p1, " would like to abort the game; ");
+ pprintf_prompt(p1, "type \"abort\" to accept.\n");
+ pprintf(p, "Abort request sent.\n");
+ player_add_request(p, p1, PEND_ABORT, 0);
+ }
+
+#endif
+
+ }
+ return COM_OK;
+}
+
+#if 0
+int Courtesy(int p, int type)
+{
+ int g;
+
+ if (parray[p].game <0) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (garray[g].wInitTime == 0) {
+ if (type == END_COURTESY)
+ pprintf(p, "You can't courtesy abort an untimed game, just resign.\n");
+ else if (type == END_COURTESYADJOURN)
+ pprintf(p, "You can't courtesy adjourn an untimed game, just resign.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+ if (((garray[g].white == p) && (garray[g].bTime <= 0) && (garray[g].wTime > 0)) ||
+ ((garray[g].black == p) && (garray[g].wTime <= 0) && (garray[g].bTime > 0))) {
+ player_decline_offers(p, -1, -1);
+ game_ended(parray[p].game, (garray[g].white == p) ? WHITE : BLACK, type);
+ } else {
+ if (type == END_COURTESY)
+ pprintf(p, "Game not aborted.\n");
+ else if (type == END_COURTESYADJOURN)
+ pprintf(p, "Game not adjourned.\n");
+ pprintf(p, "Either your opponent still has time, or you are out of time also.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_courtesyabort(int p, param_list param)
+{
+ ASSERT(param[0].type == TYPE_NULL);
+ return Courtesy(p, END_COURTESY);
+}
+
+PUBLIC int com_courtesyadjourn(int p, param_list param)
+{
+ ASSERT(param[0].type == TYPE_NULL);
+ if (!garray[parray[p].game].rated) {
+ pprintf(p, "You cannot adjourn an unrated game. Use \"courtesyabort\".\n");
+ return COM_OK;
+ }
+ return Courtesy(p, END_COURTESYADJOURN);
+}
+#endif
+
+PUBLIC int com_courtesyabort(int p, param_list param)
+{
+ pprintf(p, "Courtesyabort is obsolete; use \"abort\" instead.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_courtesyadjourn(int p, param_list param)
+{
+ pprintf(p, "Use \"adjourn\" to courtesyadjourn a game.\n");
+ return COM_OK;
+}
+
+PRIVATE int player_has_mating_material(game_state_t *gs, int color)
+{
+ int i, j;
+ int piece;
+ int minor_pieces = 0;
+
+ for (i = 0; i < 8; i++)
+ for (j = 0; j < 8; j++) {
+ piece = gs->board[i][j];
+ switch (piecetype(piece)) {
+ case BISHOP:
+ case KNIGHT:
+ if (iscolor(piece, color))
+ minor_pieces++;
+ break;
+ case KING:
+ case NOPIECE:
+ break;
+ default:
+ if (iscolor(piece, color))
+ return 1;
+ }
+ }
+ return ((minor_pieces > 1) ? 1 : 0);
+}
+
+PUBLIC int com_flag(int p, param_list param)
+{
+ int g;
+ int myColor;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ myColor = (p == garray[g].white ? WHITE : BLACK);
+ if (garray[g].wInitTime == 0) {
+ pprintf(p, "You can't flag an untimed game.\n");
+ return COM_OK;
+ }
+ if (garray[g].numHalfMoves < 2) {
+ pprintf(p, "You cannot flag if your opponent has not moved.\nYou can use abort instead.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+
+#ifdef TIMESEAL
+
+ {
+ int wt, bt;
+
+ if (con[parray[p].socket].timeseal) { /* do caller use timeseal? */
+ if (myColor == WHITE) {
+ wt = garray[g].wRealTime;
+ } else {
+ bt = garray[g].bRealTime;
+ }
+ } else {
+ if (myColor == WHITE) {
+ wt = garray[g].wTime;
+ } else {
+ bt = garray[g].bTime;
+ }
+ }
+
+ if (con[parray[parray[p].opponent].socket].timeseal) { /* opp uses timeseal? */
+ if (myColor == WHITE) {
+ bt = garray[g].bRealTime;
+ } else {
+ wt = garray[g].wRealTime;
+ }
+ } else {
+ if (myColor == WHITE) {
+ bt = garray[g].bTime;
+ } else {
+ wt = garray[g].wTime;
+ }
+ }
+
+ /* the clocks to compare is now in wt and bt */
+
+ if ((wt <= 0) && (bt <= 0)) {
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_BOTHFLAG);
+ return COM_OK;
+ }
+ if (myColor == WHITE) {
+ if (bt > 0) {
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ } else {
+ if (wt > 0) {
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ }
+ }
+
+#else
+
+ if ((garray[g].wTime <= 0) && (garray[g].bTime <= 0)) {
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_BOTHFLAG);
+ return COM_OK;
+ }
+ if (myColor == WHITE) {
+ if (garray[g].bTime > 0) {
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ } else {
+ if (garray[g].wTime > 0) {
+ pprintf(p, "Your opponent is not out of time!\n");
+ return COM_OK;
+ }
+ }
+
+#endif
+
+ player_decline_offers(p, -1, -1);
+ if (player_has_mating_material(&garray[g].game_state, myColor))
+ game_ended(g, myColor, END_FLAG);
+ else
+ game_ended(g, myColor, END_FLAGNOMATERIAL);
+ return COM_OK;
+}
+
+PUBLIC int com_adjourn(int p, param_list param)
+{
+ int p1, g, myColor, yourColor;
+
+ ASSERT(param[0].type == TYPE_NULL);
+ g = parray[p].game;
+ if ((g < 0) || (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ if (!(parray[p].registered && parray[p1].registered)) {
+ pprintf(p, "Both players must be registered to adjorn a game. Use \"abort\".\n");
+ return COM_OK;
+ }
+ myColor = (p == garray[g].white ? WHITE : BLACK);
+ yourColor = (myColor == WHITE ? BLACK : WHITE);
+
+ if (player_find_pendfrom(p, p1, PEND_ADJOURN) >= 0) {
+ player_remove_request(p1, p, PEND_ADJOURN);
+ player_decline_offers(p, -1, -1);
+ game_ended(parray[p].game, yourColor, END_ADJOURN);
+ } else {
+ game_update_time(g);
+ if (((myColor == WHITE) && (garray[g].wTime > 0) && (garray[g].bTime <= 0))
+ || ((myColor == BLACK) && (garray[g].bTime > 0) && (garray[g].wTime <= 0))) {
+/* player wants to adjourn + opponent is out of time = courtesyadjourn */
+ pprintf(p, "Since you have time, and your opponent has none, the game has been adjourned.");
+ pprintf(p1, "Your opponent has adjourned the game rather than calling your flag.");
+ player_decline_offers(p, -1, -1);
+ game_ended(g, myColor, END_COURTESYADJOURN);
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf(p1, " would like to adjourn the game; ");
+ pprintf_prompt(p1, "type \"adjourn\" to accept.\n");
+ pprintf(p, "Adjourn request sent.\n");
+ player_add_request(p, p1, PEND_ADJOURN, 0);
+ }
+ }
+ return COM_OK;
+}
+
+PRIVATE int gamesortfunc(const void *i, const void *j)
+{
+ return (GetRating(&parray[garray[*(int *) i].white], garray[*(int *) i].type) +
+ GetRating(&parray[garray[*(int *) i].black], garray[*(int *) i].type) +
+ ((garray[*(int *) i].status == GAME_EXAMINE) ? 10000 : 0) -
+ GetRating(&parray[garray[*(int *) j].white], garray[*(int *) j].type) -
+ GetRating(&parray[garray[*(int *) j].black], garray[*(int *) j].type) -
+ ((garray[*(int *) j].status == GAME_EXAMINE) ? 10000 : 0));
+}
+
+
+PUBLIC int com_games(int p, param_list param)
+{
+ int i, j;
+ int wp, bp;
+ int ws, bs;
+ int selected = 0;
+ int count = 0;
+ int totalcount;
+ char *s = NULL;
+ int slen = 0;
+ int *sortedgames; /* for qsort */
+
+ totalcount = game_count();
+ if (totalcount == 0) {
+ pprintf(p, "There are no games in progress.\n");
+ } else {
+ sortedgames = rmalloc(totalcount * sizeof(int)); /* for qsort */
+
+ if (param[0].type == TYPE_WORD) {
+ s = param[0].val.word;
+ slen = strlen(s);
+ selected = atoi(s);
+ if (selected < 0)
+ selected = 0;
+ }
+ for (i = 0; i < g_num; i++) {
+ if ((garray[i].status != GAME_ACTIVE) && (garray[i].status != GAME_EXAMINE))
+ continue;
+ if ((selected) && (selected != i + 1))
+ continue; /* not selected game number */
+ wp = garray[i].white;
+ bp = garray[i].black;
+ if ((!selected) && s && strncasecmp(s, garray[i].white_name, slen) &&
+ strncasecmp(s, garray[i].black_name, slen))
+ continue; /* player names did not match */
+ sortedgames[count++] = i;
+ }
+ if (!count)
+ pprintf(p, "No matching games were found (of %d in progress).\n", totalcount);
+ else {
+ qsort(sortedgames, count, sizeof(int), gamesortfunc);
+ pprintf(p, "\n");
+ for (j = 0; j < count; j++) {
+ i = sortedgames[j];
+ wp = garray[i].white;
+ bp = garray[i].black;
+ board_calc_strength(&garray[i].game_state, &ws, &bs);
+ if (garray[i].status != GAME_EXAMINE) {
+ pprintf_noformat(p, "%2d %4s %-11.11s %4s %-10.10s [%c%c%c%3d %3d] ",
+ i + 1,
+ ratstrii(GetRating(&parray[wp],
+ garray[i].type),
+ parray[wp].registered),
+ parray[wp].name,
+ ratstrii(GetRating(&parray[bp],
+ garray[i].type),
+ parray[bp].registered),
+ parray[bp].name,
+ (garray[i].private) ? 'p' : ' ',
+ *bstr[garray[i].type],
+ *rstr[garray[i].rated],
+ garray[i].wInitTime / 600,
+ garray[i].wIncrement / 10);
+ game_update_time(i);
+ pprintf_noformat(p, "%6s -",
+ tenth_str((garray[i].wTime > 0 ? garray[i].wTime : 0), 0));
+ pprintf_noformat(p, "%6s (%2d-%2d) %c: %2d\n",
+ tenth_str((garray[i].bTime > 0 ? garray[i].bTime : 0), 0),
+ ws, bs,
+ (garray[i].game_state.onMove == WHITE) ? 'W' : 'B',
+ garray[i].game_state.moveNum);
+ } else {
+ pprintf_noformat(p, "%2d (Exam. %4d %-11.11s %4d %-10.10s) [%c%c%c%3d %3d] ",
+ i + 1,
+ garray[i].white_rating,
+ garray[i].white_name,
+ garray[i].black_rating,
+ garray[i].black_name,
+ (garray[i].private) ? 'p' : ' ',
+ *bstr[garray[i].type],
+ *rstr[garray[i].rated],
+ garray[i].wInitTime / 600,
+ garray[i].wIncrement / 10);
+ pprintf_noformat(p, "%c: %2d\n",
+ (garray[i].game_state.onMove == WHITE) ? 'W' : 'B',
+ garray[i].game_state.moveNum);
+ }
+ }
+ if (count < totalcount)
+ pprintf(p, "\n %d game%s displayed (of %d in progress).\n", count,
+ (count == 1) ? "" : "s", totalcount);
+ else
+ pprintf(p, "\n %d game%s displayed.\n", totalcount, (totalcount == 1) ? "" : "s");
+ }
+ rfree(sortedgames);
+ }
+ return COM_OK;
+}
+
+PRIVATE int do_observe(int p, int obgame)
+{
+ if ((garray[obgame].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, game %d is a private game.\n", obgame + 1);
+ return COM_OK;
+ }
+ if ((garray[obgame].white == p) || (garray[obgame].black == p)) {
+ if (garray[obgame].status != GAME_EXAMINE) {
+ pprintf(p, "You cannot observe a game that you are playing.\n");
+ return COM_OK;
+ }
+ }
+ if (player_is_observe(p, obgame)) {
+ pprintf(p, "Removing game %d from observation list.\n", obgame + 1);
+ player_remove_observe(p, obgame);
+ } else {
+ if (!player_add_observe(p, obgame)) {
+ pprintf(p, "You are now observing game %d.\n", obgame + 1);
+ send_board_to(obgame, p);
+ } else {
+ pprintf(p, "You are already observing the maximum number of games.\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC void unobserveAll(int p)
+{
+ int i;
+
+ for (i = 0; i < parray[p].num_observe; i++) {
+ pprintf(p, "Removing game %d from observation list.\n", parray[p].observe_list[i] + 1);
+ }
+ parray[p].num_observe = 0;
+ return;
+}
+
+PUBLIC int com_unobserve(int p, param_list param)
+{
+ int gNum, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ unobserveAll(p);
+ return COM_OK;
+ }
+ gNum = GameNumFromParam(p, &p1, ¶m[0]);
+ if (gNum < 0)
+ return COM_OK;
+ if (!player_is_observe(p, gNum)) {
+ pprintf(p, "You are not observing game %d.\n", gNum);
+ } else {
+ player_remove_observe(p, gNum);
+ pprintf(p, "Removing game %d from observation list.\n", gNum + 1);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_observe(int p, param_list param)
+{
+ int i;
+ int p1, obgame;
+
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are still examining a game.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ unobserveAll(p);
+ return COM_OK;
+ }
+ obgame = GameNumFromParam(p, &p1, ¶m[0]);
+ if (obgame < 0)
+ return COM_OK;
+
+ if ((obgame >= g_num) || ((garray[obgame].status != GAME_ACTIVE) &&
+ (garray[obgame].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((p1 >= 0) && parray[p1].simul_info.numBoards) {
+ for (i = 0; i < parray[p1].simul_info.numBoards; i++)
+ if (parray[p1].simul_info.boards[i] >= 0)
+ do_observe(p, parray[p1].simul_info.boards[i]);
+ } else {
+ do_observe(p, obgame);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_allobservers(int p, param_list param)
+{
+ int obgame;
+ int p1;
+ int start, end;
+ int g;
+ int first;
+
+ if (param[0].type == TYPE_NULL) {
+ obgame = -1;
+ } else {
+ obgame = GameNumFromParam(p, &p1, ¶m[0]);
+ if (obgame < 0)
+ return COM_OK;
+ }
+ if (obgame == -1) {
+ start = 0;
+ end = g_num;
+ } else if ((obgame >= g_num) || ((obgame < g_num)
+ && ((garray[obgame].status != GAME_ACTIVE)
+ && (garray[obgame].status != GAME_EXAMINE)))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ } else {
+ start = obgame;
+ end = obgame + 1;
+ }
+
+ /* list games being played */
+
+ for (g = start; g < end; g++) {
+ if ((garray[g].status == GAME_ACTIVE) &&
+ ((parray[p].adminLevel > 0) || (garray[g].private == 0))) {
+ for (first = 1, p1 = 0; p1 < p_num; p1++) {
+ if ((parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g))) {
+ if (first) {
+ pprintf(p, "Observing %2d [%s vs. %s]:",
+ g + 1,
+ parray[garray[g].white].name,
+ parray[garray[g].black].name);
+ first = 0;
+ }
+ pprintf(p, " %s%s", (parray[p1].game >=0) ? "#" : "", parray[p1].name);
+ }
+ }
+ if (!first)
+ pprintf(p, "\n");
+ }
+ }
+
+ /* list games being examined last */
+
+ for (g = start; g < end; g++) {
+ if ((garray[g].status == GAME_EXAMINE) &&
+ ((parray[p].adminLevel > 0) || (garray[g].private == 0))) {
+ for (first = 1, p1 = 0; p1 < p_num; p1++) {
+ if ((parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g) ||
+ (parray[p1].game == g))) {
+ if (first) {
+ if (strcmp(garray[g].white_name, garray[g].black_name)) {
+ pprintf(p, "Examining %2d [%s vs %s]:", g + 1,
+ garray[g].white_name, garray[g].black_name);
+ } else {
+ pprintf(p, "Examining %2d (scratch):", g + 1);
+ }
+ first = 0;
+ }
+ pprintf(p, " %s%s", (parray[p1].game == g) ? "#" : "", parray[p1].name);
+ }
+ }
+ if (!first)
+ pprintf(p, "\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unexamine(int p, param_list param)
+{
+ int g, p1, flag = 0;
+
+ if ((parray[p].game <0) ||(garray[parray[p].game].status != GAME_EXAMINE)) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ parray[p].game = -1;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if ((parray[p1].game == g) &&(p != p1)) {
+ /* ok - there are other examiners to take over the game */
+ flag = 1;
+ }
+ if ((player_is_observe(p1, g)) || (parray[p1].game == g)) {
+ pprintf(p1, "%s stopped examining game %d.\n", parray[p].name, g + 1);
+ }
+ }
+ if (!flag) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g)) {
+ pprintf(p1, "There are no examiners.\n");
+ pcommand(p1, "unobserve %d", g + 1);
+ }
+ }
+ game_remove(g);
+ }
+ pprintf(p, "You are no longer examining game %d.\n", g + 1);
+ return COM_OK;
+}
+
+PUBLIC int com_mexamine(int p, param_list param)
+{
+ int g, p1, p2;
+
+ if ((parray[p].game <0) ||(garray[parray[p].game].status != GAME_EXAMINE)) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (!player_is_observe(p1, g)) {
+ pprintf(p, "%s must observe the game you are analysing.\n", parray[p1].name);
+ return COM_OK;
+ } else {
+ if (parray[p1].game >=0) {
+ pprintf(p, "%s is already analysing the game.\n", parray[p1].name);
+ return COM_OK;
+ }
+ /* if we get here - let's make him examiner of the game */
+ unobserveAll(p1); /* fix for Xboard */
+ player_decline_offers(p1, -1, PEND_MATCH);
+ player_withdraw_offers(p1, -1, PEND_MATCH);
+ player_withdraw_offers(p1, -1, PEND_SIMUL);
+
+ parray[p1].game = g; /* yep - it really is that easy :-) */
+ pprintf(p1, "You are now examiner of game %d.\n", g + 1);
+ send_board_to(g, p1); /* pos not changed - but fixes Xboard */
+ for (p2 = 0; p2 < p_num; p2++) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ continue;
+ if (p2 == p1)
+ continue;
+ if ((player_is_observe(p2, g)) || (parray[p2].game == g)) {
+ pprintf_prompt(p2, "%s is now examiner of game %d.\n", parray[p1].name, g + 1);
+ }
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_moves(int p, param_list param)
+{
+ int g;
+ int p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >=0) {
+ g = parray[p].game;
+ } else if (parray[p].num_observe) {
+ for (g = 0; g < parray[p].num_observe; g++) {
+ pprintf(p, "%s\n", movesToString(parray[p].observe_list[g], 0));
+ }
+ return COM_OK;
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= g_num) || ((garray[g].status != GAME_ACTIVE) &&
+ (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ pprintf(p, "%s\n", movesToString(g, 0)); /* pgn may break interfaces? */
+ return COM_OK;
+}
+
+PUBLIC int com_mailmoves(int p, param_list param)
+{
+ int g;
+ int p1;
+ char subj[81];
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailhelp command.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >=0) {
+ g = parray[p].game;
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= g_num) || ((garray[g].status != GAME_ACTIVE) && (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ sprintf(subj, "FICS game report %s vs %s", garray[g].white_name, garray[g].black_name);
+ if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn))) {
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ } else {
+ pprintf(p, "Moves mailed.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_oldmoves(int p, param_list param)
+{
+ int g;
+ int p1 = p;
+
+ if (param[0].type == TYPE_NULL) {
+ p1 = p;
+ } else if (param[0].type == TYPE_WORD) {
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ g = FindOldGameFor(p1);
+ if (g < 0) {
+ pprintf(p, "There is no old game for %s.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ pprintf(p, "%s\n", movesToString(g, 0)); /* pgn may break interfaces? */
+ return COM_OK;
+}
+
+PUBLIC int com_mailoldmoves(int p, param_list param)
+{
+ int g;
+ int p1 = p;
+ char subj[81];
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailhelp command.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ p1 = p;
+ } else if (param[0].type == TYPE_WORD) {
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ g = FindOldGameFor(p1);
+ if (g < 0) {
+ pprintf(p, "There is no old game for %s.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ sprintf(subj, "FICS game report %s vs %s", garray[g].white_name, garray[g].black_name);
+ if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn))) {
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ } else {
+ pprintf(p, "Moves mailed.\n");
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_load(int p, param_list param)
+{
+ pprintf(p, "Obsolete command, please use match <opponent>.\n");
+ return COM_OK;
+}
+
+void ExamineScratch(int p)
+{
+ char category, board;
+ int g = game_new();
+
+ unobserveAll(p);
+
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+
+ garray[g].wInitTime = garray[g].wIncrement = 0;
+ garray[g].bInitTime = garray[g].bIncrement = 0;
+ garray[g].timeOfStart = tenth_secs();
+ garray[g].wTime = garray[g].bTime = 0;
+ garray[g].rated = 0;
+ garray[g].clockStopped = 0;
+ garray[g].type = TYPE_UNTIMED;
+ garray[g].white = garray[g].black = p;
+ garray[g].status = GAME_EXAMINE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ garray[g].totalHalfMoves = 0;
+
+ parray[p].side = WHITE; /* oh well... */
+ parray[p].game = g;
+
+ category = board = '\0';
+ if (board_init(&garray[g].game_state, &category, &board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD. Game Aborted.\n");
+ }
+ garray[g].game_state.gameNum = g;
+ strcpy(garray[g].white_name, parray[p].name);
+ strcpy(garray[g].black_name, parray[p].name);
+
+ send_boards(g);
+
+ strcpy(garray[g].boardList[garray[g].numHalfMoves], boardToFEN(g));
+}
+
+PRIVATE int ExamineStored(FILE * fp, int p, char *filename)
+{
+ int g;
+ char category[100], board[100];
+ game *gg;
+
+ unobserveAll(p);
+
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+
+ g = game_new();
+ gg = &garray[g];
+ category[0] = '\0';
+ board[0] = '\0';
+ if (board_init(&gg->game_state, category, board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD %s %s. Game Aborted.\n",
+ category, board);
+ return -1;
+ }
+ gg->status = GAME_EXAMINE;
+ if (ReadGameAttrs(fp, filename, g) < 0) {
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ return -1;
+ }
+ gg->totalHalfMoves = gg->numHalfMoves;
+ gg->numHalfMoves = 0;
+ gg->revertHalfMove = 0;
+ gg->white = p;
+ gg->black = p;
+ gg->game_state.gameNum = g;
+
+ gg->startTime = tenth_secs();
+ gg->lastMoveTime = gg->startTime;
+ gg->lastDecTime = gg->startTime;
+
+ parray[p].side = WHITE; /* oh well... */
+ parray[p].game = g;
+
+ send_boards(g);
+
+ strcpy(gg->boardList[gg->numHalfMoves], boardToFEN(g));
+ return g;
+}
+
+void ExamineAdjourned(int p, int p1, int p2)
+{
+ FILE *fp;
+ char filename[1024];
+ char *p1Login, *p2Login;
+ int g;
+
+ p1Login = parray[p1].login;
+ p2Login = parray[p2].login;
+
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p1Login, p1Login, p2Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p2Login, p1Login, p2Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p2Login, p2Login, p1Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p1Login, p2Login, p1Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pprintf(p, "No stored game between \"%s\" and \"%s\".\n",
+ parray[p1].name, parray[p2].name);
+ return;
+ }
+ }
+ }
+ }
+ g = ExamineStored(fp, p, filename);
+ fclose(fp);
+
+ if (g >= 0) {
+ if (garray[g].white_name[0] == '\0')
+ strcpy(garray[g].white_name, p1Login);
+ if (garray[g].black_name[0] == '\0')
+ strcpy(garray[g].black_name, p2Login);
+ }
+ return;
+}
+
+char *FindHistory(int p, int p1, int game)
+{
+ FILE *fpHist;
+ static char fileName[MAX_FILENAME_SIZE];
+ int index;
+ long when;
+
+ sprintf(fileName, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[p1].login[0], parray[p1].login, STATS_GAMES);
+ fpHist = fopen(fileName, "r");
+ if (fpHist == NULL) {
+ pprintf(p, "No games in history for %s.\n", parray[p1].name);
+ return(NULL);
+ }
+ do {
+ fscanf(fpHist, "%d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %*s %*s %ld",
+ &index, &when);
+ } while (!feof(fpHist) && index != game);
+
+ if (feof(fpHist)) {
+ pprintf(p, "There is no history game %d for %s.\n", game, parray[p1].name);
+ fclose(fpHist);
+ return(NULL);
+ }
+ fclose(fpHist);
+
+ sprintf(fileName, "%s/%ld/%ld", hist_dir, when % 100, when);
+ return(fileName);
+}
+
+void ExamineHistory(int p, int p1, int game)
+{
+ char *fileName;
+
+ fileName = FindHistory(p, p1, game);
+ if (fileName != NULL) {
+ FILE *fpGame = fopen(fileName, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", game, parray[p1].name);
+ } else {
+ ExamineStored(fpGame, p, fileName);
+ }
+ }
+ return;
+}
+
+PUBLIC int com_examine(int p, param_list param)
+{
+ int p1, p2 = p, p1conn, p2conn = 1;
+
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are already examining a game.\n");
+ } else if (parray[p].game >=0) {
+ pprintf(p, "You are playing a game.\n");
+ } else if (param[0].type == TYPE_NULL) {
+ ExamineScratch(p);
+ } else if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, ¶m[0], &p1, &p1conn))
+ return COM_OK;
+
+ if (param[1].type == TYPE_INT)
+ ExamineHistory(p, p1, param[1].val.integer);
+ else {
+ if (param[1].type == TYPE_WORD
+ && !FindPlayer(p, ¶m[1], &p2, &p2conn))
+ return COM_OK;
+
+ ExamineAdjourned(p, p1, p2);
+ if (!p2conn)
+ player_remove(p2);
+ }
+ if (!p1conn)
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_stored(int p, param_list param)
+{
+ DIR *dirp;
+#ifdef USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+ int p1, connected;
+ char dname[MAX_FILENAME_SIZE];
+#if 0 /* replacing all the code below with a
+ FindPlayer call; This stuff was buggy
+ anyway. */
+ if (param[0].type == TYPE_WORD) {
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) { /* not logged in */
+ connected = 0;
+ p1 = player_new();
+ if (player_read(p1, param[0].val.word)) {
+ player_remove(p1);
+ pprintf(p, "There is no player by that name.\n");
+ return COM_OK;
+ }
+ } else {
+ connected = 1;
+ }
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+#endif
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ sprintf(dname, "%s/%c", adj_dir, parray[p1].login[0]);
+ dirp = opendir(dname);
+ if (!dirp) {
+ pprintf(p, "Player %s has no games stored.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ pprintf(p, "Stored games for %s:\n", parray[p1].name);
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (file_has_pname(dp->d_name, parray[p1].login)) {
+ pprintf(p, " %s vs. %s\n", file_wplayer(dp->d_name), file_bplayer(dp->d_name));
+ }
+ }
+
+ closedir(dirp);
+ pprintf(p, "\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_mailstored(int p, param_list param)
+{
+ int wp, wconnected, bp, bconnected, gotit = 0;
+ int g = -1;
+
+ if (!FindPlayer(p, ¶m[0], &wp, &wconnected))
+ return (COM_OK);
+
+ if (param[1].type == TYPE_INT) { /* look for a game from history */
+ char *fileName = FindHistory(p, wp, param[1].val.integer);
+ if (fileName != NULL) {
+ FILE *fpGame = fopen(fileName, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", param[1].val.integer, parray[wp].name);
+ } else {
+ g = game_new();
+ if (ReadGameAttrs(fpGame, fileName, g) < 0)
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ else
+ gotit = 1;
+ }
+ fclose(fpGame);
+ }
+ } else { /* look for a stored game between the players */
+ if (FindPlayer(p, ¶m[1], &bp, &bconnected)) {
+
+ g = game_new();
+ if (game_read(g, wp, bp) >= 0) { /* look for a game white-black, */
+ gotit = 1;
+ } else if (game_read(g, bp, wp) >= 0) { /* or black-white */
+ gotit = 1;
+ } else {
+ pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ }
+ if (!bconnected)
+ player_remove(bp);
+ }
+ }
+
+ if (gotit) {
+ if (strcasecmp(parray[p].name, garray[g].white_name) && strcasecmp(parray[p]
+.name, garray[g].black_name) && garray[g].private && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ char subj[81];
+ if (param[1].type == TYPE_INT)
+ sprintf(subj, "FICS history game: %s %d", parray[wp].name, param[1].val.integer);
+ else
+ sprintf(subj, "FICS adjourned game %s vs %s", garray[g].white_name, garray[g].black_name);
+ if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn)))
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ else
+ pprintf(p, "Moves mailed.\n");
+ }
+ }
+ if (!wconnected)
+ player_remove(wp);
+ if (g != -1)
+ game_remove(g);
+ return(COM_OK);
+}
+
+/* it would be good to write a FindStored and nuke all the game_read(foo,bar)
+ game_read(bar,foo) etc. this stuff is a mess... */
+
+PUBLIC int com_smoves(int p, param_list param)
+{
+ int wp, wconnected, bp, bconnected, gotit = 0;
+ int g = -1;
+
+ if (!FindPlayer(p, ¶m[0], &wp, &wconnected))
+ return(COM_OK);
+
+ if (param[1].type == TYPE_INT) {
+/* look for a game from history */
+ char *fileName = FindHistory(p, wp, param[1].val.integer);
+ if (fileName != NULL) {
+ FILE *fpGame = fopen(fileName, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", param[1].val.integer, parray[wp].name);
+ } else {
+ g = game_new();
+ if (ReadGameAttrs(fpGame, fileName, g) < 0) {
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ } else {
+ gotit = 1;
+ }
+ }
+ fclose(fpGame);
+ }
+ } else {
+/* look for a stored game between the players */
+ if (FindPlayer(p, ¶m[1], &bp, &bconnected)) {
+
+ g = game_new();
+ if (game_read(g, wp, bp) >= 0) { /* look for a game white-black, */
+ gotit = 1;
+ } else if (game_read(g, bp, wp) >= 0) { /* or black-white */
+ gotit = 1;
+ } else {
+ pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ }
+ if (!bconnected)
+ player_remove(bp);
+ }
+ }
+
+ if (gotit) {
+ if (strcasecmp(parray[p].name, garray[g].white_name) && strcasecmp(parray[p].name, garray[g].black_name) && garray[g].private && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ pprintf(p, "%s\n", movesToString(g, 0));
+ }
+ }
+ if (!wconnected)
+ player_remove(wp);
+ if (g != -1)
+ game_remove(g);
+ return(COM_OK);
+}
+
+PUBLIC int com_sposition(int p, param_list param)
+{
+ int wp, wconnected, bp, bconnected, confused = 0;
+ int g;
+
+ if (!FindPlayer(p, ¶m[0], &wp, &wconnected))
+ return (COM_OK);
+ if (!FindPlayer(p, ¶m[1], &bp, &bconnected))
+ return COM_OK;
+
+ g = game_new();
+ if (game_read(g, wp, bp) < 0) { /* if no game white-black, */
+ if (game_read(g, bp, wp) < 0) { /* look for black-white */
+ confused = 1;
+ pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ } else {
+ int tmp;
+ tmp = wp;
+ wp = bp;
+ bp = tmp;
+ tmp = wconnected;
+ wconnected = bconnected;
+ bconnected = tmp;
+ }
+ }
+ if (!confused) {
+ if ((wp != p) && (bp != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ garray[g].white = wp;
+ garray[g].black = bp;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ pprintf(p, "Position of stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ send_board_to(g, p);
+ }
+ }
+ game_remove(g);
+ if (!wconnected)
+ player_remove(wp);
+ if (!bconnected)
+ player_remove(bp);
+ return COM_OK;
+}
+
+PUBLIC int com_forward(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (!strcmp(garray[g].white_name, garray[g].black_name)) {
+ pprintf(p, "You cannot go forward; no moves are stored.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if (garray[g].numHalfMoves > garray[g].revertHalfMove) {
+ pprintf(p, "No more moves.\n");
+ return COM_OK;
+ }
+ if (garray[g].numHalfMoves < garray[g].totalHalfMoves) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s goes forward %d move%s.\n",
+ parray[p].name, nHalfMoves, (nHalfMoves == 1) ? "" : "s");
+ }
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ if (garray[g].numHalfMoves < garray[g].totalHalfMoves) {
+ execute_move(&garray[g].game_state, &garray[g].moveList[garray[g].numHalfMoves], 1);
+ if (garray[g].numHalfMoves + 1 > garray[g].examMoveListSize) {
+ garray[g].examMoveListSize += 20; /* Allocate 20 moves at a
+ time */
+ if (!garray[g].examMoveList) {
+ garray[g].examMoveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].examMoveListSize);
+ } else {
+ garray[g].examMoveList = (move_t *) rrealloc(garray[g].examMoveList, sizeof(move_t) * garray[g].examMoveListSize);
+ }
+ }
+ garray[g].examMoveList[garray[g].numHalfMoves] = garray[g].moveList[garray[g].numHalfMoves];
+ garray[g].revertHalfMove++;
+ garray[g].numHalfMoves++;
+ } else {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "End of game.\n");
+ }
+ }
+ break;
+ }
+ }
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+PUBLIC int com_backward(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if (garray[g].numHalfMoves != 0) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s backs up %d move%s.\n",
+ parray[p].name, nHalfMoves, (nHalfMoves == 1) ? "" : "s");
+ }
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ if (backup_move(g, REL_EXAMINE) != MOVE_OK) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "Beginning of game.\n");
+ }
+ }
+
+ break;
+ }
+ }
+ if (garray[g].numHalfMoves < garray[g].revertHalfMove) {
+ garray[g].revertHalfMove = garray[g].numHalfMoves;
+ }
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+PUBLIC int com_revert(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ nHalfMoves = garray[g].numHalfMoves - garray[g].revertHalfMove;
+ if (nHalfMoves == 0) {
+ pprintf(p, "Already at mainline.\n");
+ return COM_OK;
+ }
+ if (nHalfMoves < 0) { /* eek - should NEVER happen! */
+ fprintf(stderr, "OUCH! in com_revert: nHalfMoves < 0\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s reverts to mainline.\n", parray[p].name);
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ backup_move(g, REL_EXAMINE);/* should never return error */
+ }
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+PUBLIC int com_takeback(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int from;
+ int g, i;
+ int p1;
+
+ if ((parray[p].game <0) ||(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] !=
+ parray[p].game) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if ((from = player_find_pendfrom(p, parray[p].opponent, PEND_TAKEBACK)) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_TAKEBACK);
+ if (parray[p].p_from_list[from].param1 == nHalfMoves) {
+ /* Doing the takeback */
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ for (i = 0; i < nHalfMoves; i++) {
+ if (backup_move(g, REL_GAME) != MOVE_OK) {
+ pprintf(garray[g].white, "Can only backup %d moves\n", i);
+ pprintf(garray[g].black, "Can only backup %d moves\n", i);
+ break;
+ }
+ }
+
+#ifdef TIMESEAL
+
+ garray[g].wTimeWhenReceivedMove = 0;
+ garray[g].bTimeWhenReceivedMove = 0;
+
+#endif
+
+ send_boards(g);
+ } else {
+ if (garray[g].numHalfMoves < nHalfMoves) {
+ pprintf(p, "There are only %d half moves in your game.\n", garray[g].numHalfMoves);
+ pprintf_prompt(parray[p].opponent, "\n%s has declined the takeback request.\n", parray[p].name, nHalfMoves);
+ return COM_OK;
+ }
+ pprintf(p, "You disagree on the number of half-moves to takeback.\n");
+ pprintf(p, "Alternate takeback request sent.\n");
+ pprintf_prompt(parray[p].opponent, "\n%s proposes a different number (%d) of half-move(s).\n", parray[p].name, nHalfMoves);
+ player_add_request(p, parray[p].opponent, PEND_TAKEBACK, nHalfMoves);
+ }
+ } else {
+ if (garray[g].numHalfMoves < nHalfMoves) {
+ pprintf(p, "There are only %d half moves in your game.\n", garray[g].numHalfMoves);
+ return COM_OK;
+ }
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " would like to take back %d half move(s).\n",
+ nHalfMoves);
+ pprintf(p, "Takeback request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_TAKEBACK, nHalfMoves);
+ }
+ return COM_OK;
+}
+
+
+PUBLIC int com_switch(int p, param_list param)
+{
+ int g = parray[p].game;
+ int tmp, now;
+ int p1;
+ char *strTmp;
+
+ if ((g < 0) || (garray[g].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ p1 = parray[p].opponent;
+ if (parray[p1].simul_info.numBoards &&
+ parray[p1].simul_info.boards[parray[p1].simul_info.onBoard] != g) {
+ pprintf(p, "You can only make requests when the simul player is at your board.\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, parray[p].opponent, PEND_SWITCH) >= 0) {
+ player_remove_request(parray[p].opponent, p, PEND_SWITCH);
+ /* Doing the switch */
+ player_decline_offers(p, -1, -PEND_SIMUL);
+
+ tmp = garray[g].white;
+ garray[g].white = garray[g].black;
+ garray[g].black = tmp;
+ parray[p].side = (parray[p].side == WHITE) ? BLACK : WHITE;
+ strTmp = strdup(garray[g].white_name);
+ strcpy(garray[g].white_name, garray[g].black_name);
+ strcpy(garray[g].black_name, strTmp);
+ strfree(strTmp);
+
+ parray[parray[p].opponent].side =
+ (parray[parray[p].opponent].side == WHITE) ? BLACK : WHITE;
+ /* Roll back the time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+ }
+ if (garray[g].rated && garray[g].numHalfMoves > 0) {
+ pprintf(p, "You cannot switch sides once a rated game is underway.\n");
+ return COM_OK;
+ }
+ pprintf(parray[p].opponent, "\n");
+ pprintf_highlight(parray[p].opponent, "%s", parray[p].name);
+ pprintf_prompt(parray[p].opponent, " would like to switch sides.\nType \"accept\" to switch sides, or \"decline\" to refuse.\n");
+ pprintf(p, "Switch request sent.\n");
+ player_add_request(p, parray[p].opponent, PEND_SWITCH, 0);
+ return COM_OK;
+}
+
+
+PUBLIC int com_history(int p, param_list param)
+{
+ int p1, connected;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p1].login[0],
+ parray[p1].login, STATS_GAMES);
+ pgames(p, p1, fname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_time(int p, param_list param)
+{
+ int p1, g;
+
+ if (param[0].type == TYPE_NULL) {
+ g = parray[p].game;
+ if ((g < 0) || (garray[g].status == GAME_EXAMINE)) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= g_num) || (garray[g].status != GAME_ACTIVE)) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ game_update_time(g);
+ pprintf(p, "White (%s) : %d mins, %d secs\n",
+ parray[garray[g].white].name,
+ garray[g].wTime / 600,
+ (garray[g].wTime - ((garray[g].wTime / 600) * 600)) / 10);
+ pprintf(p, "Black (%s) : %d mins, %d secs\n",
+ parray[garray[g].black].name,
+ garray[g].bTime / 600,
+ (garray[g].bTime - ((garray[g].bTime / 600) * 600)) / 10);
+ return COM_OK;
+}
+
+PUBLIC int com_boards(int p, param_list param)
+{
+ char *category = NULL;
+ char dname[MAX_FILENAME_SIZE];
+ DIR *dirp;
+#ifdef USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+
+ if (param[0].type == TYPE_WORD)
+ category = param[0].val.word;
+ if (category) {
+ pprintf(p, "Boards Available For Category %s:\n", category);
+ sprintf(dname, "%s/%s", board_dir, category);
+ } else {
+ pprintf(p, "Categories Available:\n");
+ sprintf(dname, "%s", board_dir);
+ }
+ dirp = opendir(dname);
+ if (!dirp) {
+ pprintf(p, "No such category %s, try \"boards\".\n", category);
+ return COM_OK;
+ }
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (!strcmp(dp->d_name, "."))
+ continue;
+ if (!strcmp(dp->d_name, ".."))
+ continue;
+ pprintf(p, "%s\n", dp->d_name);
+ }
+ closedir(dirp);
+ return COM_OK;
+}
+
+PUBLIC int com_simmatch(int p, param_list param)
+{
+ int p1, g, adjourned;
+ int num;
+ char tmp[100];
+
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are still examining a game.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You can't simmatch yourself!\n");
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, p1, PEND_SIMUL) >= 0) {
+ player_remove_request(p, p1, PEND_MATCH);
+ player_remove_request(p1, p, PEND_MATCH);
+ player_remove_request(p, p1, PEND_SIMUL);
+ player_remove_request(p1, p, PEND_SIMUL);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+ player_decline_offers(p1, -1, PEND_SIMUL);
+ player_withdraw_offers(p1, -1, PEND_SIMUL);
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_decline_offers(p1, -1, PEND_MATCH);
+ player_withdraw_offers(p1, -1, PEND_MATCH);
+
+
+
+ /* Accepting Simul ! */
+
+
+ if (parray[p].simul_info.numBoards >= MAX_SIMUL) {
+ pprintf(p, "You are already playing the maximum of %d boards.\n", MAX_SIMUL);
+ pprintf(p1, "Simul request removed, boards filled.\n");
+ return COM_OK;
+ }
+ unobserveAll(p); /* stop observing when match starts */
+ unobserveAll(p1);
+
+ g = game_new();
+ adjourned = 0;
+ if (game_read(g, p, p1) >= 0)
+ adjourned = 1;
+ if (!adjourned) { /* no adjourned game, so begin a new game */
+ game_remove(g);
+
+ if (create_new_match(p, p1, 0, 0, 0, 0, 0, "standard", "standard", 1)) {
+ pprintf(p, "There was a problem creating the new match.\n");
+ pprintf_prompt(p1, "There was a problem creating the new match.\n");
+ return COM_OK;
+ }
+ } else { /* resume adjourned game */
+ game_delete(p, p1);
+
+ sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s simul.}\n", g + 1, parray[p].name, parray[p1].name, rstr[garray[g].rated], bstr[garray[g].type]);
+ pprintf(p, tmp);
+ pprintf(p1, tmp);
+
+ garray[g].white = p;
+ garray[g].black = p1;
+ garray[g].status = GAME_ACTIVE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ parray[p].game = g;
+ parray[p].opponent = p1;
+ parray[p].side = WHITE;
+ parray[p1].game = g;
+ parray[p1].opponent = p;
+ parray[p1].side = BLACK;
+ send_boards(g);
+ }
+
+ num = parray[p].simul_info.numBoards;
+ parray[p].simul_info.results[num] = -1;
+ parray[p].simul_info.boards[num] = parray[p].game;
+ parray[p].simul_info.numBoards++;
+ if (parray[p].simul_info.numBoards > 1 &&
+ parray[p].simul_info.onBoard >= 0)
+ player_goto_board(p, parray[p].simul_info.onBoard);
+ else
+ parray[p].simul_info.onBoard = 0;
+ return COM_OK;
+ }
+ if (player_find_pendfrom(p, -1, PEND_SIMUL) >= 0) {
+ pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards) {
+ pprintf(p, "You cannot be the simul giver and request to join another simul.\nThat would just be too confusing for me and you.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >=0) {
+ pprintf(p, "You are already playing a game.\n");
+ return COM_OK;
+ }
+ if (!parray[p1].sopen) {
+ pprintf_highlight(p, "%s", parray[p1].name);
+ pprintf(p, " is not open to receiving simul requests.\n");
+ return COM_OK;
+ }
+ if (parray[p1].simul_info.numBoards >= MAX_SIMUL) {
+ pprintf_highlight(p, "%s", parray[p1].name);
+ pprintf(p, " is already playing the maximum of %d boards.\n", MAX_SIMUL);
+ return COM_OK;
+ }
+/* loon: checking for some crazy situations we can't allow :) */
+
+ if ((parray[p1].game >=0) &&(parray[p1].simul_info.numBoards == 0)) {
+ pprintf_highlight(p, "%s", parray[p1].name);
+ if (parray[garray[parray[p1].game].white].simul_info.numBoards) {
+ pprintf(p, " is playing in ");
+ pprintf_highlight(p, "%s", parray[parray[p1].opponent].name);
+ pprintf(p, "'s simul, and can't accept.\n");
+ } else {
+ pprintf(p, " can't begin a simul while playing a non-simul game.\n");
+ }
+ return COM_OK;
+ }
+/* loon: this was (p, p1, PEND_SIMUL) but player_add_request needs 4 args...
+if 0 is the incorrect 4th arg, please fix :) */
+
+ g = game_new(); /* Check if an adjourned untimed game */
+ adjourned = ((game_read(g, p, p1) < 0) && (game_read(g, p1, p) < 0)) ? 0 : 1;
+ if (adjourned) {
+ if (!(garray[g].type == TYPE_UNTIMED))
+ adjourned = 0;
+ }
+ game_remove(g);
+
+ if (player_add_request(p, p1, PEND_SIMUL, 0)) {
+ pprintf(p, "Maximum number of pending actions reached. Your request was not sent.\nTry again later.\n");
+ return COM_OK;
+ } else {
+ pprintf(p1, "\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ if (adjourned) {
+ pprintf_prompt(p1, " requests to continue an adjourned simul game.\n");
+ pprintf(p, "Request to resume simul sent. Adjourned game found.\n");
+ } else {
+ pprintf_prompt(p1, " requests to join a simul match with you.\n");
+ pprintf(p, "Simul match request sent.\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_goboard(int p, param_list param)
+{
+ int on, g, p1;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You can't goboard yourself!\n");
+ return COM_OK;
+ }
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ if (p1 == garray[g].black) {
+ pprintf(p, "You are already at that board!\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ if (player_goto_simulgame_bynum(p, parray[p1].game) !=-1) {
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " has moved away from your board.\n");
+ }
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+PUBLIC int com_gonum(int p, param_list param)
+{
+ int on, g, gamenum;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ gamenum = param[0].val.integer - 1;
+ if (gamenum < 0)
+ gamenum = 0;
+ if (on == gamenum) {
+ pprintf(p, "You are already at that board!\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ if (player_goto_simulgame_bynum(p, gamenum) != -1) {
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " has moved away from your board.\n");
+ }
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+PUBLIC int com_simnext(int p, param_list param)
+{
+ int on, g;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " is moving away from your board.\n");
+ player_goto_next_board(p);
+ }
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+
+PUBLIC int com_simprev(int p, param_list param)
+{
+ int on, g;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ if (parray[p].simul_info.numBoards > 1) {
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ on = parray[p].simul_info.onBoard;
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0) {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " is moving back to the previous board.\n");
+ }
+ player_goto_prev_board(p);
+ } else
+ pprintf(p, "You are only playing one board!\n");
+ return COM_OK;
+}
+
+PUBLIC int com_simgames(int p, param_list param)
+{
+ int p1 = p;
+
+ if (param[0].type == TYPE_WORD) {
+ if ((p1 = player_find_part_login(param[0].val.word)) < 0) {
+ pprintf(p, "No player named %s is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ }
+ if (p1 == p)
+ pprintf(p, "You are playing %d simultaneous games.\n",
+ player_num_active_boards(p1));
+ else
+ pprintf(p, "%s is playing %d simultaneous games.\n", parray[p1].name,
+ player_num_active_boards(p1));
+ return COM_OK;
+}
+
+PUBLIC int com_simpass(int p, param_list param)
+{
+ int g, p1, on;
+
+ if (parray[p].game <0) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ p1 = garray[g].white;
+ if (!parray[p1].simul_info.numBoards) {
+ pprintf(p, "You are not participating in a simul.\n");
+ return COM_OK;
+ }
+ if (p == p1) {
+ pprintf(p, "You are the simul holder and cannot pass!\n");
+ return COM_OK;
+ }
+ if (player_num_active_boards(p1) == 1) {
+ pprintf(p, "This is the only game, so passing is futile.\n");
+ return COM_OK;
+ }
+ on = parray[p1].simul_info.onBoard;
+ if (on != g) {
+ pprintf(p, "You cannot pass until the simul holder arrives!\n");
+ return COM_OK;
+ }
+ if (garray[g].passes >= MAX_SIMPASS) {
+ if (parray[p].bell)
+ pprintf(p, "\a");
+ pprintf(p, "You have reached your maximum of %d passes.\n", MAX_SIMPASS);
+ pprintf(p, "Please move IMMEDIATELY!\n");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " tried to pass, but is out of passes.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+
+ garray[g].passes++;
+ pprintf(p, "You have passed and have %d passes left.\n",
+ (MAX_SIMPASS - garray[g].passes));
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " has decided to pass and has %d passes left.\n",
+ (MAX_SIMPASS - garray[g].passes));
+ player_goto_next_board(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_simabort(int p, param_list param)
+{
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ game_ended(parray[p].simul_info.boards[parray[p].simul_info.onBoard],
+ WHITE, END_ABORT);
+ return COM_OK;
+}
+
+PUBLIC int com_simallabort(int p, param_list param)
+{
+ int i;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ for (i = 0; i < parray[p].simul_info.numBoards; i++) {
+ if (parray[p].simul_info.boards[i] >= 0) {
+ game_ended(parray[p].simul_info.boards[i],
+ WHITE, END_ABORT);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_simadjourn(int p, param_list param)
+{
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ game_ended(parray[p].simul_info.boards[parray[p].simul_info.onBoard],
+ WHITE, END_ADJOURN);
+ return COM_OK;
+}
+
+PUBLIC int com_simalladjourn(int p, param_list param)
+{
+ int i;
+
+ if (!parray[p].simul_info.numBoards) {
+ pprintf(p, "You are not giving a simul.\n");
+ return COM_OK;
+ }
+ player_decline_offers(p, -1, -PEND_SIMUL);
+ for (i = 0; i < parray[p].simul_info.numBoards; i++) {
+ if (parray[p].simul_info.boards[i] >= 0) {
+ game_ended(parray[p].simul_info.boards[i],
+ WHITE, END_ADJOURN);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_moretime(int p, param_list param)
+{
+ int g, increment;
+
+ ASSERT(param[0].type == TYPE_INT);
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You cannot use moretime in an examined game.\n");
+ return COM_OK;
+ }
+ increment = param[0].val.integer;
+ if (increment <= 0) {
+ pprintf(p, "Moretime requires an integer value greater than zero.\n");
+ return COM_OK;
+ }
+ if (parray[p].game <0) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ }
+ if (increment > 600) {
+ pprintf(p, "Moretime has a maximum limit of 600 seconds.\n");
+ increment = 600;
+ }
+ g = parray[p].game;
+ if (garray[g].white == p) {
+ garray[g].bTime += increment * 10;
+#ifdef TIMESEAL
+ garray[g].bRealTime += increment * 10 * 100;
+#endif
+ pprintf(p, "%d seconds were added to your opponents clock\n",
+ increment);
+ pprintf_prompt(parray[p].opponent,
+ "\nYour opponent has added %d seconds to your clock.\n",
+ increment);
+ }
+ if (garray[g].black == p) {
+ garray[g].wTime += increment * 10;;
+#ifdef TIMESEAL
+ garray[g].wRealTime += increment * 10 * 100;
+#endif
+ pprintf(p, "%d seconds were added to your opponents clock\n",
+ increment);
+ pprintf_prompt(parray[p].opponent,
+ "\nYour opponent has added %d seconds to your clock.\n",
+ increment);
+ }
+ return COM_OK;
+}
blob - /dev/null
blob + 6feacf1961d04834d09d0d53847c96235038182a (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/gameproc.h
+/* gameproc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _GAMEPROC_H
+#define _GAMEPROC_H
+
+#define MAX_SIMPASS 3
+#define MAX_JOURNAL 10
+
+extern void game_ended();
+extern int pIsPlaying();
+extern void process_move();
+extern int com_resign();
+extern int com_draw();
+extern int com_pause();
+extern int com_unpause();
+extern int com_abort();
+extern int com_games();
+
+extern int com_courtesyabort();
+extern int com_courtesyadjourn();
+extern int com_load();
+extern int com_stored();
+extern int com_adjourn();
+extern int com_flag();
+extern int com_takeback();
+extern int com_switch();
+extern int com_time();
+extern int com_boards();
+
+extern int com_simmatch();
+extern int com_simnext();
+extern int com_simprev();
+extern int com_goboard();
+extern int com_gonum();
+extern int com_simgames();
+extern int com_simpass();
+extern int com_simabort();
+extern int com_simallabort();
+extern int com_simadjourn();
+extern int com_simalladjourn();
+
+extern int com_moretime();
+
+#endif /* _GAMEPROC_H */
blob - /dev/null
blob + 89311259bef32545f23efb6be10e9b6dec6e7712 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/gameproc.o differ
blob - /dev/null
blob + 904da475ae5571b4b68bd27f212deca3c0c9aa8c (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/get_tcp_conn.c
+/*
+** Routines to open a TCP connection
+**
+** New version that supports the old (pre 4.2 BSD) socket calls,
+** and systems with the old (pre 4.2 BSD) hostname lookup stuff.
+** Compile-time options are:
+**
+** OLDSOCKET - different args for socket() and connect()
+**
+** Erik E. Fair <fair@ucbarpa.berkeley.edu>
+**
+*/
+
+/* Uncomment the following line if you are using old socket calls */
+/* #define OLDSOCKET */
+
+
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <ctype.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <netdb.h>
+#include "get_tcp_conn.h"
+#include "get_tcp_conn.proto.h"
+#include "stdinclude.h"
+
+extern int errno;
+extern int close();
+
+
+
+/*
+** Take the name of an internet host in ASCII (this may either be its
+** official host name or internet number (with or without enclosing
+** backets [])), and return a list of internet addresses.
+**
+** returns NULL for failure to find the host name in the local database,
+** or for a bad internet address spec.
+*/
+unsigned long **
+ name_to_address(char *host)
+{
+ static u_long *host_addresses[2];
+ static u_long haddr;
+
+ if (host == (char *) NULL) {
+ return ((u_long **) NULL);
+ }
+ host_addresses[0] = &haddr;
+ host_addresses[1] = (u_long *) NULL;
+
+ /* * Is this an ASCII internet address? (either of [10.0.0.78] or *
+ 10.0.0.78). We get away with the second test because hostnames * and
+ domain labels are not allowed to begin in numbers. * (cf. RFC952,
+ RFC882). */
+ if (*host == '[' || isdigit(*host)) {
+ char namebuf[128];
+ register char *cp = namebuf;
+
+ /* * strip brackets [] or anything else we don't want. */
+ while (*host != '\0' && cp < &namebuf[sizeof(namebuf)]) {
+ if (isdigit(*host) || *host == '.')
+ *cp++ = *host++; /* copy */
+ else
+ host++; /* skip */
+ }
+ *cp = '\0';
+ haddr = inet_addr(namebuf);
+ return (&host_addresses[0]);
+ } else {
+ struct hostent *hstp = gethostbyname(host);
+
+ if (hstp == NULL) {
+ return ((u_long **) NULL);/* no such host */
+ }
+ if (hstp->h_length != sizeof(u_long))
+ abort(); /* this is fundamental */
+ return ((u_long **) hstp->h_addr_list);
+ }
+}
+
+u_short
+gservice(char *serv, char *proto)
+{
+ if (serv == (char *) NULL || proto == (char *) NULL)
+ return ((u_short) 0);
+
+ if (isdigit(*serv)) {
+ return (htons((u_short) (atoi(serv))));
+ } else {
+ struct servent *srvp = getservbyname(serv, proto);
+
+ if (srvp == (struct servent *) NULL)
+ return ((u_short) 0);
+ return ((u_short) srvp->s_port);
+ }
+}
+
+/*
+** given a host name (either name or internet address) and port number
+** give us a TCP connection to the
+** requested service at the requested host (or give us FAIL).
+*/
+int get_tcp_conn(host, port)
+char *host;
+int port;
+{
+ register int sock;
+ u_long **addrlist;
+ struct sockaddr_in sadr;
+#ifdef OLDSOCKET
+ struct sockproto sp;
+
+ sp.sp_family = (u_short) AF_INET;
+ sp.sp_protocol = (u_short) IPPROTO_TCP;
+#endif
+
+ if ((addrlist = name_to_address(host)) == (u_long **) NULL) {
+ return (NOHOST);
+ }
+ sadr.sin_family = (u_short) AF_INET; /* Only internet for now */
+ sadr.sin_port = htons(port);
+
+ for (; *addrlist != (u_long *) NULL; addrlist++) {
+ bcopy((caddr_t) * addrlist, (caddr_t) & sadr.sin_addr,
+ sizeof(sadr.sin_addr));
+
+#ifdef OLDSOCKET
+ if ((sock = socket(SOCK_STREAM, &sp, (struct sockaddr *) NULL, 0)) < 0)
+ return (FAIL);
+
+ if (connect(sock, (struct sockaddr *) & sadr) < 0) {
+#else
+ if ((sock = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP)) < 0)
+ return (FAIL);
+
+ if (connect(sock, (struct sockaddr *) & sadr, sizeof(sadr)) < 0) {
+#endif
+ int e_save = errno;
+
+ fprintf(stderr, "%s [%s] port %d: %d\n", host,
+ inet_ntoa(sadr.sin_addr), port, errno);
+ (void) close(sock); /* dump descriptor */
+ errno = e_save;
+ } else
+ return (sock);
+ }
+ return (FAIL);
+}
blob - /dev/null
blob + 01320ae305205d9a440285b37893216c8e6a497f (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/get_tcp_conn.h
+/*
+** Return codes from get_tcp_conn().
+*/
+#define FAIL (-1) /* routine failed */
+#define NOHOST (FAIL-1) /* no such host */
+#define NOSERVICE (FAIL-2) /* no such service */
+
+extern int get_tcp_conn(char *, int);
+extern unsigned long **name_to_address(char *);
+
+/* extern int bcopy(); */
+extern int socket();
+extern int connect();
blob - /dev/null
blob + ebddbb47c5246013e38b09decfde1aebe72fe391 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/get_tcp_conn.proto.h
+
+/* get_tcp_conn.c */
+unsigned long **name_to_address(char *);
+u_short gservice(char *, char *);
blob - /dev/null
blob + 2f2b945268f1b2e7f79f7d70f58802f49a17bc80 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/gmon.out differ
blob - /dev/null
blob + 6e1e401df01877e4136a61537ccb26e54866f94b (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/hashtbl.h
+#ifndef __FICSHashTable_h
+#define __FICSHashTable_h
+#ifdef __GNUC__
+# pragma interface
+#endif
+//-----------------------------------------------------------------------------
+// FICSHashTable.h
+//
+// A general-purpose C++ hash table object.
+//
+//-----------------------------------------------------------------------------
+//-----------------------------------------------------------------------------
+// $Id: FICSHashTable.h,v 1.0 1995/04/25 21:50:44 mabshier Exp $
+// $Log: FICSHashTable.h,v $
+// $Renamed file to HASHTBL.H to accomodate MSDOS file convention rename for Unix
+// Initial revision
+//
+//-----------------------------------------------------------------------------
+
+#include <FICSContainer.h>
+#include <FICSHash.h>
+
+class FICSHashAdaptor;
+
+class FICSHashTable : public FICSContainer
+ {
+public:
+ unsigned long const DEFAULT_CAPACITY = 47;
+ unsigned long const LOAD_FACTOR_SCALE = 16;
+ unsigned long const LOAD_FACTOR_SHIFT = 4;
+ unsigned long const LOAD_FACTOR_DEFAULT = 16;
+
+private:
+ FICSHashAdaptor* adaptor;
+ unsigned long max_load_factor; // Scaled * 16.
+ unsigned long table_count; // Number of entries.
+ unsigned long table_size; // Number of slots.
+ void** table;
+ void expand( unsigned long new_capacity );
+
+public:
+ FICSHashTable(
+ FICSHashAdaptor&,
+ unsigned long capacity = DEFAULT_CAPACITY,
+ unsigned long max_load = LOAD_FACTOR_DEFAULT );
+virtual ~FICSHashTable();
+virtual size_t vcount() const;
+ size_t count() const { return table_count; }
+ size_t capacity() const { return table_size; }
+virtual void empty();
+virtual bool findObj( void const* keyPtr, void const*& infoPtr ) const;
+virtual bool storeObj( void const* keyPtr, void const* infoPtr,
+ FICSContainer::Unique u=FICSContainer::UNIQUE );
+virtual bool removeObj( void const* keyPtr ); // Removes 1st entry with key.
+virtual int removeAllObj(void const* keyPtr); // Removes all, returns count.
+
+// These return a pointer to the hash_rec, or 0.
+virtual void const* findObj( void const* keyPtr ) const;
+virtual void const* findOrStoreObj( void const* keyPtr, void const* infoPtr );
+
+friend class FICSHashTableIterator;
+ FICSHashTableIterator* iterator() const;
+virtual FICSIterator* newIterator() const;
+
+private: // Illegal
+ FICSHashTable( FICSHashTable const& ) {} // No copy constructor.
+ void operator=(FICSHashTable const&) {}// No assignment.
+
+protected:
+ FICSHashValue getHash( void const* hash_rec ) const;
+ FICSHashValue hash( void const* key ) const;
+ void setLink( void* hash_rec, void const* hash_link ) const;
+ void const* getLink( void const* hash_rec ) const;
+ bool equal(void const* hash_rec,FICSHashValue,void const* key) const;
+ void deleteHashRec( void* );
+ void* newHashRec( FICSHashValue hash_val, void const* key_ptr,
+ void const* info, void const* link );
+ void const* getInfo( void const* hash_rec ) const;
+ void const* getKey( void const* hash_rec ) const;
+ void fakeEmpty() { table_count = 0; }
+ };
+
+
+class FICSHashTableIterator : public FICSIterator
+ {
+private:
+ FICSHashTable const& table;
+ size_t next_slot;
+ void const* curr_ptr;
+public:
+ void reset() { next_slot = 0; curr_ptr = 0; }
+ FICSHashTableIterator( FICSHashTable const& x ):table(x) { reset(); }
+virtual ~FICSHashTableIterator();
+virtual bool next( void*& );
+ };
+
+#endif // __FICSHashTable_h
blob - /dev/null
blob + 507968344285ea94143a605c489cf4dab6c7d476 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/legal.c
+/* legal.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+char legalNotice[] = "\n\
+ fics - An internet chess server.\n\
+ Copyright (C) 1993 Richard V. Nash\n\
+\n\
+ This program is free software; you can redistribute it and/or modify\n\
+ it under the terms of the GNU General Public License as published by\n\
+ the Free Software Foundation; either version 2 of the License, or\n\
+ (at your option) any later version.\n\
+\n\
+ This program is distributed in the hope that it will be useful,\n\
+ but WITHOUT ANY WARRANTY; without even the implied warranty of\n\
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the\n\
+ GNU General Public License for more details.\n\
+";
blob - /dev/null
blob + 52199382718b182954c9f961232d46636a2b93d7 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/legal.h
+/*
+ * Copyright (c) 1993 by Richard V. Nash
+ * All rights reserved world wide.
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _LEGAL_H
+#define _LEGAL_H
+
+extern char legalNotice[];
+
+#endif /* _LEGAL_H */
blob - /dev/null
blob + ae579f2234d0227ad8020157d15016c7b6f87309 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/legal.o differ
blob - /dev/null
blob + 7e3748dd4c040afb2f35e60675c17a0e6c58fe7b (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/lists.c
+/* lists.c
+
+ * New global lists code
+ *
+ * Part of: FICS
+ *
+ * Added by Shaney, 29 May 1995 :)
+ * sometime in Oct 1995: changed things a little (loon)
+ *
+
+*/
+
+#include "lists.h"
+#include "common.h"
+#include "multicol.h"
+#include "command.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "rmalloc.h"
+#include "talkproc.h"
+#include "gamedb.h"
+#include "stdinclude.h"
+#include "comproc.h"
+
+#include <string.h>
+
+List *firstGlobalList = NULL;
+
+PRIVATE ListTable ListArray[] =
+{{P_HEAD, "admin"},
+{P_GOD, "removedcom"},
+{P_ADMIN, "filter"},
+{P_ADMIN, "ban"},
+{P_ADMIN, "abuser"},
+{P_ADMIN, "muzzle"},
+{P_ADMIN, "cmuzzle"},
+{P_PUBLIC, "fm"},
+{P_PUBLIC, "im"},
+{P_PUBLIC, "gm"},
+{P_PUBLIC, "blind"},
+{P_PUBLIC, "teams"},
+{P_PUBLIC, "computer"},
+{P_PUBLIC, "td"},
+{P_PERSONAL, "censor"},
+{P_PERSONAL, "gnotify"},
+{P_PERSONAL, "noplay"},
+{P_PERSONAL, "notify"},
+{P_PERSONAL, "channel"},
+{0, NULL}};
+
+/* find a list. loads from disk if not in memory. */
+PRIVATE List *list_find(int p, enum ListWhich l)
+{
+ List *prev, *tempList, **starter;
+ int personal;
+ int count = 0;
+
+ personal = ListArray[l].rights == P_PERSONAL;
+ starter = personal ? &(parray[p].lists) : &firstGlobalList;
+
+ for (prev = NULL, tempList = *starter; tempList != NULL; tempList = tempList->next) {
+ if (l == tempList->which) {
+ if (prev != NULL) {
+ prev->next = tempList->next;
+ tempList->next = *starter;
+ *starter = tempList;
+ }
+ return tempList;
+ }
+ prev = tempList;
+ }
+
+ tempList = rmalloc(sizeof(List));
+ if (tempList == NULL)
+ return NULL;
+
+ if (!personal) { /* now we have to load the list */
+ FILE *fp;
+ char listmember[100];
+ char filename[MAX_FILENAME_SIZE];
+
+ /* fprintf(stderr,"SHANEDEBUG: Adding %s list\n", ListArray[l].name); */
+
+ sprintf(filename, "%s/%s", lists_dir, ListArray[l].name);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ rfree(tempList);
+ return NULL;
+ }
+ while (!feof(fp)) {
+ if (fgets(listmember, 100, fp) != NULL) {
+ listmember[strlen(listmember) - 1] = '\0';
+ tempList->member[count++] = strdup(listmember);
+ }
+ }
+ fclose(fp);
+ }
+ tempList->which = l;
+ tempList->numMembers = count;
+ tempList->next = *starter;
+ *starter = tempList;
+ return tempList;
+}
+
+/* add item to list */
+PUBLIC int list_add(int p, enum ListWhich l, char *s)
+{
+ List *gl = list_find(p, l);
+
+ if (gl) {
+ if (gl->numMembers < MAX_GLOBAL_LIST_SIZE) {
+ gl->member[gl->numMembers] = strdup(s);
+ gl->numMembers++;
+ return 0;
+ } else {
+ return 1;
+ }
+ } else {
+ return 1;
+ }
+}
+
+/* remove item from list */
+PUBLIC int list_sub(int p, enum ListWhich l, char *s)
+{
+ List *gl = list_find(p, l);
+
+ if (gl) {
+ int i, found = -1;
+ for (i = 0; i < gl->numMembers; i++)
+ if (!strcasecmp(s, gl->member[i])) {
+ found = i;
+ break;
+ }
+ if (found == -1)
+ return 1;
+ rfree(gl->member[found]);
+ for (i = found; i < (gl->numMembers - 1); i++)
+ gl->member[i] = gl->member[i + 1];
+ gl->numMembers--;
+ return 0;
+ } else {
+ return 1;
+ }
+}
+
+/* pretty cheesy: print each member of a list, 1 per line */
+PUBLIC void list_print(FILE * fp, int p, enum ListWhich l)
+{
+ int i;
+ List *gl = list_find(p, l);
+
+ if (gl) {
+ for (i = 0; i < gl->numMembers; i++)
+ fprintf(fp, "%s\n", gl->member[i]);
+ }
+}
+
+/* return size of a list */
+PUBLIC int list_size(int p, enum ListWhich l)
+{
+ List *gl = list_find(p, l);
+
+ if (gl)
+ return (gl->numMembers);
+ else
+ return 0;
+}
+
+/* find list by name, doesn't have to be the whole name */
+PRIVATE List *list_findpartial(int p, char *which, int gonnado)
+{
+ List *gl;
+ int i, foundit, slen;
+
+ slen = strlen(which);
+ for (i = 0, foundit = -1; ListArray[i].name != NULL; i++) {
+ if (!strncasecmp(ListArray[i].name, which, slen)) {
+ if (foundit == -1)
+ foundit = i;
+ else
+ return NULL; /* ambiguous */
+ }
+ }
+
+ if (foundit != -1) {
+ int rights = ListArray[foundit].rights;
+ int youlose = 0;
+
+ switch (rights) { /* check rights */
+ case P_HEAD:
+ if (gonnado && !player_ishead(p))
+ youlose = 1;
+ break;
+ case P_GOD:
+ if ((gonnado && (parray[p].adminLevel < ADMIN_GOD)) ||
+ (!gonnado && (parray[p].adminLevel < ADMIN_ADMIN)))
+ youlose = 1;
+ break;
+ case P_ADMIN:
+ if (parray[p].adminLevel < ADMIN_ADMIN)
+ youlose = 1;
+ break;
+ case P_PUBLIC:
+ if (gonnado && (parray[p].adminLevel < ADMIN_ADMIN))
+ youlose = 1;
+ break;
+ }
+ if (youlose) {
+ pprintf(p, "\"%s\" is not an appropriate list name or you have insufficient rights.\n", which);
+ return NULL;
+ }
+ gl = list_find(p, foundit);
+ } else {
+ pprintf(p, "\"%s\" does not match any list name.\n", which);
+ return NULL;
+ }
+ return gl;
+}
+
+/* see if something is in a list */
+PUBLIC int in_list(int p, enum ListWhich which, char *member)
+{
+ List *gl;
+ int i;
+ int filterList = (which == L_FILTER);
+
+ gl = list_find(p, which);
+ if ((gl == NULL) || (member == NULL))
+ return 0;
+ for (i = 0; i < gl->numMembers; i++) {
+ if (filterList) {
+ if (!strncasecmp(member, gl->member[i], strlen(gl->member[i])))
+ return 1;
+ } else {
+ if (!strcasecmp(member, gl->member[i]))
+ return 1;
+ }
+ }
+ return 0;
+}
+
+/* add or subtract something to/from a list */
+PUBLIC int list_addsub(int p, char* list, char* who, int addsub)
+{
+ int p1, connected, loadme, personal, ch;
+ char *listname, *member;
+ List *gl;
+ char *yourthe, *addrem;
+
+ gl = list_findpartial(p, list, addsub);
+ if (!gl)
+ return COM_OK;
+
+ personal = ListArray[gl->which].rights == P_PERSONAL;
+ loadme = (gl->which != L_FILTER) && (gl->which != L_REMOVEDCOM) && (gl->which != L_CHANNEL);
+ listname = ListArray[gl->which].name;
+ yourthe = personal ? "your" : "the";
+ addrem = (addsub == 1) ? "added to" : "removed from";
+
+ if (loadme) {
+ if (!FindPlayer(p, who, &p1, &connected)) {
+ if (addsub == 1)
+ return COM_OK;
+ member = who; /* allow sub removed/renamed player */
+ loadme = 0;
+ } else
+ member = parray[p1].name;
+ } else {
+ member = who;
+ }
+
+ if (addsub == 1) { /* add to list */
+
+ if (gl->which == L_CHANNEL) {
+
+ if (sscanf (who,"%d",&ch) == 1) {
+
+ if ((!in_list(p,L_ADMIN,parray[p].name)) && (ch == 0)) {
+ pprintf(p, "Only admins may join channel 0.\n");
+ return COM_OK;
+ }
+
+ if (ch > (MAX_CHANNELS - 1)) {
+ pprintf(p,"The maximum channel number is %d.\n",MAX_CHANNELS-1);
+ return COM_OK;
+ }
+ } else {
+ pprintf (p,"Your channel to add must be a number between 0 and %d.\n",MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ }
+ if (in_list(p, gl->which, member)) {
+ pprintf(p, "[%s] is already on %s %s list.\n", member, yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (list_add(p, gl->which, member)) {
+ pprintf(p, "Sorry, %s %s list is full.\n", yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ } else if (addsub == 2) { /* subtract from list */
+ if (!in_list(p, gl->which, member)) {
+ pprintf(p, "[%s] is not in %s %s list.\n", member, yourthe, listname);
+ if (loadme && !connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ list_sub(p, gl->which, member);
+ }
+ pprintf(p, "[%s] %s %s %s list.\n", member, addrem, yourthe, listname);
+
+ if (!personal) {
+ FILE *fp;
+ char filename[MAX_FILENAME_SIZE];
+
+ switch (gl->which) {
+ case L_MUZZLE:
+ case L_CMUZZLE:
+ case L_ABUSER:
+ case L_BAN:
+ pprintf(p, "Please leave a comment to explain why %s was %s the %s list.\n", member, addrem, listname);
+ pcommand(p, "addcomment %s %s %s list.\n", member, addrem, listname);
+ break;
+ case L_COMPUTER:
+ if (parray[p1].b_stats.rating > 0)
+ UpdateRank(TYPE_BLITZ, member, &parray[p1].b_stats, member);
+ if (parray[p1].s_stats.rating > 0)
+ UpdateRank(TYPE_STAND, member, &parray[p1].s_stats, member);
+ if (parray[p1].w_stats.rating > 0)
+ UpdateRank(TYPE_WILD, member, &parray[p1].w_stats, member);
+ break;
+ case L_ADMIN:
+ if (addsub == 1) { /* adding to list */
+ parray[p1].adminLevel = 10;
+ pprintf(p, "%s has been given an admin level of 10 - change with asetadmin.\n", member);
+ } else {
+ parray[p1].adminLevel = 0;
+ }
+ break;
+ case L_FILTER:
+ pprintf(p, "Please leave a message for filter to explain why site %s was %s filter list.\n", member, addrem);
+ break;
+ case L_REMOVEDCOM:
+ pprintf(p, "Please leave a message on anews to explain why %s was %s removedcom list.\n", member, addrem);
+ break;
+ default:
+ break;
+ }
+ if (loadme && connected) {
+ pprintf_prompt(p1, "You have been %s the %s list by %s.\n", addrem, listname, parray[p].name);
+ }
+ sprintf(filename, "%s/%s", lists_dir, listname);
+ fp = fopen(filename, "w");
+ if (fp == NULL) {
+ fprintf(stderr, "Couldn't save %s list.\n", listname);
+ } else {
+ int i;
+ for (i = 0; i < gl->numMembers; i++)
+ fprintf(fp, "%s\n", gl->member[i]);
+ fclose(fp);
+ }
+ }
+ if (loadme || (gl->which == L_ADMIN)) {
+ player_save(p1);
+ }
+ if (loadme && !connected) {
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_addlist(int p, param_list param)
+{
+ return list_addsub(p, param[0].val.word, param[1].val.word, 1);
+}
+
+PUBLIC int com_sublist(int p,param_list param)
+{
+ return list_addsub(p, param[0].val.word, param[1].val.word, 2);
+}
+
+PUBLIC int com_showlist(int p, param_list param)
+{
+ List *gl;
+ int i, rights;
+
+ char *rightnames[] = {"EDIT HEAD, READ ADMINS", "EDIT GODS, READ ADMINS", "READ/WRITE ADMINS", "PUBLIC", "PERSONAL"};
+
+ if (param[0].type == 0) { /* Show all lists */
+ pprintf(p, "Lists:\n\n");
+ for (i = 0; ListArray[i].name != NULL; i++) {
+ rights = ListArray[i].rights;
+ if ((rights > P_ADMIN) || (parray[p].adminLevel >= ADMIN_ADMIN))
+ pprintf(p, "%-20s is %s\n", ListArray[i].name, rightnames[rights]);
+ }
+ } else { /* find match in index */
+ gl = list_findpartial(p, param[0].val.word, 0);
+ if (!gl) {
+ return COM_OK;
+ }
+ rights = ListArray[gl->which].rights;
+ /* display the list */
+ {
+ multicol *m = multicol_start(gl->numMembers);
+
+ pprintf(p, "-- %s list: %d %s --", ListArray[gl->which].name,
+ gl->numMembers,
+ ((!(strcmp(ListArray[gl->which].name,"filter"))) ? "ips" : (!(strcmp(ListArray[gl->which].name,"removedcom"))) ? "commands" : (!(strcmp(ListArray[gl->which].name,"channel"))) ? "channels" : "names"));
+ for (i = 0; i < gl->numMembers; i++)
+ multicol_store_sorted(m, gl->member[i]);
+ multicol_pprint(m, p, 78, 2);
+ multicol_end(m);
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int list_channels(int p,int p1)
+{
+ List *gl;
+ int i, rights;
+
+ gl = list_findpartial(p1, "channel", 0);
+ if (!gl) {
+ return 1;
+ }
+ rights = ListArray[gl->which].rights;
+ /* display the list */
+ if (gl->numMembers == 0)
+ return 1;
+ {
+ multicol *m = multicol_start(gl->numMembers);
+
+ for (i = 0; i < gl->numMembers; i++)
+ multicol_store_sorted(m, gl->member[i]);
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ }
+ return 0;
+}
+
+/* free the memory used by a list */
+PUBLIC void list_free(List * gl)
+{
+ int i;
+ List *temp;
+
+ while (gl) {
+ for (i = 0; i < gl->numMembers; i++) {
+ strfree(gl->member[i]);
+ }
+ temp = gl->next;
+ rfree(gl);
+ gl = temp;
+ }
+}
+
+PUBLIC int titled_player(int p,char* name)
+{
+ if ((in_list(p, L_FM, name)) || (in_list(p, L_IM, name)) || (in_list(p, L_GM, name))) {
+ return 1;
+ } else {
+ return 0;
+ }
+}
blob - /dev/null
blob + 8b34a69b7dd5159c819e7b1dcbb87eba98a483fc (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/lists.h
+/* lists.h */
+
+#include <stdio.h>
+
+#ifndef _LISTS_H
+#define _LISTS_H
+
+/* yes, it's all cheesy.. there is no significance to the order, but make
+ sure it matches the order in lists.c */
+
+enum ListWhich {L_ADMIN = 0, L_REMOVEDCOM, L_FILTER, L_BAN, L_ABUSER,
+L_MUZZLE, L_CMUZZLE, L_FM, L_IM, L_GM, L_BLIND, L_TEAMS, L_COMPUTER,
+L_TD, L_CENSOR, L_GNOTIFY, L_NOPLAY, L_NOTIFY, L_CHANNEL};
+
+enum ListPerm {P_HEAD = 0, P_GOD, P_ADMIN, P_PUBLIC, P_PERSONAL};
+
+typedef struct {enum ListPerm rights; char *name;} ListTable;
+
+/* max. names in one list: 200 */
+#define MAX_GLOBAL_LIST_SIZE 200
+
+typedef struct _List List;
+struct _List {
+ enum ListWhich which;
+ int numMembers;
+ char *member[MAX_GLOBAL_LIST_SIZE];
+ struct _List *next;
+};
+
+extern int com_addlist();
+extern int com_sublist();
+extern int com_showlist();
+
+extern void list_free(List *);
+extern int in_list(int, enum ListWhich, char *);
+extern int list_size(int p, enum ListWhich);
+extern int list_add(int, enum ListWhich, char *);
+extern int list_addsub (int,char*,char*,int);
+extern int list_sub(int, enum ListWhich, char *);
+extern void list_print(FILE *, int, enum ListWhich);
+extern int titled_player(int, char *);
+extern int list_channels(int,int);
+
+#endif /* _LISTS_H */
blob - /dev/null
blob + 158a0406088ac3a4ad56413abcbbe4660b397ff9 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/lists.o differ
blob - /dev/null
blob + 8c40b7d0a58777d882365b5972ff2164f1fa9756 (mode 755)
Binary files /dev/null and FICS.DIST/FICS/makerank differ
blob - /dev/null
blob + fe04fb72b7ccb0ee235667c19cc4a3d00fd35873 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/makerank.c
+#define COMPUTER_FILE DEFAULT_LISTS "/computer"
+#define MAX_LOGIN_NAME 21
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <ctype.h>
+#include "config.h"
+
+char *rnames[] = {"std", "blitz", "wild", "lightning"};
+
+typedef struct _ratings {
+ int rating;
+ int num;
+} ratings;
+
+typedef struct _Entry {
+ char name[MAX_LOGIN_NAME];
+ ratings r[4];
+ int computer;
+} ENTRY;
+
+ENTRY **list;
+ENTRY **sortme;
+
+int GetPlayerInfo(char *fileName, ENTRY *e)
+{
+ FILE *fp;
+ char line[100];
+ char field[20];
+ char NameWithCase[30];
+ int i, done = 0;
+
+ e->computer = 0;
+ for (i = 0; i < 4; i++) {
+ e->r[i].num = 0;
+ e->r[i].rating = 0;
+ }
+
+ fp = fopen(fileName, "r");
+ fgets(line, 99, fp);
+ if (feof(fp))
+ return(0);
+ if (!strcmp(line, "v 1\n")) {
+ fgets(line, 99, fp);
+ sscanf(line, "%s", e->name);
+ fgets(line, 99, fp);
+ fgets(line, 99, fp);
+ fgets(line, 99, fp);
+ if (fscanf(fp, "%u %*u %*u %*u %u %*u %*u %*u %*u %u %*u %*u %*u %u %*u %*u %*u %*u %u %*u %*u %*u %u %*u %*u %*u %*u %u %*u %*u %*u %u %*u %*u %*u %*u", &(e->r[0].num), &(e->r[0].rating), &(e->r[1].num), &(e->r[1].rating), &(e->r[2].num), &(e->r[2].rating), &(e->r[3].num), &(e->r[3].rating)) != 8)
+ fprintf(stderr, "OOPS: couldn't parse player file %s.\n", fileName);
+ } else do {
+ sscanf(line, "%s", field);
+ if (!strcmp(field, "Name:")) {
+ sscanf(line, "%*s %s", NameWithCase);
+ if (strcasecmp(e->name, NameWithCase))
+ printf("TROUBLE: %s's handle is listed as %s.\n",
+ e->name, NameWithCase);
+ else
+ strcpy(e->name, NameWithCase);
+ } else if (!strcmp(field, "S_NUM:")) {
+ sscanf(line, "%*s %d", &(e->r[0].num));
+ } else if (!strcmp(field, "B_NUM:")) {
+ sscanf(line, "%*s %d", &(e->r[1].num));
+ } else if (!strcmp(field, "W_NUM:")) {
+ sscanf(line, "%*s %d", &(e->r[2].num));
+ } else if (!strcmp(field, "L_NUM:")) {
+ sscanf(line, "%*s %d", &(e->r[3].num));
+ } else if (!strcmp(field, "S_RATING:")) {
+ sscanf(line, "%*s %d", &(e->r[0].rating));
+ } else if (!strcmp(field, "B_RATING:")) {
+ sscanf(line, "%*s %d", &(e->r[1].rating));
+ } else if (!strcmp(field, "W_RATING:")) {
+ sscanf(line, "%*s %d", &(e->r[2].rating));
+ } else if (!strcmp(field, "L_RATING:")) {
+ sscanf(line, "%*s %d", &(e->r[3].rating));
+ } else if (!strcmp(field, "Network:")) {
+ done = 1;
+ }
+ fgets(line, 99, fp);
+ } while (!done && !feof(fp));
+ fclose(fp);
+ return (1);
+}
+
+int LoadEntries(void)
+{
+ int listsize;
+ FILE *fpPlayerList;
+ char letter1;
+ char command[90];
+ char pathInput[80];
+ ENTRY e;
+ int len, n = 0;
+
+ listsize = 100;
+ list = malloc(sizeof(ENTRY *)*listsize);
+
+ for (letter1 = 'a'; letter1 <= 'z'; letter1++) {
+ printf("Loading %c's.\n", letter1);
+ sprintf(pathInput, "%s/%c", DEFAULT_PLAYERS, letter1);
+ sprintf(command, "ls -1 %s", pathInput);
+ fpPlayerList = popen(command, "r");
+ if (fpPlayerList == NULL)
+ continue;
+ while (1) {
+ fgets(e.name, MAX_LOGIN_NAME, fpPlayerList);
+ if (feof(fpPlayerList))
+ break;
+ len = strlen(e.name);
+ e.name[len - 1] = '\0';
+ if (e.name[0] != letter1)
+ printf("File %c/%s: wrong directory.\n", letter1, e.name);
+ else {
+ sprintf(pathInput, "%s/%c/%s", DEFAULT_PLAYERS, letter1, e.name);
+ if (GetPlayerInfo(pathInput, &e)) {
+ if ((list[n] = malloc(sizeof(ENTRY))) == NULL) {
+ fprintf(stderr, "malloc() failed!\n");
+ } else {
+ memcpy(list[n], &e, sizeof(ENTRY));
+ n++;
+ if (n == listsize) {
+ listsize += 100;
+ list = realloc(list, listsize*sizeof(ENTRY *));
+ }
+ }
+ }
+ }
+ }
+ pclose(fpPlayerList);
+ }
+ return (n);
+}
+
+int SetComputers(int n)
+{
+ FILE *fpComp;
+ int i = 0;
+ char line[100], comp[30];
+
+ sprintf(line, "sort -f %s", COMPUTER_FILE);
+ fpComp = popen(line, "r");
+ if (fpComp == NULL)
+ return 0;
+ while (i < n) {
+ fgets(comp, 29, fpComp);
+ if (feof(fpComp))
+ break;
+ comp[strlen(comp) - 1] = '\0';
+
+ while (i < n && strcasecmp(list[i]->name, comp) < 0)
+ i++;
+
+ if (i < n && strcasecmp(list[i]->name, comp) == 0) {
+ list[i++]->computer = 1;
+ }
+ }
+ pclose(fpComp);
+ return(1);
+}
+
+int rtype;
+
+int sortfunc(const void *i, const void *j)
+{
+ int n = (*(ENTRY **)j)->r[rtype].rating - (*(ENTRY **)i)->r[rtype].rating;
+ return n ? n : strcasecmp((*(ENTRY **)i)->name, (*(ENTRY **)j)->name);
+}
+
+void makerank(void)
+{
+ int sortnum, sortmesize, i, n;
+ FILE *fp;
+ char fName[200];
+
+ printf("Loading players\n");
+ n = LoadEntries();
+ printf("Found %d players.\n", n);
+ printf("Setting computers.\n");
+ SetComputers(n);
+
+ for (rtype = 0; rtype < 4; rtype++) {
+ sortnum = 0; sortmesize = 100;
+ sortme = malloc(sizeof(ENTRY *)*sortmesize);
+
+ for (i = 0; i < n; i++) {
+ if (list[i]->r[rtype].rating) {
+ sortme[sortnum++] = list[i];
+ if (sortnum == sortmesize) {
+ sortmesize += 100;
+ sortme = realloc(sortme, sortmesize*sizeof(ENTRY *));
+ }
+ }
+ }
+ printf("Sorting %d %s.\n", sortnum, rnames[rtype]);
+ qsort(sortme, sortnum, sizeof(ENTRY *), sortfunc);
+ printf("Saving to file.\n");
+ sprintf(fName, "%s/rank.%s", DEFAULT_STATS, rnames[rtype]);
+ fp = fopen(fName, "w");
+ for (i = 0; i < sortnum; i++)
+ fprintf(fp, "%s %d %d %d\n", sortme[i]->name, sortme[i]->r[rtype].rating, sortme[i]->r[rtype].num, sortme[i]->computer);
+ fclose(fp);
+ free(sortme);
+ }
+}
+
+int main(int argc, char **argv)
+{
+ if (argc > 1) {
+ printf("usage: %s.\n", argv[0]);
+ exit(0);
+ } else {
+ makerank();
+ }
+ return (0);
+}
+
blob - /dev/null
blob + 793755673286d2f38f44de5bbeb6b5870a73555e (mode 644)
Binary files /dev/null and FICS.DIST/FICS/makerank.o differ
blob - /dev/null
blob + 05a2aff8c6575da776e1ad2dc6c00be4279290d4 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/matchproc.c
+/* matchproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ hersco dhersco@stmarys-ca.edu 95/7/24 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "command.h"
+#include "utils.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "variable.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "board.h"
+/* #include "hostinfo.h" */
+#include "multicol.h"
+#include "ratings.h"
+#include "formula.h"
+#include "lists.h"
+#include "eco.h"
+#include <string.h>
+
+#include <sys/resource.h>
+
+PUBLIC int create_new_match(int white_player, int black_player,
+ int wt, int winc, int bt, int binc,
+ int rated, char *category, char *board,
+ int white)
+{
+ int g = game_new(), p;
+ char outStr[1024];
+ int reverse = 0;
+
+ if (g < 0)
+ return COM_FAILED;
+ if (white == 0) {
+ reverse = 1;
+ } else if (white == -1) {
+ if ((wt == bt) && (winc == binc)) {
+ if (parray[white_player].lastColor == parray[black_player].lastColor) {
+ if ((parray[white_player].num_white - parray[white_player].num_black) >
+ (parray[black_player].num_white - parray[black_player].num_black))
+ reverse = 1;
+ } else if (parray[white_player].lastColor == WHITE)
+ reverse = 1;
+ } else
+ reverse = 1; /* Challenger is always white in unbalanced
+ match */
+ }
+ if (reverse) {
+ int tmp = white_player;
+ white_player = black_player;
+ black_player = tmp;
+ }
+ player_remove_request(white_player, black_player, PEND_MATCH);
+ player_remove_request(black_player, white_player, PEND_MATCH);
+ player_remove_request(white_player, black_player, PEND_SIMUL);
+ player_remove_request(black_player, white_player, PEND_SIMUL);
+ player_decline_offers(white_player, -1, PEND_MATCH);
+ player_withdraw_offers(white_player, -1, PEND_MATCH);
+ player_decline_offers(black_player, -1, PEND_MATCH);
+ player_withdraw_offers(black_player, -1, PEND_MATCH);
+ player_withdraw_offers(white_player, -1, PEND_SIMUL);
+ player_withdraw_offers(black_player, -1, PEND_SIMUL);
+
+ wt = wt * 60; /* To Seconds */
+ bt = bt * 60;
+ garray[g].white = white_player;
+ garray[g].black = black_player;
+ strcpy(garray[g].white_name, parray[white_player].name);
+ strcpy(garray[g].black_name, parray[black_player].name);
+ garray[g].status = GAME_ACTIVE;
+ garray[g].type = game_isblitz(wt / 60, winc, bt / 60, binc, category, board);
+ if ((garray[g].type == TYPE_UNTIMED) || (garray[g].type == TYPE_NONSTANDARD))
+ garray[g].rated = 0;
+ else
+ garray[g].rated = rated;
+ garray[g].private = parray[white_player].private ||
+ parray[black_player].private;
+ garray[g].white = white_player;
+ if (garray[g].type == TYPE_BLITZ) {
+ garray[g].white_rating = parray[white_player].b_stats.rating;
+ garray[g].black_rating = parray[black_player].b_stats.rating;
+ } else if (garray[g].type == TYPE_WILD) {
+ garray[g].white_rating = parray[white_player].w_stats.rating;
+ garray[g].black_rating = parray[black_player].w_stats.rating;
+ } else if (garray[g].type == TYPE_LIGHT) {
+ garray[g].white_rating = parray[white_player].l_stats.rating;
+ garray[g].black_rating = parray[black_player].l_stats.rating;
+ } else if (garray[g].type == TYPE_BUGHOUSE) {
+ garray[g].white_rating = parray[white_player].bug_stats.rating;
+ garray[g].black_rating = parray[black_player].bug_stats.rating;
+ } else {
+ garray[g].white_rating = parray[white_player].s_stats.rating;
+ garray[g].black_rating = parray[black_player].s_stats.rating;
+ }
+ if (board_init(&garray[g].game_state, category, board)) {
+ pprintf(white_player, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ pprintf(black_player, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD %s %s. Game Aborted.\n",
+ category, board);
+ }
+ garray[g].game_state.gameNum = g;
+ garray[g].wTime = wt * 10;
+ garray[g].wInitTime = wt * 10;
+ garray[g].wIncrement = winc * 10;
+ garray[g].bTime = bt * 10;
+ if (garray[g].type != TYPE_UNTIMED) {
+ if (wt == 0)
+ garray[g].wTime = 100;
+ if (bt == 0)
+ garray[g].bTime = 100;
+ } /* 0 x games start with 10 seconds */
+
+#ifdef TIMESEAL
+
+ garray[g].wRealTime = garray[g].wTime * 100;
+ garray[g].bRealTime = garray[g].bTime * 100;
+ garray[g].wTimeWhenReceivedMove = 0;
+ garray[g].bTimeWhenReceivedMove = 0;
+
+#endif
+ garray[g].bInitTime = bt * 10;
+ garray[g].bIncrement = binc * 10;
+ if (garray[g].game_state.onMove == BLACK) { /* Start with black */
+ garray[g].numHalfMoves = 1;
+ garray[g].moveListSize = 1;
+ garray[g].moveList = (move_t *) rmalloc(sizeof(move_t));
+ garray[g].moveList[0].fromFile = -1;
+ garray[g].moveList[0].fromRank = -1;
+ garray[g].moveList[0].toFile = -1;
+ garray[g].moveList[0].toRank = -1;
+ garray[g].moveList[0].color = WHITE;
+ strcpy(garray[g].moveList[0].moveString, "NONE");
+ strcpy(garray[g].moveList[0].algString, "NONE");
+ } else {
+ garray[g].numHalfMoves = 0;
+ garray[g].moveListSize = 0;
+ garray[g].moveList = NULL;
+ }
+ garray[g].timeOfStart = tenth_secs();
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ garray[g].clockStopped = 0;
+ sprintf(outStr, "\n{Game %d (%s vs. %s) Creating %s %s match.}\n",
+ g + 1, parray[white_player].name,
+ parray[black_player].name,
+ rstr[garray[g].rated],
+ bstr[garray[g].type]);
+ pprintf(white_player, "%s", outStr);
+ pprintf(black_player, "%s", outStr);
+
+ for (p = 0; p < p_num; p++) {
+ int gnw, gnb;
+ if ((p == white_player) || (p == black_player))
+ continue;
+ if (parray[p].status != PLAYER_PROMPT)
+ continue;
+ if (parray[p].i_game)
+ pprintf_prompt(p, "%s", outStr);
+ gnw = in_list(p, L_GNOTIFY, parray[white_player].login);
+ gnb = in_list(p, L_GNOTIFY, parray[black_player].login);
+ if (gnw || gnb) {
+ pprintf(p, "Game notification: ");
+ if (gnw)
+ pprintf_highlight(p, parray[white_player].name);
+ else
+ pprintf(p, parray[white_player].name);
+ pprintf(p, " (%s) vs. ",
+ ratstr(GetRating(&parray[white_player], garray[g].type)));
+ if (gnb)
+ pprintf_highlight(p, parray[black_player].name);
+ else
+ pprintf(p, parray[black_player].name);
+ pprintf_prompt(p, " (%s) %s %s %d %d\n",
+ ratstr(GetRating(&parray[black_player], garray[g].type)),
+ rstr[garray[g].rated], bstr[garray[g].type],
+ garray[g].wInitTime/600, garray[g].wIncrement/10);
+ }
+ }
+ parray[white_player].game = g;
+ parray[white_player].opponent = black_player;
+ parray[white_player].side = WHITE;
+ parray[white_player].promote = QUEEN;
+ parray[black_player].game = g;
+ parray[black_player].opponent = white_player;
+ parray[black_player].side = BLACK;
+ parray[black_player].promote = QUEEN;
+ send_boards(g);
+ MakeFENpos(g, garray[g].FENstartPos);
+
+ return COM_OK;
+}
+
+PRIVATE int accept_match(int p, int p1)
+{
+ int g, adjourned, foo, which;
+ int wt, winc, bt, binc, rated, white;
+ char category[50], board[50];
+ pending *pend;
+ char tmp[100];
+ int bh=0, pp, pp1;
+
+ unobserveAll(p); /* stop observing when match starts */
+ unobserveAll(p1);
+
+ which = player_find_pendfrom(p, p1, PEND_MATCH);
+ pend = &parray[p].p_from_list[which];
+ wt = pend->param1;
+ winc = pend->param2;
+ bt = pend->param3;
+ binc = pend->param4;
+ rated = pend->param5;
+ strcpy (category, pend->char1);
+ strcpy (board, pend->char2);
+ white = (pend->param6 == -1) ? -1 : 1 - pend->param6;
+
+ pprintf(p, "You accept the challenge of %s.\n", parray[p1].name);
+ pprintf(p1, "\n%s accepts your challenge.\n", parray[p].name);
+ player_remove_request(p, p1, -1);
+ player_remove_request(p1, p, -1);
+
+ while ((which = player_find_pendto(p, -1, -1)) != -1) {
+ foo = parray[p].p_to_list[which].whoto;
+ pprintf_prompt(foo, "\n%s, who was challenging you, has joined a match with %s.\n", parray[p].name, parray[p1].name);
+ pprintf(p, "Challenge to %s withdrawn.\n", parray[foo].name);
+ player_remove_request(p, foo, -1);
+ }
+
+ while ((which = player_find_pendto(p1, -1, -1)) != -1) {
+ foo = parray[p1].p_to_list[which].whoto;
+ pprintf_prompt(foo, "\n%s, who was challenging you, has joined a match with %s.\n", parray[p1].name, parray[p].name);
+ pprintf(p1, "Challenge to %s withdrawn.\n", parray[foo].name);
+ player_remove_request(p1, foo, -1);
+ }
+
+ while ((which = player_find_pendfrom(p, -1, -1)) != -1) {
+ foo = parray[p].p_from_list[which].whofrom;
+ pprintf_prompt(foo, "\n%s, whom you were challenging, has joined a match with %s.\n", parray[p].name, parray[p1].name);
+ pprintf(p, "Challenge from %s removed.\n", parray[foo].name);
+ player_remove_request(foo, p, -1);
+ }
+
+ while ((which = player_find_pendfrom(p1, -1, -1)) != -1) {
+ foo = parray[p1].p_from_list[which].whofrom;
+ pprintf_prompt(foo, "\n%s, whom you were challenging, has joined a match with %s.\n", parray[p1].name, parray[p].name);
+ pprintf(p1, "Challenge from %s removed.\n", parray[foo].name);
+ player_remove_request(foo, p1, -1);
+ }
+
+ if (game_isblitz(wt, winc, bt, binc, category, board) == TYPE_WILD &&
+ strcmp(board, "bughouse") == 0) {
+ bh = 1;
+
+ if ((pp = parray[p].partner) >= 0 &&
+ (pp1 = parray[p1].partner) >= 0) {
+ unobserveAll(pp); /* stop observing when match starts */
+ unobserveAll(pp1);
+
+ pprintf(pp, "\nYour partner accepts the challenge of %s.\n", parray[p1].name);
+ pprintf(pp1, "\nYour partner %s's challenge was accepted.\n", parray[p].name);
+
+ while ((which = player_find_pendto(pp, -1, -1)) != -1) {
+ foo = parray[pp].p_to_list[which].whoto;
+ pprintf_prompt(foo, "\n%s, who was challenging you, has joined a match with %s.\n", parray[pp].name, parray[pp1].name);
+ pprintf(pp, "Challenge to %s withdrawn.\n", parray[foo].name);
+ player_remove_request(pp, foo, -1);
+ }
+
+ while ((which = player_find_pendto(pp1, -1, -1)) != -1) {
+ foo = parray[pp1].p_to_list[which].whoto;
+ pprintf_prompt(foo, "\n%s, who was challenging you, has joined a match with %s.\n", parray[pp1].name, parray[pp].name);
+ pprintf(pp1, "Challenge to %s withdrawn.\n", parray[foo].name);
+ player_remove_request(pp1, foo, -1);
+ }
+
+ while ((which = player_find_pendfrom(pp, -1, -1)) != -1) {
+ foo = parray[pp].p_from_list[which].whofrom;
+ pprintf_prompt(foo, "\n%s, whom you were challenging, has joined a match with %s.\n", parray[pp].name, parray[pp1].name);
+ pprintf(pp, "Challenge from %s removed.\n", parray[foo].name);
+ player_remove_request(foo, pp, -1);
+ }
+
+ while ((which = player_find_pendfrom(pp1, -1, -1)) != -1) {
+ foo = parray[pp1].p_from_list[which].whofrom;
+ pprintf_prompt(foo, "\n%s, whom you were challenging, has joined a match with %s.\n", parray[pp1].name, parray[pp].name);
+ pprintf(pp1, "Challenge from %s removed.\n", parray[foo].name);
+ player_remove_request(foo, pp1, -1);
+ }
+ } else {
+ return COM_OK;
+ }
+ }
+
+ g = game_new();
+ adjourned = 0;
+ if (game_read(g, p, p1) >= 0)
+ adjourned = 1;
+ else if (game_read(g, p1, p) >= 0) {
+ int swap;
+ adjourned = 1;
+ swap = p;
+ p = p1;
+ p1 = swap;
+ }
+ if (!adjourned) { /* no adjourned game, so begin a new game */
+ game_remove(g);
+
+ if (create_new_match(p, p1, wt, winc, bt, binc, rated, category, board, white) != COM_OK) {
+ sprintf(tmp, "There was a problem creating the new match.\n");
+ pprintf(p, tmp);
+ pprintf_prompt(p1, tmp);
+ } else if (bh) {
+ white = (parray[p].side == WHITE ? 0 : 1);
+ if (create_new_match(pp, pp1, wt, winc, bt, binc, rated, category, board, white) != COM_OK) {
+/* sprintf(tmp, "There was a problem creating the new match.\n"); */
+ pprintf_prompt(pp, tmp);
+ pprintf_prompt(pp1, tmp);
+ sprintf(tmp, "There was a problem creating your partner's match.\n");
+ pprintf(p, tmp);
+ pprintf_prompt(p1, tmp);
+ /* abort first game p-p1 IanO: abort_game()? */
+ } else {
+ int g1 = parray[p].game;
+ int g2 = parray[pp].game;
+
+ garray[g1].link = g2;
+ garray[g2].link = g1;
+
+ sprintf(tmp, "\nYour partner is playing game %d (%s vs. %s).\n",
+ g2 + 1, garray[g2].white_name, garray[g2].black_name);
+ pprintf(p, tmp);
+ pprintf_prompt(p1, tmp);
+ sprintf(tmp, "\nYour partner is playing game %d (%s vs. %s).\n",
+ g1 + 1, garray[g1].white_name, garray[g1].black_name);
+ pprintf_prompt(pp, tmp);
+ pprintf_prompt(pp1, tmp);
+ }
+ }
+ } else { /* resume adjourned game */
+ game_delete(p, p1);
+
+ sprintf(tmp, "{Game %d (%s vs. %s) Continuing %s %s match.}\n",
+ g+1, parray[p].name, parray[p1].name,
+ rstr[garray[g].rated], bstr[garray[g].type]);
+ pprintf(p, tmp);
+ pprintf(p1, tmp);
+
+ garray[g].white = p;
+ garray[g].black = p1;
+ garray[g].status = GAME_ACTIVE;
+ garray[g].result = END_NOTENDED;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ parray[p].game = g;
+ parray[p].opponent = p1;
+ parray[p].side = WHITE;
+ parray[p1].game = g;
+ parray[p1].opponent = p;
+ parray[p1].side = BLACK;
+
+#ifdef TIMESEAL
+
+ garray[g].wRealTime = garray[g].wTime * 100;
+ garray[g].bRealTime = garray[g].bTime * 100;
+ garray[g].wTimeWhenReceivedMove = 0;
+ garray[g].bTimeWhenReceivedMove = 0;
+
+#endif
+
+ send_boards(g);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_match(int p, param_list param)
+{
+ int adjourned; /* adjourned game? */
+ int g; /* more adjourned game junk */
+ int p1;
+ int bh=0, pp, pp1;
+ int pendfrom, pendto;
+ int ppend, p1pend;
+ int wt = -1; /* white start time */
+ int winc = -1; /* white increment */
+ int bt = -1; /* black start time */
+ int binc = -1; /* black increment */
+ int rated = -1; /* 1 = rated, 0 = unrated */
+ int white = -1; /* 1 = want white, 0 = want black */
+ char category[100], board[100], parsebuf[100];
+ char *val;
+ textlist *clauses = NULL;
+ int type;
+ int confused = 0;
+ char *colorstr[] = {"", "[black] ", "[white] "};
+ char *adjustr[] = {"", " (adjourned)"};
+
+ if ((parray[p].game >= 0) && (garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You can't challenge while you are examining a game.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >= 0) {
+ pprintf(p, "You can't challenge while you are playing a game.\n");
+ return COM_OK;
+ }
+ stolower(param[0].val.word);
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (p1 == p) { /* Allowing to match yourself to enter
+ analysis mode */
+ ExamineScratch (p, param);
+ return COM_OK;
+ }
+ if (parray[p].open == 0) {
+ parray[p].open = 1;
+ pprintf(p, "Setting you open for matches.\n");
+ }
+ if (!parray[p1].open) {
+ pprintf(p, "Player \"%s\" is not open to match requests.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (parray[p1].game >= 0) {
+ pprintf(p, "Player \"%s\" is involved in another game.\n", parray[p1].name);
+ return COM_OK;
+ }
+/* look for an adjourned game between p and p1 */
+ g = game_new();
+ adjourned = (game_read(g, p, p1) >= 0) || (game_read(g, p1, p) >= 0);
+ if (adjourned) {
+ type = garray[g].type;
+ wt = garray[g].wInitTime / 600;
+ bt = garray[g].bInitTime / 600;
+ winc = garray[g].wIncrement / 10;
+ binc = garray[g].bIncrement / 10;
+ rated = garray[g].rated;
+ }
+ game_remove(g);
+
+ pendto = player_find_pendto(p, p1, PEND_MATCH);
+ pendfrom = player_find_pendfrom(p, p1, PEND_MATCH);
+ category[0] = '\0';
+ board[0] = '\0';
+
+ if (!adjourned) {
+ if (in_list(p1, L_NOPLAY, parray[p].login)) {
+ pprintf(p, "You are on %s's noplay list.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (player_censored(p1, p)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (player_censored(p, p1)) {
+ pprintf(p, "You are censoring \"%s\".\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (param[1].type != TYPE_NULL) {
+ int numba; /* temp for atoi() */
+
+ val = param[1].val.string;
+ while (!confused && (sscanf(val, " %99s", parsebuf) == 1)) {
+ val = eatword(eatwhite(val));
+ if ((category[0] != '\0') && (board[0] == '\0'))
+ strcpy(board, parsebuf);
+ else if (isdigit(*parsebuf)) {
+ if ((numba = atoi(parsebuf)) < 0) {
+ pprintf(p, "You can't specify negative time controls.\n");
+ return COM_OK;
+ } else if (numba > 1000) {
+ pprintf(p, "You can't specify time or inc above 1000.\n");
+ return COM_OK;
+ } else if (wt == -1) {
+ wt = numba;
+ } else if (winc == -1) {
+ winc = numba;
+ } else if (bt == -1) {
+ bt = numba;
+ } else if (binc == -1) {
+ binc = numba;
+ } else {
+ confused = 1;
+ }
+ } else if (strstr("rated", parsebuf) != NULL) {
+ if (rated == -1)
+ rated = 1;
+ else
+ confused = 1;
+ } else if (strstr("unrated", parsebuf) != NULL) {
+ if (rated == -1)
+ rated = 0;
+ else
+ confused = 1;
+ } else if (strstr("white", parsebuf) != NULL) {
+ if (white == -1)
+ white = 1;
+ else
+ confused = 1;
+ } else if (strstr("black", parsebuf) != NULL) {
+ if (white == -1)
+ white = 0;
+ else
+ confused = 1;
+ } else if (category[0] == '\0')
+ strcpy(category, parsebuf);
+ else
+ confused = 1;
+ }
+ if (confused) {
+ pprintf(p, "Can't interpret %s in match command.\n", parsebuf);
+ return COM_OK;
+ }
+ }
+ rated = ((rated == -1) ? parray[p].rated : rated) && parray[p1].registered && parray[p].registered;
+ if (winc == -1)
+ winc = (wt == -1) ? parray[p].d_inc : 0; /* match 5 == match 5 0 */
+ if (wt == -1)
+ wt = parray[p].d_time;
+ if (bt == -1)
+ bt = wt;
+ if (binc == -1)
+ binc = winc;
+
+ if (!strcmp(category,"bughouse")) { /* save mentioning wild */
+ (strcpy(board,"bughouse"));
+ (strcpy(category,"wild"));
+ }
+ if (category[0] && !board[0]) {
+ pprintf(p, "You must specify a board and a category.\n");
+ return COM_OK;
+ }
+ if (category[0]) {
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%s/%s", board_dir, category, board);
+ if (!file_exists(fname)) {
+ pprintf(p, "No such category/board: %s/%s\n", category, board);
+ return COM_OK;
+ }
+ }
+ if ((pendfrom < 0) && (parray[p1].ropen == 0) && (rated != parray[p1].rated)) {
+ pprintf(p, "%s only wants to play %s games.\n", parray[p1].name,
+ rstr[parray[p1].rated]);
+ pprintf_highlight(p1, "Ignoring");
+ pprintf(p1, " %srated match request from %s.\n",
+ (parray[p1].rated ? "un" : ""), parray[p].name);
+ return COM_OK;
+ }
+ type = game_isblitz(wt, winc, bt, binc, category, board);
+
+#if 0
+ if (rated && (type == TYPE_STAND || type == TYPE_BLITZ || type == TYPE_WILD)) {
+ if (parray[p].network_player == parray[p1].network_player) {
+ rated = 1;
+ } else {
+ pprintf(p, "Network vs. local player forced to not rated\n");
+ rated = 0;
+ }
+ }
+#endif
+
+ if (rated && (type == TYPE_WILD) && (!strcmp(board,"bughouse"))) {
+ pprintf(p, "Game is bughouse - reverting to unrated\n");
+ rated = 0; /* will need to kill wild and make TYPE_BUGHOUSE */
+ }
+ if (rated && (type == TYPE_NONSTANDARD)) {
+ pprintf(p, "Game is non-standard - reverting to unrated\n");
+ rated = 0;
+ }
+ if (rated && (type == TYPE_UNTIMED)) {
+ pprintf(p, "Game is untimed - reverting to unrated\n");
+ rated = 0;
+ }
+ /* Now check formula. */
+ if ((pendfrom < 0 || param[1].type != TYPE_NULL)
+ && !GameMatchesFormula(p, p1, wt, winc, bt, binc,
+ rated, type, &clauses)) {
+ pprintf(p, "Match request does not fit formula for %s:\n",
+ parray[p1].name);
+ pprintf(p, "%s's formula: %s\n", parray[p1].name, parray[p1].formula);
+ ShowClauses (p, p1, clauses);
+ ClearTextList(clauses);
+ pprintf_highlight(p1, "Ignoring");
+ pprintf_prompt(p1, " (formula): %s (%d) %s (%d) %s.\n",
+ parray[p].name,
+ GetRating(&parray[p], type),
+ parray[p1].name,
+ GetRating(&parray[p1], type),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ return COM_OK;
+ }
+ if (type == TYPE_WILD && strcmp(board, "bughouse") == 0) {
+ bh = 1;
+ pp = parray[p].partner;
+ pp1 = parray[p1].partner;
+
+ if (pp < 0) {
+ pprintf(p, "You have no partner for bughouse.\n");
+ return COM_OK;
+ }
+ if (pp1 < 0) {
+ pprintf(p, "Your opponent has no partner for bughouse.\n");
+ return COM_OK;
+ }
+ if (pp == pp1) {
+ pprintf(p, "You and your opponent both chose the same partner!\n");
+ return COM_OK;
+ }
+ if (pp == p1 || pp1 == p) {
+ pprintf(p, "You and your opponent can't choose each other as partners!\n");
+ return COM_OK;
+ }
+ if (parray[pp].partner != p) {
+ pprintf(p, "Your partner hasn't chosen you as his partner!\n");
+ return COM_OK;
+ }
+ if (parray[pp1].partner != p1) {
+ pprintf(p, "Your opponent's partner hasn't chosen your opponent as his partner!\n");
+ return COM_OK;
+ }
+ if (!parray[pp].open || parray[pp].game >= 0) {
+ pprintf(p, "Your partner isn't open to play right now.\n");
+ return COM_OK;
+ }
+ if (!parray[pp1].open || parray[pp1].game >= 0) {
+ pprintf(p, "Your opponent's partner isn't open to play right now.\n");
+ return COM_OK;
+ }
+ /* Bypass NOPLAY lists, censored lists, ratedness, privacy, and formula for now */
+ /* Active challenger/ee will determine these. */
+ }
+ /* Ok match offer will be made */
+
+ } /* adjourned games shouldn't have to worry
+ about that junk? */
+ if (pendto >= 0) {
+ pprintf(p, "Updating offer already made to \"%s\".\n", parray[p1].name);
+ }
+ if (pendfrom >= 0) {
+ if (pendto >= 0) {
+ pprintf(p, "Internal error\n");
+ fprintf(stderr, "FICS: This shouldn't happen. You can't have a match pending from and to the same person.\n");
+ return COM_OK;
+ }
+ if (adjourned || ((wt == parray[p].p_from_list[pendfrom].param1) &&
+ (winc == parray[p].p_from_list[pendfrom].param2) &&
+ (bt == parray[p].p_from_list[pendfrom].param3) &&
+ (binc == parray[p].p_from_list[pendfrom].param4) &&
+ (rated == parray[p].p_from_list[pendfrom].param5) &&
+ ((white == -1) || (white + parray[p].p_from_list[pendfrom].param6 == 1)) &&
+ (!strcmp(category, parray[p].p_from_list[pendfrom].char1)) &&
+ (!strcmp(board, parray[p].p_from_list[pendfrom].char2)))) {
+ /* Identical match, should accept! */
+ accept_match(p, p1);
+ return COM_OK;
+ } else {
+ player_remove_pendfrom(p, p1, PEND_MATCH);
+ player_remove_pendto(p1, p, PEND_MATCH);
+ }
+ }
+ if (pendto < 0) {
+ ppend = player_new_pendto(p);
+ if (ppend < 0) {
+ pprintf(p, "Sorry you can't have any more pending matches.\n");
+ return COM_OK;
+ }
+ p1pend = player_new_pendfrom(p1);
+ if (p1pend < 0) {
+ pprintf(p, "Sorry %s can't have any more pending matches.\n", parray[p1].name);
+ parray[p].num_to = parray[p].num_to - 1;
+ return COM_OK;
+ }
+ } else {
+ ppend = pendto;
+ p1pend = player_find_pendfrom(p1, p, PEND_MATCH);
+ }
+ parray[p].p_to_list[ppend].param1 = wt;
+ parray[p].p_to_list[ppend].param2 = winc;
+ parray[p].p_to_list[ppend].param3 = bt;
+ parray[p].p_to_list[ppend].param4 = binc;
+ parray[p].p_to_list[ppend].param5 = rated;
+ parray[p].p_to_list[ppend].param6 = white;
+ strcpy(parray[p].p_to_list[ppend].char1, category);
+ strcpy(parray[p].p_to_list[ppend].char2, board);
+ parray[p].p_to_list[ppend].type = PEND_MATCH;
+ parray[p].p_to_list[ppend].whoto = p1;
+ parray[p].p_to_list[ppend].whofrom = p;
+
+ parray[p1].p_from_list[p1pend].param1 = wt;
+ parray[p1].p_from_list[p1pend].param2 = winc;
+ parray[p1].p_from_list[p1pend].param3 = bt;
+ parray[p1].p_from_list[p1pend].param4 = binc;
+ parray[p1].p_from_list[p1pend].param5 = rated;
+ parray[p1].p_from_list[p1pend].param6 = white;
+ strcpy(parray[p1].p_from_list[p1pend].char1, category);
+ strcpy(parray[p1].p_from_list[p1pend].char2, board);
+ parray[p1].p_from_list[p1pend].type = PEND_MATCH;
+ parray[p1].p_from_list[p1pend].whoto = p1;
+ parray[p1].p_from_list[p1pend].whofrom = p;
+
+ if (pendfrom >= 0) {
+ pprintf(p, "Declining offer from %s and offering new match parameters.\n", parray[p1].name);
+ pprintf(p1, "\n%s declines your match offer a match with these parameters:", parray[p].name);
+ }
+ if (pendto >= 0) {
+ pprintf(p, "Updating match request to: ");
+ pprintf(p1, "\n%s updates the match request.\n", parray[p].name);
+ } else {
+ pprintf(p, "Issuing: ");
+ pprintf(p1, "\n", parray[p].name);
+ }
+
+ pprintf(p, "%s (%s) %s", parray[p].name,
+ ratstrii(GetRating(&parray[p], type), parray[p].registered),
+ colorstr[white + 1]);
+ pprintf_highlight(p, "%s", parray[p1].name);
+ pprintf(p, " (%s) %s%s.\n",
+ ratstrii(GetRating(&parray[p1], type), parray[p1].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board),
+ adjustr[adjourned]);
+ pprintf(p1, "Challenge: ");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf(p1, " (%s) %s", ratstrii(GetRating(&parray[p], type), parray[p].registered), colorstr[white + 1]);
+ pprintf(p1, "%s (%s) %s%s.\n", parray[p1].name,
+ ratstrii(GetRating(&parray[p1], type), parray[p1].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board),
+ adjustr[adjourned]);
+ if (parray[p1].bell == 1)
+ pprintf_noformat(p1, "\007");
+
+ if (bh) {
+ pprintf(pp, "\nYour bughouse partner issuing %s (%s) %s",
+ parray[p].name, ratstrii(GetRating(&parray[p], type),
+ parray[p].registered), colorstr[white + 1]);
+ pprintf_highlight(pp, "%s", parray[p1].name);
+ pprintf(pp, " (%s) %s.\n",
+ ratstrii(GetRating(&parray[p1], type), parray[p1].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ pprintf(pp, "Your game would be ");
+ pprintf_highlight(pp, "%s", parray[pp1].name);
+ pprintf_prompt(pp, " (%s) %s%s (%s) %s.\n",
+ ratstrii(GetRating(&parray[pp1], type), parray[pp1].registered),
+ colorstr[white + 1], parray[pp].name,
+ ratstrii(GetRating(&parray[pp], type), parray[pp].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ if (parray[pp].bell == 1)
+ pprintf_noformat(pp, "\007");
+
+ pprintf(pp1, "\nYour bughouse partner was challenged ");
+ pprintf_highlight(pp1, "%s", parray[p].name);
+ pprintf(pp1, " (%s) %s", ratstrii(GetRating(&parray[p], type), parray[p].registered), colorstr[white + 1]);
+ pprintf(pp1, "%s (%s) %s.\n", parray[p1].name,
+ ratstrii(GetRating(&parray[p1], type), parray[p1].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ pprintf(pp1, "Your game would be %s (%s) %s", parray[pp1].name,
+ ratstrii(GetRating(&parray[pp1], type), parray[pp1].registered),
+ colorstr[white + 1]);
+ pprintf_highlight(pp1, "%s", parray[pp].name);
+ pprintf_prompt(pp1, " (%s) %s.\n",
+ ratstrii(GetRating(&parray[pp], type), parray[pp].registered),
+ game_str(rated, wt * 60, winc, bt * 60, binc, category, board));
+ if (parray[pp1].bell == 1)
+ pprintf_noformat(pp1, "\007");
+ }
+
+ if (in_list(p, L_COMPUTER, parray[p].name)) {
+ pprintf(p1, "--** %s is a ", parray[p].name);
+ pprintf_highlight(p1, "computer");
+ pprintf(p1, " **--\n");
+ }
+ if (in_list(p, L_COMPUTER, parray[p1].name)) {
+ pprintf(p, "--** %s is a ", parray[p1].name);
+ pprintf_highlight(p, "computer");
+ pprintf(p, " **--\n");
+ }
+ if (in_list(p, L_ABUSER, parray[p].name)) {
+ pprintf(p1, "--** %s is in the ", parray[p].name);
+ pprintf_highlight(p1, "abuser");
+ pprintf(p1, " list **--\n");
+ }
+ if (in_list(p, L_ABUSER, parray[p1].name)) {
+ pprintf(p, "--** %s is in the ", parray[p1].name);
+ pprintf_highlight(p, "abuser");
+ pprintf(p, " list **--\n");
+ }
+ if (rated) {
+ int win, draw, loss;
+ double newsterr;
+
+ rating_sterr_delta(p1, p, type, time(0), RESULT_WIN, &win, &newsterr);
+ rating_sterr_delta(p1, p, type, time(0), RESULT_DRAW, &draw, &newsterr);
+ rating_sterr_delta(p1, p, type, time(0), RESULT_LOSS, &loss, &newsterr);
+ pprintf(p1, "Your %s rating will change: Win: %s%d, Draw: %s%d, Loss: %s%d\n",
+ bstr[type],
+ (win >= 0) ? "+" : "", win,
+ (draw >= 0) ? "+" : "", draw,
+ (loss >= 0) ? "+" : "", loss);
+ pprintf(p1, "Your new RD will be %5.1f\n", newsterr);
+
+ rating_sterr_delta(p, p1, type, time(0), RESULT_WIN, &win, &newsterr);
+ rating_sterr_delta(p, p1, type, time(0), RESULT_DRAW, &draw, &newsterr);
+ rating_sterr_delta(p, p1, type, time(0), RESULT_LOSS, &loss, &newsterr);
+ pprintf(p, "Your %s rating will change: Win: %s%d, Draw: %s%d, Loss: %s%d\n",
+ bstr[type],
+ (win >= 0) ? "+" : "", win,
+ (draw >= 0) ? "+" : "", draw,
+ (loss >= 0) ? "+" : "", loss);
+ pprintf(p, "Your new RD will be %5.1f\n", newsterr);
+ }
+ pprintf_prompt(p1, "You can \"accept\" or \"decline\", or propose different parameters.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_accept(int p, param_list param)
+{
+ int acceptNum = -1;
+ int from;
+ int type = -1;
+ int p1;
+
+ if (parray[p].num_from == 0) {
+ pprintf(p, "You have no offers to accept.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].num_from != 1) {
+ pprintf(p, "You have more than one offer to accept.\nUse \"pending\" to see them and \"accept n\" to choose which one.\n");
+ return COM_OK;
+ }
+ acceptNum = 0;
+ } else if (param[0].type == TYPE_INT) {
+ if ((param[0].val.integer < 1) || (param[0].val.integer > parray[p].num_from)) {
+ pprintf(p, "Out of range. Use \"pending\" to see the list of offers.\n");
+ return COM_OK;
+ }
+ acceptNum = param[0].val.integer - 1;
+ } else if (param[0].type == TYPE_WORD) {
+ if (!strcmp(param[0].val.word, "draw")) {
+ type = PEND_DRAW;
+ } else if (!strcmp(param[0].val.word, "pause")) {
+ type = PEND_PAUSE;
+ } else if (!strcmp(param[0].val.word, "adjourn")) {
+ type = PEND_ADJOURN;
+ } else if (!strcmp(param[0].val.word, "abort")) {
+ type = PEND_ABORT;
+ } else if (!strcmp(param[0].val.word, "takeback")) {
+ type = PEND_TAKEBACK;
+ } else if (!strcmp(param[0].val.word, "simmatch")) {
+ type = PEND_SIMUL;
+ } else if (!strcmp(param[0].val.word, "switch")) {
+ type = PEND_SWITCH;
+ } else if (!strcmp(param[0].val.word, "partner")) {
+ type = PEND_PARTNER;
+ }
+
+#if 0 /* I don't think 'accept all' makes sense. -- hersco */
+ if (!strcmp(param[0].val.word, "all")) {
+ while (parray[p].num_from != 0) {
+ pcommand(p, "accept 1");
+ }
+ return COM_OK;
+ }
+#endif
+
+ if (type >= 0) {
+ if ((acceptNum = player_find_pendfrom(p, -1, type)) < 0) {
+ pprintf(p, "There are no pending %s offers.\n", param[0].val.word);
+ return COM_OK;
+ }
+ } else { /* Word must be a name */
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if ((acceptNum = player_find_pendfrom(p, p1, -1)) < 0) {
+ pprintf(p, "There are no pending offers from %s.\n", parray[p1].name);
+ return COM_OK;
+ }
+ }
+ }
+ from = parray[p].p_from_list[acceptNum].whofrom;
+
+ switch (parray[p].p_from_list[acceptNum].type) {
+ case PEND_MATCH:
+ accept_match(p, from);
+ return (COM_OK);
+ break;
+ case PEND_DRAW:
+ pcommand(p, "draw");
+ break;
+ case PEND_PAUSE:
+ pcommand(p, "pause");
+ break;
+ case PEND_ABORT:
+ pcommand(p, "abort");
+ break;
+ case PEND_TAKEBACK:
+ pcommand(p, "takeback %d", parray[p].p_from_list[acceptNum].param1);
+ break;
+ case PEND_SIMUL:
+ pcommand(p, "simmatch %s", parray[from].name);
+ break;
+ case PEND_SWITCH:
+ pcommand(p, "switch");
+ break;
+ case PEND_ADJOURN:
+ pcommand(p, "adjourn");
+ break;
+ case PEND_PARTNER:
+ pcommand(p, "partner %s", parray[from].name);
+ break;
+ }
+ return COM_OK_NOPROMPT;
+}
+
+int WordToOffer (int p, char *Word, int *type, int *p1)
+{
+ /* Convert draw adjourn match takeback abort pause
+ simmatch switch partner or <name> to offer type. */
+ if (!strcmp(Word, "match")) {
+ *type = PEND_MATCH;
+ } else if (!strcmp(Word, "draw")) {
+ *type = PEND_DRAW;
+ } else if (!strcmp(Word, "pause")) {
+ *type = PEND_PAUSE;
+ } else if (!strcmp(Word, "abort")) {
+ *type = PEND_ABORT;
+ } else if (!strcmp(Word, "takeback")) {
+ *type = PEND_TAKEBACK;
+ } else if (!strcmp(Word, "adjourn")) {
+ *type = PEND_ADJOURN;
+ } else if (!strcmp(Word, "switch")) {
+ *type = PEND_SWITCH;
+ } else if (!strcmp(Word, "simul")) {
+ *type = PEND_SIMUL;
+ } else if (!strcmp(Word, "partner")) {
+ *type = PEND_PARTNER;
+ } else if (!strcmp(Word, "all")) {
+ } else {
+ *p1 = player_find_part_login(Word);
+ if (*p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", Word);
+ return 0;
+ }
+ }
+ return 1;
+}
+
+PUBLIC int com_decline(int p, param_list param)
+{
+ int declineNum;
+ int p1 = -1, type = -1;
+ int count;
+
+ if (parray[p].num_from == 0) {
+ pprintf(p, "You have no pending offers from other players.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].num_from == 1) {
+ p1 = parray[p].p_from_list[0].whofrom;
+ type = parray[p].p_from_list[0].type;
+ } else {
+ pprintf(p, "You have more than one pending offer. Please specify which one\nyou wish to decline.\n'Pending' will give you the list.\n");
+ return COM_OK;
+ }
+ } else {
+ if (param[0].type == TYPE_WORD) {
+ if (!WordToOffer (p, param[0].val.word, &type, &p1))
+ return COM_OK;
+ } else { /* Must be an integer */
+ declineNum = param[0].val.integer - 1;
+ if (declineNum >= parray[p].num_from || declineNum < 0) {
+ pprintf(p, "Invalid offer number. Must be between 1 and %d.\n", parray[p].num_from);
+ return COM_OK;
+ }
+ p1 = parray[p].p_from_list[declineNum].whofrom;
+ type = parray[p].p_from_list[declineNum].type;
+ }
+ }
+ count = player_decline_offers(p, p1, type);
+ if (count != 1)
+ pprintf(p, "%d offers declined\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_withdraw(int p, param_list param)
+{
+ int withdrawNum;
+ int p1 = -1, type = -1;
+ int count;
+
+ if (parray[p].num_to == 0) {
+ pprintf(p, "You have no pending offers to other players.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].num_to == 1) {
+ p1 = parray[p].p_to_list[0].whoto;
+ type = parray[p].p_to_list[0].type;
+ } else {
+ pprintf(p, "You have more than one pending offer. Please specify which one\nyou wish to withdraw.\n'Pending' will give you the list.\n");
+ return COM_OK;
+ }
+ } else {
+ if (param[0].type == TYPE_WORD) {
+ if (!WordToOffer (p, param[0].val.word, &type, &p1))
+ return COM_OK;
+ } else { /* Must be an integer */
+ withdrawNum = param[0].val.integer - 1;
+ if (withdrawNum >= parray[p].num_to || withdrawNum < 0) {
+ pprintf(p, "Invalid offer number. Must be between 1 and %d.\n", parray[p].num_to);
+ return COM_OK;
+ }
+ p1 = parray[p].p_to_list[withdrawNum].whoto;
+ type = parray[p].p_to_list[withdrawNum].type;
+ }
+ }
+ count = player_withdraw_offers(p, p1, type);
+ if (count != 1)
+ pprintf(p, "%d offers withdrawn\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_pending(int p, param_list param)
+{
+ int i;
+
+ if (!parray[p].num_to) {
+ pprintf(p, "There are no offers pending TO other players.\n");
+ } else {
+ pprintf(p, "Offers TO other players:\n");
+ for (i = 0; i < parray[p].num_to; i++) {
+ pprintf(p, " ");
+ player_pend_print(p, &parray[p].p_to_list[i]);
+ }
+ }
+ if (!parray[p].num_from) {
+ pprintf(p, "\nThere are no offers pending FROM other players.\n");
+ } else {
+ pprintf(p, "\nOffers FROM other players:\n");
+ for (i = 0; i < parray[p].num_from; i++) {
+ pprintf(p, " %d: ", i + 1);
+ player_pend_print(p, &parray[p].p_from_list[i]);
+ }
+ pprintf(p, "\nIf you wish to accept any of these offers type 'accept n'\nor just 'accept' if there is only one offer.\n");
+ }
+ return COM_OK;
+}
blob - /dev/null
blob + 8f616ae0af25819d8264cbe7eb3ff9fdcb62afca (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/matchproc.h
+/* matchproc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name yy/mm/dd Change
+ hersco 95/07/24 Created
+*/
+
+#ifndef _MATCHPROC_H
+#define _MATCHPROC_H
+
+extern int com_match();
+extern int com_decline();
+extern int com_withdraw();
+extern int com_pending();
+extern int com_accept();
+extern int create_new_match(int, int, int, int, int, int, int, char *, char *, int);
+
+#endif /* _MATCHPROC_H */
blob - /dev/null
blob + cb2686e4d1f74223f10207b9670399f205743ccf (mode 644)
Binary files /dev/null and FICS.DIST/FICS/matchproc.o differ
blob - /dev/null
blob + 7f2ee3aa25eb067df10402dfd119a43a919025cb (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/memmove.c
+/*-
+ * Copyright (c) 1990, 1993
+ * The Regents of the University of California. All rights reserved.
+ *
+ * This code is derived from software contributed to Berkeley by
+ * Chris Torek.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions
+ * are met:
+ * 1. Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ * 2. Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ * 3. All advertising materials mentioning features or use of this software
+ * must display the following acknowledgement:
+ * This product includes software developed by the University of
+ * California, Berkeley and its contributors.
+ * 4. Neither the name of the University nor the names of its contributors
+ * may be used to endorse or promote products derived from this software
+ * without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``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 REGENTS OR CONTRIBUTORS 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.
+ */
+
+#if defined(LIBC_SCCS) && !defined(lint)
+static char sccsid[] = "@(#)bcopy.c 8.1 (Berkeley) 6/4/93";
+#endif /* LIBC_SCCS and not lint */
+
+/* #include <sys/cdefs.h>
+*/
+#include <string.h>
+
+/*
+ * sizeof(word) MUST BE A POWER OF TWO
+ * SO THAT wmask BELOW IS ALL ONES
+ */
+typedef int word; /* "word" used for optimal copy speed */
+
+#define wsize sizeof(word)
+#define wmask (wsize - 1)
+
+/*
+ * Copy a block of memory, handling overlap.
+ * This is the routine that actually implements
+ * (the portable versions of) bcopy, memcpy, and memmove.
+ */
+void *
+ memmove(dst0, src0, length)
+void *dst0;
+const void *src0;
+register size_t length;
+{
+ register char *dst = dst0;
+ register const char *src = src0;
+ register size_t t;
+
+ if (length == 0 || dst == src)/* nothing to do */
+ goto done;
+
+ /* Macros: loop-t-times; and loop-t-times, t>0 */
+#define TLOOP(s) if (t) TLOOP1(s)
+#define TLOOP1(s) do { s; } while (--t)
+
+ if ((unsigned long) dst < (unsigned long) src) {
+ /* Copy forward. */
+ t = (int) src; /* only need low bits */
+ if ((t | (int) dst) & wmask) {
+ /* Try to align operands. This cannot be done unless the low bits
+ match. */
+ if ((t ^ (int) dst) & wmask || length < wsize)
+ t = length;
+ else
+ t = wsize - (t & wmask);
+ length -= t;
+ TLOOP1(*dst++ = *src++);
+ }
+ /* Copy whole words, then mop up any trailing bytes. */
+ t = length / wsize;
+ TLOOP(*(word *) dst = *(word *) src;
+ src += wsize;
+ dst += wsize);
+ t = length & wmask;
+ TLOOP(*dst++ = *src++);
+ } else {
+ /* Copy backwards. Otherwise essentially the same. Alignment works as
+ before, except that it takes (t&wmask) bytes to align, not
+ wsize-(t&wmask). */
+ src += length;
+ dst += length;
+ t = (int) src;
+ if ((t | (int) dst) & wmask) {
+ if ((t ^ (int) dst) & wmask || length <= wsize)
+ t = length;
+ else
+ t &= wmask;
+ length -= t;
+ TLOOP1(*--dst = *--src);
+ }
+ t = length / wsize;
+ TLOOP(src -= wsize;
+ dst -= wsize;
+ *(word *) dst = *(word *) src);
+ t = length & wmask;
+ TLOOP(*--dst = *--src);
+ }
+done:
+ return (dst0);
+}
blob - /dev/null
blob + 8d624869cb7a4ede137b14097c4d7f197f397e7f (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/movecheck.c
+/* movecheck.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "movecheck.h"
+#include "algcheck.h"
+#include "board.h"
+#include "gamedb.h"
+#include "utils.h"
+#include "network.h"
+#include "playerdb.h"
+
+/* Simply tests if the input string is a move or not. */
+/* If it matches patterns below */
+/* Add to this list as you improve the move parser */
+/* MS_COMP e2e4 */
+/* MS_COMPDASH e2-e4 */
+/* MS_CASTLE o-o, o-o-o */
+/* Not done yet */
+/* MS_ALG e4, Nd5 Ncd5 */
+PUBLIC int is_move(char *mstr)
+{
+ int len = strlen(mstr);
+ if ((len > 3) && (mstr[len - 2] == '='))
+ len -= 2;
+
+ if (len == 4) { /* Test for e2e4 */
+ if (isfile(mstr[0]) && isrank(mstr[1]) &&
+ isfile(mstr[2]) && isrank(mstr[3])) {
+ return MS_COMP;
+ }
+ }
+ if (len == 5) { /* Test for e2-e4 */
+ if (isfile(mstr[0]) && isrank(mstr[1]) &&
+ (mstr[2] == '-') &&
+ isfile(mstr[3]) && isrank(mstr[4])) {
+ return MS_COMPDASH;
+ }
+ }
+ if (len == 3) { /* Test for o-o */
+ if ((mstr[0] == 'o') && (mstr[1] == '-') && (mstr[2] == 'o')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == '-') && (mstr[2] == 'O')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '-') && (mstr[2] == '0')) {
+ return MS_KCASTLE;
+ }
+ }
+ if (len == 2) { /* Test for oo */
+ if ((mstr[0] == 'o') && (mstr[1] == 'o')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == 'O')) {
+ return MS_KCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '0')) {
+ return MS_KCASTLE;
+ }
+ }
+ if (len == 5) { /* Test for o-o-o */
+ if ((mstr[0] == 'o') && (mstr[1] == '-') && (mstr[2] == 'o') && (mstr[3] == '-') && (mstr[4] == 'o')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == '-') && (mstr[2] == 'O') && (mstr[3] == '-') && (mstr[4] == 'O')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '-') && (mstr[2] == '0') && (mstr[3] == '-') && (mstr[4] == '0')) {
+ return MS_QCASTLE;
+ }
+ }
+ if (len == 3) { /* Test for ooo */
+ if ((mstr[0] == 'o') && (mstr[1] == 'o') && (mstr[2] == 'o')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == 'O') && (mstr[1] == 'O') && (mstr[2] == 'O')) {
+ return MS_QCASTLE;
+ }
+ if ((mstr[0] == '0') && (mstr[1] == '0') && (mstr[2] == '0')) {
+ return MS_QCASTLE;
+ }
+ }
+ return alg_is_move(mstr);
+}
+
+
+PUBLIC int NextPieceLoop(board_t b, int *f, int *r, int color)
+{
+ while (1) {
+ (*r) = (*r) + 1;
+ if (*r > 7) {
+ *r = 0;
+ *f = *f + 1;
+ if (*f > 7)
+ break;
+ }
+ if ((b[*f][*r] != NOPIECE) && iscolor(b[*f][*r], color))
+ return 1;
+ }
+ return 0;
+}
+
+PUBLIC int InitPieceLoop(board_t b, int *f, int *r, int color)
+{
+ *f = 0;
+ *r = -1;
+ return 1;
+}
+
+/* All of the routines assume that the obvious problems have been checked */
+/* See legal_move() */
+PRIVATE int legal_pawn_move( game_state_t *gs, int ff, int fr, int tf, int tr )
+{
+ if (ff == tf) {
+ if (gs->board[tf][tr] != NOPIECE) return 0;
+ if (gs->onMove == WHITE) {
+ if (tr - fr == 1) return 1;
+ if ((fr == 1) && (tr - fr == 2) && gs->board[ff][2]==NOPIECE) return 1;
+ } else {
+ if (fr - tr == 1) return 1;
+ if ((fr == 6) && (fr - tr == 2) && gs->board[ff][5]==NOPIECE) return 1;
+ }
+ return 0;
+ }
+ if (ff != tf) { /* Capture ? */
+ if ((ff - tf != 1) && (tf - ff != 1)) return 0;
+ if ((fr - tr != 1) && (tr - fr != 1)) return 0;
+ if (gs->onMove == WHITE) {
+ if (fr > tr) return 0;
+ if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],BLACK))
+ return 1;
+ if (gs->ep_possible[0][ff] == 1) {
+ if ((tf==ff+1) && (gs->board[ff+1][fr] == B_PAWN)) return 1;
+ } else if (gs->ep_possible[0][ff] == -1) {
+ if ((tf==ff-1) && (gs->board[ff-1][fr] == B_PAWN)) return 1;
+ }
+ } else {
+ if (tr > fr) return 0;
+ if ((gs->board[tf][tr] != NOPIECE) && iscolor(gs->board[tf][tr],WHITE))
+ return 1;
+ if (gs->ep_possible[1][ff] == 1) {
+ if ((tf==ff+1) && (gs->board[ff+1][fr] == W_PAWN)) return 1;
+ } else if (gs->ep_possible[1][ff] == -1) {
+ if ((tf==ff-1) && (gs->board[ff-1][fr] == W_PAWN)) return 1;
+ }
+ }
+ }
+ return 0;
+}
+
+PRIVATE int legal_knight_move(game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ int dx, dy;
+
+ dx = ff - tf;
+ dy = fr - tr;
+ if ((dx == 2) || (dx == -2)) {
+ if ((dy == -1) || (dy == 1))
+ return 1;
+ }
+ if ((dy == 2) || (dy == -2)) {
+ if ((dx == -1) || (dx == 1))
+ return 1;
+ }
+ return 0;
+}
+
+PRIVATE int legal_bishop_move(game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ int dx, dy, x, y;
+ int startx, starty;
+ int count;
+ int incx, incy;
+
+ if (ff > tf) {
+ dx = ff - tf;
+ incx = -1;
+ } else {
+ dx = tf - ff;
+ incx = 1;
+ }
+ startx = ff + incx;
+ if (fr > tr) {
+ dy = fr - tr;
+ incy = -1;
+ } else {
+ dy = tr - fr;
+ incy = 1;
+ }
+ starty = fr + incy;
+ if (dx != dy)
+ return 0; /* Not diagonal */
+ if (dx == 1)
+ return 1; /* One square, ok */
+ count = dx - 1;
+ for (x = startx, y = starty; count; x += incx, y += incy, count--) {
+ if (gs->board[x][y] != NOPIECE)
+ return 0;
+ }
+ return 1;
+}
+
+PRIVATE int legal_rook_move(game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ int i;
+ int start, stop;
+
+ if (ff == tf) {
+ if (((fr - tr) == 1) || ((tr - fr) == 1))
+ return 1;
+ if (fr < tr) {
+ start = fr + 1;
+ stop = tr - 1;
+ } else {
+ start = tr + 1;
+ stop = fr - 1;
+ }
+ for (i = start; i <= stop; i++) {
+ if (gs->board[ff][i] != NOPIECE)
+ return 0;
+ }
+ return 1;
+ } else if (fr == tr) {
+ if (((ff - tf) == 1) || ((tf - ff) == 1))
+ return 1;
+ if (ff < tf) {
+ start = ff + 1;
+ stop = tf - 1;
+ } else {
+ start = tf + 1;
+ stop = ff - 1;
+ }
+ for (i = start; i <= stop; i++) {
+ if (gs->board[i][fr] != NOPIECE)
+ return 0;
+ }
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+PRIVATE int legal_queen_move(game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ return legal_rook_move(gs, ff, fr, tf, tr) || legal_bishop_move(gs, ff, fr, tf, tr);
+}
+
+/* Ckeck, if square (kf,kr) is attacked by enemy piece.
+ * Used in castling from/through check testing.
+ */
+
+/* new one from soso: */
+PRIVATE int is_square_attacked (game_state_t *gs, int kf, int kr)
+{
+ game_state_t fakeMove;
+
+ fakeMove = *gs;
+ fakeMove.board[4][kr] = NOPIECE;
+ fakeMove.board[kf][kr] = KING | fakeMove.onMove;
+ fakeMove.onMove = CToggle (fakeMove.onMove);
+ if (in_check(&fakeMove)) return 1;
+ else return 0;
+}
+
+/* old one:
+PRIVATE int is_square_attacked(game_state_t * gs, int kf, int kr)
+{
+ int f, r;
+ gs->onMove = CToggle(gs->onMove);
+
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if (legal_move(gs, f, r, kf, kr)) {
+ gs->onMove = CToggle(gs->onMove);
+ return 1;
+ }
+ }
+ gs->onMove = CToggle(gs->onMove);
+ return 0;
+}
+*/
+
+PRIVATE int legal_king_move(game_state_t * gs, int ff, int fr, int tf, int tr)
+{
+ if (gs->onMove == WHITE) {
+ /* King side castling */
+ if ((fr == 0) && (tr == 0) && (ff == 4) && (tf == 6) && !gs->wkmoved
+ && (!gs->wkrmoved) && (gs->board[5][0] == NOPIECE) &&
+ (gs->board[6][0] == NOPIECE) && (gs->board[7][0] == W_ROOK) &&
+ (!is_square_attacked(gs, 4, 0)) && (!is_square_attacked(gs, 5, 0))) {
+ return 1;
+ }
+ /* Queen side castling */
+ if ((fr == 0) && (tr == 0) && (ff == 4) && (tf == 2) && !gs->wkmoved
+ && (!gs->wqrmoved) && (gs->board[3][0] == NOPIECE) &&
+ (gs->board[2][0] == NOPIECE) && (gs->board[1][0] == NOPIECE) &&
+ (gs->board[0][0] == W_ROOK) &&
+ (!is_square_attacked(gs, 4, 0)) && (!is_square_attacked(gs, 3, 0))) {
+ return 1;
+ }
+ } else { /* Black */
+ /* King side castling */
+ if ((fr == 7) && (tr == 7) && (ff == 4) && (tf == 6) && !gs->bkmoved
+ && (!gs->bkrmoved) && (gs->board[5][7] == NOPIECE) &&
+ (gs->board[6][7] == NOPIECE) && (gs->board[7][7] == B_ROOK) &&
+ (!is_square_attacked(gs, 4, 7)) && (!is_square_attacked(gs, 5, 7))) {
+ return 1;
+ }
+ /* Queen side castling */
+ if ((fr == 7) && (tr == 7) && (ff == 4) && (tf == 2) && (!gs->bkmoved)
+ && (!gs->bqrmoved) && (gs->board[3][7] == NOPIECE) &&
+ (gs->board[2][7] == NOPIECE) && (gs->board[1][7] == NOPIECE) &&
+ (gs->board[0][7] == B_ROOK) &&
+ (!is_square_attacked(gs, 4, 7)) && (!is_square_attacked(gs, 3, 7))) {
+ return 1;
+ }
+ }
+ if (((ff - tf) > 1) || ((tf - ff) > 1))
+ return 0;
+ if (((fr - tr) > 1) || ((tr - fr) > 1))
+ return 0;
+ return 1;
+}
+
+PRIVATE void add_pos(int tof, int tor, int *posf, int *posr, int *numpos)
+{
+ posf[*numpos] = tof;
+ posr[*numpos] = tor;
+ (*numpos)++;
+}
+
+PRIVATE void possible_pawn_moves(game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ if (gs->onMove == WHITE) {
+ if (gs->board[onf][onr + 1] == NOPIECE) {
+ add_pos(onf, onr + 1, posf, posr, numpos);
+ if ((onr == 1) && (gs->board[onf][onr + 2] == NOPIECE))
+ add_pos(onf, onr + 2, posf, posr, numpos);
+ }
+ if ((onf > 0) && (gs->board[onf - 1][onr + 1] != NOPIECE) &&
+ (iscolor(gs->board[onf - 1][onr + 1], BLACK)))
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+ if ((onf < 7) && (gs->board[onf + 1][onr + 1] != NOPIECE) &&
+ (iscolor(gs->board[onf + 1][onr + 1], BLACK)))
+ add_pos(onf + 1, onr + 1, posf, posr, numpos);
+ if (gs->ep_possible[0][onf] == -1)
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+ if (gs->ep_possible[0][onf] == 1)
+ add_pos(onf + 1, onr + 1, posf, posr, numpos);
+ } else {
+ if (gs->board[onf][onr - 1] == NOPIECE) {
+ add_pos(onf, onr - 1, posf, posr, numpos);
+ if ((onr == 6) && (gs->board[onf][onr - 2] == NOPIECE))
+ add_pos(onf, onr - 2, posf, posr, numpos);
+ }
+ if ((onf > 0) && (gs->board[onf - 1][onr - 1] != NOPIECE) &&
+ (iscolor(gs->board[onf - 1][onr - 1], WHITE)))
+ add_pos(onf - 1, onr - 1, posf, posr, numpos);
+/* loon: changed what looks like a typo, here's the original line:
+ add_pos(onf - 1, onr + 1, posf, posr, numpos);
+*/
+ if ((onf < 7) && (gs->board[onf + 1][onr - 1] != NOPIECE) &&
+ (iscolor(gs->board[onf + 1][onr - 1], WHITE)))
+ add_pos(onf + 1, onr - 1, posf, posr, numpos);
+ if (gs->ep_possible[1][onf] == -1)
+ add_pos(onf - 1, onr - 1, posf, posr, numpos);
+ if (gs->ep_possible[1][onf] == 1)
+ add_pos(onf + 1, onr - 1, posf, posr, numpos);
+ }
+}
+
+PRIVATE void possible_knight_moves(game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ static int knightJumps[8][2] = {{-1, 2}, {1, 2}, {2, -1}, {2, 1},
+ {-1, -2}, {1, -2}, {-2, 1}, {-2, -1}};
+ int f, r;
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ f = knightJumps[j][0] + onf;
+ r = knightJumps[j][1] + onr;
+ if ((f < 0) || (f > 7))
+ continue;
+ if ((r < 0) || (r > 7))
+ continue;
+ if ((gs->board[f][r] == NOPIECE) ||
+ (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+ add_pos(f, r, posf, posr, numpos);
+ }
+}
+
+PRIVATE void possible_bishop_moves(game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ int f, r;
+
+ /* Up Left */
+ f = onf;
+ r = onr;
+ while (1) {
+ f--;
+ r++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Up Right */
+ f = onf;
+ r = onr;
+ while (1) {
+ f++;
+ r++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Down Left */
+ f = onf;
+ r = onr;
+ while (1) {
+ f--;
+ r--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Down Right */
+ f = onf;
+ r = onr;
+ while (1) {
+ f++;
+ r--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+}
+
+PRIVATE void possible_rook_moves(game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ int f, r;
+
+ /* Left */
+ f = onf;
+ r = onr;
+ while (1) {
+ f--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Right */
+ f = onf;
+ r = onr;
+ while (1) {
+ f++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Up */
+ f = onf;
+ r = onr;
+ while (1) {
+ r++;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+ /* Down */
+ f = onf;
+ r = onr;
+ while (1) {
+ r--;
+ if ((f < 0) || (f > 7))
+ break;
+ if ((r < 0) || (r > 7))
+ break;
+ if ((gs->board[f][r] != NOPIECE) && (iscolor(gs->board[f][r], gs->onMove)))
+ break;
+ add_pos(f, r, posf, posr, numpos);
+ if (gs->board[f][r] != NOPIECE)
+ break;
+ }
+}
+
+PRIVATE void possible_queen_moves(game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ possible_rook_moves(gs, onf, onr, posf, posr, numpos);
+ possible_bishop_moves(gs, onf, onr, posf, posr, numpos);
+}
+
+PRIVATE void possible_king_moves(game_state_t * gs,
+ int onf, int onr,
+ int *posf, int *posr, int *numpos)
+{
+ static int kingJumps[8][2] = {{-1, -1}, {0, -1}, {1, -1}, {-1, 1},
+ {0, 1}, {1, 1}, {-1, 0}, {1, 0}};
+ int f, r;
+ int j;
+
+ for (j = 0; j < 8; j++) {
+ f = kingJumps[j][0] + onf;
+ r = kingJumps[j][1] + onr;
+ if ((f < 0) || (f > 7))
+ continue;
+ if ((r < 0) || (r > 7))
+ continue;
+ if ((gs->board[f][r] == NOPIECE) ||
+ (iscolor(gs->board[f][r], CToggle(gs->onMove))))
+ add_pos(f, r, posf, posr, numpos);
+ }
+}
+
+/* Doesn't check for check */
+PUBLIC int legal_move(game_state_t * gs,
+ int fFile, int fRank,
+ int tFile, int tRank)
+{
+ int move_piece;
+ int legal;
+
+ if (fFile == ALG_DROP) {
+ move_piece = fRank;
+ if (move_piece == KING)
+ return 0;
+ if (gs->holding[gs->onMove==WHITE ? 0 : 1][move_piece-1] == 0)
+ return 0;
+ if (gs->board[tFile][tRank] != NOPIECE)
+ return 0;
+ if (move_piece == PAWN && (tRank == 0 || tRank == 7))
+ return 0;
+ return 1;
+ } else {
+ move_piece = piecetype(gs->board[fFile][fRank]);
+ }
+ if (gs->board[fFile][fRank] == NOPIECE)
+ return 0;
+ if (!iscolor(gs->board[fFile][fRank], gs->onMove)) /* Wrong color */
+ return 0;
+ if ((gs->board[tFile][tRank] != NOPIECE) &&
+ iscolor(gs->board[tFile][tRank], gs->onMove)) /* Can't capture own */
+ return 0;
+ if ((fFile == tFile) && (fRank == tRank)) /* Same square */
+ return 0;
+ switch (move_piece) {
+ case PAWN:
+ legal = legal_pawn_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case KNIGHT:
+ legal = legal_knight_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case BISHOP:
+ legal = legal_bishop_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case ROOK:
+ legal = legal_rook_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case QUEEN:
+ legal = legal_queen_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ case KING:
+ legal = legal_king_move(gs, fFile, fRank, tFile, tRank);
+ break;
+ default:
+ return 0;
+ break;
+ }
+ return legal;
+}
+
+
+/* This fills in the rest of the mt structure once it is determined that
+ * the move is legal. Returns MOVE_ILLEGAL if move leaves you in check */
+PRIVATE int move_calculate(game_state_t * gs, move_t * mt, int promote)
+{
+ game_state_t fakeMove;
+
+ mt->pieceCaptured = gs->board[mt->toFile][mt->toRank];
+ mt->enPassant = 0; /* Don't know yet, let execute move take care
+ of it */
+ if (mt->fromFile == ALG_DROP) {
+ mt->piecePromotionTo = NOPIECE;
+ sprintf(mt->moveString, "%s/%c%c-%c%d",
+ wpstring[mt->fromRank],
+ DROP_CHAR, DROP_CHAR,
+ mt->toFile + 'a', mt->toRank + 1);
+ } else {
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
+ ((mt->toRank == 0) || (mt->toRank == 7))) {
+ mt->piecePromotionTo = promote |
+ (colorval(gs->board[mt->fromFile][mt->fromRank]));
+ } else {
+ mt->piecePromotionTo = NOPIECE;
+ }
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == PAWN) &&
+ ((mt->fromRank - mt->toRank == 2) || (mt->toRank - mt->fromRank == 2))) {
+ mt->doublePawn = mt->fromFile;
+ } else {
+ mt->doublePawn = -1;
+ }
+ if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+ (mt->fromFile == 4) && (mt->toFile == 2)) {
+ sprintf(mt->moveString, "o-o-o");
+ } else if ((piecetype(gs->board[mt->fromFile][mt->fromRank]) == KING) &&
+ (mt->fromFile == 4) && (mt->toFile == 6)) {
+ sprintf(mt->moveString, "o-o");
+ } else {
+ sprintf(mt->moveString, "%s/%c%d-%c%d",
+ wpstring[piecetype(gs->board[mt->fromFile][mt->fromRank])],
+ mt->fromFile + 'a', mt->fromRank + 1,
+ mt->toFile + 'a', mt->toRank + 1);
+ }
+ }
+ /* Replace this with an algabraic de-parser */
+
+ sprintf(mt->algString, alg_unparse(gs, mt));
+ fakeMove = *gs;
+ /* Calculates enPassant also */
+ execute_move(&fakeMove, mt, 0);
+
+ /* Does making this move leave ME in check? */
+ if (in_check(&fakeMove))
+ return MOVE_ILLEGAL;
+ /* IanO: bughouse variants: drop cannot be check/checkmate */
+
+ return MOVE_OK;
+}
+
+PUBLIC int legal_andcheck_move(game_state_t * gs,
+ int fFile, int fRank,
+ int tFile, int tRank)
+{
+ move_t mt;
+ if (!legal_move(gs, fFile, fRank, tFile, tRank))
+ return 0;
+ mt.color = gs->onMove;
+ mt.fromFile = fFile;
+ mt.fromRank = fRank;
+ mt.toFile = tFile;
+ mt.toRank = tRank;
+ /* This should take into account a pawn promoting to another piece */
+ if (move_calculate(gs, &mt, QUEEN) == MOVE_OK)
+ return 1;
+ else
+ return 0;
+}
+
+PUBLIC int in_check(game_state_t * gs)
+{
+ int f, r;
+ int kf = -1, kr = -1;
+
+ /* Find the king */
+ if (gs->onMove == WHITE) {
+ for (f = 0; f < 8 && kf < 0; f++)
+ for (r = 0; r < 8 && kf < 0; r++)
+ if (gs->board[f][r] == B_KING) {
+ kf = f;
+ kr = r;
+ }
+ } else {
+ for (f = 0; f < 8 && kf < 0; f++)
+ for (r = 0; r < 8 && kf < 0; r++)
+ if (gs->board[f][r] == W_KING) {
+ kf = f;
+ kr = r;
+ }
+ }
+ if (kf < 0) {
+ fprintf(stderr, "FICS: Error game with no king!\n");
+ return 0;
+ }
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ if (legal_move(gs, f, r, kf, kr)) { /* In Check? */
+ return 1;
+ }
+ }
+ return 0;
+}
+
+PRIVATE int has_legal_move(game_state_t * gs)
+{
+ int i;
+ int f, r;
+ int kf,kr;
+ int possiblef[500], possibler[500];
+ int numpossible = 0;
+
+ for (InitPieceLoop(gs->board, &f, &r, gs->onMove);
+ NextPieceLoop(gs->board, &f, &r, gs->onMove);) {
+ switch (piecetype(gs->board[f][r])) {
+ case PAWN:
+ possible_pawn_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case KNIGHT:
+ possible_knight_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case BISHOP:
+ possible_bishop_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case ROOK:
+ possible_rook_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case QUEEN:
+ possible_queen_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ case KING:
+ kf = f;
+ kr = r;
+ possible_king_moves(gs, f, r, possiblef, possibler, &numpossible);
+ break;
+ }
+ if (numpossible >= 500) {
+ fprintf(stderr, "FICS: Possible move overrun\n");
+ }
+ for (i = 0; i < numpossible; i++)
+ if (legal_andcheck_move(gs, f, r, possiblef[i], possibler[i])) {
+ return 1;
+ }
+ }
+
+ /* IanO: if we got here, then kf and kr must be set */
+ if (gs->gameNum >=0 && garray[gs->gameNum].link >= 0) {
+ /* bughouse: potential drops as check interpositions */
+ gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]++;
+ for (f=kf-1; f<=kf+1; f++) for (r=kr-1; r<=kr+1; r++) {
+ if (f>=0 && f<8 && r>=0 && r<8 && gs->board[f][r] == NOPIECE) {
+ /* try a drop next to the king */
+ if (legal_andcheck_move(gs, ALG_DROP, QUEEN, f, r)) {
+ gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;
+ return 1;
+ }
+ }
+ }
+ gs->holding[gs->onMove==WHITE ? 0 : 1][QUEEN - 1]--;
+ }
+
+/* don't think this works right... 9.30.95
+ printf("NO LEGAL MOVE!\n");
+*/
+ fprintf(stderr, "FICS: NO LEGAL MOVE!\n");
+ return 0;
+}
+
+/* This will end up being a very complicated function */
+PUBLIC int parse_move(char *mstr, game_state_t * gs, move_t * mt, int promote)
+{
+ int type = is_move(mstr);
+ int result;
+
+ mt->color = gs->onMove;
+ switch (type) {
+ case MS_NOTMOVE:
+ return MOVE_ILLEGAL;
+ break;
+ case MS_COMP:
+ mt->fromFile = mstr[0] - 'a';
+ mt->fromRank = mstr[1] - '1';
+ mt->toFile = mstr[2] - 'a';
+ mt->toRank = mstr[3] - '1';
+ break;
+ case MS_COMPDASH:
+ mt->fromFile = mstr[0] - 'a';
+ mt->fromRank = mstr[1] - '1';
+ mt->toFile = mstr[3] - 'a';
+ mt->toRank = mstr[4] - '1';
+ break;
+ case MS_KCASTLE:
+ mt->fromFile = 4;
+ mt->toFile = 6;
+ if (gs->onMove == WHITE) {
+ mt->fromRank = 0;
+ mt->toRank = 0;
+ } else {
+ mt->fromRank = 7;
+ mt->toRank = 7;
+ }
+ break;
+ case MS_QCASTLE:
+ mt->fromFile = 4;
+ mt->toFile = 2;
+ if (gs->onMove == WHITE) {
+ mt->fromRank = 0;
+ mt->toRank = 0;
+ } else {
+ mt->fromRank = 7;
+ mt->toRank = 7;
+ }
+ break;
+ case MS_ALG:
+ /* Fills in the mt structure */
+ if ((result = alg_parse_move(mstr, gs, mt)) != MOVE_OK)
+ return result;
+ break;
+ default:
+ return MOVE_ILLEGAL;
+ break;
+ }
+ if (!legal_move(gs, mt->fromFile, mt->fromRank, mt->toFile, mt->toRank)) {
+ return MOVE_ILLEGAL;
+ }
+ return move_calculate(gs, mt, promote);
+}
+
+/* Returns MOVE_OK, MOVE_NOMATERIAL, MOVE_CHECKMATE, or MOVE_STALEMATE */
+/* check_game_status prevents recursion */
+PUBLIC int execute_move(game_state_t * gs, move_t * mt, int check_game_status)
+{
+ int movedPiece;
+ int tookPiece;
+ int i, j, foobar;
+
+ if (mt->fromFile == ALG_DROP) {
+ movedPiece = mt->fromRank;
+ tookPiece = NOPIECE;
+ gs->holding[gs->onMove==WHITE ? 0 : 1][movedPiece-1]--;
+ gs->board[mt->toFile][mt->toRank] = movedPiece | gs->onMove;
+ if (gs->gameNum >= 0)
+ gs->lastIrreversable = garray[gs->gameNum].numHalfMoves;
+ } else {
+ movedPiece = gs->board[mt->fromFile][mt->fromRank];
+ tookPiece = gs->board[mt->toFile][mt->toRank];
+ if (mt->piecePromotionTo == NOPIECE) {
+ gs->board[mt->toFile][mt->toRank] = gs->board[mt->fromFile][mt->fromRank];
+ } else {
+ gs->board[mt->toFile][mt->toRank] = mt->piecePromotionTo | gs->onMove;
+ }
+ gs->board[mt->fromFile][mt->fromRank] = NOPIECE;
+ /* Check if irreversable */
+ if ((piecetype(movedPiece) == PAWN) || (tookPiece != NOPIECE)) {
+ if (gs->gameNum >= 0)
+ gs->lastIrreversable = garray[gs->gameNum].numHalfMoves;
+ }
+ /* Check if this move is en-passant */
+ if ((piecetype(movedPiece) == PAWN) && (mt->fromFile != mt->toFile) &&
+ (tookPiece == NOPIECE)) {
+ if (gs->onMove == WHITE) {
+ mt->pieceCaptured = B_PAWN;
+ } else {
+ mt->pieceCaptured = W_PAWN;
+ }
+ if (mt->fromFile > mt->toFile) {
+ mt->enPassant = -1;
+ } else {
+ mt->enPassant = 1;
+ }
+ gs->board[mt->toFile][mt->fromRank] = NOPIECE;
+ }
+ /* Check en-passant flags for next moves */
+ for (i = 0; i < 8; i++) {
+ gs->ep_possible[0][i] = 0;
+ gs->ep_possible[1][i] = 0;
+ }
+/* Added by Sparky 3/16/95
+
+ From soso@Viktoria.drp.fmph.uniba.sk Thu Mar 16 13:08:51 1995
+ Subject: Re: To DAV: enpassant prob. again
+ To: chess@caissa.onenet.net (ICS)
+ Date: Thu, 16 Mar 1995 20:06:20 +0100 (MET)
+
+ Yeah !
+ There was bug in other part of code:
+
+ movecheck.c , line about 800:
+
+ if (gs->onMove == WHITE) {
+ if ((mt->toFile+1 < 7 ) .... should be : (mt->toFile < 7 ) }
+*/
+
+ if ((piecetype(movedPiece) == PAWN) &&
+ ((mt->fromRank == mt->toRank + 2) || (mt->fromRank + 2 == mt->toRank))) {
+ /* Should turn on enpassent flag if possible */
+ if (gs->onMove == WHITE) {
+ if ((mt->toFile < 7) && gs->board[mt->toFile + 1][3] == B_PAWN) {
+ gs->ep_possible[1][mt->toFile + 1] = -1;
+ }
+ if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][3] == B_PAWN) {
+ gs->ep_possible[1][mt->toFile - 1] = 1;
+ }
+ } else {
+ if ((mt->toFile < 7) && gs->board[mt->toFile + 1][4] == W_PAWN) {
+ gs->ep_possible[0][mt->toFile + 1] = -1;
+ }
+ if ((mt->toFile - 1 >= 0) && gs->board[mt->toFile - 1][4] == W_PAWN) {
+ gs->ep_possible[0][mt->toFile - 1] = 1;
+ }
+ }
+ }
+ if ((piecetype(movedPiece) == ROOK) && (mt->fromFile == 0)) {
+ if ((mt->fromRank == 0) && (gs->onMove == WHITE))
+ gs->wqrmoved = 1;
+ if ((mt->fromRank == 7) && (gs->onMove == BLACK))
+ gs->bqrmoved = 1;
+ }
+ if ((piecetype(movedPiece) == ROOK) && (mt->fromFile == 7)) {
+ if ((mt->fromRank == 0) && (gs->onMove == WHITE))
+ gs->wkrmoved = 1;
+ if ((mt->fromRank == 7) && (gs->onMove == BLACK))
+ gs->bkrmoved = 1;
+ }
+ if (piecetype(movedPiece) == KING) {
+ if (gs->onMove == WHITE)
+ gs->wkmoved = 1;
+ else
+ gs->bkmoved = 1;
+ }
+ if ((piecetype(movedPiece) == KING) &&
+ ((mt->fromFile == 4) && ((mt->toFile == 6)))) { /* Check for KS castling */
+ gs->board[5][mt->toRank] = gs->board[7][mt->toRank];
+ gs->board[7][mt->toRank] = NOPIECE;
+ }
+ if ((piecetype(movedPiece) == KING) &&
+ ((mt->fromFile == 4) && ((mt->toFile == 2)))) { /* Check for QS castling */
+ gs->board[3][mt->toRank] = gs->board[0][mt->toRank];
+ gs->board[0][mt->toRank] = NOPIECE;
+ }
+ }
+ if (gs->onMove == BLACK)
+ gs->moveNum++;
+
+ if (check_game_status) {
+ /* Does this move result in check? */
+ if (in_check(gs)) {
+ /* Check for checkmate */
+ gs->onMove = CToggle(gs->onMove);
+ if (!has_legal_move(gs))
+ return MOVE_CHECKMATE;
+ } else {
+ /* Check for stalemate */
+ gs->onMove = CToggle(gs->onMove);
+ if (!has_legal_move(gs))
+ return MOVE_STALEMATE;
+/* loon: check for insufficient mating material, first try */
+ foobar = 0;
+ for (i=0; i<8; i++) {
+ for (j=0; j<8; j++) {
+ switch(piecetype(gs->board[i][j])) {
+ case KNIGHT:
+ case BISHOP:
+ foobar++;
+ break;
+ case KING:
+ case NOPIECE:
+ break;
+ default:
+ foobar = 2;
+ break;
+ }
+ }
+ }
+ if (foobar < 2)
+ return MOVE_NOMATERIAL;
+ }
+ } else {
+ gs->onMove = CToggle(gs->onMove);
+ }
+ return MOVE_OK;
+}
+
+PUBLIC int backup_move(int g, int mode)
+{
+ game_state_t *gs;
+ move_t *m, *m1;
+ int now, i;
+
+ if (garray[g].link >= 0) /*IanO: not implemented for bughouse yet */
+ return MOVE_ILLEGAL;
+ if (garray[g].numHalfMoves < 1)
+ return MOVE_ILLEGAL;
+ gs = &garray[g].game_state;
+ m = (mode==REL_GAME) ? &garray[g].moveList[garray[g].numHalfMoves - 1] :
+ &garray[g].examMoveList[garray[g].numHalfMoves - 1];
+ if (m->toFile < 0) {
+ return MOVE_ILLEGAL;
+ }
+ gs->board[m->fromFile][m->fromRank] = gs->board[m->toFile][m->toRank];
+ if (m->piecePromotionTo != NOPIECE) {
+ gs->board[m->fromFile][m->fromRank] = PAWN |
+ colorval(gs->board[m->fromFile][m->fromRank]);
+ }
+ /******************
+ When takeback a _first_ move of rook, the ??rmoved variable
+ must be cleared . To check, if the move is first, we should
+ scan moveList.
+ *******************/
+ if (piecetype(gs->board[m->fromFile][m->fromRank]) == ROOK) {
+ if (m->color == WHITE) {
+ if ((m->fromFile == 0) && (m->fromRank == 0)) {
+ for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+ if ((m1->fromFile == 0) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == garray[g].numHalfMoves - 1)
+ gs->wqrmoved = 0;
+ }
+ if ((m->fromFile == 7) && (m->fromRank == 0)) {
+ for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+ if ((m1->fromFile == 7) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == garray[g].numHalfMoves - 1)
+ gs->wkrmoved = 0;
+ }
+ } else {
+ if ((m->fromFile == 0) && (m->fromRank == 7)) {
+ for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+ if ((m1->fromFile == 0) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == garray[g].numHalfMoves - 1)
+ gs->bqrmoved = 0;
+ }
+ if ((m->fromFile == 7) && (m->fromRank == 7)) {
+ for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+ if ((m1->fromFile == 7) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == garray[g].numHalfMoves - 1)
+ gs->bkrmoved = 0;
+ }
+ }
+ }
+ if (piecetype(gs->board[m->fromFile][m->fromRank]) == KING) {
+ gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+
+ if (m->toFile - m->fromFile == 2) {
+ gs->board[7][m->fromRank] = ROOK |
+ colorval(gs->board[m->fromFile][m->fromRank]);
+ gs->board[5][m->fromRank] = NOPIECE;
+
+ /********
+ If takeback a castling, the appropriates ??moved variables
+ must be cleared
+ ********/
+ if (m->color == WHITE) {
+ gs->wkmoved = 0;
+ gs->wkrmoved = 0;
+ } else {
+ gs->bkmoved = 0;
+ gs->bkrmoved = 0;
+ }
+ goto cleanupMove;
+ }
+ if (m->fromFile - m->toFile == 2) {
+ gs->board[0][m->fromRank] = ROOK |
+ colorval(gs->board[m->fromFile][m->fromRank]);
+ gs->board[3][m->fromRank] = NOPIECE;
+
+ /**********
+ If takeback a castling, the appropriate ??moved variables
+ must be cleared
+ ***********/
+ if (m->color == WHITE) {
+ gs->wkmoved = 0;
+ gs->wqrmoved = 0;
+ } else {
+ gs->bkmoved = 0;
+ gs->bqrmoved = 0;
+ }
+ goto cleanupMove;
+ }
+ /******************
+ When takeback a _first_ move of king (not the castling),
+ the ?kmoved variable must be cleared . To check, if the move is first,
+ we should scan moveList.
+ *******************/
+
+ if (m->color == WHITE) {
+
+ if ((m->fromFile == 4) && (m->fromRank == 0)) {
+ for (i = 2; i < garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+ if ((m1->fromFile == 4) && (m1->fromRank == 0))
+ break;
+ }
+ if (i == garray[g].numHalfMoves - 1)
+ gs->wkmoved = 0;
+ }
+ } else {
+ if ((m->fromFile == 4) && (m->fromRank == 7)) {
+ for (i = 3; i < garray[g].numHalfMoves - 1; i += 2) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[i] : &garray[g].examMoveList[i];
+ if ((m1->fromFile == 4) && (m1->fromRank == 7))
+ break;
+ }
+ if (i == garray[g].numHalfMoves - 1)
+ gs->bkmoved = 0;
+ }
+ }
+ }
+ if (m->enPassant) { /* Do enPassant */
+ gs->board[m->toFile][m->fromRank] = PAWN |
+ (colorval(gs->board[m->fromFile][m->fromRank]) == WHITE ? BLACK : WHITE);
+ gs->board[m->toFile][m->toRank] = NOPIECE;
+ /* Should set the enpassant array, but I don't care right now */
+ goto cleanupMove;
+ }
+ gs->board[m->toFile][m->toRank] = m->pieceCaptured;
+cleanupMove:
+ if (garray[g].status != GAME_EXAMINE) {
+ game_update_time(g);
+ }
+ garray[g].numHalfMoves--;
+ if (garray[g].status != GAME_EXAMINE) {
+ if (garray[g].wInitTime) { /* Don't update times in untimed games */
+ now = tenth_secs();
+
+#ifdef TIMESEAL
+
+ if (m->color == WHITE) {
+ if (con[parray[garray[g].white].socket].timeseal) { /* white uses timeseal? */
+ garray[g].wRealTime += (m->tookTime * 100);
+ garray[g].wRealTime -= (garray[g].wIncrement * 100);
+ garray[g].wTime = garray[g].wRealTime / 100;
+ if (con[parray[garray[g].black].socket].timeseal) { /* opp uses timeseal? */
+ garray[g].bTime = garray[g].bRealTime / 100;
+ } else { /* opp has no timeseal */
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ } else { /* white has no timeseal */
+ garray[g].wTime += m->tookTime;
+ garray[g].wTime -= garray[g].wIncrement;
+ if (con[parray[garray[g].black].socket].timeseal) { /* opp uses timeseal? */
+ garray[g].bTime = garray[g].bRealTime / 100;
+ } else { /* opp has no timeseal */
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ }
+ } else {
+ if (con[parray[garray[g].black].socket].timeseal) { /* black uses timeseal? */
+ garray[g].bRealTime += (m->tookTime * 100);
+ garray[g].bRealTime -= (garray[g].wIncrement * 100);
+ garray[g].bTime = garray[g].bRealTime / 100;
+ if (con[parray[garray[g].white].socket].timeseal) { /* opp uses timeseal? */
+ garray[g].wTime = garray[g].wRealTime / 100;
+ } else { /* opp has no timeseal */
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ } else { /* black has no timeseal */
+ garray[g].bTime += m->tookTime;
+ if (!garray[g].bIncrement)
+ garray[g].bTime -= garray[g].wIncrement;
+ else
+ garray[g].bTime -= garray[g].bIncrement;
+ if (con[parray[garray[g].white].socket].timeseal) { /* opp uses timeseal? */
+ garray[g].wTime = garray[g].wRealTime / 100;
+ } else { /* opp has no timeseal */
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ }
+ }
+
+#else
+
+ if (m->color == WHITE) {
+ garray[g].wTime += m->tookTime;
+ garray[g].wTime = garray[g].wTime - garray[g].wIncrement;
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += m->tookTime;
+ if (!garray[g].bIncrement)
+ garray[g].bTime = garray[g].bTime - garray[g].wIncrement;
+ else
+ garray[g].bTime = garray[g].bTime - garray[g].bIncrement;
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+
+#endif
+
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ }
+ }
+ if (gs->onMove == BLACK)
+ gs->onMove = WHITE;
+ else {
+ gs->onMove = BLACK;
+ gs->moveNum--;
+ }
+
+ /******* Here begins the patch : ********************************
+ Takeback of last move is done already, it's time to update enpassant
+ array. (patch from Soso, added by Sparky 3/17/95)
+ ********/
+
+ if (garray[g].numHalfMoves > 0) {
+ m1 = (mode==REL_GAME) ? &garray[g].moveList[garray[g].numHalfMoves - 1] :
+ &garray[g].examMoveList[garray[g].numHalfMoves - 1];
+ if (piecetype(gs->board[m1->toFile][m1->toRank]) == PAWN) {
+ if ((m1->toRank - m1->fromRank) == 2) {
+ if ((m1->toFile < 7) && gs->board[m1->toFile + 1][3] == B_PAWN) {
+ gs->ep_possible[1][m1->toFile + 1] = -1;
+ }
+ if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][3] == B_PAWN) {
+ gs->ep_possible[1][m1->toFile - 1] = 1;
+ }
+ }
+ if ((m1->toRank - m1->fromRank) == -2) {
+ if ((m1->toFile < 7) && gs->board[m1->toFile + 1][4] == W_PAWN) {
+ gs->ep_possible[0][m1->toFile + 1] = -1;
+ }
+ if ((m1->toFile - 1 >= 0) && gs->board[m1->toFile - 1][4] == W_PAWN) {
+ gs->ep_possible[0][m1->toFile - 1] = 1;
+ }
+ }
+ }
+ }
+ /************** and here's the end **************/
+ return MOVE_OK;
+}
+
+
+
+
blob - /dev/null
blob + 53a1712c6a4e197fb8dc52b6b529328c0c806ae3 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/movecheck.h
+/* movecheck.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _MOVECHECK_H
+#define _MOVECHECK_H
+
+#define MOVE_OK 0
+#define MOVE_ILLEGAL 1
+#define MOVE_STALEMATE 2
+#define MOVE_CHECKMATE 3
+#define MOVE_AMBIGUOUS 4
+#define MOVE_NOMATERIAL 5
+
+#define MS_NOTMOVE 0
+#define MS_COMP 1
+#define MS_COMPDASH 2
+#define MS_ALG 3
+#define MS_KCASTLE 4
+#define MS_QCASTLE 5
+
+#define isrank(c) (((c) <= '8') && ((c) >= '1'))
+#define isfile(c) (((c) >= 'a') && ((c) <= 'h'))
+
+#if !defined(_BOARD_H)
+#include "board.h"
+#endif
+
+extern int is_move(char *);
+extern int parse_move(char *, game_state_t *, move_t *, int);
+extern int execute_move(game_state_t *, move_t *, int);
+extern int backup_move(int, int);
+
+/* Some useful chess utilities */
+extern int NextPieceLoop(board_t, int *, int *, int);
+extern int InitPieceLoop(board_t, int *, int *, int);
+extern int legal_move(game_state_t *, int, int, int, int);
+extern int legal_andcheck_move(game_state_t *, int, int, int, int);
+extern int in_check(game_state_t *);
+
+#endif /* _MOVECHECK_H */
blob - /dev/null
blob + fc496005a895e42c872983d7bac99c391391b8e7 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/movecheck.o differ
blob - /dev/null
blob + 8d52b04edf44f4b4ef08d504ce5554f470fe6234 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/multicol.c
+/* multicol.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "multicol.h"
+#include "utils.h"
+#include "rmalloc.h"
+
+/* grimm */
+#if defined(SGI)
+#else
+/* char *strchr( char *s, int c); */
+#endif
+/* added for warning */
+
+PUBLIC multicol *multicol_start(int maxArray)
+{
+ int i;
+ multicol *m;
+
+ m = (multicol *) rmalloc(sizeof(multicol));
+ m->arraySize = maxArray;
+ m->num = 0;
+ m->strArray = (char **) rmalloc(sizeof(char *) * m->arraySize);
+ for (i = 0; i < m->arraySize; i++)
+ m->strArray[i] = NULL;
+ return m;
+}
+
+PUBLIC int multicol_store(multicol * m, char *str)
+{
+ if (m->num >= m->arraySize)
+ return -1;
+ if (!str)
+ return -1;
+ m->strArray[m->num] = strdup(str);
+ m->num++;
+ return 0;
+}
+
+PUBLIC int multicol_store_sorted(multicol * m, char *str)
+/* use this instead of milticol_store to print a list sorted */
+{
+ int i;
+ int found = 0;
+ if (m->num >= m->arraySize)
+ return -1;
+ if (!str)
+ return -1;
+ for (i = m->num; (i > 0) && (!found); i--) {
+ if (strcasecmp(str, m->strArray[i - 1]) >= 0) {
+ found = 1;
+ m->strArray[i] = strdup(str);
+ } else {
+ m->strArray[i] = m->strArray[i - 1];
+ }
+ }
+ if (!found)
+ m->strArray[0] = strdup(str);
+ m->num++;
+ return 0;
+}
+
+PUBLIC int multicol_pprint(multicol * m, int player, int cols, int space)
+{
+ int i;
+ int maxWidth = 0;
+ int numPerLine;
+ int numLines;
+ int on, theone, len;
+ int done;
+ int temp;
+ char *tempptr;
+
+ pprintf(player, "\n");
+ for (i = 0; i < m->num; i++) {
+ tempptr = m->strArray[i];
+ temp = strlen(tempptr); /* loon: yes, this is pathetic */
+ for (; *tempptr; tempptr++) {
+ if (*tempptr == '\033')
+ temp -= 4;
+ }
+ if (temp > maxWidth)
+ maxWidth = temp;
+ }
+ maxWidth += space;
+ numPerLine = cols / maxWidth;
+ numLines = m->num / numPerLine;
+ if (numLines * numPerLine < m->num)
+ numLines++;
+ on = 0;
+ done = 0;
+ while (!done) {
+ for (i = 0; i < numPerLine; i++) {
+ theone = on + numLines * i;
+ if (theone >= m->num) {
+ break;
+ }
+ tempptr = m->strArray[theone];
+ temp = strlen(tempptr); /* loon: yes, still pathetic */
+ for (; *tempptr; tempptr++) {
+ if (*tempptr == '\033')
+ temp -= 4;
+ }
+ len = maxWidth - temp;
+ if (i == numPerLine - 1)
+ len -= space;
+ pprintf(player, "%s", m->strArray[theone]);
+ while (len) {
+ pprintf(player, " ");
+ len--;
+ }
+ }
+ pprintf(player, "\n");
+ on += 1;
+ if (on >= numLines)
+ break;
+ }
+ return 0;
+}
+
+PUBLIC int multicol_end(multicol * m)
+{
+ int i;
+ for (i = 0; i < m->num; i++)
+ rfree(m->strArray[i]);
+ rfree(m->strArray);
+ rfree(m);
+ return 0;
+}
blob - /dev/null
blob + 8d52b04edf44f4b4ef08d504ce5554f470fe6234 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/multicol.c.orig
+/* multicol.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "multicol.h"
+#include "utils.h"
+#include "rmalloc.h"
+
+/* grimm */
+#if defined(SGI)
+#else
+/* char *strchr( char *s, int c); */
+#endif
+/* added for warning */
+
+PUBLIC multicol *multicol_start(int maxArray)
+{
+ int i;
+ multicol *m;
+
+ m = (multicol *) rmalloc(sizeof(multicol));
+ m->arraySize = maxArray;
+ m->num = 0;
+ m->strArray = (char **) rmalloc(sizeof(char *) * m->arraySize);
+ for (i = 0; i < m->arraySize; i++)
+ m->strArray[i] = NULL;
+ return m;
+}
+
+PUBLIC int multicol_store(multicol * m, char *str)
+{
+ if (m->num >= m->arraySize)
+ return -1;
+ if (!str)
+ return -1;
+ m->strArray[m->num] = strdup(str);
+ m->num++;
+ return 0;
+}
+
+PUBLIC int multicol_store_sorted(multicol * m, char *str)
+/* use this instead of milticol_store to print a list sorted */
+{
+ int i;
+ int found = 0;
+ if (m->num >= m->arraySize)
+ return -1;
+ if (!str)
+ return -1;
+ for (i = m->num; (i > 0) && (!found); i--) {
+ if (strcasecmp(str, m->strArray[i - 1]) >= 0) {
+ found = 1;
+ m->strArray[i] = strdup(str);
+ } else {
+ m->strArray[i] = m->strArray[i - 1];
+ }
+ }
+ if (!found)
+ m->strArray[0] = strdup(str);
+ m->num++;
+ return 0;
+}
+
+PUBLIC int multicol_pprint(multicol * m, int player, int cols, int space)
+{
+ int i;
+ int maxWidth = 0;
+ int numPerLine;
+ int numLines;
+ int on, theone, len;
+ int done;
+ int temp;
+ char *tempptr;
+
+ pprintf(player, "\n");
+ for (i = 0; i < m->num; i++) {
+ tempptr = m->strArray[i];
+ temp = strlen(tempptr); /* loon: yes, this is pathetic */
+ for (; *tempptr; tempptr++) {
+ if (*tempptr == '\033')
+ temp -= 4;
+ }
+ if (temp > maxWidth)
+ maxWidth = temp;
+ }
+ maxWidth += space;
+ numPerLine = cols / maxWidth;
+ numLines = m->num / numPerLine;
+ if (numLines * numPerLine < m->num)
+ numLines++;
+ on = 0;
+ done = 0;
+ while (!done) {
+ for (i = 0; i < numPerLine; i++) {
+ theone = on + numLines * i;
+ if (theone >= m->num) {
+ break;
+ }
+ tempptr = m->strArray[theone];
+ temp = strlen(tempptr); /* loon: yes, still pathetic */
+ for (; *tempptr; tempptr++) {
+ if (*tempptr == '\033')
+ temp -= 4;
+ }
+ len = maxWidth - temp;
+ if (i == numPerLine - 1)
+ len -= space;
+ pprintf(player, "%s", m->strArray[theone]);
+ while (len) {
+ pprintf(player, " ");
+ len--;
+ }
+ }
+ pprintf(player, "\n");
+ on += 1;
+ if (on >= numLines)
+ break;
+ }
+ return 0;
+}
+
+PUBLIC int multicol_end(multicol * m)
+{
+ int i;
+ for (i = 0; i < m->num; i++)
+ rfree(m->strArray[i]);
+ rfree(m->strArray);
+ rfree(m);
+ return 0;
+}
blob - /dev/null
blob + 5acb8504d42c01bcd4f067cc05631571a1ee85e6 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/multicol.h
+/* multicol.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _MULTICOL_H
+#define _MULTICOL_H
+
+typedef struct _multicol
+{
+ int arraySize;
+ int num;
+ char **strArray;
+} multicol;
+
+extern multicol *multicol_start(int);
+extern int multicol_store(multicol *, char *);
+extern int multicol_store_sorted(multicol *, char *);
+extern int multicol_pprint(multicol *, int, int, int);
+extern int multicol_end(multicol *);
+
+#endif /* _MULTICOL_H */
blob - /dev/null
blob + 7faeeb5465a7b1c01e95b2d14d0fd0731980e78c (mode 644)
Binary files /dev/null and FICS.DIST/FICS/multicol.o differ
blob - /dev/null
blob + d79164cac0e6c5f13c544190e6b8b6277f7425ff (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/network.c
+/* network.c
+ *
+ */
+
+#include "stdinclude.h"
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/telnet.h>
+
+#include "ficsmain.h"
+#include "common.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "config.h"
+#ifdef TIMESEAL
+#include "timeseal.h"
+#endif
+
+#include <errno.h>
+
+extern int errno;
+
+PRIVATE int sockfd = 0; /* The socket */
+PRIVATE int numConnections = 0;
+/* Sparse array */
+PUBLIC connection con[512];
+
+PUBLIC int no_file;
+PUBLIC int max_connections;
+
+/* Index == fd, for sparse array, quick lookups! wasted memory :( */
+PUBLIC int findConnection(int fd)
+{
+ if (con[fd].status == NETSTAT_EMPTY)
+ return -1;
+ else
+ return fd;
+}
+
+PUBLIC int net_addConnection(int fd, unsigned int fromHost)
+{
+ int noblock = 1;
+
+ if (findConnection(fd) >= 0) {
+ fprintf(stderr, "FICS: FD already in connection table!\n");
+ return -1;
+ }
+ if (numConnections >= max_connections)
+ return -1;
+ if (ioctl(fd, FIONBIO, &noblock) == -1) {
+ fprintf(stderr, "Error setting nonblocking mode errno=%d\n", errno);
+ }
+ con[fd].fd = fd;
+ if (fd != 0)
+ con[fd].outFd = fd;
+ else
+ con[fd].outFd = 1;
+ con[fd].fromHost = fromHost;
+ con[fd].status = NETSTAT_CONNECTED;
+#ifdef TIMESEAL
+ con[fd].user[0]='\0';
+ con[fd].sys[0]='\0';
+ con[fd].timeseal = 0;
+ con[fd].time = 0;
+#endif
+ con[fd].numPending = 0;
+ con[fd].processed = 0;
+ con[fd].outPos = 0;
+ if (con[fd].sndbuf == NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "FICS: nac(%d) allocating sndbuf.\n", fd);
+#endif
+ con[fd].sndbufpos = 0;
+ con[fd].sndbufsize = MAX_STRING_LENGTH;
+ con[fd].sndbuf = rmalloc(MAX_STRING_LENGTH);
+ } else {
+#ifdef DEBUG
+ fprintf(stderr, "FICS: nac(%d) reusing old sndbuf size %d pos %d.\n", fd, con[fd].sndbufsize, con[fd].sndbufpos);
+#endif
+ }
+ con[fd].state = 0;
+ numConnections++;
+
+#ifdef DEBUG
+ fprintf(stderr, "FICS: fd: %d connections: %d descriptors: %d \n", fd, numConnections, getdtablesize()); /* sparky 3/13/95 */
+#endif
+
+ return 0;
+}
+
+PRIVATE int remConnection(int fd)
+{
+ int which;
+ if ((which = findConnection(fd)) < 0) {
+ return -1;
+ }
+ numConnections--;
+ con[fd].status = NETSTAT_EMPTY;
+ if (con[fd].sndbuf == NULL) {
+ fprintf(stderr, "FICS: remcon(%d) SNAFU, this shouldn't happen.\n", fd);
+ } else {
+ if (con[fd].sndbufsize > MAX_STRING_LENGTH) {
+ con[fd].sndbufsize = MAX_STRING_LENGTH;
+ con[fd].sndbuf = rrealloc(con[fd].sndbuf, MAX_STRING_LENGTH);
+ }
+ if (con[fd].sndbufpos) { /* didn't send everything, bummer */
+ con[fd].sndbufpos = 0;
+ }
+ }
+ return 0;
+}
+
+PRIVATE void net_flushme(int which)
+{
+ int sent;
+
+ sent = send(con[which].outFd, con[which].sndbuf, con[which].sndbufpos, 0);
+ if (sent == -1) {
+ if (errno != EPIPE) /* EPIPE = they've disconnected */
+ fprintf(stderr, "FICS: net_flushme(%d) couldn't send, errno=%d.\n", which, errno);
+ con[which].sndbufpos = 0;
+ } else {
+ con[which].sndbufpos -= sent;
+ if (con[which].sndbufpos)
+ memmove(con[which].sndbuf, con[which].sndbuf + sent, con[which].sndbufpos);
+ }
+ if (con[which].sndbufsize > MAX_STRING_LENGTH && con[which].sndbufpos < MAX_STRING_LENGTH) {
+ /* time to shrink the buffer */
+ con[which].sndbuf = rrealloc(con[which].sndbuf, MAX_STRING_LENGTH);
+ con[which].sndbufsize = MAX_STRING_LENGTH;
+ }
+}
+
+PRIVATE void net_flush_all_connections(void)
+{
+ int which;
+ fd_set writefds;
+ struct timeval to;
+
+ FD_ZERO(&writefds);
+ for (which = 0; which < MAX_PLAYER; which++)
+ if (con[which].status == NETSTAT_CONNECTED && con[which].sndbufpos)
+ FD_SET(con[which].outFd, &writefds);
+
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(no_file, NULL, &writefds, NULL, &to);
+ for (which = 0; which < MAX_PLAYER; which++) {
+ if (FD_ISSET(con[which].outFd, &writefds)) {
+ net_flushme(which);
+ }
+ }
+}
+
+PRIVATE void net_flush_connection(int fd)
+{
+ int which;
+ fd_set writefds;
+ struct timeval to;
+
+ if (((which = findConnection(fd)) >= 0) && (con[which].sndbufpos)) {
+ FD_ZERO(&writefds);
+ FD_SET(con[which].outFd, &writefds);
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(no_file, NULL, &writefds, NULL, &to);
+ if (FD_ISSET(con[which].outFd, &writefds)) {
+ net_flushme(which);
+ }
+ }
+ return;
+}
+
+PRIVATE int sendme(int which, char *str, int len)
+{
+ int i, count;
+ fd_set writefds;
+ struct timeval to;
+ count = len;
+
+ while ((i = ((con[which].sndbufsize - con[which].sndbufpos) < len) ? (con[which].sndbufsize - con[which].sndbufpos) : len) > 0) {
+ memmove(con[which].sndbuf + con[which].sndbufpos, str, i);
+ con[which].sndbufpos += i;
+ if (con[which].sndbufpos == con[which].sndbufsize) {
+
+ FD_ZERO(&writefds);
+ FD_SET(con[which].outFd, &writefds);
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(no_file, NULL, &writefds, NULL, &to);
+ if (FD_ISSET(con[which].outFd, &writefds)) {
+ net_flushme(which);
+ } else {
+ /* time to grow the buffer */
+ con[which].sndbufsize += MAX_STRING_LENGTH;
+ con[which].sndbuf = rrealloc(con[which].sndbuf, con[which].sndbufsize);
+ }
+ }
+ str += i;
+ len -= i;
+ }
+ return count;
+}
+
+/*
+ * -1 for an error other than EWOULDBLOCK.
+ * Put <lf> after every <cr> and put \ at the end of overlength lines.
+ * Doesn't send anything unless the buffer fills, output waits until
+ * flushed
+*/
+PUBLIC int net_send_string(int fd, char *str, int format)
+{
+ int which, i, j;
+
+ if ((which = findConnection(fd)) < 0) {
+ return -1;
+ }
+ while (*str) {
+ for (i = 0; str[i] >= ' '; i++);
+ if (i) {
+ if (format && (i >= (j = LINE_WIDTH - con[which].outPos))) { /* word wrap */
+ i = j;
+ while (i > 0 && str[i - 1] != ' ')
+ i--;
+ while (i > 0 && str[i - 1] == ' ')
+ i--;
+ if (i == 0)
+ i = j - 1;
+ sendme(which, str, i);
+ sendme(which, "\n\r\\ ", 6);
+ con[which].outPos = 4;
+ while (str[i] == ' ') /* eat the leading spaces after we wrap */
+ i++;
+ } else {
+ sendme(which, str, i);
+ con[which].outPos += i;
+ }
+ str += i;
+ } else { /* non-printable stuff handled here */
+ switch (*str) {
+ case '\t':
+ sendme(which, " ", 8 - (con[which].outPos & 7));
+ con[which].outPos &= ~7;
+ if (con[which].outPos += 8 >= LINE_WIDTH)
+ con[which].outPos = 0;
+ break;
+ case '\n':
+ sendme(which, "\n\r", 2);
+ con[which].outPos = 0;
+ break;
+ case '\033':
+ con[which].outPos -= 3;
+ default:
+ sendme(which, str, 1);
+ }
+ str++;
+ }
+ }
+ return 0;
+}
+
+/* if we get a complete line (something terminated by \n), copy it to com
+ and return 1.
+ if we don't get a complete line, but there is no error, return 0.
+ if some error, return -1.
+ */
+PUBLIC int readline2(char *com, int who)
+{
+ unsigned char *start, *s, *d;
+ int howmany, state, fd, pending;
+
+ static unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'};
+ static unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'};
+ static unsigned char ayt[] = "[Responding to AYT: Yes, I'm here.]\n";
+
+ state = con[who].state;
+ if ((state == 2) || (state > 4)) {
+ fprintf(stderr, "FICS: state screwed for con[%d], this is a bug.\n", who);
+ state = 0;
+ }
+ s = start = con[who].inBuf;
+ pending = con[who].numPending;
+ fd = con[who].fd;
+
+ howmany = recv(fd, start + pending, MAX_STRING_LENGTH - 1 - pending, 0);
+ if (howmany == 0) /* error: they've disconnected */
+ return (-1);
+ else if (howmany == -1) {
+ if (errno != EWOULDBLOCK) { /* some other error */
+ return (-1);
+ } else if (con[who].processed) { /* nothing new and nothing old */
+ return (0);
+ } else { /* nothing new, but some unprocessed old */
+ howmany = 0;
+ }
+ }
+ if (con[who].processed)
+ s += pending;
+ else
+ howmany += pending;
+ d = s;
+
+ for (; howmany-- > 0; s++) {
+ switch (state) {
+ case 0: /* Haven't skipped over any control chars or
+ telnet commands */
+ if (*s == IAC) {
+ d = s;
+ state = 1;
+ } else if (*s == '\n') {
+ *s = '\0';
+ strcpy(com, start);
+ if (howmany)
+ bcopy(s + 1, start, howmany);
+ con[who].state = 0;
+ con[who].numPending = howmany;
+ con[who].processed = 0;
+ con[who].outPos = 0;
+ return (1);
+ } else if ((*s > (0xff - 0x20)) || (*s < 0x20)) {
+ d = s;
+ state = 2;
+ }
+ break;
+ case 1: /* got telnet IAC */
+ if (*s == IP)
+ return (-1); /* ^C = logout */
+ else if (*s == DO)
+ state = 4;
+ else if ((*s == WILL) || (*s == DONT) || (*s == WONT))
+ state = 3; /* this is cheesy, but we aren't using em */
+ else if (*s == AYT) {
+ send(fd, (char *) ayt, strlen((char *) ayt), 0);
+ state = 2;
+ } else if (*s == EL) { /* erase line */
+ d = start;
+ state = 2;
+ } else /* dunno what it is, so ignore it */
+ state = 2;
+ break;
+ case 2: /* we've skipped over something, need to
+ shuffle processed chars down */
+ if (*s == IAC)
+ state = 1;
+ else if (*s == '\n') {
+ *d = '\0';
+ strcpy(com, start);
+ if (howmany)
+ memmove(start, s + 1, howmany);
+ con[who].state = 0;
+ con[who].numPending = howmany;
+ con[who].processed = 0;
+ con[who].outPos = 0;
+ return (1);
+ } else if (*s >= ' ')
+ *(d++) = *s;
+ break;
+ case 3: /* some telnet junk we're ignoring */
+ state = 2;
+ break;
+ case 4: /* got IAC DO */
+ if (*s == TELOPT_TM)
+ send(fd, (char *) will_tm, strlen((char *) will_tm), 0);
+ else if (*s == TELOPT_SGA)
+ send(fd, (char *) will_sga, strlen((char *) will_sga), 0);
+ state = 2;
+ break;
+ }
+ }
+ if (state == 0)
+ d = s;
+ else if (state == 2)
+ state = 0;
+ con[who].state = state;
+ con[who].numPending = d - start;
+ con[who].processed = 1;
+ if (con[who].numPending == MAX_STRING_LENGTH - 1) { /* buffer full */
+ *d = '\0';
+ strcpy(com, start);
+ con[who].state = 0;
+ con[who].numPending = 0;
+ con[who].processed = 0;
+ return (1);
+ }
+ return (0);
+}
+
+/*
+PRIVATE int readline(int who)
+{
+ int e, fd = con[who].fd;
+ char *t = con[who].inBuf;
+ int recvCount;
+ int totalCount = 0;
+ unsigned char c;
+ static unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'};
+ static unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'};
+
+ t += con[who].numPending;
+
+ while ((recvCount = recv(fd, (char *) &c, 1, 0)) == 1) {
+ totalCount += recvCount;
+ if (c == IAC) {
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ if (recvCount == 1) {
+ totalCount += recvCount;
+ switch (c) {
+ case IP:
+ c = '\3';
+ break;
+ case DO:
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ if (recvCount == 1) {
+ totalCount += recvCount;
+ if (c == TELOPT_TM) {
+ send(fd, (char *) will_tm, strlen((char *) will_tm), 0);
+ } else if (c == TELOPT_SGA) {
+ send(fd, (char *) will_sga, strlen((char *) will_sga), 0);
+ }
+ }
+ c = '\0';
+ break;
+ case DONT:
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ break;
+ c = '\0';
+ default:
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ c = '\0';
+ break;
+ }
+ }
+ }
+ if (c != '\r' && c > 2) {
+ if (isprint(c) || (c == '\n')) {
+ *t++ = c;
+ con[who].numPending++;
+ }
+ }
+ if (c == '\n' || con[who].numPending >= MAX_STRING_LENGTH - 1) {
+ *--t = '\0';
+ con[who].numPending = 0;
+ con[fd].outPos = 0;
+ return 1;
+ }
+ }
+
+ *t = '\0';
+ e = ((totalCount == 0) || (errno != EWOULDBLOCK)) ? -1 : 0;
+ return (e);
+}
+*/
+
+PUBLIC int net_init(int port)
+{
+ int i;
+ int opt;
+ struct sockaddr_in serv_addr;
+ struct linger lingeropt;
+
+/* Although we have 256 descriptors to work with for opening files,
+ * we can only use 126 for sockets under SunOS 4.x.x socket libs. Using
+ * glibc can get you up to 256 again. Many OS's can do more than that!
+ * Sparky 9/20/95
+ */
+ no_file = getdtablesize();
+ if (no_file > MAX_PLAYER + 6)
+ no_file = MAX_PLAYER + 6;
+ max_connections = no_file - 6;
+ for (i = 0; i < no_file; i++) {
+ con[i].status = NETSTAT_EMPTY;
+ con[i].sndbuf = NULL;
+ con[i].sndbufsize = con[i].sndbufpos = 0;
+ }
+ /* Open a TCP socket (an Internet stream socket). */
+ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "FICS: can't open stream socket\n");
+ return -1;
+ }
+ /* Bind our local address so that the client can send to us */
+ memset((char *) &serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(port);
+
+ /** added in an attempt to allow rebinding to the port **/
+
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
+ lingeropt.l_onoff = 0;
+ lingeropt.l_linger = 0;
+ setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &lingeropt, sizeof(lingeropt));
+
+/*
+#ifdef DEBUG
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_DEBUG, (char *)&opt, sizeof(opt));
+#endif
+*/
+
+ if (bind(sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0) {
+ fprintf(stderr, "FICS: can't bind local address. errno=%d\n", errno);
+ return -1;
+ }
+ opt = 1;
+ ioctl(sockfd, FIONBIO, &opt);
+ listen(sockfd, 5);
+ return 0;
+}
+
+PUBLIC void net_close(void)
+{
+ int i;
+ for (i = 0; i < no_file; i++) {
+ if (con[i].status != NETSTAT_EMPTY)
+ net_close_connection(con[i].fd);
+ }
+}
+
+PUBLIC void net_close_connection(int fd)
+{
+ if (con[fd].status == NETSTAT_CONNECTED)
+ net_flush_connection(fd);
+ if (!remConnection(fd)) {
+ if (fd > 2)
+ close(fd);
+ }
+}
+
+PUBLIC void turn_echo_on(int fd)
+{
+ static unsigned char wont_echo[] = {IAC, WONT, TELOPT_ECHO, '\0'};
+
+ send(fd, (char *) wont_echo, strlen((char *) wont_echo), 0);
+}
+
+PUBLIC void turn_echo_off(int fd)
+{
+ static unsigned char will_echo[] = {IAC, WILL, TELOPT_ECHO, '\0'};
+
+ send(fd, (char *) will_echo, strlen((char *) will_echo), 0);
+}
+
+PUBLIC unsigned int net_connected_host(int fd)
+{
+ int which;
+
+ if ((which = findConnection(fd)) < 0) {
+ fprintf(stderr, "FICS: FD not in connection table!\n");
+ return -1;
+ }
+ return con[which].fromHost;
+}
+
+PUBLIC void ngc2(char *com, int timeout)
+{
+ struct sockaddr_in cli_addr;
+ int cli_len = (int) sizeof(struct sockaddr_in);
+
+ int fd, loop, nfound, lineComplete;
+ fd_set readfds;
+ struct timeval to;
+
+ while ((fd = accept(sockfd, (struct sockaddr *) & cli_addr, &cli_len)) != -1)
+ {
+ if (net_addConnection(fd, cli_addr.sin_addr.s_addr)) {
+ fprintf(stderr, "FICS is full. fd = %d.\n", fd);
+ psend_raw_file(fd, mess_dir, MESS_FULL);
+ close(fd);
+ } else
+ process_new_connection(fd, net_connected_host(fd));
+ }
+
+ if (errno != EWOULDBLOCK)
+ fprintf(stderr, "FICS: Problem with accept(). errno=%d\n", errno);
+
+ net_flush_all_connections();
+
+ FD_ZERO(&readfds);
+ for (loop = 0; loop < no_file; loop++)
+ if (con[loop].status != NETSTAT_EMPTY)
+ FD_SET(con[loop].fd, &readfds);
+
+ to.tv_usec = 0;
+ to.tv_sec = timeout;
+ nfound = select(no_file, &readfds, NULL, NULL, &to);
+ for (loop = 0; loop < no_file; loop++) {
+ if (con[loop].status != NETSTAT_EMPTY) {
+ fd = con[loop].fd;
+ lineComplete = readline2(com, fd);
+ if (lineComplete == 0) /* partial line: do nothing with it */
+ continue;
+ if (lineComplete > 0) { /* complete line: process it */
+#ifdef TIMESEAL
+ if (!(parseInput(com, &con[loop]))) continue;
+#endif
+ if (process_input(fd, com) != COM_LOGOUT) {
+ net_flush_connection(fd);
+ continue;
+ }
+ }
+ /* Disconnect anyone who gets here */
+ process_disconnection(fd);
+ net_close_connection(fd);
+ }
+ }
+}
+
+PUBLIC int net_consize(void)
+{
+ int i, total;
+
+ total = sizeof(con);
+ for (i=0; i < no_file; i++)
+ total += con[i].sndbufsize;
+
+ return(total);
+}
blob - /dev/null
blob + eed60c8b4c62b5cd51d9d753a3fe8c9d481a6a8f (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/network.c.orig
+/* network.c
+ *
+ */
+
+#include "stdinclude.h"
+
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <arpa/telnet.h>
+
+#include "common.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#ifdef TIMESEAL
+#include "timeseal.h"
+#endif
+
+extern int errno;
+
+/* grimm */
+#if defined(SGI)
+#else
+/*
+int send(int s, char *msg, int len, int flags);
+int recv(int s, char *buf, int len, int flags);
+char *memset(char *s, int c, int n);
+int setsockopt( int s, int level, int optname, char *optval, int optlen);
+int accept(int s, struct sockaddr *addr, size_t *addrlen);
+void *memmove(void *dst0, const void *src0, register size_t length);
+int bind(int s, struct sockaddr *name, int namelen);
+int select(int width, fd_set *readfds, fd_set *writefds, fd_set *exceptfds,
+ struct timeval *timeout);
+int listen(int s, int level);
+*/
+#endif
+/* added for warning */
+
+PRIVATE int sockfd = 0; /* The socket */
+PRIVATE int numConnections = 0;
+/* Sparse array */
+PUBLIC connection con[256];
+
+PUBLIC int no_file;
+PUBLIC int max_connections;
+
+/* Index == fd, for sparse array, quick lookups! wasted memory :( */
+PUBLIC int findConnection(int fd)
+{
+ if (con[fd].status == NETSTAT_EMPTY)
+ return -1;
+ else
+ return fd;
+}
+
+PUBLIC int net_addConnection(int fd, unsigned int fromHost)
+{
+ int noblock = 1;
+
+ if (findConnection(fd) >= 0) {
+ fprintf(stderr, "FICS: FD already in connection table!\n");
+ return -1;
+ }
+ if (numConnections == max_connections)
+ return -1;
+ if (ioctl(fd, FIONBIO, &noblock) == -1) {
+ fprintf(stderr, "Error setting nonblocking mode errno=%d\n", errno);
+ }
+ con[fd].fd = fd;
+ if (fd != 0)
+ con[fd].outFd = fd;
+ else
+ con[fd].outFd = 1;
+ con[fd].fromHost = fromHost;
+ con[fd].status = NETSTAT_CONNECTED;
+#ifdef TIMESEAL
+ con[fd].user[0]='\0';
+ con[fd].sys[0]='\0';
+ con[fd].timeseal = 0;
+ con[fd].time = 0;
+#endif
+ con[fd].numPending = 0;
+ con[fd].processed = 0;
+ con[fd].outPos = 0;
+ if (con[fd].sndbuf == NULL) {
+#ifdef DEBUG
+ fprintf(stderr, "FICS: nac(%d) allocating sndbuf.\n", fd);
+#endif
+ con[fd].sndbufpos = 0;
+ con[fd].sndbufsize = MAX_STRING_LENGTH;
+ con[fd].sndbuf = rmalloc(MAX_STRING_LENGTH);
+ } else {
+#ifdef DEBUG
+ fprintf(stderr, "FICS: nac(%d) reusing old sndbuf size %d pos %d.\n", fd, con[fd].sndbufsize, con[fd].sndbufpos);
+#endif
+ }
+ con[fd].state = 0;
+ numConnections++;
+
+#ifdef DEBUG
+ fprintf(stderr, "FICS: fd: %d connections: %d descriptors: %d \n", fd, numConnections, getdtablesize()); /* sparky 3/13/95 */
+#endif
+
+ return 0;
+}
+
+PRIVATE int remConnection(int fd)
+{
+ int which;
+ if ((which = findConnection(fd)) < 0) {
+ return -1;
+ }
+ numConnections--;
+ con[fd].status = NETSTAT_EMPTY;
+ if (con[fd].sndbuf == NULL) {
+ fprintf(stderr, "FICS: remcon(%d) totally screwed, this shouldn't happen.\n", fd);
+ } else {
+ if (con[fd].sndbufsize > MAX_STRING_LENGTH) {
+ con[fd].sndbufsize = MAX_STRING_LENGTH;
+ con[fd].sndbuf = rrealloc(con[fd].sndbuf, MAX_STRING_LENGTH);
+ }
+ if (con[fd].sndbufpos) { /* didn't send everything, bummer */
+ con[fd].sndbufpos = 0;
+ }
+ }
+ return 0;
+}
+
+PRIVATE void net_flushme(int which)
+{
+ int sent;
+
+ sent = send(con[which].outFd, con[which].sndbuf, con[which].sndbufpos, 0);
+ if (sent == -1) {
+ if (errno != EPIPE) /* EPIPE = they've disconnected */
+ fprintf(stderr, "FICS: net_flushme(%d) couldn't send, errno=%d.\n", which, errno);
+ con[which].sndbufpos = 0;
+ } else {
+ con[which].sndbufpos -= sent;
+ if (con[which].sndbufpos)
+ memmove(con[which].sndbuf, con[which].sndbuf + sent, con[which].sndbufpos);
+ }
+ if (con[which].sndbufsize > MAX_STRING_LENGTH && con[which].sndbufpos < MAX_STRING_LENGTH) {
+ /* time to shrink the buffer */
+ con[which].sndbuf = rrealloc(con[which].sndbuf, MAX_STRING_LENGTH);
+ con[which].sndbufsize = MAX_STRING_LENGTH;
+ }
+}
+
+PRIVATE void net_flush_all_connections(void)
+{
+ int which;
+ fd_set writefds;
+ struct timeval to;
+
+ FD_ZERO(&writefds);
+ for (which = 0; which < max_connections; which++)
+ if (con[which].status == NETSTAT_CONNECTED && con[which].sndbufpos)
+ FD_SET(con[which].outFd, &writefds);
+
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(no_file, NULL, &writefds, NULL, &to);
+ for (which = 0; which < max_connections; which++) {
+ if (FD_ISSET(con[which].outFd, &writefds)) {
+ net_flushme(which);
+ }
+ }
+}
+
+PRIVATE void net_flush_connection(int fd)
+{
+ int which;
+ fd_set writefds;
+ struct timeval to;
+
+ if (((which = findConnection(fd)) >= 0) && (con[which].sndbufpos)) {
+ FD_ZERO(&writefds);
+ FD_SET(con[which].outFd, &writefds);
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(no_file, NULL, &writefds, NULL, &to);
+ if (FD_ISSET(con[which].outFd, &writefds)) {
+ net_flushme(which);
+ }
+ }
+ return;
+}
+
+PRIVATE int sendme(int which, char *str, int len)
+{
+ int i, count;
+ fd_set writefds;
+ struct timeval to;
+ count = len;
+
+ while ((i = ((con[which].sndbufsize - con[which].sndbufpos) < len) ? (con[which].sndbufsize - con[which].sndbufpos) : len) > 0) {
+ memmove(con[which].sndbuf + con[which].sndbufpos, str, i);
+ con[which].sndbufpos += i;
+ if (con[which].sndbufpos == con[which].sndbufsize) {
+
+ FD_ZERO(&writefds);
+ FD_SET(con[which].outFd, &writefds);
+ to.tv_usec = 0;
+ to.tv_sec = 0;
+ select(no_file, NULL, &writefds, NULL, &to);
+ if (FD_ISSET(con[which].outFd, &writefds)) {
+ net_flushme(which);
+ } else {
+ /* time to grow the buffer */
+ con[which].sndbufsize += MAX_STRING_LENGTH;
+ con[which].sndbuf = rrealloc(con[which].sndbuf, con[which].sndbufsize);
+ }
+ }
+ str += i;
+ len -= i;
+ }
+ return count;
+}
+
+/*
+ * -1 for an error other than EWOULDBLOCK.
+ * Put <lf> after every <cr> and put \ at the end of overlength lines.
+ * Doesn't send anything unless the buffer fills, output waits until
+ * flushed
+*/
+PUBLIC int net_send_string(int fd, char *str, int format)
+{
+ int which, i, j;
+
+ if ((which = findConnection(fd)) < 0) {
+ return -1;
+ }
+ while (*str) {
+ for (i = 0; str[i] >= ' '; i++);
+ if (i) {
+ if (format && (i >= (j = LINE_WIDTH - con[which].outPos))) { /* word wrap */
+ i = j;
+ while (i > 0 && str[i - 1] != ' ')
+ i--;
+ while (i > 0 && str[i - 1] == ' ')
+ i--;
+ if (i == 0)
+ i = j - 1;
+ sendme(which, str, i);
+ sendme(which, "\n\r\\ ", 6);
+ con[which].outPos = 4;
+ while (str[i] == ' ') /* eat the leading spaces after we wrap */
+ i++;
+ } else {
+ sendme(which, str, i);
+ con[which].outPos += i;
+ }
+ str += i;
+ } else { /* non-printable stuff handled here */
+ switch (*str) {
+ case '\t':
+ sendme(which, " ", 8 - (con[which].outPos & 7));
+ con[which].outPos &= ~7;
+ if (con[which].outPos += 8 >= LINE_WIDTH)
+ con[which].outPos = 0;
+ break;
+ case '\n':
+ sendme(which, "\n\r", 2);
+ con[which].outPos = 0;
+ break;
+ case '\033':
+ con[which].outPos -= 3;
+ default:
+ sendme(which, str, 1);
+ }
+ str++;
+ }
+ }
+ return 0;
+}
+
+/* if we get a complete line (something terminated by \n), copy it to com
+ and return 1.
+ if we don't get a complete line, but there is no error, return 0.
+ if some error, return -1.
+ */
+PUBLIC int readline2(char *com, int who)
+{
+ unsigned char *start, *s, *d;
+ int howmany, state, fd, pending;
+
+ static unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'};
+ static unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'};
+ static unsigned char ayt[] = "[Responding to AYT: Yes, I'm here.]\n";
+
+ state = con[who].state;
+ if ((state == 2) || (state > 4)) {
+ fprintf(stderr, "FICS: state screwed for con[%d], this is a bug.\n", who);
+ state = 0;
+ }
+ s = start = con[who].inBuf;
+ pending = con[who].numPending;
+ fd = con[who].fd;
+
+ howmany = recv(fd, start + pending, MAX_STRING_LENGTH - 1 - pending, 0);
+ if (howmany == 0) /* error: they've disconnected */
+ return (-1);
+ else if (howmany == -1) {
+ if (errno != EWOULDBLOCK) { /* some other error */
+ return (-1);
+ } else if (con[who].processed) { /* nothing new and nothing old */
+ return (0);
+ } else { /* nothing new, but some unprocessed old */
+ howmany = 0;
+ }
+ }
+ if (con[who].processed)
+ s += pending;
+ else
+ howmany += pending;
+ d = s;
+
+ for (; howmany-- > 0; s++) {
+ switch (state) {
+ case 0: /* Haven't skipped over any control chars or
+ telnet commands */
+ if (*s == IAC) {
+ d = s;
+ state = 1;
+ } else if (*s == '\n') {
+ *s = '\0';
+ strcpy(com, start);
+ if (howmany)
+ bcopy(s + 1, start, howmany);
+ con[who].state = 0;
+ con[who].numPending = howmany;
+ con[who].processed = 0;
+ con[who].outPos = 0;
+ return (1);
+ } else if ((*s > (0xff - 0x20)) || (*s < 0x20)) {
+ d = s;
+ state = 2;
+ }
+ break;
+ case 1: /* got telnet IAC */
+ if (*s == IP)
+ return (-1); /* ^C = logout */
+ else if (*s == DO)
+ state = 4;
+ else if ((*s == WILL) || (*s == DONT) || (*s == WONT))
+ state = 3; /* this is cheesy, but we aren't using em */
+ else if (*s == AYT) {
+ send(fd, (char *) ayt, strlen((char *) ayt), 0);
+ state = 2;
+ } else if (*s == EL) { /* erase line */
+ d = start;
+ state = 2;
+ } else /* dunno what it is, so ignore it */
+ state = 2;
+ break;
+ case 2: /* we've skipped over something, need to
+ shuffle processed chars down */
+ if (*s == IAC)
+ state = 1;
+ else if (*s == '\n') {
+ *d = '\0';
+ strcpy(com, start);
+ if (howmany)
+ memmove(start, s + 1, howmany);
+ con[who].state = 0;
+ con[who].numPending = howmany;
+ con[who].processed = 0;
+ con[who].outPos = 0;
+ return (1);
+ } else if (*s >= ' ')
+ *(d++) = *s;
+ break;
+ case 3: /* some telnet junk we're ignoring */
+ state = 2;
+ break;
+ case 4: /* got IAC DO */
+ if (*s == TELOPT_TM)
+ send(fd, (char *) will_tm, strlen((char *) will_tm), 0);
+ else if (*s == TELOPT_SGA)
+ send(fd, (char *) will_sga, strlen((char *) will_sga), 0);
+ state = 2;
+ break;
+ }
+ }
+ if (state == 0)
+ d = s;
+ else if (state == 2)
+ state = 0;
+ con[who].state = state;
+ con[who].numPending = d - start;
+ con[who].processed = 1;
+ if (con[who].numPending == MAX_STRING_LENGTH - 1) { /* buffer full */
+ *d = '\0';
+ strcpy(com, start);
+ con[who].state = 0;
+ con[who].numPending = 0;
+ con[who].processed = 0;
+ return (1);
+ }
+ return (0);
+}
+
+/*
+PRIVATE int readline(int who)
+{
+ int e, fd = con[who].fd;
+ char *t = con[who].inBuf;
+ int recvCount;
+ int totalCount = 0;
+ unsigned char c;
+ static unsigned char will_tm[] = {IAC, WILL, TELOPT_TM, '\0'};
+ static unsigned char will_sga[] = {IAC, WILL, TELOPT_SGA, '\0'};
+
+ t += con[who].numPending;
+
+ while ((recvCount = recv(fd, (char *) &c, 1, 0)) == 1) {
+ totalCount += recvCount;
+ if (c == IAC) {
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ if (recvCount == 1) {
+ totalCount += recvCount;
+ switch (c) {
+ case IP:
+ c = '\3';
+ break;
+ case DO:
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ if (recvCount == 1) {
+ totalCount += recvCount;
+ if (c == TELOPT_TM) {
+ send(fd, (char *) will_tm, strlen((char *) will_tm), 0);
+ } else if (c == TELOPT_SGA) {
+ send(fd, (char *) will_sga, strlen((char *) will_sga), 0);
+ }
+ }
+ c = '\0';
+ break;
+ case DONT:
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ break;
+ c = '\0';
+ default:
+ recvCount = recv(fd, (char *) &c, 1, 0);
+ c = '\0';
+ break;
+ }
+ }
+ }
+ if (c != '\r' && c > 2) {
+ if (isprint(c) || (c == '\n')) {
+ *t++ = c;
+ con[who].numPending++;
+ }
+ }
+ if (c == '\n' || con[who].numPending >= MAX_STRING_LENGTH - 1) {
+ *--t = '\0';
+ con[who].numPending = 0;
+ con[fd].outPos = 0;
+ return 1;
+ }
+ }
+
+ *t = '\0';
+ e = ((totalCount == 0) || (errno != EWOULDBLOCK)) ? -1 : 0;
+ return (e);
+}
+*/
+
+PUBLIC int net_init(int port)
+{
+ int i;
+ int opt;
+ struct sockaddr_in serv_addr;
+ struct linger lingeropt;
+
+ no_file = getdtablesize();
+/* Although we have 256 descriptors to work with for opening sockets,
+ * we can only use 126 maximum of them for some reason... built in
+ * limitation of the socket libs? Sparky 3/13/95
+ */
+ if (no_file > MAX_PLAYER + 10)
+ no_file = MAX_PLAYER + 10;
+ max_connections = no_file - 10;
+ for (i = 0; i < no_file; i++) {
+ con[i].status = NETSTAT_EMPTY;
+ con[i].sndbuf = NULL;
+ con[i].sndbufsize = con[i].sndbufpos = 0;
+ }
+ /* Open a TCP socket (an Internet stream socket). */
+ if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) < 0) {
+ fprintf(stderr, "FICS: can't open stream socket\n");
+ return -1;
+ }
+ /* Bind our local address so that the client can send to us */
+ memset((char *) &serv_addr, 0, sizeof(serv_addr));
+ serv_addr.sin_family = AF_INET;
+ serv_addr.sin_addr.s_addr = htonl(INADDR_ANY);
+ serv_addr.sin_port = htons(port);
+
+ /** added in an attempt to allow rebinding to the port **/
+
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_REUSEADDR, (char *) &opt, sizeof(opt));
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_KEEPALIVE, (char *) &opt, sizeof(opt));
+ lingeropt.l_onoff = 0;
+ lingeropt.l_linger = 0;
+ setsockopt(sockfd, SOL_SOCKET, SO_LINGER, (char *) &lingeropt, sizeof(lingeropt));
+
+/*
+#ifdef DEBUG
+ opt = 1;
+ setsockopt(sockfd, SOL_SOCKET, SO_DEBUG, (char *)&opt, sizeof(opt));
+#endif
+*/
+
+ if (bind(sockfd, (struct sockaddr *) & serv_addr, sizeof(serv_addr)) < 0) {
+ fprintf(stderr, "FICS: can't bind local address. errno=%d\n", errno);
+ return -1;
+ }
+ opt = 1;
+ ioctl(sockfd, FIONBIO, &opt);
+ listen(sockfd, 5);
+ return 0;
+}
+
+PUBLIC void net_close(void)
+{
+ int i;
+ for (i = 0; i < no_file; i++) {
+ if (con[i].status != NETSTAT_EMPTY)
+ net_close_connection(con[i].fd);
+ }
+}
+
+PUBLIC void net_close_connection(int fd)
+{
+ if (con[fd].status == NETSTAT_CONNECTED)
+ net_flush_connection(fd);
+ if (!remConnection(fd)) {
+ if (fd > 2)
+ close(fd);
+ }
+}
+
+PUBLIC void turn_echo_on(int fd)
+{
+ static unsigned char wont_echo[] = {IAC, WONT, TELOPT_ECHO, '\0'};
+
+ send(fd, (char *) wont_echo, strlen((char *) wont_echo), 0);
+}
+
+PUBLIC void turn_echo_off(int fd)
+{
+ static unsigned char will_echo[] = {IAC, WILL, TELOPT_ECHO, '\0'};
+
+ send(fd, (char *) will_echo, strlen((char *) will_echo), 0);
+}
+
+PUBLIC unsigned int net_connected_host(int fd)
+{
+ int which;
+
+ if ((which = findConnection(fd)) < 0) {
+ fprintf(stderr, "FICS: FD not in connection table!\n");
+ return -1;
+ }
+ return con[which].fromHost;
+}
+
+PUBLIC void ngc2(char *com, int timeout)
+{
+ struct sockaddr_in cli_addr;
+ size_t cli_len = sizeof(struct sockaddr_in);
+
+ int fd, loop, nfound, lineComplete;
+ fd_set readfds;
+ struct timeval to;
+
+ while ((fd = accept(sockfd, (struct sockaddr *) & cli_addr, &cli_len)) != -1) {
+ if (net_addConnection(fd, cli_addr.sin_addr.s_addr)) {
+ char *woo =
+"FICS is currently full. Please try one of the following sites:\n\r\n\r"
+"E-FICS: krypton.daimi.aau.dk 5000 (130.225.18.157 5000) Main EURO server\n\r"
+"D-FICS: dds.hacktic.nl 5000 (193.78.33.69 5000) Dutch server\n\r"
+"B-FICS: holly.csv.warwick.ac.uk 5000 (137.205.192.12 5000) British server\n\r"
+"?-FICS: chess.unix-ag.uni-kl.de 5000 (131.246.89.3 5000) German server\n\r"
+"M-FICS: wisdom.weizmann.ac.il 5000 (132.76.80.77 5000) Mid-east server\n\r\n\r";
+ fprintf(stderr, "FICS is full. fd = %d\n");
+ write (fd, woo, strlen(woo));
+ sleep(1);
+ close(fd);
+ } else {
+/* int opt, optlen;
+
+ opt = 1024;
+ setsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&opt, sizeof(opt));
+ opt = 8192;
+ setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *) &opt, sizeof(opt));
+ optlen = sizeof(opt);
+ getsockopt(fd, SOL_SOCKET, SO_SNDBUF, (char *)&opt, &optlen);
+ fprintf(stderr, "%d sndbuf: %d", fd, opt);
+ optlen = sizeof(opt);
+ getsockopt(fd, SOL_SOCKET, SO_RCVBUF, (char *)&opt, &optlen);
+ fprintf(stderr, " rcvbuf: %d\n", opt);
+*/
+ process_new_connection(fd, net_connected_host(fd));
+ }
+ }
+ if (errno != EWOULDBLOCK)
+ fprintf(stderr, "FICS: Problem with accept(). errno=%d\n", errno);
+
+ net_flush_all_connections();
+
+ FD_ZERO(&readfds);
+ for (loop = 0; loop < no_file; loop++)
+ if (con[loop].status != NETSTAT_EMPTY)
+ FD_SET(con[loop].fd, &readfds);
+
+ to.tv_usec = 0;
+ to.tv_sec = timeout;
+ nfound = select(no_file, &readfds, NULL, NULL, &to);
+ for (loop = 0; loop < no_file; loop++) {
+ if (con[loop].status != NETSTAT_EMPTY) {
+ fd = con[loop].fd;
+ lineComplete = readline2(com, fd);
+ if (lineComplete == 0) /* partial line: do nothing with it */
+ continue;
+ if (lineComplete > 0) { /* complete line: process it */
+#ifdef TIMESEAL
+ if (!(parseInput(com, &con[loop]))) continue;
+#endif
+ if (process_input(fd, com) != COM_LOGOUT) {
+ net_flush_connection(fd);
+ continue;
+ }
+ }
+ /* Disconnect anyone who gets here */
+ process_disconnection(fd);
+ net_close_connection(fd);
+ }
+ }
+}
+
+PUBLIC int net_consize(void)
+{
+ int i, total;
+
+ total = sizeof(con);
+ for (i=0; i < no_file; i++)
+ total += con[i].sndbufsize;
+
+ return(total);
+}
blob - /dev/null
blob + 7ff2a2221b59435e73ffbc5859d5df1cf9076f66 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/network.h
+/* network.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _NETWORK_H
+#define _NETWORK_H
+
+#include "command.h" /* For MAX_STRING_LENGTH */
+
+#define NET_NETERROR 0
+#define NET_NEW 1
+#define NET_DISCONNECT 2
+#define NET_READLINE 3
+#define NET_TIMEOUT 4
+#define NET_NOTCOMPLETE 5
+
+#define LINE_WIDTH 80
+
+#ifndef O_NONBLOCK
+#define O_NONBLOCK 00004
+#endif
+
+#define NETSTAT_EMPTY 0
+#define NETSTAT_CONNECTED 1
+#define NETSTAT_IDENT 2
+
+typedef struct _connection {
+ int fd;
+ int outFd;
+ unsigned int fromHost;
+ int status;
+#ifdef TIMESEAL
+ char user[512];
+ char sys[512];
+ int timeseal;
+ int time;
+#endif
+/* Input buffering */
+ int numPending;
+ int processed;
+ unsigned char inBuf[MAX_STRING_LENGTH];
+/* Output buffering */
+ int sndbufsize; /* size of send buffer (this changes) */
+ int sndbufpos; /* position in send buffer */
+ char *sndbuf; /* our send buffer, or NULL if none yet */
+ int outPos; /* column count */
+ int state; /* 'telnet state' */
+/* identd stuff */
+ char ident[20];
+ int mypal;
+} connection;
+
+extern int no_file;
+extern int max_connections;
+extern connection con[512];
+
+extern int findConnection();
+extern int net_init(int);
+extern void net_close(void);
+extern void ngc2(char *, int);
+extern void net_close_connection(int);
+extern int net_send_string(int, char *, int);
+extern void turn_echo_on(int);
+extern void turn_echo_off(int);
+extern unsigned int net_connected_host(int);
+extern int net_addConnection(int, unsigned int);
+extern int net_consize(void);
+extern int readline2(char *, int);
+#endif /* _NETWORK_H */
blob - /dev/null
blob + 97f346fd8e9d364c1c537263185ed6304354736f (mode 644)
Binary files /dev/null and FICS.DIST/FICS/network.o differ
blob - /dev/null
blob + e24a116c0b170dc097964467ab3ca869b41c4468 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/obsproc.c
+/* obsproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Dave Herscovici 95/11/26 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "command.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+#include "movecheck.h"
+#include "utils.h"
+#include "ratings.h"
+#include "rmalloc.h"
+#include "comproc.h"
+#include "matchproc.h"
+#include "formula.h"
+#include "eco.h"
+#include "network.h"
+
+PUBLIC int GameNumFromParam(int p, int *p1, parameter *param)
+{
+ if (param->type == TYPE_WORD) {
+ *p1 = player_find_part_login(param->val.word);
+ if (*p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param->val.word);
+ return -1;
+ }
+ if (parray[*p1].game < 0)
+ pprintf(p, "%s is not playing a game.\n", parray[*p1].name);
+ return parray[*p1].game;
+ } else { /* Must be an integer */
+ *p1 = -1;
+ if (param->val.integer <= 0)
+ pprintf(p, "%d is not a valid game number.\n", param->val.integer);
+ return param->val.integer - 1;
+ }
+}
+
+PRIVATE int gamesortfunc(const void *i, const void *j)
+{
+/* examine mode games moved to top of "games" output */
+ return (GetRating(&parray[garray[*(int *) i].white], garray[*(int *) i].type) +
+ GetRating(&parray[garray[*(int *) i].black], garray[*(int *) i].type) -
+ ((garray[*(int *) i].status == GAME_EXAMINE) ? 10000 : 0) -
+ GetRating(&parray[garray[*(int *) j].white], garray[*(int *) j].type) -
+ GetRating(&parray[garray[*(int *) j].black], garray[*(int *) j].type) +
+ ((garray[*(int *) j].status == GAME_EXAMINE) ? 10000 : 0));
+}
+
+
+PUBLIC int com_games(int p, param_list param)
+{
+ int i, j;
+ int wp, bp;
+ int ws, bs;
+ int selected = 0;
+ int count = 0;
+ int totalcount;
+ char *s = NULL;
+ int slen = 0;
+ int *sortedgames; /* for qsort */
+
+ totalcount = game_count();
+ if (totalcount == 0) {
+ pprintf(p, "There are no games in progress.\n");
+ } else {
+ sortedgames = rmalloc(totalcount * sizeof(int)); /* for qsort */
+
+ if (param[0].type == TYPE_WORD) {
+ s = param[0].val.word;
+ slen = strlen(s);
+ selected = atoi(s);
+ if (selected < 0)
+ selected = 0;
+ }
+ for (i = 0; i < g_num; i++) {
+ if ((garray[i].status != GAME_ACTIVE) && (garray[i].status != GAME_EXAMINE))
+ continue;
+ if ((selected) && (selected != i + 1))
+ continue; /* not selected game number */
+ wp = garray[i].white;
+ bp = garray[i].black;
+ if ((!selected) && s && strncasecmp(s, garray[i].white_name, slen) &&
+ strncasecmp(s, garray[i].black_name, slen))
+ continue; /* player names did not match */
+ sortedgames[count++] = i;
+ }
+ if (!count)
+ pprintf(p, "No matching games were found (of %d in progress).\n", totalcount);
+ else {
+ qsort(sortedgames, count, sizeof(int), gamesortfunc);
+ pprintf(p, "\n");
+ for (j = 0; j < count; j++) {
+ i = sortedgames[j];
+ wp = garray[i].white;
+ bp = garray[i].black;
+ board_calc_strength(&garray[i].game_state, &ws, &bs);
+ if (garray[i].status != GAME_EXAMINE) {
+ pprintf_noformat(p, "%2d %4s %-11.11s %4s %-10.10s [%c%c%c%3d %3d] ",
+ i + 1,
+ ratstrii(GetRating(&parray[wp],
+ garray[i].type),
+ parray[wp].registered),
+ parray[wp].name,
+ ratstrii(GetRating(&parray[bp],
+ garray[i].type),
+ parray[bp].registered),
+ parray[bp].name,
+ (garray[i].private) ? 'p' : ' ',
+ *bstr[garray[i].type],
+ *rstr[garray[i].rated],
+ garray[i].wInitTime / 600,
+ garray[i].wIncrement / 10);
+ game_update_time(i);
+ pprintf_noformat(p, "%6s -",
+ tenth_str((garray[i].wTime > 0 ? garray[i].wTime : 0), 0));
+ pprintf_noformat(p, "%6s (%2d-%2d) %c: %2d\n",
+ tenth_str((garray[i].bTime > 0 ? garray[i].bTime : 0), 0),
+ ws, bs,
+ (garray[i].game_state.onMove == WHITE) ? 'W' : 'B',
+ garray[i].game_state.moveNum);
+ } else {
+ pprintf_noformat(p, "%2d (Exam. %4d %-11.11s %4d %-10.10s) [%c%c%c%3d %3d] ",
+ i + 1,
+ garray[i].white_rating,
+ garray[i].white_name,
+ garray[i].black_rating,
+ garray[i].black_name,
+ (garray[i].private) ? 'p' : ' ',
+ *bstr[garray[i].type],
+ *rstr[garray[i].rated],
+ garray[i].wInitTime / 600,
+ garray[i].wIncrement / 10);
+ pprintf_noformat(p, "%c: %2d\n",
+ (garray[i].game_state.onMove == WHITE) ? 'W' : 'B',
+ garray[i].game_state.moveNum);
+ }
+ }
+ if (count < totalcount)
+ pprintf(p, "\n %d game%s displayed (of %d in progress).\n", count,
+ (count == 1) ? "" : "s", totalcount);
+ else
+ pprintf(p, "\n %d game%s displayed.\n", totalcount, (totalcount == 1) ? "" : "s");
+ }
+ rfree(sortedgames);
+ }
+ return COM_OK;
+}
+
+PRIVATE int do_observe(int p, int obgame)
+{
+ if ((garray[obgame].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, game %d is a private game.\n", obgame + 1);
+ return COM_OK;
+ }
+ if ((garray[obgame].white == p) || (garray[obgame].black == p)) {
+ if (garray[obgame].status != GAME_EXAMINE) {
+ pprintf(p, "You cannot observe a game that you are playing.\n");
+ return COM_OK;
+ }
+ }
+ if (player_is_observe(p, obgame)) {
+ pprintf(p, "Removing game %d from observation list.\n", obgame + 1);
+ player_remove_observe(p, obgame);
+ } else {
+ if (!player_add_observe(p, obgame)) {
+ pprintf(p, "You are now observing game %d.\n", obgame + 1);
+ send_board_to(obgame, p);
+ } else {
+ pprintf(p, "You are already observing the maximum number of games.\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC void unobserveAll(int p)
+{
+ int i;
+
+ for (i = 0; i < parray[p].num_observe; i++) {
+ pprintf(p, "Removing game %d from observation list.\n", parray[p].observe_list[i] + 1);
+ }
+ parray[p].num_observe = 0;
+ return;
+}
+
+PUBLIC int com_unobserve(int p, param_list param)
+{
+ int gNum, p1;
+
+ if (param[0].type == TYPE_NULL) {
+ unobserveAll(p);
+ return COM_OK;
+ }
+ gNum = GameNumFromParam(p, &p1, ¶m[0]);
+ if (gNum < 0)
+ return COM_OK;
+ if (!player_is_observe(p, gNum)) {
+ pprintf(p, "You are not observing game %d.\n", gNum);
+ } else {
+ player_remove_observe(p, gNum);
+ pprintf(p, "Removing game %d from observation list.\n", gNum + 1);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_observe(int p, param_list param)
+{
+ int i;
+ int p1, obgame;
+
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are still examining a game.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ unobserveAll(p);
+ return COM_OK;
+ }
+ obgame = GameNumFromParam(p, &p1, ¶m[0]);
+ if (obgame < 0)
+ return COM_OK;
+
+ if ((obgame >= g_num) || ((garray[obgame].status != GAME_ACTIVE) &&
+ (garray[obgame].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((p1 >= 0) && parray[p1].simul_info.numBoards) {
+ for (i = 0; i < parray[p1].simul_info.numBoards; i++)
+ if (parray[p1].simul_info.boards[i] >= 0)
+ do_observe(p, parray[p1].simul_info.boards[i]);
+ } else {
+ do_observe(p, obgame);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_allobservers(int p, param_list param)
+{
+ int obgame;
+ int p1;
+ int start, end;
+ int g;
+ int first;
+
+ if (param[0].type == TYPE_NULL) {
+ obgame = -1;
+ } else {
+ obgame = GameNumFromParam(p, &p1, ¶m[0]);
+ if (obgame < 0)
+ return COM_OK;
+ }
+ if (obgame == -1) {
+ start = 0;
+ end = g_num;
+ } else if ((obgame >= g_num) || ((obgame < g_num)
+ && ((garray[obgame].status != GAME_ACTIVE)
+ && (garray[obgame].status != GAME_EXAMINE)))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ } else {
+ start = obgame;
+ end = obgame + 1;
+ }
+
+ /* list games being played */
+
+ for (g = start; g < end; g++) {
+ if ((garray[g].status == GAME_ACTIVE) &&
+ ((parray[p].adminLevel > 0) || (garray[g].private == 0))) {
+ for (first = 1, p1 = 0; p1 < p_num; p1++) {
+ if ((parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g))) {
+ if (first) {
+ pprintf(p, "Observing %2d [%s vs. %s]:",
+ g + 1,
+ parray[garray[g].white].name,
+ parray[garray[g].black].name);
+ first = 0;
+ }
+ pprintf(p, " %s%s", (parray[p1].game >=0) ? "#" : "", parray[p1].name);
+ }
+ }
+ if (!first)
+ pprintf(p, "\n");
+ }
+ }
+
+ /* list games being examined last */
+
+ for (g = start; g < end; g++) {
+ if ((garray[g].status == GAME_EXAMINE) &&
+ ((parray[p].adminLevel > 0) || (garray[g].private == 0))) {
+ for (first = 1, p1 = 0; p1 < p_num; p1++) {
+ if ((parray[p1].status != PLAYER_EMPTY) && (player_is_observe(p1, g) ||
+ (parray[p1].game == g))) {
+ if (first) {
+ if (strcmp(garray[g].white_name, garray[g].black_name)) {
+ pprintf(p, "Examining %2d [%s vs %s]:", g + 1,
+ garray[g].white_name, garray[g].black_name);
+ } else {
+ pprintf(p, "Examining %2d (scratch):", g + 1);
+ }
+ first = 0;
+ }
+ pprintf(p, " %s%s", (parray[p1].game == g) ? "#" : "", parray[p1].name);
+ }
+ }
+ if (!first)
+ pprintf(p, "\n");
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_unexamine(int p, param_list param)
+{
+ int g, p1, flag = 0;
+
+ if ((parray[p].game <0) ||(garray[parray[p].game].status != GAME_EXAMINE)) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ parray[p].game = -1;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if ((parray[p1].game == g) &&(p != p1)) {
+ /* ok - there are other examiners to take over the game */
+ flag = 1;
+ }
+ if ((player_is_observe(p1, g)) || (parray[p1].game == g)) {
+ pprintf(p1, "%s stopped examining game %d.\n", parray[p].name, g + 1);
+ }
+ }
+ if (!flag) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g)) {
+ pprintf(p1, "There are no examiners.\n");
+ pcommand(p1, "unobserve %d", g + 1);
+ }
+ }
+ game_remove(g);
+ }
+ pprintf(p, "You are no longer examining game %d.\n", g + 1);
+ return COM_OK;
+}
+
+PUBLIC int com_mexamine(int p, param_list param)
+{
+ int g, p1, p2;
+
+ if ((parray[p].game <0) ||(garray[parray[p].game].status != GAME_EXAMINE)) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if (p1 < 0) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (!player_is_observe(p1, g)) {
+ pprintf(p, "%s must observe the game you are analysing.\n", parray[p1].name);
+ return COM_OK;
+ } else {
+ if (parray[p1].game >=0) {
+ pprintf(p, "%s is already analysing the game.\n", parray[p1].name);
+ return COM_OK;
+ }
+ /* if we get here - let's make him examiner of the game */
+ unobserveAll(p1); /* fix for Xboard */
+ player_decline_offers(p1, -1, PEND_MATCH);
+ player_withdraw_offers(p1, -1, PEND_MATCH);
+ player_withdraw_offers(p1, -1, PEND_SIMUL);
+
+ parray[p1].game = g; /* yep - it really is that easy :-) */
+ pprintf(p1, "You are now examiner of game %d.\n", g + 1);
+ send_board_to(g, p1); /* pos not changed - but fixes Xboard */
+ for (p2 = 0; p2 < p_num; p2++) {
+ if (parray[p2].status != PLAYER_PROMPT)
+ continue;
+ if (p2 == p1)
+ continue;
+ if ((player_is_observe(p2, g)) || (parray[p2].game == g)) {
+ pprintf_prompt(p2, "%s is now examiner of game %d.\n", parray[p1].name, g + 1);
+ }
+ }
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_moves(int p, param_list param)
+{
+ int g;
+ int p1;
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >=0) {
+ g = parray[p].game;
+ } else if (parray[p].num_observe) {
+ for (g = 0; g < parray[p].num_observe; g++) {
+ pprintf(p, "%s\n", movesToString(parray[p].observe_list[g], 0));
+ }
+ return COM_OK;
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= g_num) || ((garray[g].status != GAME_ACTIVE) &&
+ (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ pprintf(p, "%s\n", movesToString(g, 0)); /* pgn may break interfaces? */
+ return COM_OK;
+}
+
+PUBLIC int com_mailmoves(int p, param_list param)
+{
+ int g;
+ int p1;
+ char subj[81];
+
+ if (!parray[p].registered) {
+ pprintf (p,"Unregistered players cannot use mailmoves.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game >=0) {
+ g = parray[p].game;
+ } else {
+ pprintf(p, "You are neither playing, observing nor examining a game.\n");
+ return COM_OK;
+ }
+ } else {
+ g = GameNumFromParam(p, &p1, ¶m[0]);
+ if (g < 0)
+ return COM_OK;
+ }
+ if ((g < 0) || (g >= g_num) || ((garray[g].status != GAME_ACTIVE) && (garray[g].status != GAME_EXAMINE))) {
+ pprintf(p, "There is no such game.\n");
+ return COM_OK;
+ }
+ if ((garray[g].white != p) && (garray[g].black != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ return COM_OK;
+ }
+ sprintf(subj, "FICS game report %s vs %s", garray[g].white_name, garray[g].black_name);
+ if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn))) {
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ } else {
+ pprintf(p, "Moves mailed.\n");
+ }
+ return COM_OK;
+}
+
+PRIVATE int old_mail_moves(int p,int mail, param_list param)
+{
+ int p1, connected;
+ int count;
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+ char tmp[2048];
+ char *ptmp = tmp;
+
+ if (mail && (!parray[p].registered)) {
+ pprintf (p,"Unregistered players cannot use mailoldmoves.\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[p1].login[0], parray[p1].login, STATS_GAMES);
+ fp = fopen(fname, "r"); /* old moves now looks in history to save mem - DAV */
+
+ if (!fp) {
+ pprintf (p,"There is no old game for %s.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+
+ while (!feof(fp))
+ fgets(tmp, 1024, fp);
+ sscanf(ptmp, "%d", &count);
+ fclose(fp); /* find the last game played in history */
+
+ pprintf (p,"Last game for %s was history game %d.\n",parray[p1].name,count);
+
+ if (mail)
+ pcommand (p,"mailstored %s %d",parray[p1].name,count);
+ else
+ pcommand (p,"smoves %s %d",parray[p1].name,count);
+
+ if (!connected)
+ player_remove(p1);
+
+ return COM_OK;
+}
+
+PUBLIC int com_oldmoves(int p, param_list param)
+{
+ return old_mail_moves(p , 0, param);
+}
+
+PUBLIC int com_mailoldmoves(int p, param_list param)
+{
+ return old_mail_moves(p , 1, param);
+}
+
+PUBLIC void ExamineScratch(int p, param_list param)
+{
+ char category[100], board[100], parsebuf[100];
+ char *val;
+ int confused = 0;
+ int g = game_new();
+
+ unobserveAll(p);
+
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+
+ garray[g].wInitTime = garray[g].wIncrement = 0;
+ garray[g].bInitTime = garray[g].bIncrement = 0;
+ garray[g].timeOfStart = tenth_secs();
+ garray[g].wTime = garray[g].bTime = 0;
+ garray[g].rated = 0;
+ garray[g].clockStopped = 0;
+ garray[g].type = TYPE_UNTIMED;
+ garray[g].white = garray[g].black = p;
+ garray[g].status = GAME_EXAMINE;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ garray[g].totalHalfMoves = 0;
+
+ parray[p].side = WHITE; /* oh well... */
+ parray[p].game = g;
+
+ category[0] = '\0';
+ board[0] = '\0';
+
+ if ((param[0].val.string != parray[p].name) &&
+ (param[1].type == TYPE_WORD)) {
+ strcpy(category, param[0].val.string);
+ strcpy(board, param[1].val.string);
+ } else if (param[1].type != TYPE_NULL) {
+
+ val = param[1].val.string;
+
+ while (!confused && (sscanf(val, " %99s", parsebuf) == 1)) {
+ val = eatword(eatwhite(val));
+ if ((category[0] != '\0') && (board[0] == '\0'))
+ strcpy(board, parsebuf);
+ else if (isdigit(*parsebuf)) {
+ pprintf(p, "You can't specify time controls.\n");
+ return;
+ } else if (category[0] == '\0')
+ strcpy(category, parsebuf);
+ else
+ confused = 1;
+ }
+ if (confused) {
+ pprintf(p, "Can't interpret %s in match command.\n", parsebuf);
+ return;
+ }
+ }
+
+
+ if (category[0] && !board[0]) {
+ pprintf(p, "You must specify a board and a category.\n");
+ return;
+ }
+
+ pprintf(p, "Starting a game in examine (scratch) mode.\n");
+
+ if (category[0]) {
+ pprintf(p, "Loading from catagory: %s, board: %s.\n", category, board);
+ }
+
+ if (board_init(&garray[g].game_state, category, board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD. Game Aborted.\n");
+ return;
+ }
+
+ garray[g].game_state.gameNum = g;
+ strcpy(garray[g].white_name, parray[p].name);
+ strcpy(garray[g].black_name, parray[p].name);
+ garray[g].white_rating = garray[g].black_rating = parray[p].s_stats.rating;
+
+ send_boards(g);
+ MakeFENpos(g, garray[g].FENstartPos);
+}
+
+PRIVATE int ExamineStored(FILE * fp, int p, char *filename)
+{
+ int g;
+ char category[100], board[100];
+ game *gg;
+
+ unobserveAll(p);
+
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_SIMUL);
+
+ g = game_new();
+ gg = &garray[g];
+ category[0] = '\0';
+ board[0] = '\0';
+ if (board_init(&gg->game_state, category, board)) {
+ pprintf(p, "PROBLEM LOADING BOARD. Game Aborted.\n");
+ fprintf(stderr, "FICS: PROBLEM LOADING BOARD %s %s. Game Aborted.\n",
+ category, board);
+ return -1;
+ }
+ gg->status = GAME_EXAMINE;
+ if (ReadGameAttrs(fp, filename, g) < 0) {
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ return -1;
+ }
+ gg->totalHalfMoves = gg->numHalfMoves;
+ gg->numHalfMoves = 0;
+ gg->revertHalfMove = 0;
+ gg->white = p;
+ gg->black = p;
+ gg->game_state.gameNum = g;
+
+ gg->startTime = tenth_secs();
+ gg->lastMoveTime = gg->startTime;
+ gg->lastDecTime = gg->startTime;
+
+ parray[p].side = WHITE; /* oh well... */
+ parray[p].game = g;
+
+ send_boards(g);
+ MakeFENpos(g, garray[g].FENstartPos);
+
+ return g;
+}
+
+PRIVATE void ExamineAdjourned(int p, int p1, int p2)
+{
+ FILE *fp;
+ char filename[1024];
+ char *p1Login, *p2Login;
+ int g;
+
+ p1Login = parray[p1].login;
+ p2Login = parray[p2].login;
+
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p1Login, p1Login, p2Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p2Login, p1Login, p2Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p2Login, p2Login, p1Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ sprintf(filename, "%s/%c/%s-%s", adj_dir, *p1Login, p2Login, p1Login);
+ fp = fopen(filename, "r");
+ if (!fp) {
+ pprintf(p, "No stored game between \"%s\" and \"%s\".\n",
+ parray[p1].name, parray[p2].name);
+ return;
+ }
+ }
+ }
+ }
+ g = ExamineStored(fp, p, filename);
+ fclose(fp);
+
+ if (g >= 0) {
+ if (garray[g].white_name[0] == '\0')
+ strcpy(garray[g].white_name, p1Login);
+ if (garray[g].black_name[0] == '\0')
+ strcpy(garray[g].black_name, p2Login);
+ }
+ return;
+}
+
+PRIVATE char *FindHistory(int p, int p1, int game)
+{
+ FILE *fpHist;
+ static char fileName[MAX_FILENAME_SIZE];
+ int index;
+ long when;
+
+ sprintf(fileName, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[p1].login[0], parray[p1].login, STATS_GAMES);
+ fpHist = fopen(fileName, "r");
+ if (fpHist == NULL) {
+ pprintf(p, "No games in history for %s.\n", parray[p1].name);
+ return(NULL);
+ }
+ do {
+ fscanf(fpHist, "%d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %*s %*s %ld",
+ &index, &when);
+ } while (!feof(fpHist) && index != game);
+
+ if (feof(fpHist)) {
+ pprintf(p, "There is no history game %d for %s.\n", game, parray[p1].name);
+ fclose(fpHist);
+ return(NULL);
+ }
+ fclose(fpHist);
+
+ sprintf(fileName, "%s/%ld/%ld", hist_dir, when % 100, when);
+ return(fileName);
+}
+
+/* I want to know how game ended */
+
+PRIVATE char *FindHistory2(int p, int p1,int game,char* End)
+{
+ FILE *fpHist;
+ static char fileName[MAX_FILENAME_SIZE];
+ int index;
+ long when;
+
+ sprintf(fileName, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[p1].login[0], parray[p1].login, STATS_GAMES);
+ fpHist = fopen(fileName, "r");
+ if (fpHist == NULL) {
+ pprintf(p, "No games in history for %s.\n", parray[p1].name);
+ return(NULL);
+ }
+ do {
+ fscanf(fpHist, "%d %*c %*d %*c %*d %*s %*s %*d %*d %*d %*d %*s %s %ld",
+ &index, End, &when);
+ } while (!feof(fpHist) && index != game);
+
+ if (feof(fpHist)) {
+ pprintf(p, "There is no history game %d for %s.\n", game, parray[p1].name);
+ fclose(fpHist);
+ return(NULL);
+ }
+ fclose(fpHist);
+
+ sprintf(fileName, "%s/%ld/%ld", hist_dir, when % 100, when);
+ return(fileName);
+}
+
+PRIVATE void ExamineHistory(int p, int p1, int game)
+{
+ char *fileName;
+
+ fileName = FindHistory(p, p1, game);
+ if (fileName != NULL) {
+ FILE *fpGame = fopen(fileName, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", game, parray[p1].name);
+ } else {
+ ExamineStored(fpGame, p, fileName);
+ fclose(fpGame);
+ }
+ }
+ return;
+}
+
+PRIVATE void ExamineJournal(int p,int p1,char slot)
+{
+ char fname[MAX_FILENAME_SIZE];
+ char* name_from = parray[p1].login;
+ FILE *fpGame;
+
+ if ((parray[p1].jprivate) && (p != p1) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf (p,"Sorry, this journal is private.\n");
+ return;
+ }
+ if (((slot - 'a' - 1) > MAX_JOURNAL) && (parray[p1].adminLevel < ADMIN_ADMIN)
+&& (!titled_player(p,parray[p1].login))) {
+ pprintf (p,"%s's maximum journal entry is %c\n",parray[p1].name,toupper((char)(MAX_JOURNAL + 'A' - 1)));
+ return;
+ }
+
+ sprintf(fname, "%s/%c/%s.%c", journal_dir, name_from[0],name_from,slot);
+ fpGame = fopen(fname, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "Journal entry %c is not available for %s.\n", toupper (slot), parray[p1].name);
+ } else {
+ ExamineStored(fpGame, p, fname);
+ fclose(fpGame);
+ }
+ return;
+}
+
+PUBLIC int com_examine(int p, param_list param)
+{
+ int p1, p2 = p, p1conn, p2conn = 1;
+ char* param2string;
+ char fname[MAX_FILENAME_SIZE];
+
+ if ((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE)) {
+ pprintf(p, "You are already examining a game.\n");
+ } else if (parray[p].game >=0) {
+ pprintf(p, "You are playing a game.\n");
+ } else if (param[0].type == TYPE_NULL) {
+ ExamineScratch(p, param);
+ } else if (param[0].type == TYPE_WORD) {
+ if (param[1].type == TYPE_WORD) {
+ sprintf(fname, "%s/%s/%s", board_dir, param[0].val.word, param[1].val.word);
+ if (file_exists(fname)) {
+ ExamineScratch(p, param);
+ return COM_OK;
+ }
+ }
+ if (!FindPlayer(p, param[0].val.word, &p1, &p1conn))
+ return COM_OK;
+
+ if (param[1].type == TYPE_INT)
+ ExamineHistory(p, p1, param[1].val.integer);
+ else {
+ if (param[1].type == TYPE_WORD) {
+
+ /* Lets check the journal */
+ param2string = param[1].val.word;
+ if ((strlen(param2string) == 1) && (isalpha(param2string[0]))) {
+ ExamineJournal(p,p1,param2string[0]);
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ } else {
+ if (!FindPlayer(p, param[1].val.word, &p2, &p2conn)) {
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ }
+ ExamineAdjourned(p, p1, p2);
+ if (!p2conn)
+ player_remove(p2);
+ }
+ if (!p1conn)
+ player_remove(p1);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_stored(int p, param_list param)
+{
+ DIR *dirp;
+#ifdef USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+ int p1, connected;
+ char dname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(dname, "%s/%c", adj_dir, parray[p1].login[0]);
+ dirp = opendir(dname);
+ if (!dirp) {
+ pprintf(p, "Player %s has no games stored.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ pprintf(p, "Stored games for %s:\n", parray[p1].name);
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (file_has_pname(dp->d_name, parray[p1].login)) {
+ pprintf(p, " %s vs. %s\n", file_wplayer(dp->d_name), file_bplayer(dp->d_name));
+ }
+ }
+
+ closedir(dirp);
+ pprintf(p, "\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PRIVATE void stored_mail_moves(int p, int mail, param_list param)
+{
+ int wp, wconnected, bp, bconnected, gotit = 0;
+ int g = -1;
+ char* param2string;
+ char* name_from;
+ char* fileName;
+ char fileName2[MAX_FILENAME_SIZE];
+ FILE* fpGame;
+
+ if (mail && (!parray[p].registered)) {
+ pprintf (p,"Unregistered players cannot use mailstored.\n");
+ return;
+ }
+
+ if (!FindPlayer(p, param[0].val.word, &wp, &wconnected))
+ return;
+
+ if (param[1].type == TYPE_INT) { /* look for a game from history */
+ fileName = FindHistory(p, wp, param[1].val.integer);
+ if (fileName != NULL) {
+ fpGame = fopen(fileName, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", param[1].val.integer, parray[wp].name);
+ } else {
+ g = game_new();
+ if (ReadGameAttrs(fpGame, fileName, g) < 0)
+ pprintf(p, "Gamefile is corrupt; please notify an admin.\n");
+ else
+ gotit = 1;
+ fclose(fpGame);
+ }
+ }
+ } else { /* Let's test for journal */
+ name_from = param[0].val.word;
+ param2string = param[1].val.word;
+ if ((strlen(param2string) == 1) && (isalpha(param2string[0]))) {
+ if ((parray[wp].jprivate) && (parray[p].adminLevel < ADMIN_ADMIN) && (p != wp)) {
+ pprintf (p,"Sorry, the journal from which you are trying to fetch is private.\n");
+ } else {
+ if (((param2string[0] - 'a' - 1) > MAX_JOURNAL) && (parray[wp].adminLevel < ADMIN_ADMIN) && (!titled_player(p,parray[wp].login))) {
+ pprintf (p,"%s's maximum journal entry is %c\n",parray[wp].name,toupper((char)(MAX_JOURNAL + 'A' - 1)));
+ } else {
+ sprintf(fileName2, "%s/%c/%s.%c", journal_dir, name_from[0],name_from,param2string[0]);
+ fpGame = fopen(fileName2, "r");
+ if (fpGame == NULL) {
+ pprintf(p, "Journal entry %c is not available for %s.\n", toupper(param2string[0]),
+ parray[wp].name);
+ } else {
+ g = game_new();
+ if (ReadGameAttrs(fpGame, fileName, g) < 0)
+ pprintf(p, "Journal entry is corrupt; please notify an admin.\n");
+ else
+ gotit = 1;
+ fclose(fpGame);
+ }
+ }
+ }
+ } else {
+
+ /* look for a stored game between the players */
+
+ if (FindPlayer(p, param[1].val.word, &bp, &bconnected)) {
+ g = game_new();
+ if (game_read(g, wp, bp) >= 0) { /* look for a game white-black, */
+ gotit = 1;
+ } else if (game_read(g, bp, wp) >= 0) { /* or black-white */
+ gotit = 1;
+ } else {
+ pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ }
+ if (!bconnected)
+ player_remove(bp);
+ }
+ }
+ }
+ if (gotit) {
+ if (strcasecmp(parray[p].name, garray[g].white_name) && strcasecmp(parray[p]
+.name, garray[g].black_name) && garray[g].private && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ if (mail == 1) { /*Do mailstored */
+ char subj[81];
+ if (param[1].type == TYPE_INT)
+ sprintf(subj, "FICS history game: %s %d", parray[wp].name, param[1].val.integer);
+ else
+ if ((strlen(param2string) == 1) && (isalpha(param2string[0]))) {
+ sprintf(subj, "FICS journal game %s vs %s", garray[g].white_name, garray[g].black_name);
+ } else {
+ sprintf(subj, "FICS adjourned game %s vs %s", garray[g].white_name, garray[g].black_name);
+ }
+ if (mail_string_to_user(p, subj, movesToString(g, parray[p].pgn)))
+ pprintf(p, "Moves NOT mailed, perhaps your address is incorrect.\n");
+ else
+ pprintf(p, "Moves mailed.\n");
+ } else {
+ pprintf(p, "%s\n", movesToString(g, 0));
+ } /* Do smoves */
+ }
+ }
+ if (!wconnected)
+ player_remove(wp);
+ if (g != -1)
+ game_remove(g);
+}
+
+/* Tidied up a bit but still messy */
+
+PUBLIC int com_mailstored(int p, param_list param)
+{
+ stored_mail_moves(p, 1, param);
+ return COM_OK;
+}
+
+PUBLIC int com_smoves(int p, param_list param)
+{
+ stored_mail_moves(p, 0, param);
+ return COM_OK;
+}
+
+PUBLIC int com_sposition(int p, param_list param)
+{
+ int wp, wconnected, bp, bconnected, confused = 0;
+ int g;
+
+ if (!FindPlayer(p, param[0].val.word, &wp, &wconnected))
+ return (COM_OK);
+ if (!FindPlayer(p, param[1].val.word, &bp, &bconnected)) {
+ if (!wconnected)
+ player_remove(wp);
+ return (COM_OK);
+ }
+
+ g = game_new();
+ if (game_read(g, wp, bp) < 0) { /* if no game white-black, */
+ if (game_read(g, bp, wp) < 0) { /* look for black-white */
+ confused = 1;
+ pprintf(p, "There is no stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ } else {
+ int tmp;
+ tmp = wp;
+ wp = bp;
+ bp = tmp;
+ tmp = wconnected;
+ wconnected = bconnected;
+ bconnected = tmp;
+ }
+ }
+ if (!confused) {
+ if ((wp != p) && (bp != p) && (garray[g].private) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf(p, "Sorry, that is a private game.\n");
+ } else {
+ garray[g].white = wp;
+ garray[g].black = bp;
+ garray[g].startTime = tenth_secs();
+ garray[g].lastMoveTime = garray[g].startTime;
+ garray[g].lastDecTime = garray[g].startTime;
+ pprintf(p, "Position of stored game %s vs. %s\n", parray[wp].name, parray[bp].name);
+ send_board_to(g, p);
+ }
+ }
+ game_remove(g);
+ if (!wconnected)
+ player_remove(wp);
+ if (!bconnected)
+ player_remove(bp);
+ return COM_OK;
+}
+
+PUBLIC int com_forward(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (!strcmp(garray[g].white_name, garray[g].black_name)) {
+ pprintf(p, "You cannot go forward; no moves are stored.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if (garray[g].numHalfMoves > garray[g].revertHalfMove) {
+ pprintf(p, "No more moves.\n");
+ return COM_OK;
+ }
+ if (garray[g].numHalfMoves < garray[g].totalHalfMoves) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s goes forward %d move%s.\n",
+ parray[p].name, nHalfMoves, (nHalfMoves == 1) ? "" : "s");
+ }
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ if (garray[g].numHalfMoves < garray[g].totalHalfMoves) {
+ execute_move(&garray[g].game_state, &garray[g].moveList[garray[g].numHalfMoves], 1);
+ if (garray[g].numHalfMoves + 1 > garray[g].examMoveListSize) {
+ garray[g].examMoveListSize += 20; /* Allocate 20 moves at a
+ time */
+ if (!garray[g].examMoveList) {
+ garray[g].examMoveList = (move_t *) rmalloc(sizeof(move_t) * garray[g].examMoveListSize);
+ } else {
+ garray[g].examMoveList = (move_t *) rrealloc(garray[g].examMoveList, sizeof(move_t) * garray[g].examMoveListSize);
+ }
+ }
+ garray[g].examMoveList[garray[g].numHalfMoves] = garray[g].moveList[garray[g].numHalfMoves];
+ garray[g].revertHalfMove++;
+ garray[g].numHalfMoves++;
+ } else {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "End of game.\n");
+ }
+ }
+ break;
+ }
+ }
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+PUBLIC int com_backward(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ if (param[0].type == TYPE_INT) {
+ nHalfMoves = param[0].val.integer;
+ }
+ if (garray[g].numHalfMoves != 0) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s backs up %d move%s.\n",
+ parray[p].name, nHalfMoves, (nHalfMoves == 1) ? "" : "s");
+ }
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ if (backup_move(g, REL_EXAMINE) != MOVE_OK) {
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "Beginning of game.\n");
+ }
+ }
+
+ break;
+ }
+ }
+ if (garray[g].numHalfMoves < garray[g].revertHalfMove) {
+ garray[g].revertHalfMove = garray[g].numHalfMoves;
+ }
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+PUBLIC int com_revert(int p, param_list param)
+{
+ int nHalfMoves = 1;
+ int g, i;
+ int p1;
+ unsigned now;
+
+ if (!((parray[p].game >=0) &&(garray[parray[p].game].status == GAME_EXAMINE))) {
+ pprintf(p, "You are not examining any games.\n");
+ return COM_OK;
+ }
+ g = parray[p].game;
+ nHalfMoves = garray[g].numHalfMoves - garray[g].revertHalfMove;
+ if (nHalfMoves == 0) {
+ pprintf(p, "Already at mainline.\n");
+ return COM_OK;
+ }
+ if (nHalfMoves < 0) { /* eek - should NEVER happen! */
+ fprintf(stderr, "OUCH! in com_revert: nHalfMoves < 0\n");
+ return COM_OK;
+ }
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) || parray[p1].game == g) {
+ pprintf(p1, "%s reverts to mainline.\n", parray[p].name);
+ }
+ }
+ for (i = 0; i < nHalfMoves; i++) {
+ backup_move(g, REL_EXAMINE);/* should never return error */
+ }
+ /* roll back time */
+ if (garray[g].game_state.onMove == WHITE) {
+ garray[g].wTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ } else {
+ garray[g].bTime += (garray[g].lastDecTime - garray[g].lastMoveTime);
+ }
+ now = tenth_secs();
+ if (garray[g].numHalfMoves == 0)
+ garray[g].timeOfStart = now;
+ garray[g].lastMoveTime = now;
+ garray[g].lastDecTime = now;
+ send_boards(g);
+ return COM_OK;
+}
+
+PUBLIC int com_history(int p, param_list param)
+{
+ int p1, connected;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p1].login[0],
+ parray[p1].login, STATS_GAMES);
+ pgames(p, p1, fname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_journal(int p, param_list param)
+{
+ int p1, connected;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+if (!parray[p1].registered) {
+ pprintf (p,"Only registered players may keep a journal.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if ((parray[p1].jprivate) && (p != p1) && (parray[p].adminLevel < ADMIN_ADMIN)) {
+ pprintf (p,"Sorry, this journal is private.\n");
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p1].login[0],
+ parray[p1].login, STATS_JOURNAL);
+ pjournal(p, p1, fname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PRIVATE void jsave_journalentry(int p,char save_spot,int p1,char from_spot,char* to_file)
+
+{
+ FILE *Game;
+
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+ char command[MAX_FILENAME_SIZE*2+3];
+ char* name_from = parray[p1].login;
+ char* name_to = parray[p].login;
+ char WhiteName[MAX_LOGIN_NAME + 1];
+ char BlackName[MAX_LOGIN_NAME + 1];
+ int WhiteRating;
+ int BlackRating;
+ int i,t;
+ char type[100];
+ char eco[100];
+ char ending[100];
+ char result[100];
+
+ sprintf(fname, "%s/%c/%s.%c", journal_dir, name_from[0],name_from,from_spot);
+ Game = fopen(fname, "r");
+ if (Game == NULL) {
+ pprintf(p, "Journal entry %c not available for %s.\n", toupper(from_spot), parray[p1].name);
+ return;
+ }
+ fclose (Game);
+
+ sprintf(fname2, "%s/%c/%s.%c", journal_dir, name_to[0],name_to,save_spot);
+ unlink (fname2); /* necessarity if cp is hard aliased to cp -i */
+ sprintf(command, "cp %s %s",fname,fname2);
+
+ if (system(command)) { /* A little messy, but works */
+ pprintf (p,"System command in jsave_journalentry failed!\n");
+ pprintf (p,"Please report this to an admin.\n");
+ fprintf (stderr, "FICS: System command failed in jsave_journalentry\n");
+ return;
+ }
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, name_to[0],
+ name_to, STATS_JOURNAL);
+
+ if (!journal_get_info(p,from_spot,WhiteName,&WhiteRating,
+ BlackName,&BlackRating,type,&t,&i,eco,
+ ending,result,fname)) {
+ return;
+ }
+
+ addjournalitem(p, toupper(save_spot), WhiteName, WhiteRating,
+ BlackName,BlackRating,type,t,i,eco,
+ ending,result, to_file);
+
+ pprintf(p,"Journal entry %s %c saved in slot %c in journal.\n",parray[p1].name, toupper(from_spot), toupper(save_spot));
+}
+
+PUBLIC void jsave_history(int p,char save_spot,int p1,int from,char* to_file)
+{
+
+
+ char End[100];
+ char jfname[MAX_FILENAME_SIZE];
+ char* HistoryFname = FindHistory2(p, p1, from, End);
+ /* End symbol Mat Res, etc is the only thing we can't find out */
+ char command[MAX_FILENAME_SIZE*2+3];
+ char* name_to = parray[p].login;
+ char* EndSymbol;
+ FILE *Game;
+ char type[4];
+ int g;
+ char* filename[MAX_FILENAME_SIZE+1];
+
+ if (HistoryFname != NULL) {
+ Game = fopen(HistoryFname, "r");
+ if (Game == NULL) {
+ pprintf(p, "History game %d not available for %s.\n", from, parray[p1].name);
+ } else {
+ sprintf(jfname, "%s/%c/%s.%c", journal_dir, name_to[0],name_to,save_spot);
+ unlink(jfname); /* necessary if cp is hard aliased to cp -i */
+ sprintf(command, "cp %s %s",HistoryFname,jfname);
+ if (system(command)) { /* A little messy, but works */
+ pprintf (p,"System command in jsave_history failed!\n");
+ pprintf (p,"Please report this to an admin.\n");
+ fprintf (stderr, "FICS: System command failed in jsave_journalentry\n");
+ return;
+ }
+ g = game_new(); /* Open a dummy game */
+
+ if (ReadGameAttrs(Game, filename, g) < 0) {
+ pprintf (p,"Gamefile is corrupt. Please tell an admin.\n");
+ game_free(g);
+ fclose (Game);
+ return;
+ }
+ fclose (Game);
+ if (garray[g].private) {
+ type[0] = 'p';
+ } else {
+ type[0] = ' ';
+ }
+ if (garray[g].type == TYPE_BLITZ) {
+ type[1] = 'b';
+ } else if (garray[g].type == TYPE_WILD) {
+ type[1] = 'w';
+ } else if (garray[g].type == TYPE_STAND) {
+ type[1] = 's';
+ } else {
+ if (garray[g].type == TYPE_NONSTANDARD)
+ type[1] = 'n';
+ else
+ type[1] = 'u';
+ }
+ if (garray[g].rated) {
+ type[2] = 'r';
+ } else {
+ type[2] = 'u';
+ }
+ type[3] = '\0';
+
+ EndSymbol = EndSym(g);
+ addjournalitem(p, toupper(save_spot), garray[g].white_name, garray[g].white_rating,
+ garray[g].black_name,garray[g].black_rating,type,garray[g].wInitTime,garray[g].wIncrement,getECO(g),
+ End,EndSymbol, to_file);
+ game_free(g);
+ pprintf(p,"Game %s %d saved in slot %c in journal.\n",parray[p1].name, from, toupper(save_spot));
+ }
+ }
+}
+
+PUBLIC int com_jsave(int p, param_list param)
+{
+ int p1, p1conn;
+ char* to = param[0].val.word;
+ char* from;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered) {
+ pprintf (p,"Only registered players may keep a journal.\n");
+ return COM_OK;
+ }
+
+ if ((strlen(to) != 1) || (!(isalpha(to[0])))) {
+ pprintf (p,"Journal entries are referenced by single letters.\n");
+ return COM_OK;
+ }
+
+ if (((to[0] - 'a' - 1) > MAX_JOURNAL) && (parray[p].adminLevel < ADMIN_ADMIN) && (!titled_player(p,parray[p].login))) {
+ pprintf (p,"Your maximum journal entry is %c\n",toupper ((char)(MAX_JOURNAL + 'A' - 1)));
+ return COM_OK;
+ }
+
+ if (!FindPlayer(p, param[1].val.word, &p1, &p1conn))
+ return COM_OK;
+
+ if (param[2].type == TYPE_INT) {
+
+ /* grab from a history */
+ sprintf (fname,"%s/player_data/%c/%s.%s",stats_dir,parray[p].login[0],parray[p].login, STATS_JOURNAL);
+ jsave_history(p, to[0], p1, param[2].val.integer,fname);
+
+ } else {
+
+ from = param[2].val.word;
+
+ if ((strlen(from) != 1) || (!(isalpha(from[0])))) {
+ pprintf (p,"Journal entries are referenced by single letters.\n");
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+
+ if ((parray[p1].jprivate) && (parray[p].adminLevel < ADMIN_ADMIN) && (p != p1)) {
+ pprintf (p,"Sorry, the journal from which you are trying to fetch is private.\n");
+
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+
+ if (((to[0] - 'a' - 1) > MAX_JOURNAL) && (parray[p1].adminLevel < ADMIN_ADMIN) && (!titled_player(p,parray[p1].login))) {
+ pprintf (p,"%s's maximum journal entry is %c\n",parray[p1].name,toupper((char)(MAX_JOURNAL + 'A' - 1)));
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (( p == p1) && (to[0] == from [0])) {
+ pprintf (p,"Source and destination entries are the same.\n");
+ return COM_OK;
+ }
+
+ /* grab from a journal */
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0],
+ parray[p].login, STATS_JOURNAL);
+ jsave_journalentry(p,to[0],p1, from[0], fname);
+
+ }
+ if (!p1conn)
+ player_remove(p1);
+ return COM_OK;
+}
blob - /dev/null
blob + 0d85e9aef85f99c48ca437aeeb39ded8f3808f7d (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/obsproc.h
+/* obsproc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Dave Herscovici 95/11/26 Created
+*/
+
+#ifndef _OBSPROC_H
+#define _OBSPROC_H
+
+#define MAX_JOURNAL 10
+
+extern int GameNumFromParam();
+extern int com_games();
+extern int com_observe();
+extern void unobserveAll(int);
+extern int com_unobserve();
+extern int com_allobservers();
+extern int com_moves();
+extern int com_mailmoves();
+extern int com_oldmoves();
+extern int com_mailoldmoves();
+extern int com_mailstored();
+extern int com_stored();
+extern int com_smoves();
+extern int com_sposition();
+extern int com_history();
+extern int com_journal();
+extern int com_jsave();
+
+extern int com_examine();
+extern int com_mexamine();
+extern int com_unexamine();
+extern int com_forward();
+extern int com_backward();
+extern int com_revert();
+
+extern void ExamineScratch ();
+
+#endif /* _OBSPROC_H */
blob - /dev/null
blob + 455aab83864cfe1b6fec337ec235a06204d0bd85 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/obsproc.o differ
blob - /dev/null
blob + 2cb30c5f291f7b7abe5c83687a0773eb89d6fa6c (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/playerdb.c
+/* playerdb.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+#include "common.h"
+#include "command.h"
+#include "comproc.h"
+#include "playerdb.h"
+#include "rmalloc.h"
+#include "utils.h"
+#include "network.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "talkproc.h"
+#include "gamedb.h"
+#include "lists.h"
+/*#include "hostinfo.h" */
+#include "ratings.h"
+
+PUBLIC player parray[PARRAY_SIZE];
+PUBLIC int p_num = 0;
+
+#if 0 /* This never gets used! -- hersco */
+PUBLIC char *pend_strings[7] = {"match", "draw", "abort", "take back", "adjourn", "switch", "simul"};
+#endif
+
+PRIVATE int get_empty_slot(void)
+{
+ int i;
+
+ for (i = 0; i < p_num; i++) {
+ if (parray[i].status == PLAYER_EMPTY) {
+/*** fprintf(stderr,"New player put in parray[%d/%d]\n", i, p_num-1);*/
+ return i;
+ }
+ }
+
+ p_num++;
+
+ if (p_num+1 >= PARRAY_SIZE) {
+ fprintf(stderr, "*** Bogus attempt to get_empty_slot() past end of parray ***\n");
+ }
+
+/*** fprintf(stderr,"New player added in parray[%d]\n", p_num-1); */
+ parray[p_num - 1].status = PLAYER_EMPTY;
+ return p_num - 1;
+}
+
+PUBLIC void player_array_init()
+{
+ int i;
+
+ for (i = 0; i < PARRAY_SIZE; i++)
+ parray[i].status = PLAYER_EMPTY;
+}
+
+PUBLIC void player_init(int startConsole)
+{
+ int p;
+
+ if (startConsole) {
+ net_addConnection(0, 0);
+ p = player_new();
+ parray[p].login = strdup("console");
+ parray[p].name = strdup("console");
+ parray[p].passwd = strdup("*");
+ parray[p].fullName = strdup("The Operator");
+ parray[p].emailAddress = NULL;
+ parray[p].prompt = strdup("fics%");
+ parray[p].adminLevel = ADMIN_GOD;
+ parray[p].socket = 0;
+ parray[p].busy[0] = '\0';
+ pprintf_prompt(p, "\nLogged in on console.\n");
+ }
+}
+
+PUBLIC int player_new()
+{
+ int new;
+
+ new = get_empty_slot();
+ player_zero(new);
+ return new;
+}
+
+#define INVALID ((char *) -42)
+
+PUBLIC int player_zero(int p)
+{
+ int i;
+
+ parray[p].name = NULL;
+ parray[p].login = NULL;
+ parray[p].fullName = NULL;
+ parray[p].emailAddress = NULL;
+ parray[p].prompt = def_prompt;
+ parray[p].partner = -1;
+ parray[p].passwd = NULL;
+ parray[p].socket = -1;
+ parray[p].registered = 0;
+ parray[p].status = PLAYER_NEW;
+ parray[p].s_stats.num = 0;
+ parray[p].s_stats.win = 0;
+ parray[p].s_stats.los = 0;
+ parray[p].s_stats.dra = 0;
+ parray[p].s_stats.rating = 0;
+ parray[p].s_stats.sterr = 350.0;
+ parray[p].s_stats.ltime = 0;
+ parray[p].s_stats.best = 0;
+ parray[p].s_stats.whenbest = 0;
+ parray[p].b_stats.num = 0;
+ parray[p].b_stats.win = 0;
+ parray[p].b_stats.los = 0;
+ parray[p].b_stats.dra = 0;
+ parray[p].b_stats.rating = 0;
+ parray[p].b_stats.sterr = 350.0;
+ parray[p].b_stats.ltime = 0;
+ parray[p].b_stats.best = 0;
+ parray[p].b_stats.whenbest = 0;
+ parray[p].w_stats.num = 0;
+ parray[p].w_stats.win = 0;
+ parray[p].w_stats.los = 0;
+ parray[p].w_stats.dra = 0;
+ parray[p].w_stats.rating = 0;
+ parray[p].w_stats.sterr = 350.0;
+ parray[p].w_stats.ltime = 0;
+ parray[p].w_stats.best = 0;
+ parray[p].w_stats.whenbest = 0;
+ parray[p].l_stats.num = 0;
+ parray[p].l_stats.win = 0;
+ parray[p].l_stats.los = 0;
+ parray[p].l_stats.dra = 0;
+ parray[p].l_stats.rating = 0;
+ parray[p].l_stats.sterr = 350.0;
+ parray[p].l_stats.ltime = 0;
+ parray[p].l_stats.best = 0;
+ parray[p].l_stats.whenbest = 0;
+ parray[p].bug_stats.num = 0;
+ parray[p].bug_stats.win = 0;
+ parray[p].bug_stats.los = 0;
+ parray[p].bug_stats.dra = 0;
+ parray[p].bug_stats.rating = 0;
+ parray[p].bug_stats.sterr = 350.0;
+ parray[p].bug_stats.ltime = 0;
+ parray[p].bug_stats.best = 0;
+ parray[p].bug_stats.whenbest = 0;
+ parray[p].d_time = 2;
+ parray[p].d_inc = 12;
+ parray[p].d_height = 24;
+ parray[p].d_width = 79;
+ parray[p].language = LANG_DEFAULT;
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+ parray[p].open = 1;
+ parray[p].rated = 0;
+ parray[p].ropen = 1;
+ parray[p].bell = 0;
+ parray[p].timeOfReg = 0;
+ parray[p].totalTime = 0;
+ parray[p].pgn = 0;
+ parray[p].notifiedby = 0;
+ parray[p].i_login = 0;
+ parray[p].i_game = 0;
+ parray[p].i_shout = 1;
+ parray[p].i_cshout = 1;
+ parray[p].i_tell = 1;
+ parray[p].i_kibitz = 1;
+ parray[p].kiblevel = 0;
+ parray[p].private = 0;
+ parray[p].jprivate = 0;
+ parray[p].automail = 0;
+ parray[p].i_mailmess = 0;
+ parray[p].style = 0;
+ parray[p].promote = QUEEN;
+ parray[p].game = -1;
+ parray[p].last_tell = -1;
+ parray[p].last_channel = -1;
+ parray[p].logon_time = 0;
+ parray[p].last_command_time = 0;
+ parray[p].num_from = 0;
+ parray[p].num_to = 0;
+ parray[p].adminLevel = 0;
+ parray[p].i_admin = 1;
+/* parray[p].computer = 0; */
+ parray[p].num_plan = 0;
+ for (i = 0; i < MAX_PLAN; i++)
+ parray[p].planLines[i] = INVALID;
+ parray[p].num_formula = 0;
+ for (i = 0; i < MAX_FORMULA; i++)
+ parray[p].formulaLines[i] = NULL;
+ parray[p].formula = NULL;
+/* parray[p].nochannels = 0; */
+ parray[p].num_white = 0;
+ parray[p].num_black = 0;
+ parray[p].num_observe = 0;
+/* parray[p].uscfRating = 0; */
+/* parray[p].network_player = 0; */
+ parray[p].thisHost = 0;
+ parray[p].lastHost = 0;
+ parray[p].lastColor = WHITE;
+ parray[p].numAlias = 0;
+ for (i = 0; i < MAX_ALIASES; i++) {
+ parray[p].alias_list[i].comm_name = INVALID;
+ parray[p].alias_list[i].alias = INVALID;
+ }
+ parray[p].opponent = -1;
+ parray[p].last_opponent = -1;
+ parray[p].highlight = 0;
+/* parray[p].query_log = NULL; */
+ parray[p].lastshout_a = 0;
+ parray[p].lastshout_b = 0;
+ parray[p].sopen = 0;
+ parray[p].simul_info.numBoards = 0;
+ parray[p].num_comments = 0;
+ parray[p].flip = 0;
+ parray[p].lists = NULL;
+ return 0;
+}
+
+PUBLIC int player_free(int p)
+{
+ int i;
+
+ strfree(parray[p].login);
+ strfree(parray[p].name);
+ strfree(parray[p].passwd);
+ strfree(parray[p].fullName);
+ strfree(parray[p].emailAddress);
+ if (parray[p].prompt != def_prompt)
+ strfree(parray[p].prompt);
+/* strfree(parray[p].partner); */
+ for (i = 0; i < parray[p].num_plan; i++)
+ strfree(parray[p].planLines[i]);
+ for (i = 0; i < parray[p].num_formula; i++)
+ strfree(parray[p].formulaLines[i]);
+ strfree(parray[p].formula);
+ list_free(parray[p].lists);
+ for (i = 0; i < parray[p].numAlias; i++) {
+ strfree(parray[p].alias_list[i].comm_name);
+ strfree(parray[p].alias_list[i].alias);
+ }
+/*
+ if (parray[p].query_log != NULL)
+ tl_free(parray[p].query_log);
+*/
+ return 0;
+}
+
+PUBLIC int player_clear(int p)
+{
+ player_free(p);
+ player_zero(p);
+ return 0;
+}
+
+PUBLIC int player_remove(int p)
+{
+ int i;
+
+ player_decline_offers(p, -1, -1);
+ player_withdraw_offers(p, -1, -1);
+ if (parray[p].simul_info.numBoards) { /* Player disconnected in middle of
+ simul */
+ for (i = 0; i < parray[p].simul_info.numBoards; i++) {
+ if (parray[p].simul_info.boards[i] >= 0) {
+ game_disconnect(parray[p].simul_info.boards[i], p);
+ }
+ }
+ }
+#if 0 /* was finished elsewhere */
+ if ((parray[p].game >=0) && (garray[parray[p].game].status == GAME_EXAMINE)) {
+ if (garray[parray[p].game].white == p) { /* owner of exam game */
+
+ /* not yet done */
+
+ }
+#endif
+
+ if (parray[p].game >=0) { /* Player disconnected in the middle of a
+ game! */
+ pprintf(parray[p].opponent, "Your opponent has lost contact or quit.");
+ game_disconnect(parray[p].game, p);
+ }
+/* ReallyRemoveOldGamesForPlayer(p); */
+ for (i = 0; i < p_num; i++) {
+ if (parray[i].status == PLAYER_EMPTY)
+ continue;
+ if (parray[i].last_tell == p)
+ parray[i].last_tell = -1;
+ if (parray[i].last_opponent == p)
+ parray[i].last_opponent = -1;
+ if (parray[i].partner == p) {
+ pprintf_prompt (i, "Your partner has disconnected.\n");
+ player_withdraw_offers(i, -1, PEND_BUGHOUSE);
+ player_decline_offers(i, -1, PEND_BUGHOUSE);
+ parray[i].partner = -1;
+ }
+ }
+ player_clear(p);
+ parray[p].status = PLAYER_EMPTY;
+/*** fprintf(stderr, "Removed parray[%d/%d]\n", p, p_num-1);*/
+ return 0;
+}
+
+void ReadV1PlayerFmt(int p,player *pp, FILE * fp, char *file, int version)
+{
+
+ int i,size_cens, size_noplay, size_not, size_gnot, size_chan, len;
+ int bs,ss,ws,ls,bugs;
+
+ char* tmp;
+ char tmp2[MAX_STRING_LENGTH];
+
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->name = strdup (tmp2);
+ } else
+ pp->name = NULL;
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->fullName = strdup (tmp2);
+ } else
+ pp->fullName = NULL;
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->passwd = strdup (tmp2);
+ } else
+ pp->passwd = NULL;
+ fgets(tmp2, MAX_STRING_LENGTH, fp);
+ if (strcmp(tmp2,"NONE\n")) {
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->emailAddress = strdup (tmp2);
+ } else
+ pp->emailAddress = NULL;
+ if (fscanf(fp, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d\n",
+
+ &pp->s_stats.num, &pp->s_stats.win, &pp->s_stats.los,
+ &pp->s_stats.dra, &pp->s_stats.rating, &ss,
+ &pp->s_stats.ltime, &pp->s_stats.best, &pp->s_stats.whenbest,
+
+ &pp->b_stats.num, &pp->b_stats.win, &pp->b_stats.los,
+ &pp->b_stats.dra, &pp->b_stats.rating, &bs,
+ &pp->b_stats.ltime, &pp->b_stats.best, &pp->b_stats.whenbest,
+
+ &pp->w_stats.num, &pp->w_stats.win, &pp->w_stats.los,
+ &pp->w_stats.dra, &pp->w_stats.rating, &ws,
+ &pp->w_stats.ltime, &pp->w_stats.best, &pp->w_stats.whenbest,
+
+ &pp->l_stats.num, &pp->l_stats.win, &pp->l_stats.los,
+ &pp->l_stats.dra, &pp->l_stats.rating, &ls,
+ &pp->l_stats.ltime, &pp->l_stats.best, &pp->l_stats.whenbest,
+
+ &pp->bug_stats.num, &pp->bug_stats.win, &pp->bug_stats.los,
+ &pp->bug_stats.dra, &pp->bug_stats.rating, &bugs,
+ &pp->bug_stats.ltime, &pp->bug_stats.best, &pp->bug_stats.whenbest,
+ &pp->lastHost) != 46) {
+ fprintf(stderr,"Player %s is corrupt\n",parray[p].name);
+ return;
+ }
+
+ pp->b_stats.sterr = bs / 10.0;
+ pp->s_stats.sterr = ss / 10.0;
+ pp->w_stats.sterr = ws / 10.0;
+ pp->l_stats.sterr = ls / 10.0;
+ pp->bug_stats.sterr = bugs / 10.0;
+
+ fgets (tmp2, MAX_STRING_LENGTH, fp);
+ tmp2[strlen(tmp2)-1] = '\0';
+ pp->prompt = strdup(tmp2);
+ if (fscanf (fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ &pp->open, &pp->rated, &pp->ropen, &pp->timeOfReg,
+ &pp->totalTime, &pp->bell, &pp->pgn, &pp->notifiedby,
+ &pp->i_login, &pp->i_game, &pp->i_shout, &pp->i_cshout,
+ &pp->i_tell, &pp->i_kibitz, &pp->private, &pp->jprivate,
+ &pp->automail, &pp->i_mailmess, &pp->style, &pp->d_time,
+ &pp->d_inc, &pp->d_height, &pp->d_width, &pp->language,
+ &pp->adminLevel, &pp->num_white, &pp->num_black, &pp->highlight,
+ &pp->num_comments,
+ &pp->num_plan, &pp->num_formula,&size_cens,
+ &size_not, &size_noplay,
+ &size_gnot, &pp->numAlias, &size_chan) != 37) {
+ fprintf(stderr,"Player %s is corrupt\n",parray[p].name);
+ return;
+ }
+
+ if (pp->num_plan > 0) {
+ for (i = 0; i < pp->num_plan; i++) {
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp2))) {
+ fprintf(stderr, "FICS: Error bad plan in file %s\n", file);
+ i--;
+ pp->num_plan--;
+ } else {
+ tmp2[len - 1] = '\0'; /* Get rid of '\n' */
+ pp->planLines[i] = (len > 1) ? strdup(tmp2) : NULL;
+ }
+ }
+ }
+ if (pp->num_formula > 0) {
+ for (i = 0; i < pp->num_formula; i++) {
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp2))) {
+ fprintf(stderr, "FICS: Error bad formula in file %s\n", file);
+ i--;
+ pp->num_formula--;
+ } else {
+ tmp2[len - 1] = '\0'; /* Get rid of '\n' */
+ pp->formulaLines[i] = (len > 1) ? strdup(tmp2) : NULL;
+ }
+ }
+ }
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ tmp2[strlen(tmp2) - 1] = '\0';
+ if (!strcmp (tmp2,"NONE"))
+ pp->formula = NULL;
+ else
+ pp->formula = strdup(tmp2);
+
+ if (pp->numAlias > 0) {
+ for (i = 0; i < pp->numAlias; i++) {
+ fgets(tmp2, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp2))) {
+ fprintf(stderr, "FICS: Error bad alias in file %s\n", file);
+ i--;
+ pp->numAlias--;
+ } else {
+ tmp2[len - 1] = '\0'; /* Get rid of '\n' */
+ tmp = tmp2;
+ tmp = eatword(tmp2);
+ *tmp = '\0';
+ tmp++;
+ tmp = eatwhite(tmp);
+ pp->alias_list[i].comm_name = strdup(tmp2);
+ pp->alias_list[i].alias = strdup(tmp);
+ }
+ }
+ }
+
+ while (size_cens--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_CENSOR, tmp2);
+ }
+
+ while(size_not--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_NOTIFY, tmp2);
+ }
+
+ while(size_noplay--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_NOPLAY, tmp2);
+ }
+
+ while(size_gnot--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_GNOTIFY, tmp2);
+ }
+
+ while(size_chan--) {
+ fscanf(fp,"%s",tmp2);
+ list_add(p, L_CHANNEL, tmp2);
+ }
+}
+
+PRIVATE int got_attr_value_player(int p, char *attr, char *value, FILE * fp, char *file)
+{
+ int i, len;
+ char tmp[MAX_LINE_SIZE], *tmp1;
+
+ if (!strcmp(attr, "name:")) {
+ parray[p].name = strdup(value);
+ } else if (!strcmp(attr, "password:")) {
+ parray[p].passwd = strdup(value);
+ } else if (!strcmp(attr, "fullname:")) {
+ parray[p].fullName = strdup(value);
+ } else if (!strcmp(attr, "email:")) {
+ parray[p].emailAddress = strdup(value);
+ } else if (!strcmp(attr, "prompt:")) {
+ parray[p].prompt = strdup(value);
+ } else if (!strcmp(attr, "s_num:")) {
+ parray[p].s_stats.num = atoi(value);
+ } else if (!strcmp(attr, "s_win:")) {
+ parray[p].s_stats.win = atoi(value);
+ } else if (!strcmp(attr, "s_loss:")) {
+ parray[p].s_stats.los = atoi(value);
+ } else if (!strcmp(attr, "s_draw:")) {
+ parray[p].s_stats.dra = atoi(value);
+ } else if (!strcmp(attr, "s_rating:")) {
+ parray[p].s_stats.rating = atoi(value);
+ } else if (!strcmp(attr, "s_sterr:")) {
+ parray[p].s_stats.sterr = (atoi(value) / 10.0);
+ } else if (!strcmp(attr, "s_ltime:")) {
+ parray[p].s_stats.ltime = atoi(value);
+ } else if (!strcmp(attr, "s_best:")) {
+ parray[p].s_stats.best = atoi(value);
+ } else if (!strcmp(attr, "s_wbest:")) {
+ parray[p].s_stats.whenbest = atoi(value);
+ } else if (!strcmp(attr, "b_num:")) {
+ parray[p].b_stats.num = atoi(value);
+ } else if (!strcmp(attr, "b_win:")) {
+ parray[p].b_stats.win = atoi(value);
+ } else if (!strcmp(attr, "b_loss:")) {
+ parray[p].b_stats.los = atoi(value);
+ } else if (!strcmp(attr, "b_draw:")) {
+ parray[p].b_stats.dra = atoi(value);
+ } else if (!strcmp(attr, "b_rating:")) {
+ parray[p].b_stats.rating = atoi(value);
+ } else if (!strcmp(attr, "b_sterr:")) {
+ parray[p].b_stats.sterr = (atoi(value) / 10.0);
+ } else if (!strcmp(attr, "b_ltime:")) {
+ parray[p].b_stats.ltime = atoi(value);
+ } else if (!strcmp(attr, "b_best:")) {
+ parray[p].b_stats.best = atoi(value);
+ } else if (!strcmp(attr, "b_wbest:")) {
+ parray[p].b_stats.whenbest = atoi(value);
+ } else if (!strcmp(attr, "w_num:")) {
+ parray[p].w_stats.num = atoi(value);
+ } else if (!strcmp(attr, "w_win:")) {
+ parray[p].w_stats.win = atoi(value);
+ } else if (!strcmp(attr, "w_loss:")) {
+ parray[p].w_stats.los = atoi(value);
+ } else if (!strcmp(attr, "w_draw:")) {
+ parray[p].w_stats.dra = atoi(value);
+ } else if (!strcmp(attr, "w_rating:")) {
+ parray[p].w_stats.rating = atoi(value);
+ } else if (!strcmp(attr, "w_sterr:")) {
+ parray[p].w_stats.sterr = (atoi(value) / 10.0);
+ } else if (!strcmp(attr, "w_ltime:")) {
+ parray[p].w_stats.ltime = atoi(value);
+ } else if (!strcmp(attr, "w_best:")) {
+ parray[p].w_stats.best = atoi(value);
+ } else if (!strcmp(attr, "w_wbest:")) {
+ parray[p].w_stats.whenbest = atoi(value);
+ } else if (!strcmp(attr, "open:")) {
+ parray[p].open = atoi(value);
+ } else if (!strcmp(attr, "rated:")) {
+ parray[p].rated = atoi(value);
+ } else if (!strcmp(attr, "ropen:")) {
+ parray[p].ropen = atoi(value);
+ } else if (!strcmp(attr, "bell:")) {
+ parray[p].bell = atoi(value);
+ } else if (!strcmp(attr, "pgn:")) {
+ parray[p].pgn = atoi(value);
+ } else if (!strcmp(attr, "timeofreg:")) {
+ parray[p].timeOfReg = atoi(value);
+ } else if (!strcmp(attr, "totaltime:")) {
+ parray[p].totalTime = atoi(value);
+ } else if (!strcmp(attr, "notifiedby:")) {
+ parray[p].notifiedby = atoi(value);
+ } else if (!strcmp(attr, "i_login:")) {
+ parray[p].i_login = atoi(value);
+ } else if (!strcmp(attr, "i_game:")) {
+ parray[p].i_game = atoi(value);
+ } else if (!strcmp(attr, "i_shout:")) {
+ parray[p].i_shout = atoi(value);
+ } else if (!strcmp(attr, "i_cshout:")) {
+ parray[p].i_cshout = atoi(value);
+ } else if (!strcmp(attr, "i_tell:")) {
+ parray[p].i_tell = atoi(value);
+ } else if (!strcmp(attr, "i_kibitz:")) {
+ parray[p].i_kibitz = atoi(value);
+ } else if (!strcmp(attr, "kiblevel:")) {
+ parray[p].kiblevel = atoi(value);
+ } else if (!strcmp(attr, "private:")) {
+ parray[p].private = atoi(value);
+ } else if (!strcmp(attr, "jprivate:")) {
+ parray[p].jprivate = atoi(value);
+ } else if (!strcmp(attr, "automail:")) {
+ parray[p].automail = atoi(value);
+ } else if (!strcmp(attr, "i_mailmess:")) {
+ parray[p].i_mailmess = atoi(value);
+ } else if (!strcmp(attr, "style:")) {
+ parray[p].style = atoi(value);
+ } else if (!strcmp(attr, "d_time:")) {
+ parray[p].d_time = atoi(value);
+ } else if (!strcmp(attr, "d_inc:")) {
+ parray[p].d_inc = atoi(value);
+ } else if (!strcmp(attr, "d_height:")) {
+ parray[p].d_height = atoi(value);
+ } else if (!strcmp(attr, "d_width:")) {
+ parray[p].d_width = atoi(value);
+ } else if (!strcmp(attr, "language:")) {
+ parray[p].language = atoi(value);
+ } else if (!strcmp(attr, "admin_level:")) {
+ parray[p].adminLevel = atoi(value);
+ if (parray[p].adminLevel >= ADMIN_ADMIN)
+ parray[p].i_admin = 1;
+ } else if (!strcmp(attr, "i_admin:")) {
+/* parray[p].i_admin = atoi(value); */
+ } else if (!strcmp(attr, "computer:")) {
+/* parray[p].computer = atoi(value); */
+ } else if (!strcmp(attr, "black_games:")) {
+ parray[p].num_black = atoi(value);
+ } else if (!strcmp(attr, "white_games:")) {
+ parray[p].num_white = atoi(value);
+ } else if (!strcmp(attr, "uscf:")) {
+/* parray[p].uscfRating = atoi(value); */
+ } else if (!strcmp(attr, "muzzled:")) { /* ignore these: obsolete */
+ } else if (!strcmp(attr, "cmuzzled:")) { /* ignore these: obsolete */
+ } else if (!strcmp(attr, "highlight:")) {
+ parray[p].highlight = atoi(value);
+ } else if (!strcmp(attr, "network:")) {
+/* parray[p].network_player = atoi(value); */
+ } else if (!strcmp(attr, "lasthost:")) {
+ parray[p].lastHost = atoi(value);
+ } else if (!strcmp(attr, "channel:")) {
+ list_addsub(p,"channel",value, 1);
+ } else if (!strcmp(attr, "num_comments:")) {
+ parray[p].num_comments = atoi(value);
+ } else if (!strcmp(attr, "num_plan:")) {
+ parray[p].num_plan = atoi(value);
+ if (parray[p].num_plan > 0) {
+ for (i = 0; i < parray[p].num_plan; i++) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp))) {
+ fprintf(stderr, "FICS: Error bad plan in file %s\n", file);
+ i--;
+ parray[p].num_plan--;
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ parray[p].planLines[i] = (len > 1) ? strdup(tmp) : NULL;
+ }
+ }
+ }
+ } else if (!strcmp(attr, "num_formula:")) {
+ parray[p].num_formula = atoi(value);
+ if (parray[p].num_formula > 0) {
+ for (i = 0; i < parray[p].num_formula; i++) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp))) {
+ fprintf(stderr, "FICS: Error bad formula in file %s\n", file);
+ i--;
+ parray[p].num_formula--;
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ parray[p].formulaLines[i] = (len > 1) ? strdup(tmp) : NULL;
+ }
+ }
+ }
+ } else if (!strcmp(attr, "formula:")) {
+ parray[p].formula = strdup(value);
+ } else if (!strcmp(attr, "num_alias:")) {
+ parray[p].numAlias = atoi(value);
+ if (parray[p].numAlias > 0) {
+ for (i = 0; i < parray[p].numAlias; i++) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!(len = strlen(tmp))) {
+ fprintf(stderr, "FICS: Error bad alias in file %s\n", file);
+ i--;
+ parray[p].numAlias--;
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ tmp1 = tmp;
+ tmp1 = eatword(tmp1);
+ *tmp1 = '\0';
+ tmp1++;
+ tmp1 = eatwhite(tmp1);
+ parray[p].alias_list[i].comm_name = strdup(tmp);
+ parray[p].alias_list[i].alias = strdup(tmp1);
+ }
+ }
+ }
+ } else if (!strcmp(attr, "num_censor:")) {
+ i = atoi(value);
+ while (i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ fprintf(stderr, "FICS: Error bad censor in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_CENSOR, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_notify:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ fprintf(stderr, "FICS: Error bad notify in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_NOTIFY, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_noplay:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ fprintf(stderr, "FICS: Error bad noplay in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_NOPLAY, tmp);
+ }
+ }
+ } else if (!strcmp(attr, "num_gnotify:")) {
+ i = atoi(value);
+ while(i--) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if ((!(len = strlen(tmp))) || (len == 1)) { /* blank lines do occur!! */
+ fprintf(stderr, "FICS: Error bad gnotify in file %s\n", file);
+ } else {
+ tmp[len - 1] = '\0'; /* Get rid of '\n' */
+ list_add(p, L_GNOTIFY, tmp);
+ }
+ }
+ } else {
+ fprintf(stderr, "FICS: Error bad attribute >%s< from file %s\n", attr, file);
+ }
+ return 0;
+}
+
+PUBLIC int player_read(int p, char *name)
+{
+ char fname[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ char *attr, *value;
+ FILE *fp;
+ int len;
+ int version = 0;
+
+ parray[p].login = stolower(strdup(name));
+
+ sprintf(fname, "%s/%c/%s", player_dir, parray[p].login[0], parray[p].login);
+ fp = fopen(fname, "r");
+
+ if (!fp) { /* unregistered player */
+ parray[p].name = strdup(name);
+ parray[p].registered = 0;
+ return -1;
+ }
+
+ parray[p].registered = 1; /* lets load the file */
+
+ fgets(line, MAX_LINE_SIZE, fp); /* ok so which version file? */
+
+ if (line[0] == 'v') {
+ sscanf(line, "%*c %d", &version);
+ }
+
+ if (version > 0) {
+ ReadV1PlayerFmt(p,&parray[p], fp, fname, version); /* Quick method */
+ }
+ else /* do it the old SLOW way */
+ do {
+ if (feof(fp))
+ break;
+ if ((len = strlen(line)) <= 1)
+ continue;
+ line[len - 1] = '\0';
+ attr = eatwhite(line);
+ if (attr[0] == '#')
+ continue; /* Comment */
+ value = eatword(attr);
+ if (!*value) {
+ fprintf(stderr, "FICS: Error reading file %s\n", fname);
+ continue;
+ }
+ *value = '\0';
+ value++;
+ value = eatwhite(value);
+ stolower(attr);
+ got_attr_value_player(p, attr, value, fp, fname);
+ fgets(line, MAX_LINE_SIZE, fp);
+ } while (!feof(fp));
+
+ fclose(fp);
+
+ if (version == 0)
+ player_save (p); /* ensure old files are quickly converted eg when someone
+ fingers */
+ if (!parray[p].name) {
+ parray[p].name = strdup(name);
+ pprintf(p, "\n*** WARNING: Your Data file is corrupt. Please tell an admin ***\n");
+ }
+ return 0;
+}
+
+PUBLIC int player_delete(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered) { /* Player must not be registered */
+ return -1;
+ }
+/* if (iamserver)
+ sprintf(fname, "%s.server/%c/%s", player_dir, parray[p].login[0], parray[p].login);
+ else */
+ sprintf(fname, "%s/%c/%s", player_dir, parray[p].login[0], parray[p].login);
+ unlink(fname);
+ return 0;
+}
+
+PUBLIC int player_markdeleted(int p)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered) { /* Player must not be registered */
+ return -1;
+ }
+/* if (iamserver) {
+ sprintf(fname, "%s.server/%c/%s", player_dir, parray[p].login[0], parray[p].login);
+ sprintf(fname2, "%s.server/%c/%s.delete", player_dir, parray[p].login[0], parray[p].login);
+ } else {*/
+ sprintf(fname, "%s/%c/%s", player_dir, parray[p].login[0], parray[p].login);
+ sprintf(fname2, "%s/%c/%s.delete", player_dir, parray[p].login[0], parray[p].login);
+/* } */
+ rename(fname, fname2);
+ fp = fopen(fname2, "a"); /* Touch the file */
+ if (fp) {
+ fprintf(fp, "\n");
+ fclose(fp);
+ }
+ return 0;
+}
+
+void WritePlayerFile(FILE* fp, int p)
+{
+ int i;
+ player *pp = &parray[p];
+
+ fprintf (fp, "v %d\n", PLAYER_VERSION);
+ if (pp->name == NULL) /* This should never happen! */
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->name);
+ if (pp->fullName == NULL)
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->fullName);
+ if (pp->passwd == NULL)
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->passwd);
+ if (pp->emailAddress == NULL)
+ fprintf (fp,"NONE\n");
+ else
+ fprintf(fp, "%s\n", pp->emailAddress);
+ fprintf(fp, "%u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %u %d\n",
+
+ pp->s_stats.num, pp->s_stats.win, pp->s_stats.los,
+ pp->s_stats.dra, pp->s_stats.rating, (int) (pp->s_stats.sterr * 10.0),
+ pp->s_stats.ltime, pp->s_stats.best, pp->s_stats.whenbest,
+
+ pp->b_stats.num, pp->b_stats.win, pp->b_stats.los,
+ pp->b_stats.dra, pp->b_stats.rating, (int) (pp->b_stats.sterr * 10.0),
+ pp->b_stats.ltime, pp->b_stats.best, pp->b_stats.whenbest,
+
+ pp->w_stats.num, pp->w_stats.win, pp->w_stats.los,
+ pp->w_stats.dra, pp->w_stats.rating, (int) (pp->w_stats.sterr * 10.0),
+ pp->w_stats.ltime, pp->w_stats.best, pp->w_stats.whenbest,
+
+ pp->l_stats.num, pp->l_stats.win, pp->l_stats.los,
+ pp->l_stats.dra, pp->l_stats.rating, (int) (pp->l_stats.sterr * 10.0),
+ pp->l_stats.ltime, pp->l_stats.best, pp->l_stats.whenbest,
+
+ pp->bug_stats.num, pp->bug_stats.win, pp->bug_stats.los,
+ pp->bug_stats.dra, pp->bug_stats.rating, (int) (pp->bug_stats.sterr * 10.0),
+ pp->bug_stats.ltime, pp->bug_stats.best, pp->bug_stats.whenbest,
+ pp->lastHost);
+
+ fprintf (fp, "%s\n", pp->prompt);
+ fprintf (fp, "%d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d %d\n",
+ pp->open, pp->rated, pp->ropen, pp->timeOfReg,
+ pp->totalTime, pp->bell, pp->pgn, pp->notifiedby,
+ pp->i_login, pp->i_game, pp->i_shout, pp->i_cshout,
+ pp->i_tell, pp->i_kibitz, pp->private, pp->jprivate,
+ pp->automail, pp->i_mailmess, pp->style, pp->d_time,
+ pp->d_inc, pp->d_height, pp->d_width, pp->language,
+ pp->adminLevel, pp->num_white, pp->num_black, pp->highlight,
+ pp->num_comments,
+ pp->num_plan, pp->num_formula,list_size(p, L_CENSOR),
+ list_size(p, L_NOTIFY), list_size(p, L_NOPLAY),
+ list_size(p, L_GNOTIFY), pp->numAlias, list_size(p, L_CHANNEL ));
+ for (i = 0; i < pp->num_plan; i++)
+ fprintf(fp, "%s\n", (pp->planLines[i] ? pp->planLines[i] : ""));
+ for (i = 0; i < pp->num_formula; i++)
+ fprintf(fp, "%s\n", (pp->formulaLines[i] ? pp->formulaLines[i] : ""));
+ if (parray[p].formula != NULL)
+ fprintf(fp, "%s\n", pp->formula);
+ else
+ fprintf(fp, "NONE\n");
+ for (i = 0; i < pp->numAlias; i++)
+ fprintf(fp, "%s %s\n", pp->alias_list[i].comm_name,
+ pp->alias_list[i].alias);
+
+ list_print(fp, p, L_CENSOR);
+ list_print(fp, p, L_NOTIFY);
+ list_print(fp, p, L_NOPLAY);
+ list_print(fp, p, L_GNOTIFY);
+ list_print(fp, p, L_CHANNEL);
+}
+
+ #if 0 /* the old way */
+ if (parray[p].name)
+ fprintf(fp, "Name: %s\n", parray[p].name);
+ if (parray[p].fullName)
+ fprintf(fp, "Fullname: %s\n", parray[p].fullName);
+ if (parray[p].passwd)
+ fprintf(fp, "Password: %s\n", parray[p].passwd);
+ if (parray[p].emailAddress)
+ fprintf(fp, "Email: %s\n", parray[p].emailAddress);
+ fprintf(fp, "S_NUM: %u\n", parray[p].s_stats.num);
+ fprintf(fp, "S_WIN: %u\n", parray[p].s_stats.win);
+ fprintf(fp, "S_LOSS: %u\n", parray[p].s_stats.los);
+ fprintf(fp, "S_DRAW: %u\n", parray[p].s_stats.dra);
+ fprintf(fp, "S_RATING: %u\n", parray[p].s_stats.rating);
+ fprintf(fp, "S_STERR: %u\n", (int) (parray[p].s_stats.sterr * 10.0));
+ fprintf(fp, "S_LTIME: %u\n", parray[p].s_stats.ltime);
+ fprintf(fp, "S_BEST: %u\n", parray[p].s_stats.best);
+ fprintf(fp, "S_WBEST: %u\n", parray[p].s_stats.whenbest);
+ fprintf(fp, "B_NUM: %u\n", parray[p].b_stats.num);
+ fprintf(fp, "B_WIN: %u\n", parray[p].b_stats.win);
+ fprintf(fp, "B_LOSS: %u\n", parray[p].b_stats.los);
+ fprintf(fp, "B_DRAW: %u\n", parray[p].b_stats.dra);
+ fprintf(fp, "B_RATING: %u\n", parray[p].b_stats.rating);
+ fprintf(fp, "B_STERR: %u\n", (int) (parray[p].b_stats.sterr * 10.0));
+ fprintf(fp, "B_LTIME: %u\n", parray[p].b_stats.ltime);
+ fprintf(fp, "B_BEST: %u\n", parray[p].b_stats.best);
+ fprintf(fp, "B_WBEST: %u\n", parray[p].b_stats.whenbest);
+ fprintf(fp, "W_NUM: %u\n", parray[p].w_stats.num);
+ fprintf(fp, "W_WIN: %u\n", parray[p].w_stats.win);
+ fprintf(fp, "W_LOSS: %u\n", parray[p].w_stats.los);
+ fprintf(fp, "W_DRAW: %u\n", parray[p].w_stats.dra);
+ fprintf(fp, "W_RATING: %u\n", parray[p].w_stats.rating);
+ fprintf(fp, "W_STERR: %u\n", (int) (parray[p].w_stats.sterr * 10.0));
+ fprintf(fp, "W_LTIME: %u\n", parray[p].w_stats.ltime);
+ fprintf(fp, "W_BEST: %u\n", parray[p].w_stats.best);
+ fprintf(fp, "W_WBEST: %u\n", parray[p].w_stats.whenbest);
+ /* fprintf(fp, "Network: %d\n", parray[p].network_player); */
+ /* if (iamserver)
+ return 0; *//* No need to write any more */
+
+ fprintf(fp, "LastHost: %d\n", parray[p].lastHost);
+ if (parray[p].prompt != def_prompt)
+ fprintf(fp, "Prompt: %s\n", parray[p].prompt);
+ fprintf(fp, "Open: %d\n", parray[p].open);
+ fprintf(fp, "Rated: %d\n", parray[p].rated);
+ fprintf(fp, "Ropen: %d\n", parray[p].ropen);
+ fprintf(fp, "timeofreg: %d\n", parray[p].timeOfReg);
+ fprintf(fp, "totaltime: %d\n", parray[p].totalTime);
+ fprintf(fp, "Bell: %d\n", parray[p].bell);
+ fprintf(fp, "PGN: %d\n", parray[p].pgn);
+ fprintf(fp, "Notifiedby: %d\n", parray[p].notifiedby);
+ fprintf(fp, "I_Login: %d\n", parray[p].i_login);
+ fprintf(fp, "I_Game: %d\n", parray[p].i_game);
+ fprintf(fp, "I_Shout: %d\n", parray[p].i_shout);
+ fprintf(fp, "I_CShout: %d\n", parray[p].i_cshout);
+ fprintf(fp, "I_Tell: %d\n", parray[p].i_tell);
+ fprintf(fp, "I_Kibitz: %d\n", parray[p].i_kibitz);
+ fprintf(fp, "Private: %d\n", parray[p].private);
+ fprintf(fp, "JPrivate: %d\n", parray[p].jprivate);
+ fprintf(fp, "Automail: %d\n", parray[p].automail);
+ fprintf(fp, "I_Mailmess: %d\n", parray[p].i_mailmess);
+ fprintf(fp, "Style: %d\n", parray[p].style);
+ fprintf(fp, "D_Time: %d\n", parray[p].d_time);
+ fprintf(fp, "D_Inc: %d\n", parray[p].d_inc);
+ fprintf(fp, "D_Height: %d\n", parray[p].d_height);
+ fprintf(fp, "D_Width: %d\n", parray[p].d_width);
+ fprintf(fp, "Language: %d\n", parray[p].language);
+ fprintf(fp, "Admin_level: %d\n", parray[p].adminLevel);
+ /* fprintf(fp, "I_Admin: %d\n", parray[p].i_admin); */
+ /* if (parray[p].computer) {
+ fprintf(fp, "Computer: %d\n", parray[p].computer);
+ } */
+ fprintf(fp, "White_Games: %d\n", parray[p].num_white);
+ fprintf(fp, "Black_Games: %d\n", parray[p].num_black);
+ /* fprintf(fp, "USCF: %d\n", parray[p].uscfRating); */
+ fprintf(fp, "Highlight: %d\n", parray[p].highlight);
+ fprintf(fp, "Num_Comments: %d\n", parray[p].num_comments);
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (on_channel(i, p))
+ fprintf(fp, "Channel: %d\n", i);
+ }
+ fprintf(fp, "Num_plan: %d\n", parray[p].num_plan);
+ for (i = 0; i < parray[p].num_plan; i++)
+ fprintf(fp, "%s\n", (parray[p].planLines[i] ? parray[p].planLines[i] : ""));
+ fprintf(fp, "Num_formula: %d\n", parray[p].num_formula);
+ for (i = 0; i < parray[p].num_formula; i++)
+ fprintf(fp, "%s\n", (parray[p].formulaLines[i] ? parray[p].formulaLines[i] : ""));
+ if (parray[p].formula != NULL)
+ fprintf(fp, "Formula: %s\n", parray[p].formula);
+ fprintf(fp, "Num_censor: %d\n", list_size(p, L_CENSOR));
+ list_print(fp, p, L_CENSOR);
+ fprintf(fp, "Num_notify: %d\n", list_size(p, L_NOTIFY));
+ list_print(fp, p, L_NOTIFY);
+ fprintf(fp, "Num_noplay: %d\n", list_size(p, L_NOPLAY));
+ list_print(fp, p, L_NOPLAY);
+ fprintf(fp, "Num_gnotify: %d\n", list_size(p, L_GNOTIFY));
+ list_print(fp, p, L_GNOTIFY);
+ fprintf(fp, "Num_alias: %d\n", parray[p].numAlias);
+ for (i = 0; i < parray[p].numAlias; i++)
+ fprintf(fp, "%s %s\n", parray[p].alias_list[i].comm_name,
+ parray[p].alias_list[i].alias);
+ }
+ #endif
+
+PUBLIC int player_save(int p)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered) { /* Player must not be registered */
+ return -1;
+ }
+ if (parray[p].name == NULL) { /* fixes a bug if name is null */
+ pprintf(p, "WARNING: Your player file could not be updated, due to corrupt data.\n");
+ return -1;
+ }
+ if (strcasecmp(parray[p].login, parray[p].name)) {
+ pprintf(p, "WARNING: Your player file could not be updated, due to corrupt data.\n");
+ return -1;
+ }
+
+ sprintf(fname, "%s/%c/%s", player_dir, parray[p].login[0], parray[p].login);
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Problem opening file %s for write\n", fname);
+ return -1;
+ }
+
+ WritePlayerFile(fp,p);
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int player_find(int fd)
+{
+ int i;
+
+ for (i = 0; i < p_num; i++) {
+ if (parray[i].status == PLAYER_EMPTY)
+ continue;
+ if (parray[i].socket == fd)
+ return i;
+ }
+ return -1;
+}
+
+PUBLIC int player_find_bylogin(char *name)
+{
+ int i;
+
+ for (i = 0; i < p_num; i++) {
+ if ((parray[i].status == PLAYER_EMPTY) ||
+ (parray[i].status == PLAYER_LOGIN) ||
+ (parray[i].status == PLAYER_PASSWORD))
+ continue;
+ if (!parray[i].login)
+ continue;
+ if (!strcmp(parray[i].login, name))
+ return i;
+ }
+ return -1;
+}
+
+PUBLIC int player_find_part_login(char *name)
+{
+ int i;
+ int found = -1;
+
+ i = player_find_bylogin(name);
+ if (i >= 0)
+ return i;
+ for (i = 0; i < p_num; i++) {
+ if ((parray[i].status == PLAYER_EMPTY) ||
+ (parray[i].status == PLAYER_LOGIN) ||
+ (parray[i].status == PLAYER_PASSWORD))
+ continue;
+ if (!parray[i].login)
+ continue;
+ if (!strncmp(parray[i].login, name, strlen(name))) {
+ if (found >= 0) { /* Ambiguous */
+ return -2;
+ }
+ found = i;
+ }
+ }
+ return found;
+}
+
+PUBLIC int player_censored(int p, int p1)
+{
+ if (in_list(p, L_CENSOR, parray[p1].login))
+ return 1;
+ else
+ return 0;
+}
+
+/* is p1 on p's notify list? */
+PUBLIC int player_notified(int p, int p1)
+{
+ if (!parray[p1].registered)
+ return 0;
+
+ /* possible bug: p has just arrived! */
+ if (!parray[p].name)
+ return 0;
+
+ return (in_list(p, L_NOTIFY, parray[p1].login));
+}
+
+PUBLIC void player_notify_departure(int p)
+/* Notify those with notifiedby set on a departure */
+{
+ int p1;
+
+ if (!parray[p].registered)
+ return;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].notifiedby && !player_notified(p1, p) && player_notified(p, p1)
+ && (parray[p1].status == PLAYER_PROMPT)) {
+ if (parray[p1].bell)
+ pprintf_noformat(p1, "\007");
+ pprintf(p1, "\nNotification: ");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " has departed and isn't on your notify list.\n");
+ }
+ }
+}
+
+PUBLIC int player_notify_present(int p)
+/* output Your arrival was notified by..... */
+/* also notify those with notifiedby set if necessary */
+{
+ int p1;
+ int count = 0;
+
+ if (!parray[p].registered)
+ return count;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if ((player_notified(p, p1)) && (parray[p1].status == PLAYER_PROMPT)) {
+ if (!count) {
+ pprintf(p, "Present company includes:");
+ }
+ count++;
+ pprintf(p, " %s", parray[p1].name);
+ if ((parray[p1].notifiedby) && (!player_notified(p1, p))
+ && (parray[p1].status == PLAYER_PROMPT)) {
+ if (parray[p1].bell)
+ pprintf_noformat(p1, "\007");
+ pprintf(p1, "\nNotification: ");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " has arrived and isn't on your notify list.\n");
+ }
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ return count;
+}
+
+PUBLIC int player_notify(int p, char *note1, char *note2)
+/* notify those interested that p has arrived/departed */
+{
+ int p1;
+ int count = 0;
+
+ if (!parray[p].registered)
+ return count;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if ((player_notified(p1, p)) && (parray[p1].status == PLAYER_PROMPT)) {
+ if (parray[p1].bell)
+ pprintf_noformat(p1, "\007");
+ pprintf(p1, "\nNotification: ");
+ pprintf_highlight(p1, "%s", parray[p].name);
+ pprintf_prompt(p1, " has %s.\n", note1);
+ if (!count) {
+ pprintf(p, "Your %s was noted by:", note2);
+ }
+ count++;
+ pprintf(p, " %s", parray[p1].name);
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ return count;
+}
+
+/* Show adjourned games upon logon. connex/sous@ipp.tu-clausthal.de
+24.10.1995 */
+PUBLIC int showstored(int p)
+{
+ DIR *dirp;
+#ifdef USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+ int c=0,p1;
+ char dname[MAX_FILENAME_SIZE];
+ multicol *m = multicol_start(50); /* Limit to 50, should be enough*/
+
+ sprintf(dname, "%s/%c", adj_dir, parray[p].login[0]);
+ dirp = opendir(dname);
+ if (!dirp) {
+ multicol_end(m);
+ return COM_OK;
+ }
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (file_has_pname(dp->d_name, parray[p].login)) {
+ if (strcmp(file_wplayer(dp->d_name),parray[p].login) != 0) {
+ p1=player_find_bylogin(file_wplayer(dp->d_name));
+ } else {
+ p1=player_find_bylogin(file_bplayer(dp->d_name));
+ }
+ if (p1>=0) {
+ if (c<50)
+ multicol_store(m,parray[p1].name);
+ pprintf(p1,"\nNotification: ");
+ pprintf_highlight(p1,"%s",parray[p].name);
+ pprintf_prompt(p1,", who has an adjourned game with you, has arrived.\n");
+ c++;
+ }
+ }
+ }
+ closedir(dirp);
+ if (c == 1) {
+ pprintf(p, "1 player, who has an adjourned game with you, is online:\007");
+ } else if (c > 1) {
+ pprintf(p, "\n%d players, who have an adjourned game with you, are online:\007",c);
+ }
+ if (c != 0)
+ multicol_pprint(m,p,parray[p].d_width,2);
+ multicol_end(m);
+/* pprintf(p,"\n"); */
+ return COM_OK;
+}
+
+
+PUBLIC int player_count(int CountAdmins)
+{
+ int count;
+ int i;
+
+ for (count = 0, i = 0; i < p_num; i++) {
+ if ((parray[i].status == PLAYER_PROMPT) &&
+ (CountAdmins || !in_list(i, L_ADMIN, parray[i].name)))
+ count++;
+ }
+ if (count > player_high)
+ player_high = count;
+
+ return count;
+}
+
+PUBLIC int player_idle(int p)
+{
+ if (parray[p].status != PLAYER_PROMPT)
+ return time(0) - parray[p].logon_time;
+ else
+ return time(0) - parray[p].last_command_time;
+}
+
+PUBLIC int player_ontime(int p)
+{
+ return time(0) - parray[p].logon_time;
+}
+
+PRIVATE void write_p_inout(int inout, int p, char *file, int maxlines)
+{
+ FILE *fp;
+
+ fp = fopen(file, "a");
+ if (!fp)
+ return;
+ fprintf(fp, "%d %s %d %d %s\n", inout, parray[p].name, (int) time(0),
+ parray[p].registered, dotQuad(parray[p].thisHost));
+ fclose(fp);
+ if (maxlines)
+ truncate_file(file, maxlines);
+}
+
+PUBLIC void player_write_login(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (parray[p].registered) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS);
+ write_p_inout(P_LOGIN, p, fname, 8);
+ }
+ sprintf(fname, "%s/%s", stats_dir, STATS_LOGONS);
+ write_p_inout(P_LOGIN, p, fname, 30);
+ /* added complete login/logout log to "logons.log" file */
+ sprintf(fname, "%s/%s", stats_dir, "logons.log");
+ write_p_inout(P_LOGIN, p, fname, 0);
+}
+
+PUBLIC void player_write_logout(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (parray[p].registered) {
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS);
+ write_p_inout(P_LOGOUT, p, fname, 8);
+ }
+ sprintf(fname, "%s/%s", stats_dir, STATS_LOGONS);
+ write_p_inout(P_LOGOUT, p, fname, 30);
+ /* added complete login/logout log to "logons.log" file */
+ sprintf(fname, "%s/%s", stats_dir, "logons.log");
+ write_p_inout(P_LOGOUT, p, fname, 0);
+}
+
+PUBLIC int player_lastconnect(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ int inout, thetime, registered;
+ int last = 0;
+ char loginName[MAX_LOGIN_NAME];
+ char ipstr[20];
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir,
+ parray[p].login[0], parray[p].login, STATS_LOGONS);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return 0;
+ inout = 1;
+ while (!feof(fp)) {
+ if (inout == P_LOGIN)
+ last = thetime;
+ if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime,
+ ®istered, ipstr) != 5) {
+ fprintf(stderr, "FICS: Error in login info format. %s\n", fname);
+ fclose(fp);
+ return 0;
+ }
+ }
+ fclose(fp);
+ return last;
+}
+
+PUBLIC int player_lastdisconnect(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ int inout, thetime, registered;
+ int last = 0;
+ char ipstr[20];
+ char loginName[MAX_LOGIN_NAME];
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0], parray[p].login, STATS_LOGONS);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return 0;
+ while (!feof(fp)) {
+ if (fscanf(fp, "%d %s %d %d %s\n", &inout, loginName, &thetime, ®istered, ipstr) != 5) {
+ fprintf(stderr, "FICS: Error in login info format. %s\n", fname);
+ fclose(fp);
+ return 0;
+ }
+ if (inout == P_LOGOUT)
+ last = thetime;
+ }
+ fclose(fp);
+ return last;
+}
+
+PUBLIC void player_pend_print(int p, pending *pend)
+{
+ char outstr[200];
+ char tmp[200];
+
+ if (p == pend->whofrom) {
+ sprintf(outstr, "You are offering ");
+ } else {
+ sprintf(outstr, "%s is offering ", parray[pend->whofrom].name);
+ }
+
+ if (p == pend->whoto) {
+ strcpy(tmp, "");
+ } else {
+ sprintf(tmp, "%s ", parray[pend->whoto].name);
+ }
+
+ strcat(outstr, tmp);
+ switch (pend->type) {
+ case PEND_MATCH:
+ sprintf(tmp, "%s.", game_str(pend->param5, pend->param1 * 60, pend->param2, pend->param3 * 60, pend->param4, pend->char1, pend->char2));
+ break;
+ case PEND_DRAW:
+ sprintf(tmp, "a draw.\n");
+ break;
+ case PEND_PAUSE:
+ sprintf(tmp, "to pause the clock.\n");
+ break;
+ case PEND_ABORT:
+ sprintf(tmp, "to abort the game.\n");
+ break;
+ case PEND_TAKEBACK:
+ sprintf(tmp, "to takeback the last %d half moves.\n", pend->param1);
+ break;
+ case PEND_SIMUL:
+ sprintf(tmp, "to play a simul match.\n");
+ break;
+ case PEND_SWITCH:
+ sprintf(tmp, "to switch sides.\n");
+ break;
+ case PEND_ADJOURN:
+ sprintf(tmp, "an adjournment.\n");
+ break;
+ case PEND_PARTNER:
+ sprintf(tmp, "to be bughouse partners.\n");
+ break;
+ }
+ strcat(outstr, tmp);
+ pprintf(p, "%s\n", outstr);
+}
+
+PUBLIC int player_find_pendto(int p, int p1, int type)
+{
+ int i;
+
+ for (i = 0; i < parray[p].num_to; i++) {
+ if (parray[p].p_to_list[i].whoto != p1 && p1 != -1)
+ continue;
+ if (type < 0 || parray[p].p_to_list[i].type == type)
+ return i;
+ if (type == PEND_BUGHOUSE
+ && parray[p].p_to_list[i].type == PEND_MATCH
+ && !strcmp(parray[p].p_to_list[i].char2, "bughouse"))
+ return i;
+ }
+ return -1;
+}
+
+PUBLIC int player_new_pendto(int p)
+{
+ if (parray[p].num_to >= MAX_PENDING)
+ return -1;
+ parray[p].num_to++;
+ return parray[p].num_to - 1;
+}
+
+PUBLIC int player_remove_pendto(int p, int p1, int type)
+{
+ int w;
+ if ((w = player_find_pendto(p, p1, type)) < 0)
+ return -1;
+ for (; w < parray[p].num_to - 1; w++)
+ parray[p].p_to_list[w] = parray[p].p_to_list[w + 1];
+ parray[p].num_to = parray[p].num_to - 1;
+ return 0;
+}
+
+PUBLIC int player_find_pendfrom(int p, int p1, int type)
+{
+ int i;
+
+ for (i = 0; i < parray[p].num_from; i++) {
+ if (parray[p].p_from_list[i].whofrom != p1 && p1 != -1)
+ continue;
+ if (type == PEND_ALL || parray[p].p_from_list[i].type == type)
+ return i;
+ if (type < 0 && parray[p].p_from_list[i].type != -type)
+ return i;
+ /* The above "if" allows a type of -PEND_SIMUL to match every request
+ EXCEPT simuls, for example. I'm doing this because Heringer does
+ not want to decline simul requests when he makes a move in a sumul.
+ -- hersco. */
+ if (type == PEND_BUGHOUSE
+ && parray[p].p_from_list[i].type == PEND_MATCH
+ && !strcmp(parray[p].p_from_list[i].char2, "bughouse"))
+ return i;
+ }
+ return -1;
+}
+
+PUBLIC int player_new_pendfrom(int p)
+{
+ if (parray[p].num_from >= MAX_PENDING)
+ return -1;
+ parray[p].num_from++;
+ return parray[p].num_from - 1;
+}
+
+PUBLIC int player_remove_pendfrom(int p, int p1, int type)
+{
+ int w;
+ if ((w = player_find_pendfrom(p, p1, type)) < 0)
+ return -1;
+ for (; w < parray[p].num_from - 1; w++)
+ parray[p].p_from_list[w] = parray[p].p_from_list[w + 1];
+ parray[p].num_from = parray[p].num_from - 1;
+ return 0;
+}
+
+PUBLIC int player_add_request(int p, int p1, int type, int param)
+{
+ int pendt;
+ int pendf;
+
+ if (player_find_pendto(p, p1, type) >= 0)
+ return -1; /* Already exists */
+ pendt = player_new_pendto(p);
+ if (pendt == -1) {
+ return -1;
+ }
+ pendf = player_new_pendfrom(p1);
+ if (pendf == -1) {
+ parray[p].num_to--; /* Remove the pendto we allocated */
+ return -1;
+ }
+ parray[p].p_to_list[pendt].type = type;
+ parray[p].p_to_list[pendt].whoto = p1;
+ parray[p].p_to_list[pendt].whofrom = p;
+ parray[p].p_to_list[pendt].param1 = param;
+ parray[p1].p_from_list[pendf].type = type;
+ parray[p1].p_from_list[pendf].whoto = p1;
+ parray[p1].p_from_list[pendf].whofrom = p;
+ parray[p1].p_from_list[pendf].param1 = param;
+ return 0;
+}
+
+PUBLIC int player_remove_request(int p, int p1, int type)
+{
+ int to = 0, from = 0;
+
+ while (to != -1) {
+ to = player_find_pendto(p, p1, type);
+ if (to != -1) {
+ for (; to < parray[p].num_to - 1; to++)
+ parray[p].p_to_list[to] = parray[p].p_to_list[to + 1];
+ parray[p].num_to = parray[p].num_to - 1;
+ }
+ }
+ while (from != -1) {
+ from = player_find_pendfrom(p1, p, type);
+ if (from != -1) {
+ for (; from < parray[p1].num_from - 1; from++)
+ parray[p1].p_from_list[from] = parray[p1].p_from_list[from + 1];
+ parray[p1].num_from = parray[p1].num_from - 1;
+ }
+ }
+ if ((type == PEND_ALL || type == PEND_MATCH)
+ && parray[p].partner >= 0)
+ player_remove_request (parray[p].partner, p1, PEND_BUGHOUSE);
+ return 0;
+}
+
+
+PUBLIC int player_decline_offers(int p, int p1, int offerType)
+{
+ int offer;
+ int type, p2;
+ int count = 0;
+ int part, p2part;
+ char *pName = parray[p].name, *p2Name;
+
+ /* First get rid of bughouse offers from partner. */
+ if ((offerType == PEND_MATCH || offerType == PEND_ALL)
+ && parray[p].partner >= 0 && parray[parray[p].partner].partner == p)
+ count += player_decline_offers(parray[p].partner, p1, PEND_BUGHOUSE);
+
+ while ((offer = player_find_pendfrom(p, p1, offerType)) >= 0) {
+ type = parray[p].p_from_list[offer].type;
+ p2 = parray[p].p_from_list[offer].whofrom;
+ p2Name = parray[p2].name;
+
+ part = parray[p].partner;
+ if (part >= 0 && parray[part].partner != p)
+ part = -1;
+ p2part = parray[p2].partner;
+ if (p2part >= 0 && parray[p2part].partner != p2)
+ p2part = -1;
+
+ switch (type) {
+ case PEND_MATCH:
+ pprintf_prompt(p2, "\n%s declines the match offer.\n", pName);
+ pprintf(p, "You decline the match offer from %s.\n", p2Name);
+ if (!strcmp(parray[p].p_from_list[offer].char2, "bughouse")) {
+ if (part >= 0)
+ pprintf_prompt(part,
+ "Your partner declines the bughouse offer from %s.\n",
+ parray[p2].name);
+ if (p2part >= 0)
+ pprintf_prompt(p2part,
+ "%s declines the bughouse offer from your partner.\n",
+ parray[p].name);
+ }
+ break;
+ case PEND_DRAW:
+ pprintf_prompt(p2, "\n%s declines draw request.\n", pName);
+ pprintf(p, "You decline the draw request from %s.\n", p2Name);
+ break;
+ case PEND_PAUSE:
+ pprintf_prompt(p2, "\n%s declines pause request.\n", pName);
+ pprintf(p, "You decline the pause request from %s.\n", p2Name);
+ break;
+ case PEND_ABORT:
+ pprintf_prompt(p2, "\n%s declines abort request.\n", pName);
+ pprintf(p, "You decline the abort request from %s.\n", p2Name);
+ break;
+ case PEND_TAKEBACK:
+ pprintf_prompt(p2, "\n%s declines the takeback request.\n", pName);
+ pprintf(p, "You decline the takeback request from %s.\n", p2Name);
+ break;
+ case PEND_ADJOURN:
+ pprintf_prompt(p2, "\n%s declines the adjourn request.\n", pName);
+ pprintf(p, "You decline the adjourn request from %s.\n", p2Name);
+ break;
+ case PEND_SWITCH:
+ pprintf_prompt(p2, "\n%s declines the switch sides request.\n", pName);
+ pprintf(p, "You decline the switch sides request from %s.\n", p2Name);
+ break;
+ case PEND_SIMUL:
+ pprintf_prompt(p2, "\n%s declines the simul offer.\n", pName);
+ pprintf(p, "You decline the simul offer from %s.\n", p2Name);
+ break;
+ case PEND_PARTNER:
+ pprintf_prompt(p2, "\n%s declines your partnership request.\n", pName);
+ pprintf(p, "You decline the partnership request from %s.\n", p2Name);
+ break;
+ }
+ player_remove_request(p2, p, type);
+ count++;
+ }
+ return count;
+}
+
+
+PUBLIC int player_withdraw_offers(int p, int p1, int offerType)
+{
+ int offer;
+ int type, p2;
+ int count = 0;
+ int part, p2part;
+ char *pName = parray[p].name, *p2Name;
+
+ /* First get rid of bughouse offers from partner. */
+ if ((offerType == PEND_MATCH || offerType == PEND_ALL)
+ && parray[p].partner >= 0 && parray[parray[p].partner].partner == p)
+ count += player_withdraw_offers(parray[p].partner, p1, PEND_BUGHOUSE);
+
+ while ((offer = player_find_pendto(p, p1, offerType)) >= 0) {
+ type = parray[p].p_to_list[offer].type;
+ p2 = parray[p].p_to_list[offer].whoto;
+ p2Name = parray[p2].name;
+
+ part = parray[p].partner;
+ if (part >= 0 && parray[part].partner != p)
+ part = -1;
+ p2part = parray[p2].partner;
+ if (p2part >= 0 && parray[p2part].partner != p2)
+ p2part = -1;
+
+ switch (type) {
+ case PEND_MATCH:
+ pprintf_prompt(p2, "\n%s withdraws the match offer.\n", pName);
+ pprintf(p, "You withdraw the match offer to %s.\n", p2Name);
+ if (!strcmp(parray[p].p_to_list[offer].char2, "bughouse")) {
+ if (part >= 0)
+ pprintf_prompt(part,
+ "Your partner withdraws the bughouse offer to %s.\n",
+ parray[p2].name);
+ if (p2part >= 0)
+ pprintf_prompt(p2part,
+ "%s withdraws the bughouse offer to your partner.\n",
+ parray[p].name);
+ }
+ break;
+ case PEND_DRAW:
+ pprintf_prompt(p2, "\n%s withdraws draw request.\n", pName);
+ pprintf(p, "You withdraw the draw request to %s.\n", p2Name);
+ break;
+ case PEND_PAUSE:
+ pprintf_prompt(p2, "\n%s withdraws pause request.\n", pName);
+ pprintf(p, "You withdraw the pause request to %s.\n", p2Name);
+ break;
+ case PEND_ABORT:
+ pprintf_prompt(p2, "\n%s withdraws abort request.\n", pName);
+ pprintf(p, "You withdraw the abort request to %s.\n", p2Name);
+ break;
+ case PEND_TAKEBACK:
+ pprintf_prompt(p2, "\n%s withdraws the takeback request.\n", pName);
+ pprintf(p, "You withdraw the takeback request to %s.\n", p2Name);
+ break;
+ case PEND_ADJOURN:
+ pprintf_prompt(p2, "\n%s withdraws the adjourn request.\n", pName);
+ pprintf(p, "You withdraw the adjourn request to %s.\n", p2Name);
+ break;
+ case PEND_SWITCH:
+ pprintf_prompt(p2, "\n%s withdraws the switch sides request.\n", pName);
+ pprintf(p, "You withdraw the switch sides request to %s.\n", p2Name);
+ break;
+ case PEND_SIMUL:
+ pprintf_prompt(p2, "\n%s withdraws the simul offer.\n", pName);
+ pprintf(p, "You withdraw the simul offer to %s.\n", p2Name);
+ break;
+ case PEND_PARTNER:
+ pprintf_prompt(p2, "\n%s withdraws partnership request.\n", pName);
+ pprintf(p, "You withdraw the partnership request to %s.\n", p2Name);
+ break;
+ }
+ player_remove_request(p, p2, type);
+ count++;
+ }
+ return count;
+}
+
+
+PUBLIC int player_is_observe(int p, int g)
+{
+ int i;
+
+ for (i = 0; i < parray[p].num_observe; i++) {
+ if (parray[p].observe_list[i] == g)
+ break;
+ }
+ if (i == parray[p].num_observe)
+ return 0;
+ else
+ return 1;
+}
+
+PUBLIC int player_add_observe(int p, int g)
+{
+ if (parray[p].num_observe == MAX_OBSERVE)
+ return -1;
+ parray[p].observe_list[parray[p].num_observe] = g;
+ parray[p].num_observe++;
+ return 0;
+}
+
+PUBLIC int player_remove_observe(int p, int g)
+{
+ int i;
+
+ for (i = 0; i < parray[p].num_observe; i++) {
+ if (parray[p].observe_list[i] == g)
+ break;
+ }
+ if (i == parray[p].num_observe)
+ return -1; /* Not found! */
+ for (; i < parray[p].num_observe - 1; i++) {
+ parray[p].observe_list[i] = parray[p].observe_list[i + 1];
+ }
+ parray[p].num_observe--;
+ return 0;
+}
+
+PUBLIC int player_game_ended(int g)
+{
+ int p;
+
+ for (p = 0; p < p_num; p++) {
+ if (parray[p].status == PLAYER_EMPTY)
+ continue;
+ player_remove_observe(p, g);
+ }
+ player_remove_request(garray[g].white, garray[g].black, -1);
+ player_remove_request(garray[g].black, garray[g].white, -1);
+ player_save(garray[g].white); /* Hawk: Added to save finger-info after each
+ game */
+ player_save(garray[g].black);
+ return 0;
+}
+
+PUBLIC int player_goto_board(int p, int board_num)
+{
+ int start, count = 0, on, g;
+
+ if (board_num < 0 || board_num >= parray[p].simul_info.numBoards)
+ return -1;
+ if (parray[p].simul_info.boards[board_num] < 0)
+ return -1;
+ parray[p].simul_info.onBoard = board_num;
+ parray[p].game = parray[p].simul_info.boards[board_num];
+ parray[p].opponent = garray[parray[p].game].black;
+ if (parray[p].simul_info.numBoards == 1)
+ return 0;
+ send_board_to(parray[p].game, p);
+ start = parray[p].game;
+ on = parray[p].simul_info.onBoard;
+ do {
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0) {
+ if (count == 0) {
+ if (parray[garray[g].black].bell) {
+ pprintf(garray[g].black, "\007");
+ }
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " is at your board!\n");
+ } else if (count == 1) {
+ if (parray[garray[g].black].bell) {
+ pprintf(garray[g].black, "\007");
+ }
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " will be at your board NEXT!\n");
+ } else {
+ pprintf(garray[g].black, "\n");
+ pprintf_highlight(garray[g].black, "%s", parray[p].name);
+ pprintf_prompt(garray[g].black, " is %d boards away.\n", count);
+ }
+ count++;
+ }
+ on++;
+ if (on >= parray[p].simul_info.numBoards)
+ on = 0;
+ } while (start != parray[p].simul_info.boards[on]);
+ return 0;
+}
+
+PUBLIC int player_goto_next_board(int p)
+{
+ int on;
+ int start;
+ int g;
+
+ on = parray[p].simul_info.onBoard;
+ start = on;
+ g = -1;
+ do {
+ on++;
+ if (on >= parray[p].simul_info.numBoards)
+ on = 0;
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0)
+ break;
+ } while (start != on);
+ if (g == -1) {
+ pprintf(p, "\nMajor Problem! Can't find your next board.\n");
+ return -1;
+ }
+ return player_goto_board(p, on);
+}
+
+PUBLIC int player_goto_prev_board(int p)
+{
+ int on;
+ int start;
+ int g;
+
+ on = parray[p].simul_info.onBoard;
+ start = on;
+ g = -1;
+ do {
+ --on;
+ if (on < 0)
+ on = (parray[p].simul_info.numBoards) - 1;
+ g = parray[p].simul_info.boards[on];
+ if (g >= 0)
+ break;
+ } while (start != on);
+ if (g == -1) {
+ pprintf(p, "\nMajor Problem! Can't find your previous board.\n");
+ return -1;
+ }
+ return player_goto_board(p, on);
+}
+
+PUBLIC int player_goto_simulgame_bynum(int p, int num)
+{
+ int on;
+ int start;
+ int g;
+
+ on = parray[p].simul_info.onBoard;
+ start = on;
+ do {
+ on++;
+ if (on >= parray[p].simul_info.numBoards)
+ on = 0;
+ g = parray[p].simul_info.boards[on];
+ if (g == num)
+ break;
+ } while (start != on);
+ if (g != num) {
+ pprintf(p, "\nYou aren't playing that game!!\n");
+ return -1;
+ }
+ return player_goto_board(p, on);
+}
+
+PUBLIC int player_num_active_boards(int p)
+{
+ int count = 0, i;
+
+ if (!parray[p].simul_info.numBoards)
+ return 0;
+ for (i = 0; i < parray[p].simul_info.numBoards; i++)
+ if (parray[p].simul_info.boards[i] >= 0)
+ count++;
+ return count;
+}
+
+PUBLIC int player_num_results(int p, int result)
+{
+ int count = 0, i;
+
+ if (!parray[p].simul_info.numBoards)
+ return 0;
+ for (i = 0; i < parray[p].simul_info.numBoards; i++)
+ if (parray[p].simul_info.results[i] == result)
+ count++;
+ return count;
+}
+
+PUBLIC int player_simul_over(int p, int g, int result)
+{
+ int on, ong, p1, which = -1, won;
+ char tmp[1024];
+
+ for (won = 0; won < parray[p].simul_info.numBoards; won++) {
+ if (parray[p].simul_info.boards[won] == g) {
+ which = won;
+ break;
+ }
+ }
+ if (which == -1) {
+ pprintf(p, "I can't find that game!\n");
+ return -1;
+ }
+ pprintf(p, "\nBoard %d has completed.\n", won + 1);
+ on = parray[p].simul_info.onBoard;
+ ong = parray[p].simul_info.boards[on];
+ parray[p].simul_info.boards[won] = -1;
+ parray[p].simul_info.results[won] = result;
+ if (player_num_active_boards(p) == 0) {
+ sprintf(tmp, "\n{Simul (%s vs. %d) is over.}\nResults: %d Wins, %d Losses, %d Draws, %d Aborts\n",
+ parray[p].name,
+ parray[p].simul_info.numBoards,
+ player_num_results(p, RESULT_WIN),
+ player_num_results(p, RESULT_LOSS),
+ player_num_results(p, RESULT_DRAW),
+ player_num_results(p, RESULT_ABORT));
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_game && !player_is_observe(p1, g) && (p1 != p))
+ continue;
+ pprintf_prompt(p1, "%s", tmp);
+ }
+ parray[p].simul_info.numBoards = 0;
+ pprintf_prompt(p, "\nThat was the last board, thanks for playing.\n");
+ return 0;
+ }
+ if (ong == g) { /* This game is over */
+ player_goto_next_board(p);
+ } else {
+ player_goto_board(p, parray[p].simul_info.onBoard);
+ }
+ pprintf_prompt(p, "\nThere are %d boards left.\n",
+ player_num_active_boards(p));
+ return 0;
+}
+
+PRIVATE void GetMsgFile (int p, char *fName)
+{
+ sprintf(fName, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0],
+ parray[p].login, STATS_MESSAGES);
+ }
+
+PUBLIC int player_num_messages(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered)
+ return 0;
+ GetMsgFile (p, fname);
+ return lines_file(fname);
+}
+
+PUBLIC int player_add_message(int top, int fromp, char *message)
+{
+/* char command[MAX_FILENAME_SIZE]; */
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ char subj[256];
+ char messbody[1024];
+ int t = time(0);
+
+ if (!parray[top].registered)
+ return -1;
+ if (!parray[fromp].registered)
+ return -1;
+ GetMsgFile (top, fname);
+ if ((lines_file(fname) >= MAX_MESSAGES) && (parray[top].adminLevel == 0))
+ return -1;
+ fp = fopen(fname, "a");
+ if (!fp)
+ return -1;
+ fprintf(fp, "%s at %s: %s\n", parray[fromp].name, strltime(&t), message);
+ fclose(fp);
+ pprintf(fromp, "\nThe following message was sent ");
+ if (parray[top].i_mailmess) {
+ sprintf(subj, "FICS message from %s at FICS %s (Do not reply by mail)", parray[fromp].name, fics_hostname);
+ sprintf(messbody, "%s at %s: %s\n", parray[fromp].name, strltime(&t), message);
+ mail_string_to_user(top, subj, messbody);
+ pprintf(fromp, "(and emailed) ");
+ }
+ pprintf(fromp, "to %s: \n %s\n", parray[top].name, message);
+ return 0;
+}
+
+#if 0
+/* Function changed and moved lower to have messages numbered. */
+PUBLIC int player_show_messages(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered)
+ return -1;
+ GetMsgFile (p, fname);
+ if (lines_file(fname) <= 0)
+ return -1;
+ psend_file(p, NULL, fname);
+ return 0;
+}
+#endif
+
+PUBLIC void SaveTextListEntry(textlist **Entry, char *string, int n)
+{
+ *Entry = (textlist *) rmalloc(sizeof(textlist));
+ (*Entry)->text = strdup(string);
+ (*Entry)->index = n;
+ (*Entry)->next = NULL;
+}
+
+PUBLIC textlist *ClearTextListEntry(textlist *entry)
+{
+ textlist *ret = entry->next;
+ strfree(entry->text);
+ rfree(entry);
+ return ret;
+}
+
+PUBLIC void ClearTextList(textlist *head)
+{
+ textlist *cur;
+
+ for (cur = head; cur != NULL; cur = ClearTextListEntry(cur));
+}
+
+/* if which=0 load all messages; if it's (p1+1) load messages only from
+ p1; if it's -(p1+1) load all messages EXCEPT those from p1. */
+PRIVATE int SaveThisMsg (int which, char *line)
+{
+ char Sender[MAX_LOGIN_NAME];
+ int p1;
+
+ if (which == 0) return 1;
+
+ sscanf (line, "%s", Sender);
+ if (which < 0) {
+ p1 = -which - 1;
+ return strcmp(Sender, parray[p1].name);
+ }
+ else {
+ p1 = which - 1;
+ return !strcmp(Sender, parray[p1].name);
+ }
+}
+
+PRIVATE int LoadMsgs(int p, int which, textlist **Head)
+ /* which=0 to load all messages; it's (p1+1) to load messages only from
+ p1, and it's -(p1+1) to load all messages EXCEPT those from p1. */
+{
+ FILE *fp;
+ textlist **Cur = Head;
+ char fName[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ int n=0, nSave=0;
+
+ *Head = NULL;
+ GetMsgFile (p, fName);
+ fp = fopen(fName, "r");
+ if (fp == NULL) {
+ return -1;
+ }
+ while (!feof(fp)) {
+ fgets(line, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (SaveThisMsg(which, line)) {
+ SaveTextListEntry(Cur, line, ++n);
+ Cur = &(*Cur)->next;
+ nSave++;
+ }
+ else n++;
+ }
+ fclose (fp);
+ return nSave;
+}
+
+/* start > 0 and end > start (or end = 0) to save messages in range;
+ start < 0 and end < start (or end = 0) to clear messages in range;
+ if end = 0, range goes to end of file (not tested yet). */
+PRIVATE int LoadMsgRange(int p, int start, int end, textlist **Head)
+{
+ FILE *fp;
+ char fName[MAX_FILENAME_SIZE];
+ char line[MAX_LINE_SIZE];
+ textlist **Cur = Head;
+ int n=1, nSave=0, nKill=0;
+
+ *Head = NULL;
+ GetMsgFile (p, fName);
+ fp = fopen (fName, "r");
+ if (fp == NULL) {
+ pprintf (p, "You have no messages.\n");
+ return -1;
+ }
+ for (n=1; n <= end || end <= 0; n++) {
+ fgets (line, MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if ((start < 0 && (n < -start || n > -end))
+ || (start >= 0 && n >= start)) {
+ SaveTextListEntry (Cur, line, n);
+ Cur = &(*Cur)->next;
+ nSave++;
+ }
+ else nKill++;
+ }
+ fclose (fp);
+ if (start < 0) {
+ if (n <= -start)
+ pprintf (p, "You do not have a message %d.\n", -start);
+ return nKill;
+ } else {
+ if (n <= start)
+ pprintf (p, "You do not have a message %d.\n", start);
+ return nSave;
+ }
+}
+
+#if 0
+PRIVATE int LoadMsgsFromP1(int p, int p1, int saveP1, textlist **Head)
+{
+ textlist **Cur=Head;
+ char Sender[MAX_LOGIN_NAME];
+ int nKeep = 0;
+ int nKill = 0;
+
+ /* First load all messages; then get rid of the ones we don't want. */
+ LoadMsgs(p, 0, Head);
+ while (Cur != NULL && *Cur != NULL) {
+ sscanf ((*Cur)->text, "%s", Sender);
+ if ((saveP1 && strcmp(Sender, parray[p1].name))
+ || (!saveP1 && !strcmp(Sender, parray[p1].name)))
+ /* either the message is from p1 and we're not saving his message
+ or it's not from p1, and we're only saving his messages. In
+ either case, we want to get rid of this one. */
+ *Cur = ClearTextListEntry (*Cur);
+ nKill++;
+ }
+ else {
+ /* Save this message; move on to the next one. */
+ if ((*Cur)->next != NULL)
+ Cur = &(*Cur)->next;
+ else Cur = NULL;
+ nKeep++;
+ }
+ }
+ return (saveP1 ? nKeep : nKill);
+}
+#endif
+
+PRIVATE int WriteMsgFile (int p, textlist *Head)
+{
+ char fName[MAX_FILENAME_SIZE];
+ FILE *fp;
+ textlist *Cur;
+
+ GetMsgFile (p, fName);
+ fp = fopen(fName, "w");
+ if (fp == NULL)
+ return 0;
+ for (Cur = Head; Cur != NULL; Cur = Cur->next)
+ fprintf(fp, "%s", Cur->text);
+ fclose(fp);
+ return 1;
+}
+
+PUBLIC int ClearMsgsBySender(int p, param_list param)
+{
+ textlist *Head;
+ int p1, connected;
+ int nFound;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return -1;
+
+ nFound = LoadMsgs(p, -(p1+1), &Head);
+ if (nFound < 0) {
+ pprintf(p, "You have no messages.\n");
+ } else if (nFound == 0) {
+ pprintf(p, "You have no messages from %s.\n", parray[p1].name);
+ } else {
+ if (WriteMsgFile (p, Head))
+ pprintf(p, "Messages from %s cleared.\n", parray[p1].name);
+ else {
+ pprintf(p, "Problem writing message file; please contact an admin.\n");
+ fprintf(stderr, "Problem writing message file for %s.\n", parray[p].name);
+ }
+ ClearTextList(Head);
+ }
+ if (!connected)
+ player_remove(p1);
+ return nFound;
+}
+
+PRIVATE void ShowTextList (int p, textlist *Head, int ShowIndex)
+{
+ textlist *CurMsg;
+
+ if (ShowIndex) {
+ for (CurMsg = Head; CurMsg != NULL; CurMsg = CurMsg->next)
+ pprintf(p, "%2d. %s", CurMsg->index, CurMsg->text);
+ }
+ else {
+ for (CurMsg = Head; CurMsg != NULL; CurMsg = CurMsg->next)
+ pprintf(p, "%s", CurMsg->text);
+ }
+}
+
+PUBLIC int player_show_messages(int p)
+{
+ textlist *Head;
+ int n;
+
+ n = LoadMsgs (p, 0, &Head);
+ if (n <= 0) {
+ pprintf (p, "You have no messages.\n");
+ return -1;
+ } else {
+ pprintf (p, "Messages:\n");
+ ShowTextList (p, Head, 1);
+ ClearTextList (Head);
+ return 0;
+ }
+}
+
+PUBLIC int ShowMsgsBySender(int p, param_list param)
+{
+ textlist *Head;
+ int p1, connected;
+ int nFrom, nTo;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return -1;
+
+ if (!parray[p1].registered) {
+ pprintf(p, "Player \"%s\" is unregistered and cannot send or receive messages.\n",
+ parray[p1].name);
+ return -1; /* no need to disconnect */
+ }
+
+ if (p != p1) {
+ nTo = LoadMsgs(p1, p+1, &Head);
+ if (nTo <= 0) {
+ pprintf(p, "%s has no messages from you.\n", parray[p1].name);
+ } else {
+ pprintf(p, "Messages to %s:\n", parray[p1].name);
+ ShowTextList (p, Head, 0);
+ ClearTextList(Head);
+ }
+ }
+ nFrom = LoadMsgs(p, p1+1, &Head);
+ if (nFrom <= 0) {
+ pprintf(p, "\nYou have no messages from %s.\n", parray[p1].name);
+ } else {
+ pprintf(p, "Messages from %s:\n", parray[p1].name);
+ ShowTextList (p, Head, 1);
+ ClearTextList(Head);
+ }
+ if (!connected)
+ player_remove(p1);
+ return (nFrom > 0 || nTo > 0);
+}
+
+PUBLIC int ShowMsgRange (int p, int start, int end)
+{
+ textlist *Head;
+ int n;
+
+ n = LoadMsgRange (p, start, end, &Head);
+ if (n > 0) {
+ ShowTextList (p, Head, 1);
+ ClearTextList (Head);
+ }
+ return n;
+}
+
+PUBLIC int ClrMsgRange (int p, int start, int end)
+{
+ textlist *Head;
+ int n;
+
+ n = LoadMsgRange (p, -start, -end, &Head);
+ if (n > 0) {
+/* You can use ShowTextList to see what's left after the real code. */
+/* ShowTextList (p, Head, 1); */
+ if (WriteMsgFile (p, Head))
+ pprintf (p, "Message %d cleared.\n", start);
+ }
+ if (n >= 0)
+ ClearTextList (Head);
+ return n;
+}
+
+PUBLIC int player_clear_messages(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered)
+ return -1;
+ GetMsgFile (p, fname);
+ unlink(fname);
+ return 0;
+}
+
+PUBLIC int player_search(int p, char *name)
+/*
+ * Find player matching the given string. First looks for exact match
+ * with a logged in player, then an exact match with a registered player,
+ * then a partial unique match with a logged in player, then a partial
+ * match with a registered player.
+ * Returns player number if the player is connected, negative (player number)
+ * if the player had to be connected, and 0 if no player was found
+ */
+{
+ int p1, count;
+ char *buffer[1000];
+ char pdir[MAX_FILENAME_SIZE];
+
+ /* exact match with connected player? */
+ if ((p1 = player_find_bylogin(name)) >= 0) {
+ return p1 + 1;
+ }
+ /* exact match with registered player? */
+ sprintf(pdir, "%s/%c", player_dir, name[0]);
+ count = search_directory(pdir, name, buffer, 1000);
+ if (count > 0 && !strcmp(name, *buffer)) {
+ goto ReadPlayerFromFile; /* found an unconnected registered player */
+ }
+ /* partial match with connected player? */
+ if ((p1 = player_find_part_login(name)) >= 0) {
+ return p1 + 1;
+ } else if (p1 == -2) {
+ /* ambiguous; matches too many connected players. */
+ pprintf (p, "Ambiguous name '%s'; matches more than one player.\n", name);
+ return 0;
+ }
+ /* partial match with registered player? */
+ if (count < 1) {
+ pprintf(p, "There is no player matching that name.\n");
+ return 0;
+ }
+ if (count > 1) {
+ pprintf(p, "-- Matches: %d names --", count);
+ display_directory(p, buffer, count);
+ return(0);
+/*
+ char *s = buffer;
+ multicol *m = multicol_start(2000);
+ for (i = 0; i < count; i++) {
+ multicol_store(m, s);
+ s += strlen(s) + 1;
+ }
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ return 0;
+*/
+ }
+ReadPlayerFromFile:
+ p1 = player_new();
+ if (player_read(p1, *buffer)) {
+ player_remove(p1);
+ pprintf(p, "ERROR: a player named %s was expected but not found!\n",
+ *buffer);
+ pprintf(p, "Please tell an admin about this incident. Thank you.\n");
+ return 0;
+ }
+ return (-p1) - 1; /* negative to indicate player was not
+ connected */
+}
+
+
+PUBLIC int player_kill(char *name)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", player_dir, name[0], name);
+ sprintf(fname2, "%s/%c/.rem.%s", player_dir, name[0], name);
+ rename(fname, fname2);
+ RemHist (name);
+ sprintf(fname, "%s/player_data/%c/%s.games", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.games", stats_dir, name[0], name);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.comments", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.comments", stats_dir, name[0], name);
+ rename(fname, fname2);
+
+ sprintf(fname, "%s/player_data/%c/%s.logons", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.logons", stats_dir, name[0], name);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.messages", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.messages", stats_dir, name[0], name);
+ rename(fname, fname2);
+ return 0;
+}
+
+PUBLIC int player_rename(char *name, char *newname)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", player_dir, name[0], name);
+ sprintf(fname2, "%s/%c/%s", player_dir, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.games", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.games", stats_dir, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.comments", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.comments", stats_dir, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.logons", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.logons", stats_dir, newname[0], newname);
+ rename(fname, fname2);
+ sprintf(fname, "%s/player_data/%c/%s.messages", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/%s.messages", stats_dir, newname[0], newname);
+ rename(fname, fname2);
+ return 0;
+}
+
+PUBLIC int player_raise(char *name)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", player_dir, name[0], name);
+ sprintf(fname2, "%s/%c/.rem.%s", player_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.games", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.games", stats_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.comments", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.comments", stats_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.logons", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.logons", stats_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.messages", stats_dir, name[0], name);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.messages", stats_dir, name[0], name);
+ rename(fname2, fname);
+ return 0;
+}
+
+PUBLIC int player_reincarn(char *name, char *newname)
+{
+ char fname[MAX_FILENAME_SIZE], fname2[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/%c/%s", player_dir, newname[0], newname);
+ sprintf(fname2, "%s/%c/.rem.%s", player_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.games", stats_dir, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.games", stats_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.comments", stats_dir, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.comments", stats_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.logons", stats_dir, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.logons", stats_dir, name[0], name);
+ rename(fname2, fname);
+ sprintf(fname, "%s/player_data/%c/%s.messages", stats_dir, newname[0], newname);
+ sprintf(fname2, "%s/player_data/%c/.rem.%s.messages", stats_dir, name[0], name);
+ rename(fname2, fname);
+ return 0;
+}
+
+PUBLIC int player_num_comments(int p)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ if (!parray[p].registered)
+ return 0;
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p].login[0],
+ parray[p].login, "comments");
+ return lines_file(fname);
+}
+
+PUBLIC int player_add_comment(int p_by, int p_to, char *comment)
+{
+ char fname[MAX_FILENAME_SIZE];
+ FILE *fp;
+ int t = time(0);
+
+ if (!parray[p_to].registered)
+ return -1;
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p_to].login[0],
+ parray[p_to].login, "comments");
+ fp = fopen(fname, "a");
+ if (!fp)
+ return -1;
+ fprintf(fp, "%s at %s: %s\n", parray[p_by].name, strltime(&t), comment);
+ fclose(fp);
+ parray[p_to].num_comments = player_num_comments(p_to);
+ return 0;
+}
+
+PUBLIC int player_show_comments(int p, int p1)
+{
+ char fname[MAX_FILENAME_SIZE];
+
+ sprintf(fname, "%s/player_data/%c/%s.%s", stats_dir, parray[p1].login[0],
+ parray[p1].login, "comments");
+ psend_file(p, NULL, fname);
+ return 0;
+}
+
+/* returns 1 if player is head admin, 0 otherwise */
+PUBLIC int player_ishead(int p)
+{
+ return (!strcasecmp(parray[p].name, hadmin_handle));
+}
blob - /dev/null
blob + 4a40ef6a93e6e79a9d7b6c2dbc36f5e4fc84d82d (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/playerdb.h
+/* playerdb.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "command.h"
+#include "lists.h"
+
+#ifndef _PLAYERDB_H
+#define _PLAYERDB_H
+
+#define PLAYER_VERSION 1
+
+#define MAX_PLAYER 500
+#define MAX_PENDING 10
+#define MAX_OBSERVE 30 /* max # of games one person can observe */
+#define MAX_PLAN 10
+#define MAX_FORMULA 9
+#define MAX_CENSOR 50
+#define MAX_NOTIFY 80
+#define MAX_ALIASES 30
+#define MAX_SIMUL 30
+#define MAX_MESSAGES 40
+#define MAX_INCHANNELS 16
+
+#define PLAYER_EMPTY 0
+#define PLAYER_NEW 1
+#define PLAYER_INQUEUE 2
+#define PLAYER_LOGIN 3
+#define PLAYER_PASSWORD 4
+#define PLAYER_PROMPT 5
+
+#define P_LOGIN 0
+#define P_LOGOUT 1
+
+#define SORT_BLITZ 0
+#define SORT_STAND 1
+#define SORT_ALPHA 2
+#define SORT_WILD 3
+
+typedef struct _statistics {
+ int num, win, los, dra, rating, ltime, best, whenbest;
+ double sterr;
+} statistics;
+
+#define PEND_MATCH 0 /* Params 1=wt 2=winc 3=bt 4=binc 5=registered */
+#define PEND_DRAW 1
+#define PEND_ABORT 2
+#define PEND_TAKEBACK 3
+#define PEND_ADJOURN 4
+#define PEND_SWITCH 5
+#define PEND_SIMUL 6
+#define PEND_PAUSE 7
+#define PEND_PARTNER 8
+#define PEND_BUGHOUSE 9
+#define PEND_ALL -1
+
+#if 0 /* We never use this. -- hersco */
+extern char *pend_strings[7];
+#endif
+
+#define PEND_TO 0
+#define PEND_FROM 1
+typedef struct _pending {
+ int type;
+ int whoto;
+ int whofrom;
+ int param1, param2, param3, param4, param5, param6;
+ char char1[50], char2[50];
+} pending;
+
+typedef struct _simul_info_t {
+ int numBoards;
+ int onBoard;
+ int results[MAX_SIMUL];
+ int boards[MAX_SIMUL];
+} simul_info_t;
+
+typedef struct _player {
+/* This first block is not saved between logins */
+ char *login;
+ int registered;
+ int socket;
+ int status;
+ int game;
+ int opponent; /* Only valid if game is >= 0 */
+ int side; /* Only valid if game is >= 0 */
+ int timeOfReg;
+ int totalTime;
+ int last_tell;
+ int last_channel;
+ int last_opponent;
+ int logon_time;
+ int last_command_time;
+ int num_from;
+ pending p_from_list[MAX_PENDING];
+ int num_to;
+ pending p_to_list[MAX_PENDING];
+ int num_observe;
+ int observe_list[MAX_OBSERVE];
+ int lastColor;
+ unsigned int thisHost;
+/* timelog *query_log; */
+ int lastshout_a;
+ int lastshout_b;
+ int sopen;
+ simul_info_t simul_info;
+ char busy[100]; /* more than enough */
+ char *identptr; /* identd stuff */
+ int num_comments; /* number of lines in comments file */
+ int flip;
+ List *lists;
+ int partner;
+ long last_file_byte;
+ char *last_file;
+ int i_admin;
+ int kiblevel;
+
+/* All of this is saved between logins */
+ char *name;
+ char *passwd;
+ char *fullName;
+ char *emailAddress;
+ char *prompt;
+ statistics s_stats;
+ statistics b_stats;
+ statistics w_stats;
+ statistics l_stats;
+ statistics bug_stats;
+ int d_time;
+ int d_inc;
+ int d_height;
+ int d_width;
+ int language;
+ int open;
+ int rated;
+ int ropen;
+ int notifiedby;
+ int bell;
+ int pgn;
+ int i_login;
+ int i_game;
+ int i_shout;
+ int i_cshout;
+ int i_tell;
+ int i_kibitz;
+ int private;
+ int jprivate;
+ int automail;
+ int i_mailmess;
+ int style;
+ int promote;
+ int adminLevel;
+/* int computer; */ /* 1 if the player is a computer */
+ int num_plan;
+ char *planLines[MAX_PLAN];
+ int num_formula;
+ char *formulaLines[MAX_FORMULA];
+ char *formula;
+ int nochannels;
+ int num_white;
+ int num_black;
+/* int uscfRating; */
+/* int network_player; */
+ unsigned int lastHost;
+ int numAlias;
+ alias_type alias_list[MAX_ALIASES];
+ int highlight;
+} player;
+
+typedef struct _textlist {
+ char *text;
+ int index;
+ struct _textlist *next;
+} textlist;
+
+#define PARRAY_SIZE (MAX_PLAYER + 50)
+extern player parray[PARRAY_SIZE];
+extern int p_num;
+
+extern void player_init(int);
+
+extern int player_new(void);
+extern int player_remove(int);
+extern int player_read(int, char *);
+extern int player_delete(int);
+extern int player_markdeleted(int);
+extern int player_save(int);
+extern int player_find(int);
+extern int player_find_bylogin(char *);
+extern int player_find_part_login(char *);
+extern int player_censored(int, int);
+extern int player_notified(int, int);
+extern int player_notified_departure(int);
+extern int player_notify_present (int);
+extern int player_notify(int, char *, char *);
+extern int showstored(int);
+
+extern int player_count(int);
+extern int player_idle(int);
+extern int player_ontime(int);
+
+extern int player_zero(int);
+extern int player_free(int);
+extern int player_clear(int);
+
+extern void player_write_login(int);
+extern void player_write_logout(int);
+extern int player_lastconnect(int);
+extern int player_lastdisconnect(int);
+
+extern void player_pend_print(int, pending *);
+
+extern int player_find_pendto(int, int, int);
+extern int player_new_pendto(int);
+extern int player_remove_pendto(int, int, int);
+
+extern int player_find_pendfrom(int, int, int);
+extern int player_new_pendfrom(int);
+extern int player_remove_pendfrom(int, int, int);
+extern int player_add_request(int, int, int, int);
+extern int player_remove_request(int, int, int);
+extern int player_decline_offers(int, int, int);
+extern int player_withdraw_offers(int, int, int);
+
+extern int player_is_observe(int, int);
+extern int player_add_observe(int, int);
+extern int player_remove_observe(int, int);
+extern int player_game_ended(int);
+
+extern int player_goto_board(int, int);
+extern int player_goto_next_board(int);
+extern int player_goto_prev_board(int);
+extern int player_goto_simulgame_bynum(int,int);
+extern int player_num_active_boards(int);
+extern int player_num_results(int, int);
+extern int player_simul_over(int, int, int);
+
+extern int player_num_messages(int);
+extern int player_add_message(int, int, char *);
+extern int player_show_messages(int);
+extern int player_clear_messages(int);
+extern void ClearTextList(textlist *);
+extern void SaveTextListEntry(textlist **, char *, int);
+extern int ShowMsgsBySender(int, param_list);
+extern int ClrMsgRange(int, int, int);
+extern int ShowMsgRange(int, int, int);
+extern int ClearMsgsBySender(int, param_list);
+#if 0
+extern int MessagesBySender(int, param_list, int);
+#endif
+extern int player_search(int, char *);
+
+extern int sort_blitz[];
+extern int sort_stand[];
+extern int sort_alpha[];
+extern int sort_wild[];
+
+extern int player_kill(char *);
+extern int player_rename(char *, char *);
+extern int player_raise(char *);
+extern int player_reincarn(char *,char *);
+
+extern int player_num_comments(int);
+extern int player_add_comment(int, int, char *);
+extern int player_show_comments(int, int);
+extern int player_ishead(int);
+
+#endif /* _PLAYERDB_H */
+
blob - /dev/null
blob + ee0c980677313e5fce5af3e3e6762781940b144c (mode 644)
Binary files /dev/null and FICS.DIST/FICS/playerdb.o differ
blob - /dev/null
blob + 553b4b05920b26ad0e9cf5813bce124cf7ee527d (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/rating_conv.c
+/* Ratings conversions by DAV */
+/* GNU licensing applies */
+
+#include "rating_conv.h"
+#include "common.h"
+#include "stdinclude.h"
+#include "command.h"
+#include "utils.h"
+
+PRIVATE int elo_to_uscf(int elo)
+{
+ return elo + 100;
+}
+
+PRIVATE int uscf_to_elo(int uscf)
+{
+ return uscf - 100;
+}
+
+PRIVATE int bcf_to_elo(int bcf)
+{
+ return bcf * 8 + 600;
+}
+
+PRIVATE int elo_to_bcf(int elo)
+{
+ return (elo - 600) / 8;
+}
+
+PRIVATE int uscf_to_bcf(int uscf)
+{
+ return (uscf - 700) / 8;
+}
+
+PRIVATE int bcf_to_uscf(int bcf)
+{
+ return bcf * 8 + 700;
+}
+
+PRIVATE void printgrades(int p, int elo, int uscf, int bcf)
+{
+ pprintf(p, "Grading conversion:\n");
+ pprintf(p, " ELO = %d, USCF = %d, BCF = %d\n", elo, uscf, bcf);
+}
+
+PUBLIC int com_CONVERT_BCF(int p, param_list param)
+{
+ int elo = bcf_to_elo(param[0].val.integer);
+ int uscf = elo_to_uscf(elo);
+
+ printgrades(p, elo, uscf, param[0].val.integer);
+ return COM_OK;
+}
+
+PUBLIC int com_CONVERT_ELO(int p, param_list param)
+{
+ int bcf = elo_to_bcf(param[0].val.integer);
+ int uscf = elo_to_uscf(param[0].val.integer);
+
+ printgrades(p, param[0].val.integer, uscf, bcf);
+ return COM_OK;
+}
+
+
+PUBLIC int com_CONVERT_USCF(int p, param_list param)
+{
+ int elo = uscf_to_elo(param[0].val.integer);
+ int bcf = elo_to_bcf(elo);
+
+ printgrades(p, elo, param[0].val.integer, bcf);
+ return COM_OK;
+}
+
blob - /dev/null
blob + cf12b276556dfa58e2bdd4226dad49a60ff132a9 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/rating_conv.h
+/* rating_conv.h */
+
+
+#ifndef _RATINGCONV_H
+#define _RATINGCONV_H
+
+extern int com_CONVERT_BCF();
+extern int com_CONVERT_ELO();
+extern int com_CONVERT_USCF();
+
+#endif /* _RATINGCONV_H */
blob - /dev/null
blob + 6e08f6472177a497e0b46cb8ce9c22d76e1b7703 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/rating_conv.o differ
blob - /dev/null
blob + 007e613b069c0e075bc665e6bb02dbd547b2d477 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/ratings.c
+/*
+ ratings.c
+
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ vek leeds@math.gatech.edu 95/04/05 Glicko system, with sterr
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "gamedb.h"
+#include "command.h"
+#include "comproc.h"
+#include "lists.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "utils.h"
+
+/* grimm */
+#if defined(SGI)
+#else
+/* int system(char *arg); */
+/* int rewind(FILE *stream); */
+#endif
+
+
+PUBLIC double Ratings_B_Average;
+PUBLIC double Ratings_B_StdDev;
+
+PUBLIC double Ratings_S_Average;
+PUBLIC double Ratings_S_StdDev;
+
+PUBLIC double Ratings_L_Average;
+PUBLIC double Ratings_L_StdDev;
+
+PUBLIC double Ratings_W_Average;
+PUBLIC double Ratings_W_StdDev;
+
+
+PRIVATE double Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0;
+PRIVATE int Rb_count = 0;
+
+PRIVATE double Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0;
+PRIVATE int Rs_count = 0;
+
+PRIVATE double Rl_M = 0.0, Rl_S = 0.0, Rl_total = 0.0;
+PRIVATE int Rl_count = 0;
+
+PRIVATE double Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0;
+PRIVATE int Rw_count = 0;
+
+/*
+PUBLIC rateStruct bestS[MAX_BEST];
+PUBLIC int numS = 0;
+PUBLIC rateStruct bestB[MAX_BEST];
+PUBLIC int numB = 0;
+PUBLIC rateStruct bestW[MAX_BEST];
+PUBLIC int numW = 0;
+*/
+
+#define MAXHIST 30
+#define LOWESTHIST 800
+PUBLIC int sHist[MAXHIST];
+PUBLIC int bHist[MAXHIST];
+PUBLIC int wHist[MAXHIST];
+PUBLIC int lHist[MAXHIST];
+
+char sdir[] = DEFAULT_STATS;
+
+PUBLIC int is_active(int Games)
+{
+ return (Games >= PROVISIONAL);
+}
+
+
+PUBLIC void rating_add(int rating, int type)
+{
+ int which;
+
+ which = (rating - LOWESTHIST) / 100;
+ if (which < 0)
+ which = 0;
+ if (which >= MAXHIST)
+ which = MAXHIST - 1;
+ if (type == TYPE_BLITZ) {
+ bHist[which] += 1;
+ Rb_count++;
+ Rb_total += rating;
+ if (Rb_count == 1) {
+ Rb_M = rating;
+ } else {
+ Rb_S = Rb_S + (rating - Rb_M) * (rating - Rb_M);
+ Rb_M = Rb_M + (rating - Rb_M) / (Rb_count);
+ }
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else if (type == TYPE_WILD) { /* TYPE_WILD */
+ wHist[which] += 1;
+ Rw_count++;
+ Rw_total += rating;
+ if (Rw_count == 1) {
+ Rw_M = rating;
+ } else {
+ Rw_S = Rw_S + (rating - Rw_M) * (rating - Rw_M);
+ Rw_M = Rw_M + (rating - Rw_M) / (Rw_count);
+ }
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else if (type == TYPE_LIGHT) { /* TYPE_LIGHT */
+ lHist[which] += 1;
+ Rl_count++;
+ Rl_total += rating;
+ if (Rl_count == 1) {
+ Rl_M = rating;
+ } else {
+ Rl_S = Rl_S + (rating - Rl_M) * (rating - Rl_M);
+ Rl_M = Rl_M + (rating - Rl_M) / (Rl_count);
+ }
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+
+/* Insert bughouse stuff */
+ } else { /* TYPE_STAND */
+ sHist[which] += 1;
+ Rs_count++;
+ Rs_total += rating;
+ if (Rs_count == 1) {
+ Rs_M = rating;
+ } else {
+ Rs_S = Rs_S + (rating - Rs_M) * (rating - Rs_M);
+ Rs_M = Rs_M + (rating - Rs_M) / (Rs_count);
+ }
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ }
+}
+
+PUBLIC void rating_remove(int rating, int type)
+{
+ int which;
+
+ which = (rating - LOWESTHIST) / 100;
+ if (which < 0)
+ which = 0;
+ if (which >= MAXHIST)
+ which = MAXHIST - 1;
+ if (type == TYPE_BLITZ) {
+ bHist[which] = bHist[which] - 1;
+ if (bHist[which] < 0)
+ bHist[which] = 0;
+ if (Rb_count == 0)
+ return;
+ Rb_count--;
+ Rb_total -= rating;
+ if (Rb_count == 0) {
+ Rb_M = 0;
+ Rb_S = 0;
+ } else {
+ Rb_M = Rb_M - (rating - Rb_M) / (Rb_count);
+ Rb_S = Rb_S - (rating - Rb_M) * (rating - Rb_M);
+ /* added this 3.11.95 foxbat */ if (Rb_S < 0)
+ Rb_S = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ } else if (type == TYPE_WILD) { /* TYPE_WILD */
+ wHist[which] = wHist[which] - 1;
+ if (wHist[which] < 0)
+ wHist[which] = 0;
+ if (Rw_count == 0)
+ return;
+ Rw_count--;
+ Rw_total -= rating;
+ if (Rw_count == 0) {
+ Rw_M = 0;
+ Rw_S = 0;
+ } else {
+ Rw_M = Rw_M - (rating - Rw_M) / (Rw_count);
+ Rw_S = Rw_S - (rating - Rw_M) * (rating - Rw_M);
+ /* added this 3.10.95 foxbat */ if (Rw_S < 0)
+ Rw_S = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ } else if (type == TYPE_LIGHT) { /* TYPE_LIGHT */
+ lHist[which] = lHist[which] - 1;
+ if (lHist[which] < 0)
+ lHist[which] = 0;
+ if (Rl_count == 0)
+ return;
+ Rl_count--;
+ Rl_total -= rating;
+ if (Rl_count == 0) {
+ Rl_M = 0;
+ Rl_S = 0;
+ } else {
+ Rl_M = Rl_M - (rating - Rl_M) / (Rl_count);
+ Rl_S = Rl_S - (rating - Rl_M) * (rating - Rl_M);
+ /* added this 3.10.95 foxbat */ if (Rl_S < 0)
+ Rl_S = 0;
+ }
+ if (Rl_count) {
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+ } else {
+ Ratings_L_StdDev = 0;
+ Ratings_L_Average = 0;
+ }
+/* insert bughouse stuff here */
+ } else { /* TYPE_STAND */
+ sHist[which] = sHist[which] - 1;
+ if (sHist[which] < 0)
+ sHist[which] = 0;
+ if (Rs_count == 0)
+ return;
+ Rs_count--;
+ Rs_total -= rating;
+ if (Rs_count == 0) {
+ Rs_M = 0;
+ Rs_S = 0;
+ } else {
+ Rs_M = Rs_M - (rating - Rs_M) / (Rs_count);
+ Rs_S = Rs_S - (rating - Rs_M) * (rating - Rs_M);
+ /* added this 3.10.95 foxbat */ if (Rs_S < 0)
+ Rs_S = 0;
+ }
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ }
+}
+
+PRIVATE void load_ratings(void)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+ int i;
+
+ sprintf(fname, "%s/newratingsV%d_data", stats_dir,STATS_VERSION);
+ fp = fopen(fname, "r");
+ if (!fp) {
+ fprintf(stderr, "FICS: Can't read ratings data!\n");
+ return;
+ }
+ fscanf(fp, "%lf %lf %lf %d", &Rb_M, &Rb_S, &Rb_total, &Rb_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rs_M, &Rs_S, &Rs_total, &Rs_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rw_M, &Rw_S, &Rw_total, &Rw_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rl_M, &Rl_S, &Rl_total, &Rl_count);
+
+ for (i = 0; i < MAXHIST; i++) {
+ fscanf(fp, "%d %d %d %d", &sHist[i], &bHist[i], &wHist[i], &lHist[i]);
+ }
+ fclose(fp);
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ if (Rl_count) {
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+ } else {
+ Ratings_L_StdDev = 0;
+ Ratings_L_Average = 0;
+ }
+}
+
+PUBLIC void save_ratings(void)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+ int i;
+
+ sprintf(fname, "%s/newratingsV%d_data", stats_dir,STATS_VERSION);
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Can't write ratings data!\n");
+ return;
+ }
+ fprintf(fp, "%10f %10f %10f %d\n", Rb_M, Rb_S, Rb_total, Rb_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rs_M, Rs_S, Rs_total, Rs_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rw_M, Rw_S, Rw_total, Rw_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rl_M, Rl_S, Rl_total, Rl_count);
+
+ for (i = 0; i < MAXHIST; i++) {
+ fprintf(fp, "%d %d %d %d\n", sHist[i], bHist[i], wHist[i], lHist[i]);
+ }
+ fclose(fp);
+}
+
+/*
+PRIVATE void BestRemove(int p)
+{
+ int i;
+
+ for (i = 0; i < numB; i++) {
+ if (!strcmp(bestB[i].name, parray[p].name))
+ break;
+ }
+ if (i < numB) {
+ for (; i < numB - 1; i++) {
+ strcpy(bestB[i].name, bestB[i + 1].name);
+ bestB[i].rating = bestB[i + 1].rating;
+ }
+ numB--;
+ }
+ for (i = 0; i < numS; i++) {
+ if (!strcmp(bestS[i].name, parray[p].name))
+ break;
+ }
+ if (i < numS) {
+ for (; i < numS - 1; i++) {
+ strcpy(bestS[i].name, bestS[i + 1].name);
+ bestS[i].rating = bestS[i + 1].rating;
+ }
+ numS--;
+ }
+ for (i = 0; i < numW; i++) {
+ if (!strcmp(bestW[i].name, parray[p].name))
+ break;
+ }
+ if (i < numW) {
+ for (; i < numW - 1; i++) {
+ strcpy(bestW[i].name, bestW[i + 1].name);
+ bestW[i].rating = bestW[i + 1].rating;
+ }
+ numW--;
+ }
+}
+
+PRIVATE void BestAdd(int p)
+{
+ int where, j;
+
+ if ((parray[p].b_stats.rating > 0) && (parray[p].b_stats.num > 19)) {
+ for (where = 0; where < numB; where++) {
+ if (parray[p].b_stats.rating > bestB[where].rating)
+ break;
+ }
+ if (where < MAX_BEST) {
+ for (j = numB; j > where; j--) {
+ if (j == MAX_BEST)
+ continue;
+ strcpy(bestB[j].name, bestB[j - 1].name);
+ bestB[j].rating = bestB[j - 1].rating;
+ }
+ strcpy(bestB[where].name, parray[p].name);
+ bestB[where].rating = parray[p].b_stats.rating;
+ if (numB < MAX_BEST)
+ numB++;
+ }
+ }
+ if ((parray[p].s_stats.rating > 0) && (parray[p].s_stats.num > 19)) {
+ for (where = 0; where < numS; where++) {
+ if (parray[p].s_stats.rating > bestS[where].rating)
+ break;
+ }
+ if (where < MAX_BEST) {
+ for (j = numS; j > where; j--) {
+ if (j == MAX_BEST)
+ continue;
+ strcpy(bestS[j].name, bestS[j - 1].name);
+ bestS[j].rating = bestS[j - 1].rating;
+ }
+ strcpy(bestS[where].name, parray[p].name);
+ bestS[where].rating = parray[p].s_stats.rating;
+ if (numS < MAX_BEST)
+ numS++;
+ }
+ }
+ if ((parray[p].w_stats.rating > 0) && (parray[p].w_stats.num > 19)) {
+ for (where = 0; where < numW; where++) {
+ if (parray[p].w_stats.rating > bestW[where].rating)
+ break;
+ }
+ if (where < MAX_BEST) {
+ for (j = numW; j > where; j--) {
+ if (j == MAX_BEST)
+ continue;
+ strcpy(bestW[j].name, bestW[j - 1].name);
+ bestW[j].rating = bestW[j - 1].rating;
+ }
+ strcpy(bestW[where].name, parray[p].name);
+ bestW[where].rating = parray[p].w_stats.rating;
+ if (numW < MAX_BEST)
+ numW++;
+ }
+ }
+}
+
+PUBLIC void BestUpdate(int p)
+{
+ BestRemove(p);
+ BestAdd(p);
+}
+
+*/
+
+PUBLIC void zero_stats(void)
+{
+ int i;
+ for (i = 0; i < MAXHIST; i++) {
+ sHist[i] = 0;
+ bHist[i] = 0;
+ wHist[i] = 0;
+ lHist[i] = 0;
+ }
+ Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0;
+ Rb_count = 0;
+
+ Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0;
+ Rs_count = 0;
+
+ Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0;
+ Rw_count = 0;
+
+ Rl_M = 0.0, Rl_S = 0.0, Rl_total = 0.0;
+ Rl_count = 0;
+
+/*
+ numS = 0;
+ numB = 0;
+ numW = 0;
+*/
+}
+
+PUBLIC void rating_init(void)
+{
+ zero_stats();
+ load_ratings();
+}
+
+/* This recalculates the rating info from the player data, it can take
+ a long time! */
+PUBLIC void rating_recalc(void)
+{
+ char dname[MAX_FILENAME_SIZE];
+ int p1;
+ int c;
+ int t = time(0);
+ DIR *dirp;
+#if USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+
+ fprintf(stderr, "FICS: Recalculating ratings at %s\n", strltime(&t));
+ zero_stats();
+ for (c = 'a'; c <= 'z'; c++) {
+ /* Never done as ratings server */
+ sprintf(dname, "%s/%c", player_dir, c);
+ dirp = opendir(dname);
+ if (!dirp)
+ continue;
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (dp->d_name[0] != '.') {
+ p1 = player_new();
+ if (player_read(p1, dp->d_name)) {
+ player_remove(p1);
+ fprintf(stderr, "FICS: Problem reading player %s.\n", dp->d_name);
+ continue;
+ }
+ if (parray[p1].b_stats.rating > 0) {
+ rating_add(parray[p1].b_stats.rating, TYPE_BLITZ);
+ }
+ if (parray[p1].s_stats.rating > 0) {
+ rating_add(parray[p1].s_stats.rating, TYPE_STAND);
+ }
+ if (parray[p1].l_stats.rating > 0) {
+ rating_add(parray[p1].l_stats.rating, TYPE_LIGHT);
+ }
+/* insert bughouse stuff here */
+ if (parray[p1].w_stats.rating > 0) {
+ rating_add(parray[p1].w_stats.rating, TYPE_WILD);
+ }
+ player_remove(p1);
+ }
+ }
+ closedir(dirp);
+ }
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ if (Rl_count) {
+ Ratings_L_StdDev = sqrt(Rl_S / Rl_count);
+ Ratings_L_Average = Rl_total / (double) Rl_count;
+ } else {
+ Ratings_L_StdDev = 0;
+ Ratings_L_Average = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ save_ratings();
+ t = time(0);
+ fprintf(stderr, "FICS: Finished at %s\n", strltime(&t));
+}
+
+PRIVATE int Round (double x)
+{
+ return (x < 0 ? (int) (x - 0.5) : (int) (x + 0.5));
+}
+
+/* Constants for Glicko system */
+#define Gd 3.25
+#define Gr0 1720
+#define Gs0 350
+#define Gq 0.00575646273249
+#define Gp 0.000010072398601964
+
+/* End of Glicko system variables */
+
+PRIVATE double Gf(double ss)
+{
+ return (1.0 / sqrt(1.0 + Gp * ss * ss));
+}
+
+/* Confusing but economical: calculate error and attenuation function together */
+PRIVATE double GE(int r, int rr, double ss, double *fss)
+{
+ *fss = Gf(ss);
+ return (1.0 / (1.0 + pow(10.0, (rr - r) * (*fss) / 400.0)));
+}
+
+PUBLIC double current_sterr(double s, int t)
+{
+ if (t < 0)
+ t = 0; /* this shouldn't happen */
+ return (sqrt(s * s + Gd * Gd * log(1.0 + t / 60.0)));
+}
+
+/* Calculates new rating and standard error. By vek. The person */
+/* who invented the ratings system is Mark E. Glickman, Ph.D. */
+/* His e-mail address is glickman@hustat.harvard.edu as of April '95. */
+/* Postscript copy of the note I coded this from should be available */
+/* for ftp from ics.onenet.net, if not elsewhere. */
+
+PUBLIC void rating_sterr_delta(int p1, int p2, int type, int gtime, int result,
+ int *deltarating, double *newsterr)
+{
+ statistics *p1_stats;
+ statistics *p2_stats;
+
+ double s1, s2;
+ int t1, r1, t2, r2; /* Initial sterrs and ratings */
+ double E, fs2, denominator, GK, w; /* Parts of fancy formulas */
+ double delta, sigma; /* Results to return */
+
+ if (type == TYPE_BLITZ) {
+ p1_stats = &parray[p1].b_stats;
+ p2_stats = &parray[p2].b_stats;
+ } else if (type == TYPE_WILD) {
+ p1_stats = &parray[p1].w_stats;
+ p2_stats = &parray[p2].w_stats;
+ } else if (type == TYPE_LIGHT) {
+ p1_stats = &parray[p1].l_stats;
+ p2_stats = &parray[p2].l_stats;
+/* insert bughouse stuff here */
+ } else {
+ p1_stats = &parray[p1].s_stats;
+ p2_stats = &parray[p2].s_stats;
+ }
+
+ /* Calculate effective pre-game sterrs. ltime==0 implies never had sterr. */
+
+ if (p1_stats->ltime == 0)
+ s1 = Gs0;
+ else {
+ t1 = gtime - p1_stats->ltime;
+ s1 = current_sterr(p1_stats->sterr, t1);
+ if (s1 > Gs0)
+ s1 = Gs0;
+ }
+
+ if (p2_stats->ltime == 0)
+ s2 = Gs0;
+ else {
+ t2 = gtime - p2_stats->ltime;
+ s2 = current_sterr(p2_stats->sterr, t2);
+ if (s2 > Gs0)
+ s2 = Gs0;
+ }
+
+ /* pre-game ratings */
+ if (p1_stats->rating == 0 && p1_stats->num == 0)
+ r1 = Gr0;
+ else
+ r1 = p1_stats->rating;
+
+ if (p2_stats->rating == 0 && p2_stats->num == 0)
+ r2 = Gr0;
+ else
+ r2 = p2_stats->rating;
+
+ /* now crunch */
+
+ if (result == RESULT_WIN) {
+ w = 1.0;
+ } else if (result == RESULT_DRAW) {
+ w = 0.5;
+ } else {
+ w = 0.0;
+ }
+
+ E = GE(r1, r2, s2, &fs2); /* side effect: calculate fs2 */
+
+ denominator = 1.0 / (s1 * s1) + Gq * Gq * fs2 * fs2 * E * (1.0 - E);
+ GK = Gq * fs2 / denominator;
+
+ delta = GK * (w - E);
+ if (p1_stats->rating == 0 && p1_stats->num == 0)
+ *deltarating = Round(Gr0 + delta);
+ else
+ *deltarating = Round(delta); /* Returned values: deltarating,
+ newsterr */
+ sigma = 1.0 / sqrt(denominator);
+ *newsterr = (double) sigma;
+}
+
+/* vek: Next is for when we want just the delta, and not the sigma. */
+
+PUBLIC int rating_delta(int p1, int p2, int type, int result, int gtime)
+{
+ int delta;
+ double sigma;
+
+ rating_sterr_delta(p1, p2, type, gtime, result, &delta, &sigma);
+ return (delta);
+
+}
+
+PUBLIC int rating_update(int g)
+{
+ int wDelta, bDelta;
+ double wSigma, bSigma; /* vek */
+
+ int wRes, bRes;
+ statistics *w_stats;
+ statistics *b_stats;
+
+ int gtime;
+
+ int inprogress = (g == parray[garray[g].black].game);
+ /* if this is adjudication of stored game, be quiet about ratings change */
+
+ if (garray[g].type == TYPE_BLITZ) {
+ w_stats = &parray[garray[g].white].b_stats;
+ b_stats = &parray[garray[g].black].b_stats;
+ } else if (garray[g].type == TYPE_STAND) {
+ w_stats = &parray[garray[g].white].s_stats;
+ b_stats = &parray[garray[g].black].s_stats;
+ } else if (garray[g].type == TYPE_WILD) {
+ w_stats = &parray[garray[g].white].w_stats;
+ b_stats = &parray[garray[g].black].w_stats;
+ } else if (garray[g].type == TYPE_LIGHT) {
+ w_stats = &parray[garray[g].white].l_stats;
+ b_stats = &parray[garray[g].black].l_stats;
+ } else {
+ fprintf(stderr, "FICS: Can't update untimed ratings!\n");
+ return -1;
+ }
+
+ switch (garray[g].result) {
+ case END_CHECKMATE:
+ case END_RESIGN:
+ case END_FLAG:
+ case END_ADJWIN:
+ if (garray[g].winner == WHITE) {
+ wRes = RESULT_WIN;
+ bRes = RESULT_LOSS;
+ } else {
+ bRes = RESULT_WIN;
+ wRes = RESULT_LOSS;
+ }
+ break;
+ case END_AGREEDDRAW:
+ case END_REPETITION:
+ case END_50MOVERULE:
+ case END_STALEMATE:
+ case END_NOMATERIAL:
+ case END_BOTHFLAG:
+ case END_ADJDRAW:
+ case END_FLAGNOMATERIAL:
+ wRes = bRes = RESULT_DRAW;
+ break;
+ default:
+ fprintf(stderr, "FICS: Update undecided game %d?\n", garray[g].result);
+ return -1;
+ }
+ gtime = untenths(garray[g].timeOfStart);
+ rating_sterr_delta(garray[g].white, garray[g].black,
+ garray[g].type, gtime, wRes,
+ &wDelta, &wSigma);
+
+ rating_sterr_delta(garray[g].black, garray[g].white,
+ garray[g].type, gtime, bRes,
+ &bDelta, &bSigma);
+
+ /* vek: Update time of last rated game played, for future ratings calcs. */
+ /* Kept independently for blitz and standard. */
+ w_stats->ltime = gtime;
+ b_stats->ltime = gtime;
+ /* end vek add 4/5/95 */
+
+ if (wRes == RESULT_WIN) {
+ w_stats->win++;
+ } else if (wRes == RESULT_LOSS) {
+ w_stats->los++;
+ } else {
+ w_stats->dra++;
+ }
+ w_stats->num++;
+ if (bRes == RESULT_WIN) {
+ b_stats->win++;
+ } else if (bRes == RESULT_LOSS) {
+ b_stats->los++;
+ } else {
+ b_stats->dra++;
+ }
+ b_stats->num++;
+ rating_remove(w_stats->rating, garray[g].type);
+ rating_remove(b_stats->rating, garray[g].type);
+
+ if (inprogress) {
+ pprintf(garray[g].white, "%s rating adjustment: %d ",
+ ((garray[g].type == TYPE_BLITZ) ? "Blitz" : ((garray[g].type == TYPE_WILD) ? "Wild" : ((garray[g].type == TYPE_LIGHT) ? "Lightning" : "Standard"))), w_stats->rating);
+ pprintf(garray[g].black, "%s rating adjustment: %d ",
+ ((garray[g].type == TYPE_BLITZ) ? "Blitz" : ((garray[g].type == TYPE_WILD) ? "Wild" : ((garray[g].type == TYPE_LIGHT) ? "Lightning" : "Standard"))), b_stats->rating);
+ }
+ if (wDelta < -1000) {
+ pprintf(garray[g].white, "not changed due to bug (way too small)! sorry!\n");
+ fprintf(stderr, "FICS: Got too small ratings bug for %s (w) vs. %s\n",
+ parray[garray[g].white].login, parray[garray[g].black].login);
+ } else if (wDelta > 3000) {
+ pprintf(garray[g].white, "not changed due to bug (way too big)! sorry!\n");
+ fprintf(stderr, "FICS: Got too big ratings bug for %s (w) vs. %s\n",
+ parray[garray[g].white].login, parray[garray[g].black].login);
+ } else {
+ w_stats->rating += wDelta;
+ w_stats->sterr = wSigma;
+ }
+
+ if (bDelta < -1000) {
+ pprintf(garray[g].black, "not changed due to bug (way too small)! sorry! ");
+ fprintf(stderr, "FICS: Got too small ratings bug for %s (b) vs. %s\n",
+ parray[garray[g].black].login, parray[garray[g].white].login);
+ } else if (bDelta > 3000) {
+ pprintf(garray[g].black, "not changed due to bug (way too big)! sorry! ");
+ fprintf(stderr, "FICS: Got too big ratings bug for %s (b) vs. %s\n",
+ parray[garray[g].black].login, parray[garray[g].white].login);
+ } else {
+ b_stats->rating += bDelta;
+ b_stats->sterr = bSigma;
+ } /* error messages down to vek */
+
+ rating_add(w_stats->rating, garray[g].type);
+ rating_add(b_stats->rating, garray[g].type);
+
+ if ((w_stats->rating > w_stats->best) && (is_active(w_stats->num))) {
+ w_stats->best = w_stats->rating;
+ w_stats->whenbest = time(NULL);
+ }
+ if ((b_stats->rating > b_stats->best) && (is_active(b_stats->num))) {
+ b_stats->best = b_stats->rating;
+ b_stats->whenbest = time(NULL);
+ }
+/* Ratings are now saved to disk after each game */
+ player_save(garray[g].white);
+ player_save(garray[g].black);
+
+/* foxbat 3.11.95 */
+ if (garray[g].type == TYPE_BLITZ) {
+ Rb_count++;
+ Rb_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (garray[g].type == TYPE_STAND) {
+ Rs_count++;
+ Rs_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (garray[g].type == TYPE_LIGHT) {
+ Rl_count++;
+ Rl_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (garray[g].type == TYPE_WILD) {
+ Rw_count++;
+ Rw_total += (w_stats->rating + b_stats->rating) / 2.0;
+ }
+/* end add */
+ if (inprogress) {
+ pprintf(garray[g].white, "--> %d\n", w_stats->rating);
+ pprintf(garray[g].black, "--> %d\n", b_stats->rating);
+ }
+ save_ratings();
+ UpdateRank(garray[g].type, parray[garray[g].white].name,
+ w_stats, parray[garray[g].white].name);
+ UpdateRank(garray[g].type, parray[garray[g].black].name,
+ b_stats, parray[garray[g].black].name);
+ return 0;
+}
+
+PUBLIC int com_assess(int p, param_list param)
+{
+ int p1 = p, p2, nowtime;
+ int p1_connected = 1, p2_connected = 1;
+ int win1, draw1, loss1;
+ double newsterr1;
+ int win2, draw2, loss2;
+ double newsterr2;
+
+ nowtime = time(0);
+
+/* Hawk: Now assess can be used with players not */
+/* logged on -- I wonder if anyone doesn't */
+/* get just a bit confused here :) */
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game < 0) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ } else if (garray[parray[p].game].status == GAME_EXAMINE) {
+ if (!strcmp(garray[parray[p].game].black_name, parray[p].name)) {
+ pcommand(p, "assess %s\n", garray[parray[p].game].white_name);
+ } else {
+ pcommand(p, "assess %s %s\n",
+ garray[parray[p].game].white_name,
+ garray[parray[p].game].black_name);
+ }
+ return COM_OK;
+ } else {
+ p2 = parray[p].opponent;
+ }
+ } else {
+ if (!FindPlayer(p, param[0].val.word, &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" was found.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (param[1].type != TYPE_NULL) {
+ p1 = p2;
+ p1_connected = p2_connected;
+ if (!FindPlayer(p, param[1].val.word, &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" was found.\n", param[1].val.word);
+ if (!p1_connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ }
+ if (p1 == p2) {
+ pprintf(p, "You can't assess the same players.\n");
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+ }
+ rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nBlitz\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].b_stats.rating, parray[p1].registered), parray[p1].b_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].b_stats.rating, parray[p2].registered), parray[p2].b_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nStandard\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].s_stats.rating, parray[p1].registered), parray[p1].s_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].s_stats.rating, parray[p2].registered), parray[p2].s_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ rating_sterr_delta(p1, p2, TYPE_LIGHT, nowtime, RESULT_WIN, &win1, &newsterr1); rating_sterr_delta(p1, p2, TYPE_LIGHT, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_LIGHT, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_LIGHT, nowtime, RESULT_WIN, &win2, &newsterr2); rating_sterr_delta(p2, p1, TYPE_LIGHT, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_LIGHT, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nLightning\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].l_stats.rating, parray[p1].registered), parray[p1].l_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].l_stats.rating, parray[p2].registered), parray[p2].l_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nWild\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].w_stats.rating, parray[p1].registered), parray[p1].w_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].w_stats.rating, parray[p2].registered), parray[p2].w_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+}
+
+
+PUBLIC int com_best(int p, param_list param)
+{
+ return Best(p, param, 1);
+}
+
+PUBLIC int com_hbest(int p, param_list param)
+{
+ return Best(p, param, 0);
+}
+
+#if 0
+PUBLIC int com_best(int p, param_list param)
+{
+ int i;
+
+ pprintf(p, "Standard Blitz Wild\n");
+ for (i = 0; i < MAX_BEST; i++) {
+ if ((i >= numS) && (i >= numB))
+ break;
+ if (i < numS) {
+ pprintf(p, "%4d %-17s ", bestS[i].rating, bestS[i].name);
+ } else {
+ pprintf(p, " ");
+ }
+ if (i < numB) {
+ pprintf(p, "%4d %-17s ", bestB[i].rating, bestB[i].name);
+ } else {
+ pprintf(p, " ");
+ }
+ if (i < numW) {
+ pprintf(p, "%4d %-17s\n", bestW[i].rating, bestW[i].name);
+ } else {
+ pprintf(p, "\n");
+ }
+ }
+ return COM_OK;
+}
+#endif
+
+PUBLIC int com_statistics(int p, param_list param)
+{
+ pprintf(p, " Standard Blitz Lightning Wild\n");
+ pprintf(p, "average: %7.2f %7.2f %7.2f %7.2f\n", Ratings_S_Average, Ratings_B_Average, Ratings_L_Average, Ratings_W_Average);
+ pprintf(p, "std dev: %7.2f %7.2f %7.2f %7.2f\n", Ratings_S_StdDev, Ratings_B_StdDev, Ratings_L_StdDev, Ratings_W_StdDev);
+ pprintf(p, "number : %7d %7d %7d %7d\n", Rs_count, Rb_count, Rl_count, Rw_count);
+ return COM_OK;
+}
+
+PUBLIC int com_fixrank(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ UpdateRank(TYPE_BLITZ, parray[p1].name, &parray[p1].b_stats,
+ parray[p1].name);
+ UpdateRank(TYPE_STAND, parray[p1].name, &parray[p1].s_stats,
+ parray[p1].name);
+ UpdateRank(TYPE_WILD, parray[p1].name, &parray[p1].w_stats,
+ parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_rank(int p, param_list param)
+{
+ return DisplayRank(p, param, 1);
+}
+
+PUBLIC int com_hrank(int p, param_list param)
+{
+ return DisplayRank(p, param, 0);
+}
+
+PUBLIC int DisplayRank(int p, param_list param, int showComputers)
+{
+ int start, end, target, connected;
+ int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+
+ if (param[0].type == TYPE_NULL) {
+ DisplayTargetRank(p, parray[p].name, show, showComputers);
+ return COM_OK;
+ } else if (isdigit(param[0].val.word[0])) {
+ end = -1;
+ sscanf(param[0].val.word, "%d-%d", &start, &end);
+ if (end > 0 && (param[1].type != TYPE_NULL))
+ show = ShowFromString(param[1].val.word);
+ DisplayRankedPlayers(p, start, end, show, showComputers);
+ return COM_OK;
+ } else {
+ target = player_search(p, param[0].val.word);
+ if (target == 0) {
+ pprintf(p, "Target %s not found.\n", param[0].val.word);
+ return COM_OK;
+ }
+ connected = (target > 0);
+ if (!connected)
+ target = -target - 1;
+ else
+ target--;
+
+ if (param[1].type != TYPE_NULL)
+ show = ShowFromString(param[1].val.word);
+ DisplayTargetRank(p, parray[target].name, show, showComputers);
+ if (!connected)
+ player_remove(target);
+ return COM_OK;
+ }
+}
+
+/* CompareStats returns 1 if s1 comes first, -1 if s2 comes first, and 0
+ if neither takes precedence. */
+#if 0
+PRIVATE int CompareStats(char *name1, statistics *s1,
+ char *name2, statistics *s2)
+{
+ int i, l1;
+
+ if (s1 == NULL)
+ if (s2 == NULL)
+ return 0;
+ else
+ return -1;
+ else if (s2 == NULL)
+ return 1;
+
+ if (s1->rating > s2->rating)
+ return 1;
+ if (s1->rating < s2->rating)
+ return -1;
+ l1 = strlen(name1);
+ for (i = 0; i < l1; i++) {
+ if (name2[i] == '\0')
+ return -1;
+ if (tolower(name1[i]) < tolower(name2[i]))
+ return 1;
+ if (tolower(name1[i]) > tolower(name2[i]))
+ return -1;
+ }
+ if (name2[i] != '\0')
+ return 1;
+/* if (s1->sterr < s2->sterr) return 1;
+ if (s1->sterr > s2->sterr) return -1;
+ if (s1->num > s2->num) return 1;
+ if (s1->num < s2->num) return -1;
+*/
+ fprintf(stderr, "Duplicate entries found: %s.\n", name1);
+ return 0;
+}
+#endif
+PRIVATE int GetRankFileName(char *out, int type)
+{
+ switch (type) {
+ case TYPE_BLITZ:
+ sprintf(out, "%s/rank.blitz", sdir);
+ return type;
+ case TYPE_STAND:
+ sprintf(out, "%s/rank.std", sdir);
+ return type;
+ case TYPE_WILD:
+ sprintf(out, "%s/rank.wild", sdir);
+ return type;
+ default:
+ return -1;
+ }
+}
+
+/* loon: Turning this off 28 Oct 1995 (temporary:)) since we're lagged
+ into outer space */
+PUBLIC void UpdateRank(int type, char *addName,
+ statistics *sNew, char *delName)
+{}
+
+#if 0
+PUBLIC void UpdateRank(int type, char *addName,
+ statistics *sNew, char *delName)
+{
+ char RankFile[MAX_FILENAME_SIZE];
+ char TmpRankFile[MAX_FILENAME_SIZE];
+ char line[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+ char command[MAX_STRING_LENGTH];
+ int comp;
+ statistics sCur;
+ FILE *fp;
+ FILE *fptemp;
+
+ if (GetRankFileName(RankFile, type) < 0)
+ return;
+ fp = fopen(RankFile, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "Can't open rank file to update.\n");
+ return;
+ }
+ sprintf(TmpRankFile, "%s/tmpRank", sdir);
+ fptemp = fopen(TmpRankFile, "w");
+ if (fptemp == NULL) {
+ fprintf (stderr, "Unable to open rank file for updating.\n");
+ return;
+ }
+ while (fgets(line, MAX_RANK_LINE - 1, fp)) {
+ sscanf(line, "%s %d %d %d", login, &sCur.rating,
+ &sCur.num, &comp);
+ if (delName != NULL && !strcasecmp(delName, login)) { /* Kill name. */
+ delName = NULL;
+ continue;
+ }
+ if (addName != NULL && CompareStats(addName, sNew, login, &sCur) > 0) {
+ int computer = in_list(-1, L_COMPUTER, addName);
+ fprintf(fptemp, "%s %d %d %d\n", addName, sNew->rating,
+ sNew->num, computer);
+ addName = NULL;
+ }
+ fprintf(fptemp, "%s %d %d %d\n", login, sCur.rating, sCur.num, comp);
+ }
+ fclose(fptemp);
+ fclose(fp);
+
+ sprintf(command, "mv %s %s", TmpRankFile, RankFile);
+ system(command);
+}
+#endif
+
+PRIVATE void DisplayRankHead(int p, int show)
+{
+ char Line[MAX_STRING_LENGTH];
+
+ Line[0] = '\0';
+ if (CheckFlag(show, SHOW_BLITZ))
+ strcat(Line, " Blitz ");
+ if (CheckFlag(show, SHOW_STANDARD))
+ strcat(Line, " Standard ");
+ if (CheckFlag(show, SHOW_WILD))
+ strcat(Line, " Wild");
+ pprintf(p, "%s\n\n", Line);
+}
+
+PRIVATE int CountRankLine(int countComp, char *loginName,
+ int num, int is_computer)
+{
+ if (loginName == NULL || loginName[0] == '\0')
+ return 0;
+ return (countComp || !is_computer) && (is_active(num));
+}
+
+PRIVATE int GetRank(FILE * fp, char *target, int countComp)
+{
+ int count = 0;
+ int nGames, is_computer;
+ int playerFound = 0;
+ char line[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+
+ while (fgets(line, MAX_RANK_LINE - 1, fp) && !playerFound) {
+ sscanf(line, "%s %*d %d %d", login, &nGames, &is_computer);
+ if ((playerFound = !strcasecmp(login, target))
+ || CountRankLine(countComp, login, nGames, is_computer))
+ count++;
+ }
+ return (playerFound ? count : -1);
+}
+
+PRIVATE void PositionFilePtr(FILE * fp, int count, int *last,
+ int *nTied, int showComp)
+{
+ int i, rating, nGames, is_computer;
+ char login[MAX_LOGIN_NAME];
+ char line[MAX_RANK_LINE];
+
+ if (fp == NULL)
+ return;
+ rewind(fp);
+ for (i = 1; i < count; i++) {
+ do {
+ fgets(line, MAX_RANK_LINE - 1, fp);
+ if (feof(fp))
+ break;
+ sscanf(line, "%s %d %d %d", login, &rating, &nGames, &is_computer);
+ } while (!CountRankLine(showComp, login, nGames, is_computer));
+ if (rating != *last) {
+ *nTied = 1;
+ *last = rating;
+ } else
+ (*nTied)++;
+ }
+}
+
+PRIVATE int ShowRankEntry(int p, FILE * fp, int count, int comp,
+ char *target, int *lastRating, int *nTied)
+{
+ char newLine[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+ int rating, findable, nGames, is_comp;
+
+ findable = (count > 0) && !feof(fp);
+ if (findable) {
+ do {
+ fgets(newLine, MAX_RANK_LINE - 1, fp);
+ if (feof(fp))
+ findable = 0;
+ else if (newLine[0] != '\0')
+ sscanf(newLine, "%s %d %d %d",
+ login, &rating, &nGames, &is_comp);
+ else
+ login[0] = '\0';
+ } while (!CountRankLine(comp, login, nGames, is_comp) && findable
+ && strcasecmp(login, target));
+ }
+ if (findable) {
+ if (!strcasecmp(login, target)
+ && !CountRankLine(comp, login, nGames, is_comp)) {
+ pprintf_highlight(p, "---- %-12.12s %4s", login, ratstr(rating));
+ pprintf(p, " ");
+ return 0;
+ } else if (*lastRating == rating && *nTied < 1) {
+ pprintf(p, " ");
+ if (!strcasecmp(login, target))
+ pprintf_highlight(p, "%-12.12s %4s", login, ratstr(rating));
+ else
+ pprintf(p, "%-12.12s %4s", login, ratstr(rating));
+ pprintf(p, " ");
+ return 1;
+ } else {
+ if (*nTied >= 1) {
+ if (*lastRating == rating)
+ count -= *nTied;
+ *nTied = -1;
+ }
+ if (!strcasecmp(login, target))
+ pprintf_highlight(p, "%4d. %-12.12s %4s",
+ count, login, ratstr(rating));
+ else
+ pprintf(p, "%4d. %-12.12s %4s",
+ count, login, ratstr(rating));
+ pprintf(p, " ");
+ *lastRating = rating;
+ return 1;
+ }
+ } else {
+ pprintf(p, "%25s", "");
+ return 1;
+ }
+}
+
+PRIVATE int CountAbove(int num, int blitz, int std, int wild, int which)
+{
+ int max = blitz;
+
+ if (max < std)
+ max = std;
+ if (max < wild)
+ max = wild;
+ return (max <= (num + 1) / 2 ? max - 1 : (num + 1) / 2);
+}
+
+PRIVATE int ShowRankLines(int p, FILE * fb, FILE * fs, FILE * fw, int bCount,
+ int sCount, int wCount, int n, int showComp, int show, char *target)
+{
+ int lastBlitz = 9999, nTiedBlitz = 0;
+ int lastStd = 9999, nTiedStd = 0;
+ int lastWild = 9999, nTiedWild = 0;
+ int i;
+
+ if (n <= 0)
+ return 0;
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ PositionFilePtr(fb, bCount, &lastBlitz, &nTiedBlitz, showComp);
+ if (feof(fb))
+ ClearFlag(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ PositionFilePtr(fs, sCount, &lastStd, &nTiedStd, showComp);
+ if (feof(fs))
+ ClearFlag(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ PositionFilePtr(fw, wCount, &lastWild, &nTiedWild, showComp);
+ if (feof(fw))
+ ClearFlag(show, SHOW_WILD);
+ }
+ if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD))
+ return 0;
+ DisplayRankHead(p, show);
+
+ for (i = 0; i < n && show; i++) {
+ if (CheckFlag(show, SHOW_BLITZ))
+ bCount += ShowRankEntry(p, fb, bCount, showComp, target,
+ &lastBlitz, &nTiedBlitz);
+ if (CheckFlag(show, SHOW_STANDARD))
+ sCount += ShowRankEntry(p, fs, sCount, showComp, target,
+ &lastStd, &nTiedStd);
+ if (CheckFlag(show, SHOW_WILD))
+ wCount += ShowRankEntry(p, fw, wCount, showComp, target,
+ &lastWild, &nTiedWild);
+ pprintf(p, "\n");
+ }
+ return 1;
+}
+
+PUBLIC int DisplayTargetRank(int p, char *target, int show, int showComp)
+{
+ int numToShow = 20;
+ int blitzRank = -1, blitzCount;
+ int stdRank = -1, stdCount;
+ int wildRank = -1, wildCount;
+ int numAbove;
+ char Path[MAX_FILENAME_SIZE];
+ FILE *fb = NULL, *fs = NULL, *fw = NULL;
+
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ GetRankFileName(Path, TYPE_BLITZ);
+ fb = (FILE *) fopen(Path, "r");
+ if (fb != NULL)
+ blitzRank = GetRank(fb, target, showComp);
+ if (blitzRank < 0)
+ ClearFlag(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ GetRankFileName(Path, TYPE_STAND);
+ fs = (FILE *) fopen(Path, "r");
+ if (fs != NULL)
+ stdRank = GetRank(fs, target, showComp);
+ if (stdRank < 0)
+ ClearFlag(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ GetRankFileName(Path, TYPE_WILD);
+ if (CheckFlag(show, SHOW_WILD))
+ fw = (FILE *) fopen(Path, "r");
+ if (fw != NULL)
+ wildRank = GetRank(fw, target, showComp);
+ if (wildRank < 0)
+ ClearFlag(show, SHOW_WILD);
+ }
+ if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD)) {
+ pprintf(p, "No ratings to show.\n");
+ if (fb != NULL) fclose(fb);
+ if (fs != NULL) fclose(fs);
+ if (fw != NULL) fclose(fw);
+ return (0);
+ }
+ numAbove = CountAbove(numToShow, blitzRank, stdRank, wildRank, show);
+ blitzCount = blitzRank - numAbove;
+ stdCount = stdRank - numAbove;
+ wildCount = wildRank - numAbove;
+
+ ShowRankLines(p, fb, fs, fw, blitzCount, stdCount, wildCount,
+ numToShow, showComp, show, target);
+ if (fb != NULL) fclose(fb);
+ if (fs != NULL) fclose(fs);
+ if (fw != NULL) fclose(fw);
+ return (1);
+}
+
+PUBLIC int DisplayRankedPlayers(int p, int start, int end,
+ int show, int showComp)
+{
+ int num = end - start + 1;
+ FILE *fb = NULL, *fs = NULL, *fw = NULL;
+ char Path[MAX_FILENAME_SIZE];
+
+ if (start <= 0)
+ start = 1;
+ if (num <= 0)
+ return 0;
+ if (num > 100)
+ num = 100;
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ GetRankFileName(Path, TYPE_BLITZ);
+ fb = (FILE *) fopen(Path, "r");
+ if (fb == NULL)
+ ClearFlag(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ GetRankFileName(Path, TYPE_STAND);
+ fs = (FILE *) fopen(Path, "r");
+ if (fs == NULL)
+ ClearFlag(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ GetRankFileName(Path, TYPE_WILD);
+ fw = (FILE *) fopen(Path, "r");
+ if (fw == NULL)
+ ClearFlag(show, SHOW_WILD);
+ }
+ ShowRankLines(p, fb, fs, fw, start, start, start,
+ num, showComp, show, "");
+ if (fb)
+ fclose(fb);
+ if (fs)
+ fclose(fs);
+ if (fw)
+ fclose(fw);
+ return 1;
+}
+
+PUBLIC int ShowFromString(char *s)
+{
+ int i, len = strlen(s);
+ int show = 0;
+
+ if (s == NULL || s[0] == '\0')
+ return SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+ for (i = 0; i < len; i++) {
+ switch (s[i]) {
+ case 'b':
+ SetFlag(show, SHOW_BLITZ);
+ break;
+ case 's':
+ SetFlag(show, SHOW_STANDARD);
+ break;
+ case 'w':
+ SetFlag(show, SHOW_WILD);
+ break;
+ }
+ }
+ return (show);
+}
+
+PUBLIC int Best(int p, param_list param, int ShowComp)
+{
+ int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+
+ if (param[0].type != TYPE_NULL)
+ show = ShowFromString(param[0].val.word);
+
+ DisplayRankedPlayers(p, 1, 20, show, ShowComp);
+ return COM_OK;
+}
blob - /dev/null
blob + 37e26f953e5082140e397247bfbbf4a71653a7ca (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/ratings.c.orig
+/*
+ ratings.c
+
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ vek leeds@math.gatech.edu 95/04/05 Glicko system, with sterr
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "playerdb.h"
+#include "ratings.h"
+#include "gamedb.h"
+#include "command.h"
+#include "comproc.h"
+#include "lists.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "utils.h"
+
+/* grimm */
+#if defined(SGI)
+#else
+/* int system(char *arg); */
+/* int rewind(FILE *stream); */
+#endif
+
+
+PUBLIC double Ratings_B_Average;
+PUBLIC double Ratings_B_StdDev;
+
+PUBLIC double Ratings_S_Average;
+PUBLIC double Ratings_S_StdDev;
+
+PUBLIC double Ratings_W_Average;
+PUBLIC double Ratings_W_StdDev;
+
+PRIVATE double Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0;
+PRIVATE int Rb_count = 0;
+
+PRIVATE double Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0;
+PRIVATE int Rs_count = 0;
+
+PRIVATE double Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0;
+PRIVATE int Rw_count = 0;
+
+/*
+PUBLIC rateStruct bestS[MAX_BEST];
+PUBLIC int numS = 0;
+PUBLIC rateStruct bestB[MAX_BEST];
+PUBLIC int numB = 0;
+PUBLIC rateStruct bestW[MAX_BEST];
+PUBLIC int numW = 0;
+*/
+
+#define MAXHIST 30
+#define LOWESTHIST 800
+PUBLIC int sHist[MAXHIST];
+PUBLIC int bHist[MAXHIST];
+PUBLIC int wHist[MAXHIST];
+
+char sdir[] = DEFAULT_STATS;
+
+PUBLIC int is_active(int Games)
+{
+ return (Games >= PROVISIONAL);
+}
+
+
+PUBLIC void rating_add(int rating, int type)
+{
+ int which;
+
+ which = (rating - LOWESTHIST) / 100;
+ if (which < 0)
+ which = 0;
+ if (which >= MAXHIST)
+ which = MAXHIST - 1;
+ if (type == TYPE_BLITZ) {
+ bHist[which] += 1;
+ Rb_count++;
+ Rb_total += rating;
+ if (Rb_count == 1) {
+ Rb_M = rating;
+ } else {
+ Rb_S = Rb_S + (rating - Rb_M) * (rating - Rb_M);
+ Rb_M = Rb_M + (rating - Rb_M) / (Rb_count);
+ }
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else if (type == TYPE_WILD) { /* TYPE_WILD */
+ wHist[which] += 1;
+ Rw_count++;
+ Rw_total += rating;
+ if (Rw_count == 1) {
+ Rw_M = rating;
+ } else {
+ Rw_S = Rw_S + (rating - Rw_M) * (rating - Rw_M);
+ Rw_M = Rw_M + (rating - Rw_M) / (Rw_count);
+ }
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else { /* TYPE_STAND */
+ sHist[which] += 1;
+ Rs_count++;
+ Rs_total += rating;
+ if (Rs_count == 1) {
+ Rs_M = rating;
+ } else {
+ Rs_S = Rs_S + (rating - Rs_M) * (rating - Rs_M);
+ Rs_M = Rs_M + (rating - Rs_M) / (Rs_count);
+ }
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ }
+}
+
+PUBLIC void rating_remove(int rating, int type)
+{
+ int which;
+
+ which = (rating - LOWESTHIST) / 100;
+ if (which < 0)
+ which = 0;
+ if (which >= MAXHIST)
+ which = MAXHIST - 1;
+ if (type == TYPE_BLITZ) {
+ bHist[which] = bHist[which] - 1;
+ if (bHist[which] < 0)
+ bHist[which] = 0;
+ if (Rb_count == 0)
+ return;
+ Rb_count--;
+ Rb_total -= rating;
+ if (Rb_count == 0) {
+ Rb_M = 0;
+ Rb_S = 0;
+ } else {
+ Rb_M = Rb_M - (rating - Rb_M) / (Rb_count);
+ Rb_S = Rb_S - (rating - Rb_M) * (rating - Rb_M);
+ /* added this 3.11.95 foxbat */ if (Rb_S < 0)
+ Rb_S = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ } else if (type == TYPE_WILD) { /* TYPE_WILD */
+ wHist[which] = wHist[which] - 1;
+ if (wHist[which] < 0)
+ wHist[which] = 0;
+ if (Rw_count == 0)
+ return;
+ Rw_count--;
+ Rw_total -= rating;
+ if (Rw_count == 0) {
+ Rw_M = 0;
+ Rw_S = 0;
+ } else {
+ Rw_M = Rw_M - (rating - Rw_M) / (Rw_count);
+ Rw_S = Rw_S - (rating - Rw_M) * (rating - Rw_M);
+ /* added this 3.10.95 foxbat */ if (Rw_S < 0)
+ Rw_S = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ } else { /* TYPE_STAND */
+ sHist[which] = sHist[which] - 1;
+ if (sHist[which] < 0)
+ sHist[which] = 0;
+ if (Rs_count == 0)
+ return;
+ Rs_count--;
+ Rs_total -= rating;
+ if (Rs_count == 0) {
+ Rs_M = 0;
+ Rs_S = 0;
+ } else {
+ Rs_M = Rs_M - (rating - Rs_M) / (Rs_count);
+ Rs_S = Rs_S - (rating - Rs_M) * (rating - Rs_M);
+ /* added this 3.10.95 foxbat */ if (Rs_S < 0)
+ Rs_S = 0;
+ }
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ }
+}
+
+PRIVATE void load_ratings(void)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+ int i;
+
+ sprintf(fname, "%s/newratings_data", stats_dir);
+ fp = fopen(fname, "r");
+ if (!fp) {
+ fprintf(stderr, "FICS: Can't read ratings data!\n");
+ return;
+ }
+ fscanf(fp, "%lf %lf %lf %d", &Rb_M, &Rb_S, &Rb_total, &Rb_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rs_M, &Rs_S, &Rs_total, &Rs_count);
+ fscanf(fp, "%lf %lf %lf %d", &Rw_M, &Rw_S, &Rw_total, &Rw_count);
+/* loon testing
+ fscanf(fp, "%d", &numB);
+ for (i = 0; i < numB; i++) {
+ fscanf(fp, "%s %d", bestB[i].name, &(bestB[i].rating));
+ }
+ fscanf(fp, "%d", &numS);
+ for (i = 0; i < numS; i++) {
+ fscanf(fp, "%s %d", bestS[i].name, &bestS[i].rating);
+ }
+ fscanf(fp, "%d", &numW);
+ for (i = 0; i < numW; i++) {
+ fscanf(fp, "%s %d", bestW[i].name, &bestW[i].rating);
+ }
+*/
+ for (i = 0; i < MAXHIST; i++) {
+ fscanf(fp, "%d %d %d", &sHist[i], &bHist[i], &wHist[i]);
+ }
+ fclose(fp);
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+}
+
+PUBLIC void save_ratings(void)
+{
+ FILE *fp;
+ char fname[MAX_FILENAME_SIZE];
+ int i;
+
+ sprintf(fname, "%s/newratings_data", stats_dir);
+ fp = fopen(fname, "w");
+ if (!fp) {
+ fprintf(stderr, "FICS: Can't write ratings data!\n");
+ return;
+ }
+ fprintf(fp, "%10f %10f %10f %d\n", Rb_M, Rb_S, Rb_total, Rb_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rs_M, Rs_S, Rs_total, Rs_count);
+ fprintf(fp, "%10f %10f %10f %d\n", Rw_M, Rw_S, Rw_total, Rw_count);
+/* loon testing
+ fprintf(fp, "%d\n", numB);
+ for (i = 0; i < numB; i++) {
+ fprintf(fp, "%s %d\n", bestB[i].name, bestB[i].rating);
+ }
+ fprintf(fp, "%d\n", numS);
+ for (i = 0; i < numS; i++) {
+ fprintf(fp, "%s %d\n", bestS[i].name, bestS[i].rating);
+ }
+ fprintf(fp, "%d\n", numW);
+ for (i = 0; i < numW; i++) {
+ fprintf(fp, "%s %d\n", bestW[i].name, bestW[i].rating);
+ }
+*/
+ for (i = 0; i < MAXHIST; i++) {
+ fprintf(fp, "%d %d %d\n", sHist[i], bHist[i], wHist[i]);
+ }
+ fclose(fp);
+}
+
+/*
+PRIVATE void BestRemove(int p)
+{
+ int i;
+
+ for (i = 0; i < numB; i++) {
+ if (!strcmp(bestB[i].name, parray[p].name))
+ break;
+ }
+ if (i < numB) {
+ for (; i < numB - 1; i++) {
+ strcpy(bestB[i].name, bestB[i + 1].name);
+ bestB[i].rating = bestB[i + 1].rating;
+ }
+ numB--;
+ }
+ for (i = 0; i < numS; i++) {
+ if (!strcmp(bestS[i].name, parray[p].name))
+ break;
+ }
+ if (i < numS) {
+ for (; i < numS - 1; i++) {
+ strcpy(bestS[i].name, bestS[i + 1].name);
+ bestS[i].rating = bestS[i + 1].rating;
+ }
+ numS--;
+ }
+ for (i = 0; i < numW; i++) {
+ if (!strcmp(bestW[i].name, parray[p].name))
+ break;
+ }
+ if (i < numW) {
+ for (; i < numW - 1; i++) {
+ strcpy(bestW[i].name, bestW[i + 1].name);
+ bestW[i].rating = bestW[i + 1].rating;
+ }
+ numW--;
+ }
+}
+
+PRIVATE void BestAdd(int p)
+{
+ int where, j;
+
+ if ((parray[p].b_stats.rating > 0) && (parray[p].b_stats.num > 19)) {
+ for (where = 0; where < numB; where++) {
+ if (parray[p].b_stats.rating > bestB[where].rating)
+ break;
+ }
+ if (where < MAX_BEST) {
+ for (j = numB; j > where; j--) {
+ if (j == MAX_BEST)
+ continue;
+ strcpy(bestB[j].name, bestB[j - 1].name);
+ bestB[j].rating = bestB[j - 1].rating;
+ }
+ strcpy(bestB[where].name, parray[p].name);
+ bestB[where].rating = parray[p].b_stats.rating;
+ if (numB < MAX_BEST)
+ numB++;
+ }
+ }
+ if ((parray[p].s_stats.rating > 0) && (parray[p].s_stats.num > 19)) {
+ for (where = 0; where < numS; where++) {
+ if (parray[p].s_stats.rating > bestS[where].rating)
+ break;
+ }
+ if (where < MAX_BEST) {
+ for (j = numS; j > where; j--) {
+ if (j == MAX_BEST)
+ continue;
+ strcpy(bestS[j].name, bestS[j - 1].name);
+ bestS[j].rating = bestS[j - 1].rating;
+ }
+ strcpy(bestS[where].name, parray[p].name);
+ bestS[where].rating = parray[p].s_stats.rating;
+ if (numS < MAX_BEST)
+ numS++;
+ }
+ }
+ if ((parray[p].w_stats.rating > 0) && (parray[p].w_stats.num > 19)) {
+ for (where = 0; where < numW; where++) {
+ if (parray[p].w_stats.rating > bestW[where].rating)
+ break;
+ }
+ if (where < MAX_BEST) {
+ for (j = numW; j > where; j--) {
+ if (j == MAX_BEST)
+ continue;
+ strcpy(bestW[j].name, bestW[j - 1].name);
+ bestW[j].rating = bestW[j - 1].rating;
+ }
+ strcpy(bestW[where].name, parray[p].name);
+ bestW[where].rating = parray[p].w_stats.rating;
+ if (numW < MAX_BEST)
+ numW++;
+ }
+ }
+}
+
+PUBLIC void BestUpdate(int p)
+{
+ BestRemove(p);
+ BestAdd(p);
+}
+
+*/
+
+PUBLIC void zero_stats(void)
+{
+ int i;
+ for (i = 0; i < MAXHIST; i++) {
+ sHist[i] = 0;
+ bHist[i] = 0;
+ wHist[i] = 0;
+ }
+ Rb_M = 0.0, Rb_S = 0.0, Rb_total = 0.0;
+ Rb_count = 0;
+
+ Rs_M = 0.0, Rs_S = 0.0, Rs_total = 0.0;
+ Rs_count = 0;
+
+ Rw_M = 0.0, Rw_S = 0.0, Rw_total = 0.0;
+ Rw_count = 0;
+
+/*
+ numS = 0;
+ numB = 0;
+ numW = 0;
+*/
+}
+
+PUBLIC void rating_init(void)
+{
+ zero_stats();
+ load_ratings();
+}
+
+/* This recalculates the rating info from the player data, it can take
+ a long time! */
+PUBLIC void rating_recalc(void)
+{
+ char dname[MAX_FILENAME_SIZE];
+ int p1;
+ int c;
+ int t = time(0);
+ DIR *dirp;
+#if USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+
+ fprintf(stderr, "FICS: Recalculating ratings at %s\n", strltime(&t));
+ zero_stats();
+ for (c = 'a'; c <= 'z'; c++) {
+ /* Never done as ratings server */
+ sprintf(dname, "%s/%c", player_dir, c);
+ dirp = opendir(dname);
+ if (!dirp)
+ continue;
+ for (dp = readdir(dirp); dp != NULL; dp = readdir(dirp)) {
+ if (dp->d_name[0] != '.') {
+ p1 = player_new();
+ if (player_read(p1, dp->d_name)) {
+ player_remove(p1);
+ fprintf(stderr, "FICS: Problem reading player %s.\n", dp->d_name);
+ continue;
+ }
+ if (parray[p1].b_stats.rating > 0) {
+ rating_add(parray[p1].b_stats.rating, TYPE_BLITZ);
+ }
+ if (parray[p1].s_stats.rating > 0) {
+ rating_add(parray[p1].s_stats.rating, TYPE_STAND);
+ }
+ if (parray[p1].w_stats.rating > 0) {
+ rating_add(parray[p1].w_stats.rating, TYPE_WILD);
+ }
+ player_remove(p1);
+ }
+ }
+ closedir(dirp);
+ }
+ if (Rs_count) {
+ Ratings_S_StdDev = sqrt(Rs_S / Rs_count);
+ Ratings_S_Average = Rs_total / (double) Rs_count;
+ } else {
+ Ratings_S_StdDev = 0;
+ Ratings_S_Average = 0;
+ }
+ if (Rb_count) {
+ Ratings_B_StdDev = sqrt(Rb_S / Rb_count);
+ Ratings_B_Average = Rb_total / (double) Rb_count;
+ } else {
+ Ratings_B_StdDev = 0;
+ Ratings_B_Average = 0;
+ }
+ if (Rw_count) {
+ Ratings_W_StdDev = sqrt(Rw_S / Rw_count);
+ Ratings_W_Average = Rw_total / (double) Rw_count;
+ } else {
+ Ratings_W_StdDev = 0;
+ Ratings_W_Average = 0;
+ }
+ save_ratings();
+ t = time(0);
+ fprintf(stderr, "FICS: Finished at %s\n", strltime(&t));
+}
+
+/* Constants for Glicko system */
+#define Gd 3.25
+#define Gr0 1720
+#define Gs0 350
+#define Gq 0.00575646273249
+#define Gp 0.000010072398601964
+
+/* End of Glicko system variables */
+
+PRIVATE double Gf(double ss)
+{
+ return (1.0 / sqrt(1.0 + Gp * ss * ss));
+}
+
+/* Confusing but economical: calculate error and attenuation function together */
+PRIVATE double GE(int r, int rr, double ss, double *fss)
+{
+ *fss = Gf(ss);
+ return (1.0 / (1.0 + pow(10.0, (rr - r) * (*fss) / 400.0)));
+}
+
+PUBLIC double current_sterr(double s, int t)
+{
+ if (t < 0)
+ t = 0; /* this shouldn't happen */
+ return (sqrt(s * s + Gd * Gd * log(1.0 + t / 60.0)));
+}
+
+/* Calculates new rating and standard error. By vek. The person */
+/* who invented the ratings system is Mark E. Glickman, Ph.D. */
+/* His e-mail address is glickman@hustat.harvard.edu as of April '95. */
+/* Postscript copy of the note I coded this from should be available */
+/* for ftp from ics.onenet.net, if not elsewhere. */
+
+PUBLIC void rating_sterr_delta(int p1, int p2, int type, int gtime, int result,
+ int *deltarating, double *newsterr)
+{
+ statistics *p1_stats;
+ statistics *p2_stats;
+
+ double s1, s2;
+ int t1, r1, t2, r2; /* Initial sterrs and ratings */
+ double E, fs2, denominator, GK, w; /* Parts of fancy formulas */
+ double delta, sigma; /* Results to return */
+
+ if (type == TYPE_BLITZ) {
+ p1_stats = &parray[p1].b_stats;
+ p2_stats = &parray[p2].b_stats;
+ } else if (type == TYPE_WILD) {
+ p1_stats = &parray[p1].w_stats;
+ p2_stats = &parray[p2].w_stats;
+ } else {
+ p1_stats = &parray[p1].s_stats;
+ p2_stats = &parray[p2].s_stats;
+ }
+
+ /* Calculate effective pre-game sterrs. ltime==0 implies never had sterr. */
+
+ if (p1_stats->ltime == 0)
+ s1 = Gs0;
+ else {
+ t1 = gtime - p1_stats->ltime;
+ s1 = current_sterr(p1_stats->sterr, t1);
+ if (s1 > Gs0)
+ s1 = Gs0;
+ }
+
+ if (p2_stats->ltime == 0)
+ s2 = Gs0;
+ else {
+ t2 = gtime - p2_stats->ltime;
+ s2 = current_sterr(p2_stats->sterr, t2);
+ if (s2 > Gs0)
+ s2 = Gs0;
+ }
+
+ /* pre-game ratings */
+ if (p1_stats->rating == 0 && p1_stats->num == 0)
+ r1 = Gr0;
+ else
+ r1 = p1_stats->rating;
+
+ if (p2_stats->rating == 0 && p2_stats->num == 0)
+ r2 = Gr0;
+ else
+ r2 = p2_stats->rating;
+
+ /* now crunch */
+
+ if (result == RESULT_WIN) {
+ w = 1.0;
+ } else if (result == RESULT_DRAW) {
+ w = 0.5;
+ } else {
+ w = 0.0;
+ }
+
+ E = GE(r1, r2, s2, &fs2); /* side effect: calculate fs2 */
+
+ denominator = 1.0 / (s1 * s1) + Gq * Gq * fs2 * fs2 * E * (1.0 - E);
+ GK = Gq * fs2 / denominator;
+
+ delta = GK * (w - E);
+ if (p1_stats->rating == 0 && p1_stats->num == 0)
+ *deltarating = (int) (Gr0 + delta + 0.5);
+ else
+ *deltarating = (int) delta + 0.5; /* Returned values: deltarating,
+ newsterr */
+
+ sigma = 1.0 / sqrt(denominator);
+ *newsterr = (double) sigma;
+
+}
+
+/* vek: Next is for when we want just the delta, and not the sigma. */
+
+PUBLIC int rating_delta(int p1, int p2, int type, int result, int gtime)
+{
+ int delta;
+ double sigma;
+
+ rating_sterr_delta(p1, p2, type, gtime, result, &delta, &sigma);
+ return (delta);
+
+}
+
+PUBLIC int rating_update(int g)
+{
+ int wDelta, bDelta;
+ double wSigma, bSigma; /* vek */
+
+ int wRes, bRes;
+ statistics *w_stats;
+ statistics *b_stats;
+
+ int gtime;
+
+ int inprogress = (g == parray[garray[g].black].game);
+ /* if this is adjudication of stored game, be quiet about ratings change */
+
+ if (garray[g].type == TYPE_BLITZ) {
+ w_stats = &parray[garray[g].white].b_stats;
+ b_stats = &parray[garray[g].black].b_stats;
+ } else if (garray[g].type == TYPE_STAND) {
+ w_stats = &parray[garray[g].white].s_stats;
+ b_stats = &parray[garray[g].black].s_stats;
+ } else if (garray[g].type == TYPE_WILD) {
+ w_stats = &parray[garray[g].white].w_stats;
+ b_stats = &parray[garray[g].black].w_stats;
+ } else {
+ fprintf(stderr, "FICS: Can't update untimed ratings!\n");
+ return -1;
+ }
+
+ switch (garray[g].result) {
+ case END_CHECKMATE:
+ case END_RESIGN:
+ case END_FLAG:
+ case END_ADJWIN:
+ if (garray[g].winner == WHITE) {
+ wRes = RESULT_WIN;
+ bRes = RESULT_LOSS;
+ } else {
+ bRes = RESULT_WIN;
+ wRes = RESULT_LOSS;
+ }
+ break;
+ case END_AGREEDDRAW:
+ case END_REPETITION:
+ case END_50MOVERULE:
+ case END_STALEMATE:
+ case END_NOMATERIAL:
+ case END_BOTHFLAG:
+ case END_ADJDRAW:
+ case END_FLAGNOMATERIAL:
+ wRes = bRes = RESULT_DRAW;
+ break;
+ default:
+ fprintf(stderr, "FICS: Update undecided game %d?\n", garray[g].result);
+ return -1;
+ }
+ gtime = untenths(garray[g].timeOfStart);
+ rating_sterr_delta(garray[g].white, garray[g].black,
+ garray[g].type, gtime, wRes,
+ &wDelta, &wSigma);
+
+ rating_sterr_delta(garray[g].black, garray[g].white,
+ garray[g].type, gtime, bRes,
+ &bDelta, &bSigma);
+
+ /* vek: Update time of last rated game played, for future ratings calcs. */
+ /* Kept independently for blitz and standard. */
+ w_stats->ltime = gtime;
+ b_stats->ltime = gtime;
+ /* end vek add 4/5/95 */
+
+ if (wRes == RESULT_WIN) {
+ w_stats->win++;
+ } else if (wRes == RESULT_LOSS) {
+ w_stats->los++;
+ } else {
+ w_stats->dra++;
+ }
+ w_stats->num++;
+ if (bRes == RESULT_WIN) {
+ b_stats->win++;
+ } else if (bRes == RESULT_LOSS) {
+ b_stats->los++;
+ } else {
+ b_stats->dra++;
+ }
+ b_stats->num++;
+ rating_remove(w_stats->rating, garray[g].type);
+ rating_remove(b_stats->rating, garray[g].type);
+
+ if (inprogress) {
+ pprintf(garray[g].white, "%s rating adjustment: %d ",
+ ((garray[g].type == TYPE_BLITZ) ? "Blitz" : ((garray[g].type == TYPE_WILD) ? "Wild" : "Standard")), w_stats->rating);
+ pprintf(garray[g].black, "%s rating adjustment: %d ",
+ ((garray[g].type == TYPE_BLITZ) ? "Blitz" : ((garray[g].type == TYPE_WILD) ? "Wild" : "Standard")), b_stats->rating);
+ }
+ if (wDelta < -1000) {
+ pprintf(garray[g].white, "not changed due to bug (way too small)! sorry!\n");
+ fprintf(stderr, "FICS: Got too small ratings bug for %s (w) vs. %s\n",
+ parray[garray[g].white].login, parray[garray[g].black].login);
+ } else if (wDelta > 3000) {
+ pprintf(garray[g].white, "not changed due to bug (way too big)! sorry!\n");
+ fprintf(stderr, "FICS: Got too big ratings bug for %s (w) vs. %s\n",
+ parray[garray[g].white].login, parray[garray[g].black].login);
+ } else {
+ w_stats->rating += wDelta;
+ w_stats->sterr = wSigma;
+ }
+
+ if (bDelta < -1000) {
+ pprintf(garray[g].black, "not changed due to bug (way too small)! sorry! ");
+ fprintf(stderr, "FICS: Got too small ratings bug for %s (b) vs. %s\n",
+ parray[garray[g].black].login, parray[garray[g].white].login);
+ } else if (bDelta > 3000) {
+ pprintf(garray[g].black, "not changed due to bug (way too big)! sorry! ");
+ fprintf(stderr, "FICS: Got too big ratings bug for %s (b) vs. %s\n",
+ parray[garray[g].black].login, parray[garray[g].white].login);
+ } else {
+ b_stats->rating += bDelta;
+ b_stats->sterr = bSigma;
+ } /* error messages down to vek */
+
+ rating_add(w_stats->rating, garray[g].type);
+ rating_add(b_stats->rating, garray[g].type);
+
+ if ((w_stats->rating > w_stats->best) && (is_active(w_stats->num))) {
+ w_stats->best = w_stats->rating;
+ w_stats->whenbest = time(NULL);
+ }
+ if ((b_stats->rating > b_stats->best) && (is_active(b_stats->num))) {
+ b_stats->best = b_stats->rating;
+ b_stats->whenbest = time(NULL);
+ }
+/* Ratings are now saved to disk after each game */
+ player_save(garray[g].white);
+ player_save(garray[g].black);
+
+/* foxbat 3.11.95 */
+ if (garray[g].type == TYPE_BLITZ) {
+ Rb_count++;
+ Rb_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (garray[g].type == TYPE_STAND) {
+ Rs_count++;
+ Rs_total += (w_stats->rating + b_stats->rating) / 2.0;
+ } else if (garray[g].type == TYPE_WILD) {
+ Rw_count++;
+ Rw_total += (w_stats->rating + b_stats->rating) / 2.0;
+ }
+/* end add */
+/* loon testing
+ BestUpdate(garray[g].white);
+ BestUpdate(garray[g].black);
+*/
+ if (inprogress) {
+ pprintf(garray[g].white, "--> %d\n", w_stats->rating);
+ pprintf(garray[g].black, "--> %d\n", b_stats->rating);
+ }
+ save_ratings();
+ UpdateRank(garray[g].type, parray[garray[g].white].name,
+ w_stats, parray[garray[g].white].name);
+ UpdateRank(garray[g].type, parray[garray[g].black].name,
+ b_stats, parray[garray[g].black].name);
+ return 0;
+}
+
+PUBLIC int com_assess(int p, param_list param)
+{
+ int p1 = p, p2, nowtime;
+ int p1_connected = 1, p2_connected = 1;
+ int win1, draw1, loss1;
+ double newsterr1;
+ int win2, draw2, loss2;
+ double newsterr2;
+
+ nowtime = time(0);
+
+/* Hawk: Now assess can be used with players not */
+/* logged on -- I wonder if anyone doesn't */
+/* get just a bit confused here :) */
+
+ if (param[0].type == TYPE_NULL) {
+ if (parray[p].game <0) {
+ pprintf(p, "You are not playing a game.\n");
+ return COM_OK;
+ } else if (garray[parray[p].game].status == GAME_EXAMINE) {
+ if (!strcmp(garray[parray[p].game].black_name, parray[p].name)) {
+ pcommand(p, "assess %s\n", garray[parray[p].game].white_name);
+ } else {
+ pcommand(p, "assess %s %s\n",
+ garray[parray[p].game].white_name,
+ garray[parray[p].game].black_name);
+ }
+ return COM_OK;
+ } else {
+ p2 = parray[p].opponent;
+ }
+ } else {
+ if (!FindPlayer(p, ¶m[0], &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" was found.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (param[1].type != TYPE_NULL) {
+ p1 = p2;
+ p1_connected = p2_connected;
+ if (!FindPlayer(p, ¶m[1], &p2, &p2_connected)) {
+ pprintf(p, "No user named \"%s\" was found.\n", param[1].val.word);
+ if (!p1_connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ }
+ if (p1 == p2) {
+ pprintf(p, "You can't assess the same players.\n");
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+ }
+ rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_BLITZ, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_BLITZ, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nBlitz\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].b_stats.rating, parray[p1].registered), parray[p1].b_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].b_stats.rating, parray[p2].registered), parray[p2].b_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_STAND, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_STAND, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nStandard\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].s_stats.rating, parray[p1].registered), parray[p1].s_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].s_stats.rating, parray[p2].registered), parray[p2].s_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_WIN, &win1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_DRAW, &draw1, &newsterr1);
+ rating_sterr_delta(p1, p2, TYPE_WILD, nowtime, RESULT_LOSS, &loss1, &newsterr1);
+ rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_WIN, &win2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_DRAW, &draw2, &newsterr2);
+ rating_sterr_delta(p2, p1, TYPE_WILD, nowtime, RESULT_LOSS, &loss2, &newsterr2);
+
+ pprintf(p, "\nWild\n %10s (%4s, RD: %5.1f) %10s (%4s, RD: %5.1f)\n",
+ parray[p1].name, ratstrii(parray[p1].w_stats.rating, parray[p1].registered), parray[p1].w_stats.sterr,
+ parray[p2].name, ratstrii(parray[p2].w_stats.rating, parray[p2].registered), parray[p2].w_stats.sterr);
+ pprintf(p, "Win : %4d %4d\n", win1, loss2);
+ pprintf(p, "Draw: %4d %4d\n", draw1, draw2);
+ pprintf(p, "Loss: %4d %4d\n", loss1, win2);
+ pprintf(p, "New RD: %5.1f %5.1f\n", newsterr1, newsterr2);
+
+ if (!p1_connected)
+ player_remove(p1);
+ if (!p2_connected)
+ player_remove(p2);
+ return COM_OK;
+}
+
+
+PUBLIC int com_best(int p, param_list param)
+{
+ return Best(p, param, 1);
+}
+
+PUBLIC int com_hbest(int p, param_list param)
+{
+ return Best(p, param, 0);
+}
+
+#if 0
+PUBLIC int com_best(int p, param_list param)
+{
+ int i;
+
+ pprintf(p, "Standard Blitz Wild\n");
+ for (i = 0; i < MAX_BEST; i++) {
+ if ((i >= numS) && (i >= numB))
+ break;
+ if (i < numS) {
+ pprintf(p, "%4d %-17s ", bestS[i].rating, bestS[i].name);
+ } else {
+ pprintf(p, " ");
+ }
+ if (i < numB) {
+ pprintf(p, "%4d %-17s ", bestB[i].rating, bestB[i].name);
+ } else {
+ pprintf(p, " ");
+ }
+ if (i < numW) {
+ pprintf(p, "%4d %-17s\n", bestW[i].rating, bestW[i].name);
+ } else {
+ pprintf(p, "\n");
+ }
+ }
+ return COM_OK;
+}
+#endif
+
+PUBLIC int com_statistics(int p, param_list param)
+{
+ pprintf(p, " Standard Blitz Wild\n");
+ pprintf(p, "average: %7.2f %7.2f %7.2f\n", Ratings_S_Average, Ratings_B_Average, Ratings_W_Average);
+ pprintf(p, "std dev: %7.2f %7.2f %7.2f\n", Ratings_S_StdDev, Ratings_B_StdDev, Ratings_W_StdDev);
+ pprintf(p, "number : %7d %7d %7d\n", Rs_count, Rb_count, Rw_count);
+ return COM_OK;
+}
+
+PUBLIC int com_fixrank(int p, param_list param)
+{
+ int p1, connected;
+
+ if (!FindPlayer(p, ¶m[0], &p1, &connected))
+ return COM_OK;
+ UpdateRank(TYPE_BLITZ, parray[p1].name, &parray[p1].b_stats,
+ parray[p1].name);
+ UpdateRank(TYPE_STAND, parray[p1].name, &parray[p1].s_stats,
+ parray[p1].name);
+ UpdateRank(TYPE_WILD, parray[p1].name, &parray[p1].w_stats,
+ parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_rank(int p, param_list param)
+{
+ return DisplayRank(p, param, 1);
+}
+
+PUBLIC int com_hrank(int p, param_list param)
+{
+ return DisplayRank(p, param, 0);
+}
+
+PUBLIC int DisplayRank(int p, param_list param, int showComputers)
+{
+ int start, end, target, connected;
+ int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+
+ if (param[0].type == TYPE_NULL) {
+ DisplayTargetRank(p, parray[p].name, show, showComputers);
+ return COM_OK;
+ } else if (isdigit(param[0].val.word[0])) {
+ end = -1;
+ sscanf(param[0].val.word, "%d-%d", &start, &end);
+ if (end > 0 && (param[1].type != TYPE_NULL))
+ show = ShowFromString(param[1].val.word);
+ DisplayRankedPlayers(p, start, end, show, showComputers);
+ return COM_OK;
+ } else {
+ target = player_search(p, param[0].val.word);
+ if (target == 0) {
+ pprintf(p, "Target %s not found.\n", param[0].val.word);
+ return COM_OK;
+ }
+ connected = (target > 0);
+ if (!connected)
+ target = -target - 1;
+ else
+ target--;
+
+ if (param[1].type != TYPE_NULL)
+ show = ShowFromString(param[1].val.word);
+ DisplayTargetRank(p, parray[target].name, show, showComputers);
+ if (!connected)
+ player_remove(target);
+ return COM_OK;
+ }
+}
+
+/* CompareStats returns 1 if s1 comes first, -1 if s2 comes first, and 0
+ if neither takes precedence. */
+PRIVATE int CompareStats(char *name1, statistics *s1,
+ char *name2, statistics *s2)
+{
+ int i, l1;
+
+ if (s1 == NULL)
+ if (s2 == NULL)
+ return 0;
+ else
+ return -1;
+ else if (s2 == NULL)
+ return 1;
+
+ if (s1->rating > s2->rating)
+ return 1;
+ if (s1->rating < s2->rating)
+ return -1;
+ l1 = strlen(name1);
+ for (i = 0; i < l1; i++) {
+ if (name2[i] == '\0')
+ return -1;
+ if (tolower(name1[i]) < tolower(name2[i]))
+ return 1;
+ if (tolower(name1[i]) > tolower(name2[i]))
+ return -1;
+ }
+ if (name2[i] != '\0')
+ return 1;
+/* if (s1->sterr < s2->sterr) return 1;
+ if (s1->sterr > s2->sterr) return -1;
+ if (s1->num > s2->num) return 1;
+ if (s1->num < s2->num) return -1;
+*/
+ fprintf(stderr, "Duplicate entries found: %s.\n", name1);
+ return 0;
+}
+
+PRIVATE int GetRankFileName(char *out, int type)
+{
+ switch (type) {
+ case TYPE_BLITZ:sprintf(out, "%s/rank.blitz", sdir);
+ return type;
+ case TYPE_STAND:
+ sprintf(out, "%s/rank.std", sdir);
+ return type;
+ case TYPE_WILD:
+ sprintf(out, "%s/rank.wild", sdir);
+ return type;
+ default:
+ return -1;
+ }
+}
+
+PUBLIC void UpdateRank(int type, char *addName,
+ statistics *sNew, char *delName)
+{
+ char RankFile[MAX_FILENAME_SIZE];
+ char TmpRankFile[MAX_FILENAME_SIZE];
+ char line[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+ char command[MAX_STRING_LENGTH];
+ int comp;
+ statistics sCur;
+ FILE *fp;
+ FILE *fptemp;
+
+ if (GetRankFileName(RankFile, type) < 0)
+ return;
+ fp = fopen(RankFile, "r");
+ if (fp == NULL) {
+ fprintf(stderr, "Can't open rank file to update.\n");
+ return;
+ }
+ sprintf(TmpRankFile, "%s/tmpRank", sdir);
+ fptemp = fopen(TmpRankFile, "w");
+
+ while (fgets(line, MAX_RANK_LINE - 1, fp)) {
+ sscanf(line, "%s %d %d %d", login, &sCur.rating,
+ &sCur.num, &comp);
+ if (delName != NULL && !strcasecmp(delName, login)) { /* Kill name. */
+ delName = NULL;
+ continue;
+ }
+ if (addName != NULL && CompareStats(addName, sNew, login, &sCur) > 0) {
+ int computer = in_list("computer", addName);
+ fprintf(fptemp, "%s %d %d %d\n", addName, sNew->rating,
+ sNew->num, computer);
+ addName = NULL;
+ }
+ fprintf(fptemp, "%s %d %d %d\n", login, sCur.rating, sCur.num, comp);
+ }
+ fclose(fptemp);
+ fclose(fp);
+
+ sprintf(command, "mv %s %s", TmpRankFile, RankFile);
+ system(command);
+}
+
+PRIVATE void DisplayRankHead(int p, int show)
+{
+ char Line[MAX_STRING_LENGTH];
+
+ Line[0] = '\0';
+ if (CheckFlag(show, SHOW_BLITZ))
+ strcat(Line, " Blitz ");
+ if (CheckFlag(show, SHOW_STANDARD))
+ strcat(Line, " Standard ");
+ if (CheckFlag(show, SHOW_WILD))
+ strcat(Line, " Wild");
+ pprintf(p, "%s\n\n", Line);
+}
+
+PRIVATE int CountRankLine(int countComp, char *loginName,
+ int num, int is_computer)
+{
+ if (loginName == NULL || loginName[0] == '\0')
+ return 0;
+ return (countComp || !is_computer) && (is_active(num));
+}
+
+PRIVATE int GetRank(FILE * fp, char *target, int countComp)
+{
+ int count = 0;
+ int nGames, is_computer;
+ int playerFound = 0;
+ char line[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+
+ while (fgets(line, MAX_RANK_LINE - 1, fp) && !playerFound) {
+ sscanf(line, "%s %*d %d %d", login, &nGames, &is_computer);
+ if ((playerFound = !strcasecmp(login, target))
+ || CountRankLine(countComp, login, nGames, is_computer))
+ count++;
+ }
+ return (playerFound ? count : -1);
+}
+
+PRIVATE void PositionFilePtr(FILE * fp, int count, int *last,
+ int *nTied, int showComp)
+{
+ int i, rating, nGames, is_computer;
+ char login[MAX_LOGIN_NAME];
+ char line[MAX_RANK_LINE];
+
+ if (fp == NULL)
+ return;
+ rewind(fp);
+ for (i = 1; i < count; i++) {
+ do {
+ fgets(line, MAX_RANK_LINE - 1, fp);
+ if (feof(fp))
+ break;
+ sscanf(line, "%s %d %d %d", login, &rating, &nGames, &is_computer);
+ } while (!CountRankLine(showComp, login, nGames, is_computer));
+ if (rating != *last) {
+ *nTied = 1;
+ *last = rating;
+ } else
+ (*nTied)++;
+ }
+}
+
+PRIVATE int ShowRankEntry(int p, FILE * fp, int count, int comp,
+ char *target, int *lastRating, int *nTied)
+{
+ char newLine[MAX_RANK_LINE];
+ char login[MAX_LOGIN_NAME];
+ int rating, findable, nGames, is_comp;
+
+ findable = (count > 0) && !feof(fp);
+ if (findable) {
+ do {
+ fgets(newLine, MAX_RANK_LINE - 1, fp);
+ if (feof(fp))
+ findable = 0;
+ else if (newLine[0] != '\0')
+ sscanf(newLine, "%s %d %d %d",
+ login, &rating, &nGames, &is_comp);
+ else
+ login[0] = '\0';
+ } while (!CountRankLine(comp, login, nGames, is_comp) && findable
+ && strcasecmp(login, target));
+ }
+ if (findable) {
+ if (!strcasecmp(login, target)
+ && !CountRankLine(comp, login, nGames, is_comp)) {
+ pprintf_highlight(p, "---- %-12.12s %4s", login, ratstr(rating));
+ pprintf(p, " ");
+ return 0;
+ } else if (*lastRating == rating && *nTied < 1) {
+ pprintf(p, " ");
+ if (!strcasecmp(login, target))
+ pprintf_highlight(p, "%-12.12s %4s", login, ratstr(rating));
+ else
+ pprintf(p, "%-12.12s %4s", login, ratstr(rating));
+ pprintf(p, " ");
+ return 1;
+ } else {
+ if (*nTied >= 1) {
+ if (*lastRating == rating)
+ count -= *nTied;
+ *nTied = -1;
+ }
+ if (!strcasecmp(login, target))
+ pprintf_highlight(p, "%4d. %-12.12s %4s",
+ count, login, ratstr(rating));
+ else
+ pprintf(p, "%4d. %-12.12s %4s",
+ count, login, ratstr(rating));
+ pprintf(p, " ");
+ *lastRating = rating;
+ return 1;
+ }
+ } else {
+ pprintf(p, "%25s", "");
+ return 1;
+ }
+}
+
+PRIVATE int CountAbove(int num, int blitz, int std, int wild, int which)
+{
+ int max = blitz;
+
+ if (max < std)
+ max = std;
+ if (max < wild)
+ max = wild;
+ return (max <= (num + 1) / 2 ? max - 1 : (num + 1) / 2);
+}
+
+PRIVATE int ShowRankLines(int p, FILE * fb, FILE * fs, FILE * fw, int bCount,
+ int sCount, int wCount, int n, int showComp, int show, char *target)
+{
+ int lastBlitz = 9999, nTiedBlitz = 0;
+ int lastStd = 9999, nTiedStd = 0;
+ int lastWild = 9999, nTiedWild = 0;
+ int i;
+
+ if (n <= 0)
+ return 0;
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ PositionFilePtr(fb, bCount, &lastBlitz, &nTiedBlitz, showComp);
+ if (feof(fb))
+ ClearFlag(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ PositionFilePtr(fs, sCount, &lastStd, &nTiedStd, showComp);
+ if (feof(fs))
+ ClearFlag(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ PositionFilePtr(fw, wCount, &lastWild, &nTiedWild, showComp);
+ if (feof(fw))
+ ClearFlag(show, SHOW_WILD);
+ }
+ if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD))
+ return 0;
+ DisplayRankHead(p, show);
+
+ for (i = 0; i < n && show; i++) {
+ if (CheckFlag(show, SHOW_BLITZ))
+ bCount += ShowRankEntry(p, fb, bCount, showComp, target,
+ &lastBlitz, &nTiedBlitz);
+ if (CheckFlag(show, SHOW_STANDARD))
+ sCount += ShowRankEntry(p, fs, sCount, showComp, target,
+ &lastStd, &nTiedStd);
+ if (CheckFlag(show, SHOW_WILD))
+ wCount += ShowRankEntry(p, fw, wCount, showComp, target,
+ &lastWild, &nTiedWild);
+ pprintf(p, "\n");
+ }
+ return 1;
+}
+
+PUBLIC int DisplayTargetRank(int p, char *target, int show, int showComp)
+{
+ int numToShow = 20;
+ int blitzRank = -1, blitzCount;
+ int stdRank = -1, stdCount;
+ int wildRank = -1, wildCount;
+ int numAbove;
+ char Path[MAX_FILENAME_SIZE];
+ FILE *fb = NULL, *fs = NULL, *fw = NULL;
+
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ GetRankFileName(Path, TYPE_BLITZ);
+ fb = (FILE *) fopen(Path, "r");
+ if (fb != NULL)
+ blitzRank = GetRank(fb, target, showComp);
+ if (blitzRank < 0)
+ ClearFlag(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ GetRankFileName(Path, TYPE_STAND);
+ fs = (FILE *) fopen(Path, "r");
+ if (fs != NULL)
+ stdRank = GetRank(fs, target, showComp);
+ if (stdRank < 0)
+ ClearFlag(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ GetRankFileName(Path, TYPE_WILD);
+ if (CheckFlag(show, SHOW_WILD))
+ fw = (FILE *) fopen(Path, "r");
+ if (fw != NULL)
+ wildRank = GetRank(fw, target, showComp);
+ if (wildRank < 0)
+ ClearFlag(show, SHOW_WILD);
+ }
+ if (!CheckFlag(show, SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD)) {
+ pprintf(p, "No ratings to show.\n");
+ return (0);
+ }
+ numAbove = CountAbove(numToShow, blitzRank, stdRank, wildRank, show);
+ blitzCount = blitzRank - numAbove;
+ stdCount = stdRank - numAbove;
+ wildCount = wildRank - numAbove;
+
+ ShowRankLines(p, fb, fs, fw, blitzCount, stdCount, wildCount,
+ numToShow, showComp, show, target);
+ if (fb != NULL)
+ fclose(fb);
+ if (fs != NULL)
+ fclose(fs);
+ if (fw != NULL)
+ fclose(fw);
+ return (1);
+}
+
+PUBLIC int DisplayRankedPlayers(int p, int start, int end,
+ int show, int showComp)
+{
+ int num = end - start + 1;
+ FILE *fb = NULL, *fs = NULL, *fw = NULL;
+ char Path[MAX_FILENAME_SIZE];
+
+ if (start <= 0)
+ start = 1;
+ if (num <= 0)
+ return 0;
+ if (num > 100)
+ num = 100;
+ if (CheckFlag(show, SHOW_BLITZ)) {
+ GetRankFileName(Path, TYPE_BLITZ);
+ fb = (FILE *) fopen(Path, "r");
+ if (fb == NULL)
+ ClearFlag(show, SHOW_BLITZ);
+ }
+ if (CheckFlag(show, SHOW_STANDARD)) {
+ GetRankFileName(Path, TYPE_STAND);
+ fs = (FILE *) fopen(Path, "r");
+ if (fs == NULL)
+ ClearFlag(show, SHOW_STANDARD);
+ }
+ if (CheckFlag(show, SHOW_WILD)) {
+ GetRankFileName(Path, TYPE_WILD);
+ fw = (FILE *) fopen(Path, "r");
+ if (fw == NULL)
+ ClearFlag(show, SHOW_WILD);
+ }
+ ShowRankLines(p, fb, fs, fw, start, start, start,
+ num, showComp, show, "");
+ if (fb)
+ fclose(fb);
+ if (fs)
+ fclose(fs);
+ if (fw)
+ fclose(fw);
+ return 1;
+}
+
+PUBLIC int ShowFromString(char *s)
+{
+ int i, len = strlen(s);
+ int show = 0;
+
+ if (s == NULL || s[0] == '\0')
+ return SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+ for (i = 0; i < len; i++) {
+ switch (s[i]) {
+ case 'b':
+ SetFlag(show, SHOW_BLITZ);
+ break;
+ case 's':
+ SetFlag(show, SHOW_STANDARD);
+ break;
+ case 'w':
+ SetFlag(show, SHOW_WILD);
+ break;
+ }
+ }
+ return (show);
+}
+
+PUBLIC int Best(int p, param_list param, int ShowComp)
+{
+ int show = SHOW_BLITZ | SHOW_STANDARD | SHOW_WILD;
+
+ if (param[0].type != TYPE_NULL)
+ show = ShowFromString(param[0].val.word);
+
+ DisplayRankedPlayers(p, 1, 20, show, ShowComp);
+ return COM_OK;
+}
blob - /dev/null
blob + a9823dad07b9c20a0145fc840234c01544e82037 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/ratings.h
+/* ratings.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _RATINGS_H
+#define _RATINGS_H
+
+#define STATS_VERSION 2
+
+#define RESULT_WIN 0
+#define RESULT_DRAW 1
+#define RESULT_LOSS 2
+#define RESULT_ABORT 3
+
+#define PROVISIONAL 20
+
+#define MAX_RANK_LINE 50
+#define MAX_BEST 20
+
+#define SHOW_BLITZ 0x1
+#define SHOW_STANDARD 0x2
+#define SHOW_WILD 0x4
+
+#include "command.h"
+
+typedef struct _rateStruct {
+ char name[MAX_LOGIN_NAME];
+ int rating;
+} rateStruct;
+
+extern int is_active(int);
+extern void rating_init(void);
+extern void rating_recalc(void);
+extern void rating_sterr_delta(int, int, int, int, int, int *, double *);
+extern int rating_delta(int, int, int, int, int);
+extern int rating_update(int);
+
+extern int com_assess(int, param_list);
+extern int com_best(int, param_list);
+extern int com_hbest(int, param_list);
+extern int com_statistics(int, param_list);
+extern int com_fixrank(int, param_list);
+extern int com_rank(int, param_list);
+extern int com_hrank(int, param_list);
+
+extern void save_ratings(void);
+/*extern void BestUpdate(int); */
+extern void rating_remove(int, int);
+extern void rating_add(int, int);
+
+extern int DisplayRank(int, param_list, int);
+extern void UpdateRank(int, char *, statistics *, char *);
+extern int DisplayTargetRank(int, char *, int, int);
+extern int DisplayRankedPlayers(int, int, int, int, int);
+extern int ShowFromString(char *);
+/* extern time_t time(); */
+extern int Best(int, param_list, int);
+
+#endif /* _RATINGS_H */
+
blob - /dev/null
blob + e7a512576272cfed2ab16ea34ae5b50bef3e86da (mode 644)
Binary files /dev/null and FICS.DIST/FICS/ratings.o differ
blob - /dev/null
blob + 9eb0dbca9bec41cc513a69dc31a209555283c01f (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/rmalloc.c
+/* rmalloc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+
+#include "stdinclude.h"
+
+#include "common.h"
+
+PUBLIC unsigned int allocated_size = 0;
+PUBLIC unsigned int malloc_count = 0;
+PUBLIC unsigned int free_count = 0;
+
+PUBLIC void *rmalloc(int byteSize)
+{
+ void *newptr;
+#ifdef HASMALLOCSIZE
+ allocated_size += byteSize;
+#endif
+ malloc_count++;
+ newptr = malloc(byteSize);
+ if (newptr == NULL) {
+ fprintf(stderr, "Out of memory in malloc!\n");
+ abort();
+ }
+ return newptr;
+}
+
+PUBLIC void *rrealloc(void *ptr, int byteSize)
+{
+#ifdef HASMALLOCSIZE
+ allocated_size += (byteSize - malloc_size(ptr));
+#endif
+ if (ptr == NULL) { /* Sparky 3/16/95 */
+ fprintf(stderr, "Hoser! Null ptr passed to rrealloc!!\n");
+ return NULL;
+ } else {
+ void *newptr = realloc(ptr, byteSize);
+ if (newptr == NULL) {
+ fprintf(stderr, "Out of memory in rrealloc!\n");
+ abort();
+ }
+ return newptr;
+ }
+}
+
+PUBLIC void rfree(void *ptr)
+{
+#ifdef HASMALLOCSIZE
+ allocated_size = allocated_size - malloc_size(ptr);
+#endif
+ if (ptr == NULL) { /* Sparky 3/16/95 */
+ fprintf(stderr, "Hoser! Null ptr passed to rfree!!\n");
+ } else {
+ free_count++;
+ free(ptr);
+ }
+}
+
+PUBLIC void strfree (char *string)
+{
+ /* This routine is often called on strings that are either
+ a rmalloc'd value or NULL. So it's not an error to see
+ a NULL here. --mann
+ */
+ if (string != NULL) rfree (string);
+}
blob - /dev/null
blob + cde1d06dfca14392c2a4a4b0207547d71336e63b (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/rmalloc.h
+/* rmalloc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _RMALLOC_H
+#define _RMALLOC_H
+
+extern unsigned int allocated_size;
+extern unsigned int malloc_count;
+extern unsigned int free_count;
+
+extern void *rmalloc(int);
+extern void *rrealloc(void *, int);
+extern void rfree(void *);
+extern void strfree(char *);
+
+#endif /* _RMALLOC_H */
+
blob - /dev/null
blob + 578ac1da6eb76ba1e3841550d9b4407f227813d7 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/rmalloc.o differ
blob - /dev/null
blob + 4f6f91c98e6dc63a554aeab8468c80fa9d10ccab (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/shutdown.c
+/* shutdown.c
+
+ Contains stuff related to shutdowns
+
+ */
+ /* 12/9/95 - added reason to shutdown - DAV */
+
+#include "stdinclude.h"
+#include "common.h"
+#include "shutdown.h"
+#include "command.h"
+#include "ficsmain.h"
+#include "network.h"
+#include "playerdb.h"
+#include "utils.h"
+
+PRIVATE int shutdownTime = 0;
+PRIVATE int lastTimeLeft;
+PRIVATE int shutdownStartTime;
+PRIVATE char downer[1024];
+PRIVATE char reason[1024];
+
+PUBLIC void output_shut_mess()
+{
+ int shuttime = time(0);
+ fprintf(stderr, "FICS: Shutting down at %s\n", strltime(&shuttime));
+}
+
+PUBLIC void ShutDown(void)
+{
+ int p1;
+ int shuttime = time(0);
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Server shutdown ordered by %s. ****\n", downer);
+ if (reason[0] != '\0')
+ pprintf(p1, "\n **** We are going down because: %s. ****\n", reason);
+ }
+ TerminateCleanup();
+ fprintf(stderr, "FICS: Shut down ordered at %s by %s.\n", strltime(&shuttime), downer);
+ output_shut_mess();
+ net_close();
+ exit(0);
+}
+
+PUBLIC void ShutHeartBeat(void)
+{
+ int t = time(0);
+ int p1;
+ int timeLeft;
+ int crossing = 0;
+
+ if (!shutdownTime)
+ return;
+ if (!lastTimeLeft)
+ lastTimeLeft = shutdownTime;
+ timeLeft = shutdownTime - (t - shutdownStartTime);
+ if ((lastTimeLeft > 3600) && (timeLeft <= 3600))
+ crossing = 1;
+ if ((lastTimeLeft > 2400) && (timeLeft <= 2400))
+ crossing = 1;
+ if ((lastTimeLeft > 1200) && (timeLeft <= 1200))
+ crossing = 1;
+ if ((lastTimeLeft > 600) && (timeLeft <= 600))
+ crossing = 1;
+ if ((lastTimeLeft > 300) && (timeLeft <= 300))
+ crossing = 1;
+ if ((lastTimeLeft > 120) && (timeLeft <= 120))
+ crossing = 1;
+ if ((lastTimeLeft > 60) && (timeLeft <= 60))
+ crossing = 1;
+ if ((lastTimeLeft > 10) && (timeLeft <= 10))
+ crossing = 1;
+ if (crossing) {
+ fprintf(stderr,
+ "FICS: **** Server going down in %d minutes and %d seconds. ****\n\n",
+ timeLeft / 60,
+ timeLeft - ((timeLeft / 60) * 60));
+ if (reason[0] != '\0')
+ fprintf(stderr,"FICS: We are going down because: %s.\n",reason);
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1,
+ "\n\n **** Server going down in %d minutes and %d seconds. ****\n",
+ timeLeft / 60,
+ timeLeft - ((timeLeft / 60) * 60));
+ if (reason[0] != '\0')
+ pprintf_prompt(p1,"\n **** We are going down because: %s. ****\n",reason);
+ else
+ pprintf_prompt(p1,"\n");
+ }
+ }
+ lastTimeLeft = timeLeft;
+ if (timeLeft <= 0) {
+ ShutDown();
+ }
+}
+
+PUBLIC int check_and_print_shutdown(int p)
+
+ /* Tells a user if they is to be a shutdown */
+ /* returns 0 if there is not to be one, 1 if there is to be one */
+ /* for whenshut command */
+
+{
+
+
+ int timeLeft;
+ int t = time(0);
+
+ if (!shutdownTime)
+ return 0; /* no shut down */
+
+ timeLeft = shutdownTime - (t - shutdownStartTime);
+
+ pprintf(p,
+ "\n **** Server going down in %d minutes and %d seconds. ****\n",
+ timeLeft / 60,
+ timeLeft - ((timeLeft / 60) * 60));
+ if (reason[0] != '\0')
+ pprintf(p, "\n **** We are going down because: %s. ****\n", reason);
+ return 1;
+}
+
+
+/*
+ * shutdown
+ *
+ * Usage: shutdown [now,cancel,time]
+ *
+ * This command shutsdown the server. If the parameter is omitted or
+ * is 'now' then the server is immediately halted cleanly. If a time is
+ * given then a countdown commences and the server is halted when time is
+ * up. If 'cancel' is given then the countdown is stopped.
+ */
+PUBLIC int com_shutdown(int p, param_list param)
+{
+ char *ptr;
+ int p1, secs;
+
+ ASSERT(parray[p].adminLevel >= ADMIN_ADMIN);
+ strcpy(downer, parray[p].name);
+ shutdownStartTime = time(0);
+ if (shutdownTime) { /* Cancel any pending shutdowns */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Server shutdown canceled by %s. ****\n", downer);
+ }
+ shutdownTime = 0;
+ if (param[0].type == TYPE_NULL)
+ return COM_OK;
+ }
+ /* Work out how soon to shut down */
+ if (param[0].type == TYPE_NULL)
+ shutdownTime = 300;
+ else {
+ if (!strcmp(param[0].val.word, "now"))
+ shutdownTime = 0;
+ else if (!strcmp(param[0].val.word, "die")) {
+ fprintf (stderr,"%s salutes FICS and presses the self-destruct button.\n",
+ parray[p].name);
+ output_shut_mess();
+ abort();
+ } else if (!strcmp(param[0].val.word, "cancel"))
+ return COM_OK;
+ else {
+ ptr = param[0].val.word;
+ shutdownTime = secs = 0;
+ p1 = 2;
+ while (*ptr) {
+ switch (*ptr) {
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ secs = secs * 10 + *ptr - '0';
+ break;
+ case ':':
+ if (p1--) {
+ shutdownTime = shutdownTime * 60 + secs;
+ secs = 0;
+ break;
+ }
+ default:
+ shutdownTime = 0;
+ pprintf(p, "I don't know what you mean by %s\n", param[0].val.word);
+ return COM_OK;
+ }
+ ptr++;
+ }
+ shutdownTime = shutdownTime * 60 + secs;
+ }
+ }
+ if (shutdownTime <= 0)
+ ShutDown();
+ if (param[1].type == TYPE_STRING)
+ strcpy (reason,param[1].val.string);
+ else
+ reason[0] = '\0'; /* No reason - perhaps admin is in a bad mood? :) */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Server shutdown ordered by %s. ****\n", downer);
+ if (reason[0] != '\0')
+ pprintf(p1, " **** We are going down because: %s. ****\n",reason);
+ pprintf(p1,
+ " **** Server going down in %d minutes and %d seconds. ****\n",
+ shutdownTime / 60, shutdownTime % 60);
+ if (p != p1) /* fix double prompt - DAV */
+ pprintf_prompt (p1,"\n");
+ else
+ pprintf (p1,"\n");
+ }
+ lastTimeLeft = 0;
+ return COM_OK;
+}
+
+PUBLIC int server_shutdown(int secs, char *why)
+{
+ int p1;
+
+ if (shutdownTime && (shutdownTime <= secs)) {
+ /* Server is already shutting down, I'll let it go */
+ return 0;
+ }
+ strcpy(downer, "Automatic");
+ shutdownTime = secs;
+ shutdownStartTime = time(0);
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ pprintf(p1, "\n\n **** Automatic Server shutdown. ****\n");
+ pprintf(p1, "%s\n", why);
+ pprintf_prompt(p1,
+ " **** Server going down in %d minutes and %d seconds. ****\n\n",
+ shutdownTime / 60,
+ shutdownTime - ((shutdownTime / 60) * 60));
+ }
+ fprintf(stderr, "FICS: **** Automatic Server shutdown. ****\n");
+ fprintf(stderr, "FICS: %s\n", why);
+ return 0;
+}
+
+PUBLIC int com_whenshut(int p, param_list param)
+
+{
+ int result = check_and_print_shutdown(p);
+ if (result == 0) {
+ pprintf (p,"No shutdown currently in progress\n");
+ }
+ return COM_OK;
+}
blob - /dev/null
blob + 5bbf77bf37b4d43e5658ee9fd10aacc628b08b47 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/shutdown.h
+/* shutdown.h */
+
+#ifndef _SHUTDOWN_H
+#define _SHUTDOWN_H
+
+extern void output_shut_mess();
+extern int com_shutdown();
+extern void ShutHeartBeat();
+extern void ShutDown();
+extern int server_shutdown();
+extern int check_and_print_shutdown(int);
+extern int com_whenshut();
+
+#endif /* _SHUTDOWN_H */
blob - /dev/null
blob + b5a957a35892a64b94618e509672ff2df190e130 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/shutdown.o differ
blob - /dev/null
blob + 62dbd2bd04d339e1010f1dcad3db55ffda7e4cb1 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/stdinclude.h
+/* stdinclude.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _STDINCLUDE_H
+#define _STDINCLUDE_H
+
+#include <sys/types.h>
+
+/* Set up system specific defines */
+#if defined(SYSTEM_NEXT)
+
+#define HASMALLOCSIZE
+#include <sys/vfs.h>
+
+#elif defined(SYSTEM_ULTRIX)
+
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#endif
+
+#ifdef SYSTEM_USL
+# define NO_TM_ZONE
+#endif
+
+#ifdef SYSTEM_SUN4
+# define USE_VARARGS
+#endif
+
+#ifdef SGI
+#define _BSD_SIGNALS
+#include <fcntl.h>
+#include <bstring.h>
+#endif
+
+#if defined(SYSTEM_RS6K)
+#include <sys/select.h>
+#include <dirent.h>
+#define USE_DIRENT
+#endif
+
+#include <string.h>
+
+/* These are included into every .c file */
+#if defined(SYSTEM_SUN5)
+#define USE_RLIMIT
+#define USE_TIMES
+#define USE_WAITPID
+#define GOOD_STDIO
+#define NO_TM_ZONE
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/filio.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#define direct dirent
+
+#else
+#include <strings.h>
+#include <sys/dir.h>
+#endif
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/errno.h>
+#include <signal.h>
+#include <time.h>
+#include <math.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+
+/* Forward declare the functions that aren't defined above */
+
+#if defined(SGI)
+#include <errno.h>
+#define GOOD_STDIO
+#define NO_TM_ZONE
+#else
+#define GOOD_STDIO
+/*
+extern FILE *popen(char *, char *);
+extern int pclose(FILE *);
+extern int fputs(char *, FILE *);
+extern int fseek(FILE *, long, int);
+extern int fread(char *, int, int, FILE *);
+extern int fwrite(char *, int, int, FILE *);
+extern int socket(int, int, int);
+extern int atoi (char *nptr);
+extern long atol (char *nptr);
+extern int truncate(char *, off_t), ftruncate(int, off_t);
+*/
+#endif
+
+#ifndef GOOD_STDIO
+extern int fclose(FILE *);
+extern int fscanf(FILE *, char *, ...);
+extern int fprintf(FILE *, char *, ...);
+extern int printf(char *, ...);
+#endif
+
+
+#ifndef NETBSD
+extern char *crypt (char *key, char *salt);
+#endif
+
+extern time_t time(time_t *);
+extern int rand(void);
+extern int close(int);
+extern size_t malloc_size(void *ptr);
+
+#ifdef __STDC__
+/* extern fcntl(int fildes, int cmd, ...); */
+/* extern open(char *path, int oflag, ...); */
+/* extern int ioctl(int, long, ...); */
+
+#else
+ extern fcntl();
+ extern open();
+ extern int ioctl();
+
+#endif /* __STDC__ */
+/* extern void *malloc(unsigned int size); */
+/* extern void *calloc(unsigned int num, unsigned int size); */
+/* extern void *realloc(void *addr, unsigned int size); */
+/* extern void free(void *data); */
+/* extern void malloc_good_size(unsigned int size); */
+/* extern int link(); */
+/* extern int unlink(); */
+/* extern int rename(); */
+/* extern int getpid(); */
+/* extern int kill(); */
+/* extern int fork(); */
+/* extern int access(); */
+/* extern int getdtablesize(); */
+/* extern int write(); */
+#if !defined(SYSTEM_ULTRIX)
+/* extern int sleep(); */
+/* extern int getuid(); */
+extern int statfs();
+#endif
+
+#endif /* _STDINCLUDE_H */
+
blob - /dev/null
blob + 394b0070b3e6b0fac183443cd309da871d999598 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/stdinclude.h.orig
+/* stdinclude.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+#include <sys/types.h>
+
+/* Set up system specific defines */
+#if defined(SYSTEM_NEXT)
+
+#define HASMALLOCSIZE
+#include <sys/vfs.h>
+
+#elif defined(SYSTEM_ULTRIX)
+
+#include <sys/param.h>
+#include <sys/mount.h>
+
+#endif
+
+#ifdef SYSTEM_USL
+# define NO_TM_ZONE
+#endif
+
+#ifdef SYSTEM_SUN4
+# define USE_VARARGS
+#endif
+
+#ifdef SGI
+#define _BSD_SIGNALS
+#include <fcntl.h>
+#include <bstring.h>
+#endif
+
+#if defined(SYSTEM_RS6K)
+#include <sys/select.h>
+#include <dirent.h>
+#define USE_DIRENT
+#endif
+
+/* These are included into every .c file */
+#if defined(SYSTEM_SUN5)
+#define USE_RLIMIT
+#define USE_TIMES
+#define USE_WAITPID
+#define GOOD_STDIO
+#define NO_TM_ZONE
+#include <string.h>
+#include <dirent.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <sys/filio.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#define direct dirent
+
+#else
+#include <strings.h>
+#include <sys/dir.h>
+#endif
+
+#include <sys/stat.h>
+#include <stdio.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <netdb.h>
+#include <unistd.h>
+#include <ctype.h>
+#include <sys/errno.h>
+#include <signal.h>
+#include <time.h>
+#include <math.h>
+#include <sys/time.h>
+#include <sys/file.h>
+#include <sys/ioctl.h>
+#include <sys/wait.h>
+
+/* Forward declare the functions that aren't defined above */
+
+#if defined(SGI)
+#include <errno.h>
+#define GOOD_STDIO
+#define NO_TM_ZONE
+#else
+#define GOOD_STDIO
+/*
+extern FILE *popen(char *, char *);
+extern int pclose(FILE *);
+extern int fputs(char *, FILE *);
+extern int fseek(FILE *, long, int);
+extern int fread(char *, int, int, FILE *);
+extern int fwrite(char *, int, int, FILE *);
+extern int socket(int, int, int);
+extern int atoi (char *nptr);
+extern long atol (char *nptr);
+extern int truncate(char *, off_t), ftruncate(int, off_t);
+*/
+#endif
+
+#ifndef GOOD_STDIO
+extern int fclose(FILE *);
+extern int fscanf(FILE *, char *, ...);
+extern int fprintf(FILE *, char *, ...);
+extern int printf(char *, ...);
+#endif
+
+extern time_t time(time_t *);
+extern int rand(void);
+extern int close(int);
+extern char *crypt (char *key, char *salt);
+extern size_t malloc_size(void *ptr);
+
+#ifdef __STDC__
+/* extern fcntl(int fildes, int cmd, ...); */
+/* extern open(char *path, int oflag, ...); */
+/* extern int ioctl(int, long, ...); */
+
+#else
+ extern fcntl();
+ extern open();
+ extern int ioctl();
+
+#endif /* __STDC__ */
+/* extern void *malloc(unsigned int size); */
+/* extern void *calloc(unsigned int num, unsigned int size); */
+/* extern void *realloc(void *addr, unsigned int size); */
+/* extern void free(void *data); */
+/* extern void malloc_good_size(unsigned int size); */
+/* extern int link(); */
+/* extern int unlink(); */
+/* extern int rename(); */
+/* extern int getpid(); */
+/* extern int kill(); */
+/* extern int fork(); */
+/* extern int access(); */
+/* extern int getdtablesize(); */
+/* extern int write(); */
+#if !defined(SYSTEM_ULTRIX)
+/* extern int sleep(); */
+/* extern int getuid(); */
+extern int statfs();
+#endif
+
blob - /dev/null
blob + cfd35b6b986f5051771c542fa72f10e380250678 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/talkproc.c
+/* talkproc.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name yy/mm/dd Change
+ hersco and Marsalis 95/07/24 Created
+ Sparky 95/10/05
+ Modifed tell function for the following
+ changes: no longer informs you that someone
+ is censoring in tells to channels, whisper or
+ kibitz. Titles now shown instead of ratings
+ in kibitz and whisper, admins on duty now are
+ shown as (*), and computers marked as (C) as
+ well as with rating.
+
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "talkproc.h"
+#include "comproc.h"
+#include "command.h"
+#include "utils.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "variable.h"
+#include "gamedb.h"
+#include "gameproc.h"
+#include "obsproc.h"
+/* #include "hostinfo.h" */
+#include "multicol.h"
+#include "lists.h"
+#include "formula.h"
+#include <string.h>
+
+#include <sys/resource.h>
+
+/* grimm */
+#if defined(SGI)
+#else
+/* int system(char *arg); */
+#endif
+
+int quota_time;
+
+#if 0
+PUBLIC int com_query(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the query command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_MUZZLE, parray[p].login)) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ if (!parray[p].query_log) {
+ parray[p].query_log = tl_new(5);
+ } else {
+ if (tl_numinlast(parray[p].query_log, 60 * 60) >= 2) {
+ pprintf(p, "Your can only query twice per hour.\n");
+ return COM_OK;
+ }
+ }
+ in_push(IN_SHOUT);
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ if (parray[p1].highlight) {
+ pprintf_prompt(p1, "\n\033[7m%s queries:\033[0m %s\n", parray[p].name,
+ param[0].val.string);
+ } else {
+ pprintf_prompt(p1, "\n%s queries: %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ }
+ pprintf(p, "Query heard by %d player(s).\n", count);
+ tl_logevent(parray[p].query_log, 1);
+ in_pop();
+ return COM_OK;
+}
+#endif
+
+/* hawk: hacked it to fit ALL persons - quota list is not needed anymore */
+int CheckShoutQuota(int p)
+{
+ int timenow = time(0);
+ int timeleft = 0;
+
+ if (((timeleft = timenow - parray[p].lastshout_a) < quota_time) &&
+ (parray[p].adminLevel == 0)) {
+ return (quota_time - timeleft);
+ } else {
+ return 0;
+ }
+}
+
+PUBLIC int com_shout(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+ int timeleft; /* time left for quota if applicable */
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the shout command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_MUZZLE, parray[p].login)) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Next shout available in %d seconds.\n", timeleft);
+ } else {
+ pprintf(p, "Your next shout is ready for use.\n");
+ }
+ return COM_OK;
+ }
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ parray[p].lastshout_a = parray[p].lastshout_b;
+ parray[p].lastshout_b = time(0);
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* in_push(IN_SHOUT); */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_shout)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n%s shouts: %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ pprintf(p, "(%d) %s shouts: %s\n", count, parray[p].name,
+ param[0].val.string);
+/* in_pop(); */
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_cshout(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the cshout command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_CMUZZLE, parray[p].login)) {
+ pprintf(p, "You are c-muzzled.\n");
+ return COM_OK;
+ }
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* in_push(IN_SHOUT); */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_cshout)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ pprintf_prompt(p1, "\n%s c-shouts: %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ pprintf(p, "(%d) %s c-shouts: %s\n", count, parray[p].name,
+ param[0].val.string);
+/* in_pop(); */
+ return COM_OK;
+}
+
+PUBLIC int com_it(int p, param_list param)
+{
+ int p1;
+ int count = 0;
+ int timeleft;
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered players can use the it command.\n");
+ return COM_OK;
+ }
+ if (in_list(p, L_MUZZLE, parray[p].login)) {
+ pprintf(p, "You are muzzled.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Next shout available in %d seconds.\n", timeleft);
+ } else {
+ pprintf(p, "Your next shout is ready for use.\n");
+ }
+ return COM_OK;
+ }
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Shout not sent. Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ parray[p].lastshout_a = parray[p].lastshout_b;
+ parray[p].lastshout_b = time(0);
+
+ if (!printablestring(param[0].val.string)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* in_push(IN_SHOUT); */
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (!parray[p1].i_shout)
+ continue;
+ if (player_censored(p1, p))
+ continue;
+ count++;
+ if ((!strncmp(param[0].val.string, "\'", 1)) ||
+ (!strncmp(param[0].val.string, ",", 1)) ||
+ (!strncmp(param[0].val.string, ".", 1))) {
+ pprintf_prompt(p1, "\n--> %s%s\n", parray[p].name,
+ param[0].val.string);
+ } else {
+ pprintf_prompt(p1, "\n--> %s %s\n", parray[p].name,
+ param[0].val.string);
+ }
+ }
+ if ((!strncmp(param[0].val.string, "\'", 1)) ||
+ (!strncmp(param[0].val.string, ",", 1)) ||
+ (!strncmp(param[0].val.string, ".", 1))) {
+ pprintf(p, "(%d) --> %s%s\n", count, parray[p].name, param[0].val.string);
+ } else {
+ pprintf(p, "(%d) --> %s %s\n", count, parray[p].name, param[0].val.string);
+ }
+/* in_pop(); */
+ if ((timeleft = CheckShoutQuota(p))) {
+ pprintf(p, "Next shout in %d seconds.\n", timeleft);
+ return COM_OK;
+ }
+ return COM_OK;
+}
+
+#define TELL_TELL 0
+#define TELL_SAY 1
+#define TELL_WHISPER 2
+#define TELL_KIBITZ 3
+#define TELL_CHANNEL 4
+PRIVATE int tell(int p, int p1, char *msg, int why, int ch)
+{
+ char tmp[MAX_LINE_SIZE];
+ int rating;
+ int rating1;
+
+ if (!printablestring(msg)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+/* if (p1 == p) {
+ * pprintf(p, "Quit talking to yourself! It's embarrassing.\n");
+ * return COM_OK;
+ * }
+ */
+ if ((!parray[p1].i_tell) && (!parray[p].registered)) {
+ pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
+ parray[p1].name);
+ return COM_OK;
+ }
+ if ((player_censored(p1, p)) && (parray[p].adminLevel == 0)) {
+ if ((why != TELL_KIBITZ) || (why != TELL_WHISPER) || (why != TELL_CHANNEL))
+ {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ }
+ return COM_OK;
+ }
+/* in_push(IN_TELL); */
+ switch (why) {
+ case TELL_SAY:
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ pprintf_prompt(p1, " says: %s\n", msg);
+ break;
+ case TELL_WHISPER:
+ case TELL_KIBITZ:
+ rating = GetRating(&parray[p], TYPE_BLITZ);
+ if (rating < ( rating1 = ( GetRating(&parray[p], TYPE_STAND ) ) ) )
+ rating = rating1;
+ if (in_list(p, L_FM, parray[p].name))
+ pprintf(p1, "\n%s(FM)", parray[p].name);
+ else if (in_list(p, L_IM, parray[p].name))
+ pprintf(p1, "\n%s(IM)", parray[p].name);
+ else if (in_list(p, L_GM, parray[p].name))
+ pprintf(p1, "\n%s(GM)", parray[p].name);
+ else if ((parray[p].adminLevel >= 10) && (parray[p].i_admin))
+ pprintf(p1, "\n%s(*)", parray[p].name);
+ else if ((rating >= parray[p1].kiblevel) ||
+ ((parray[p].adminLevel >= 10) && (parray[p].i_admin)))
+ if (!parray[p].registered)
+ pprintf(p1, "\n%s(++++)", parray[p].name);
+
+ else if (rating != 0)
+ if (in_list(p, L_COMPUTER, parray[p].name))
+ pprintf(p1, "\n%s(%d)(C)", parray[p].name, rating);
+ else
+ pprintf(p1, "\n%s(%d)", parray[p].name, rating);
+ else
+ pprintf(p1, "\n%s(----)", parray[p].name, rating);
+ else break;
+
+ if (why == TELL_WHISPER)
+ pprintf_prompt(p1, " whispers: %s\n", msg);
+ else
+ pprintf_prompt(p1, " kibitzes: %s\n", msg);
+
+ break;
+ case TELL_CHANNEL:
+ pprintf(p1, "\n%s", parray[p].name);
+ pprintf_prompt(p1, "(%d): %s\n", ch, msg);
+ break;
+ case TELL_TELL:
+ default:
+ if (parray[p1].highlight) {
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ } else {
+ pprintf(p1, "\n%s", parray[p].name);
+ }
+ pprintf_prompt(p1, " tells you: %s\n", msg);
+ break;
+ }
+ tmp[0] = '\0';
+ if (!(parray[p1].busy[0] == '\0')) {
+ sprintf(tmp, ", who %s (idle: %s)", parray[p1].busy,
+ hms_desc(player_idle(p1)));
+ } else {
+ if (((player_idle(p1) % 3600) / 60) > 2) {
+ sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
+ }
+ /* else sprintf(tmp," "); */
+ }
+ if ((why == TELL_SAY) || (why == TELL_TELL)) {
+ pprintf(p, "(told %s%s)\n", parray[p1].name,
+ (((parray[p1].game>=0) && (garray[parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ (parray[p1].game >= 0 && (parray[p1].game != parray[p].game))
+ ? ", who is playing" : tmp));
+ parray[p].last_tell = p1;
+ }
+/* in_pop(); */
+ return COM_OK;
+}
+
+PUBLIC int com_ptell(int p, param_list param) /*tells partner - doesn't change last tell */
+
+{
+ char tmp[MAX_LINE_SIZE];
+ int p1;
+
+ if (parray[p].partner < 0) {
+ pprintf (p, "You do not have a partner at present.\n");
+ return COM_OK;
+ }
+
+ p1 = parray[p].partner;
+ if ((p1 < 0) || (parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "Your partner is not logged in.\n");
+ return COM_OK;
+ }
+ if (parray[p1].highlight) {
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ } else {
+ pprintf(p1, "\n%s", parray[p].name);
+ }
+ pprintf_prompt(p1, " (your partner) tells you: %s\n", param[0].val.string);
+ tmp[0] = '\0';
+ if (!(parray[p1].busy[0] == '\0')) {
+ sprintf(tmp, ", who %s (idle: %s)", parray[p1].busy,
+ hms_desc(player_idle(p1)));
+ } else {
+ if (((player_idle(p1) % 3600) / 60) > 2) {
+ sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
+ }
+ }
+ /* else sprintf(tmp," "); */
+ pprintf(p, "(told %s%s)\n", parray[p1].name,
+ (((parray[p1].game>=0) && (garray[parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ (parray[p1].game >= 0 && (parray[p1].game != parray[p].game))
+ ? ", who is playing" : tmp));
+ return COM_OK;
+}
+
+PRIVATE int chtell(int p, int ch, char *msg)
+{
+ int p1, count = 0;
+
+ if ((ch == 0) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Only admins may send tells to channel 0.\n");
+ return COM_OK;
+ }
+
+ if (ch < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+
+ if (ch >= MAX_CHANNELS) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if ((p1 == p) || (parray[p1].status != PLAYER_PROMPT))
+ continue;
+ if ((on_channel(ch, p1)) && (!player_censored(p1, p))) {
+ tell(p, p1, msg, TELL_CHANNEL, ch);
+ count++;
+ }
+ }
+
+ if (count)
+ parray[p].last_channel = ch;
+
+ pprintf(p, "(%d->(%d))\n", ch, count);
+ if (!on_channel(ch, p))
+ pprintf(p, " (You're not listening to channel %d.)\n", ch);
+
+ return COM_OK;
+}
+
+PUBLIC int com_whisper(int p, param_list param)
+{
+ int g;
+ int p1;
+ int count = 0;
+
+ if (!parray[p].num_observe && parray[p].game < 0) {
+ pprintf(p, "You are not playing or observing a game.\n");
+ return COM_OK;
+ }
+ if (!parray[p].registered && (parray[p].game == -1)) {
+ pprintf(p, "You must be registered to whisper other people's games.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >= 0)
+ g = parray[p].game;
+ else
+ g = parray[p].observe_list[0];
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (player_is_observe(p1, g) ||
+ (garray[g].link >= 0 && player_is_observe(p1, garray[g].link))) {
+ tell(p, p1, param[0].val.string, TELL_WHISPER, 0);
+ if ((parray[p].adminLevel >= ADMIN_ADMIN) || !garray[g].private)
+ count++;
+ }
+ }
+ pprintf(p, "whispered to %d.\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_kibitz(int p, param_list param)
+{
+ int g;
+ int p1;
+ int count = 0;
+
+ if (!parray[p].num_observe && parray[p].game < 0) {
+ pprintf(p, "You are not playing or observing a game.\n");
+ return COM_OK;
+ }
+ if (!parray[p].registered && (parray[p].game == -1)) {
+ pprintf(p, "You must be registered to kibitz other people's games.\n");
+ return COM_OK;
+ }
+ if (parray[p].game >= 0)
+ g = parray[p].game;
+ else
+ g = parray[p].observe_list[0];
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (p1 == p)
+ continue;
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if ((player_is_observe(p1, g) || parray[p1].game == g ||
+ (garray[g].link >= 0 &&
+ (player_is_observe(p1, garray[g].link) || parray[p1].game == garray[g].link)
+ )
+ ) && parray[p1].i_kibitz) {
+ tell(p, p1, param[0].val.string, TELL_KIBITZ, 0);
+ if ((parray[p].adminLevel >= ADMIN_ADMIN) || !garray[g].private || (parray[p1].game == g))
+ count++;
+ }
+ }
+ pprintf(p, "kibitzed to %d.\n", count);
+ return COM_OK;
+}
+
+PUBLIC int com_tell(int p, param_list param)
+{
+ int p1;
+
+ if (param[0].type == TYPE_NULL)
+ return COM_BADPARAMETERS;
+ if (param[0].type == TYPE_WORD) {
+ stolower(param[0].val.word);
+ if (!strcmp(param[0].val.word, ".")) {
+ if (parray[p].last_tell < 0) {
+ pprintf(p, "No one to tell anything to.\n");
+ return COM_OK;
+ } else {
+ return tell(p, parray[p].last_tell, param[1].val.string, TELL_TELL, 0);
+ }
+ }
+ if (!strcmp(param[0].val.word, ",")) {
+ if (parray[p].last_channel < 0) {
+ pprintf(p, "No previous channel.\n");
+ return COM_OK;
+ } else {
+ return chtell(p, parray[p].last_channel, param[1].val.string);
+ }
+ }
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ return tell(p, p1, param[1].val.string, TELL_TELL, 0);
+ } else { /* Channel */
+ return chtell(p, param[0].val.integer, param[1].val.string);
+ }
+}
+
+PUBLIC int com_xtell(int p, param_list param)
+{
+ int p1;
+ char *msg;
+ char tmp[2048];
+
+ msg = param[1].val.string;
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (parray[p1].status == PLAYER_PASSWORD)
+ || (parray[p1].status == PLAYER_LOGIN)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (!printablestring(msg)) {
+ pprintf(p, "Your message contains some unprintable character(s).\n");
+ return COM_OK;
+ }
+ if ((!parray[p1].i_tell) && (!parray[p].registered)) {
+ pprintf(p, "Player \"%s\" isn't listening to unregistered tells.\n",
+ parray[p1].name);
+ return COM_OK;
+ }
+ if ((player_censored(p1, p)) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ return COM_OK;
+ }
+ if (parray[p1].highlight) {
+ pprintf_highlight(p1, "\n%s", parray[p].name);
+ } else {
+ pprintf(p1, "\n%s", parray[p].name);
+ }
+ pprintf_prompt(p1, " tells you: %s\n", msg);
+
+ tmp[0] = '\0';
+ if (!(parray[p1].busy[0] == '\0')) {
+ sprintf(tmp, ", who %s (idle: %s)", parray[p1].busy,
+ hms_desc(player_idle(p1)));
+ } else {
+ if (((player_idle(p1) % 3600) / 60) > 2) {
+ sprintf(tmp, ", who has been idle %s", hms_desc(player_idle(p1)));
+ }
+ }
+ pprintf(p, "(told %s%s)\n", parray[p1].name,
+ (((parray[p1].game>=0) && (garray[parray[p1].game].status == GAME_EXAMINE))
+ ? ", who is examining a game" :
+ (parray[p1].game >= 0 && (parray[p1].game != parray[p].game))
+ ? ", who is playing" : tmp));
+ return COM_OK;
+}
+
+PUBLIC int com_say(int p, param_list param)
+{
+ if (parray[p].opponent < 0) {
+ if (parray[p].last_opponent < 0) {
+ pprintf(p, "No one to say anything to, try tell.\n");
+ return COM_OK;
+ } else {
+ return tell(p, parray[p].last_opponent, param[0].val.string, TELL_SAY, 0);
+ }
+ }
+ return tell(p, parray[p].opponent, param[0].val.string, TELL_SAY, 0);
+}
+
+#if 0
+PRIVATE int notorcen(int p, param_list param, int *num, int max,
+ char **list, char *listname)
+{
+ int i, p1, connected;
+
+ if (param[0].type != TYPE_WORD) {
+ if (!*num) {
+ pprintf(p, "Your %s list is empty.\n", listname);
+ return COM_OK;
+ } else
+ pprintf(p, "-- Your %s list contains %d names: --", listname, *num);
+ /* New code to print names in columns */
+ {
+ multicol *m = multicol_start(MAX_NOTIFY + 1);
+ for (i = 0; i < *num; i++)
+ multicol_store_sorted(m, list[i]);
+ multicol_pprint(m, p, 78, 2);
+ multicol_end(m);
+ }
+ return COM_OK;
+ }
+ if (*num >= max) {
+ pprintf(p, "Sorry, your %s list is already full.\n", listname);
+ return COM_OK;
+ }
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ for (i = 0; i < *num; i++) {
+ if (!strcasecmp(list[i], param[0].val.word)) {
+ pprintf(p, "Your %s list already includes %s.\n",
+ listname, parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ }
+ if (p1 == p) {
+ pprintf(p, "You can't %s yourself.\n", listname);
+ return COM_OK;
+ }
+ list[*num] = strdup(parray[p1].name);
+ ++(*num);
+ pprintf(p, "%s is now on your %s list.\n", parray[p1].name, listname);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PRIVATE int unnotorcen(int p, param_list param, int *num, int max,
+ char **list, char *listname)
+{
+ char *pname = NULL;
+ int i, j;
+ int unc = 0;
+
+ if (param[0].type == TYPE_WORD) {
+ pname = param[0].val.word;
+ }
+ for (i = 0; i < *num; i++) {
+ if (!pname || !strcasecmp(pname, list[i])) {
+ pprintf(p, "%s is removed from your %s list.\n",
+ list[i], listname);
+ rfree(list[i]);
+ list[i] = NULL;
+ unc++;
+ }
+ }
+ if (unc) {
+ i = 0;
+ j = 0;
+ while (j < *num) {
+ if (list[j] != NULL) {
+ list[i++] = list[j];
+ }
+ j++;
+ }
+ while (i < j) {
+ list[i++] = NULL;
+ }
+ (*num) -= unc;
+ } else {
+ pprintf(p, "No one was removed from your %s list.\n", listname);
+ }
+ return COM_OK;
+}
+
+
+PUBLIC int com_notify(int p, param_list param)
+{
+ return notorcen(p, param, &parray[p].num_notify, MAX_NOTIFY,
+ parray[p].notifyList, "notify");
+}
+
+PUBLIC int com_censor(int p, param_list param)
+{
+ return notorcen(p, param, &parray[p].num_censor, MAX_CENSOR,
+ parray[p].censorList, "censor");
+}
+
+PUBLIC int com_unnotify(int p, param_list param)
+{
+ return unnotorcen(p, param, &parray[p].num_notify, MAX_NOTIFY,
+ parray[p].notifyList, "notify");
+}
+
+PUBLIC int com_uncensor(int p, param_list param)
+{
+ return unnotorcen(p, param, &parray[p].num_censor, MAX_CENSOR,
+ parray[p].censorList, "censor");
+}
+
+#endif
+
+#if 0 /* now in lists.c */
+PUBLIC int com_channel(int p, param_list param)
+{
+ int i, err;
+
+ if (param[0].type == TYPE_NULL) { /* Turn off all channels */
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (!channel_remove(i, p))
+ pprintf(p, "Channel %d turned off.\n", i);
+ }
+ } else {
+ i = param[0].val.integer;
+ if ((i == 0) && (!on_channel(i, p)) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Only admins may join channel 0.\n");
+ return COM_OK;
+ }
+ if (i < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ if (i >= MAX_CHANNELS) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ if (on_channel(i, p)) {
+ if (!channel_remove(i, p))
+ pprintf(p, "Channel %d turned off.\n", i);
+ } else {
+ if (!(err = channel_add(i, p)))
+ pprintf(p, "Channel %d turned on.\n", i);
+ else {
+ if (err == 1)
+ pprintf(p, "Channel %d is already full.\n", i);
+ if (err == 3)
+ pprintf(p, "Maximum channel number exceeded.\n");
+ }
+ }
+ }
+ return COM_OK;
+}
+#endif
+
+PUBLIC int com_inchannel(int p, param_list param)
+{
+ int p1,count = 0;
+ char tmp[18];
+
+
+ if (param[0].type == NULL) {
+ pprintf (p,"inchannel [no params] has been removed\n");
+ pprintf (p,"Please use inchannel [name] or inchannel [number]\n");
+ return COM_OK;
+ }
+
+ if (param[0].type == TYPE_WORD) {
+ p1 = player_find_part_login(param[0].val.word);
+ if ((p1 < 0) || (parray[p1].status != PLAYER_PROMPT)) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf (p,"%s is in the following channels:",parray[p1].name); /* no \n */
+ if (list_channels (p,p1))
+ pprintf (p," No channels found.\n",parray[p1].name);
+ return COM_OK;
+ } else {
+ sprintf (tmp,"%d",param[0].val.integer);
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (parray[p1].status != PLAYER_PROMPT)
+ continue;
+ if (in_list(p1,L_CHANNEL,tmp)) {
+ if (!count)
+ pprintf(p,"Channel %d:",param[0].val.integer);
+ pprintf (p," %s%s",parray[p1].name,(((parray[p1].adminLevel >= 10) && (parray[p1].i_admin) && (param[0].val.integer < 2)) ? "(*)" : ""));
+ count++;
+ }
+ }
+ if (!count)
+ pprintf(p,"Channel %d is empty.\n",param[0].val.integer);
+ else
+ pprintf (p,"\n%d %s in channel %d.\n",count,(count == 1 ? "person is" : "people are"),param[0].val.integer);
+ return COM_OK;
+ }
+}
+
+#if 0 /* if anyone can do inchannel NULL without n^3 computation
+ please do so*/
+PUBLIC int com_inchannel(int p, param_list param)
+{
+ int c1, c2;
+ int i, j, count = 0;
+
+ if (param[0].type == TYPE_NULL) { /* List everyone on every channel */
+ c1 = -1;
+ c2 = -1;
+ } else if (param[1].type == TYPE_NULL) { /* One parameter */
+ c1 = param[0].val.integer;
+ if (c1 < 0) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ c2 = -1;
+ } else { /* Two parameters */
+ c1 = param[0].val.integer;
+ c2 = param[1].val.integer;
+ if ((c1 < 0) || (c2 < 0)) {
+ pprintf(p, "The lowest channel number is 0.\n");
+ return COM_OK;
+ }
+ pprintf(p, "Two parameter inchannel is not implemented.\n");
+ return COM_OK;
+ }
+ if ((c1 >= MAX_CHANNELS) || (c2 >= MAX_CHANNELS)) {
+ pprintf(p, "The maximum channel number is %d.\n", MAX_CHANNELS - 1);
+ return COM_OK;
+ }
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (numOn[i] && ((c1 < 0) || (i == c1))) {
+ /* First get rid of ghosts. */
+ for (j=0; j < numOn[i]; j++) {
+ if (parray[channels[i][j]].status == PLAYER_PROMPT)
+ continue;
+ channels[i][j] = channels[i][--numOn[i]];
+ j--;
+ }
+ pprintf(p, "Channel %d:", i);
+ for (j = 0; j < numOn[i]; j++) {
+ pprintf(p, " %s", parray[channels[i][j]].name);
+ if ((i==0 || i==1) && parray[channels[i][j]].adminLevel >= 10
+ && parray[channels[i][j]].i_admin)
+ pprintf(p, "(*)");
+ }
+ count++;
+ pprintf(p, "\n");
+ }
+ }
+ if (!count) {
+ if (c1 < 0)
+ pprintf(p, "No channels in use.\n");
+ else
+ pprintf(p, "Channel not in use.\n");
+ }
+ return COM_OK;
+}
+#endif
+
+PUBLIC int com_sendmessage(int p, param_list param)
+{
+ int p1, connected = 1;
+
+ if (!parray[p].registered) {
+ pprintf(p, "You are not registered and cannot send messages.\n");
+ return COM_OK;
+ }
+ if ((param[0].type == TYPE_NULL) || (param[1].type == TYPE_NULL)) {
+ pprintf(p, "No message sent.\n");
+ return COM_OK;
+ }
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+
+ if (!parray[p1].registered) {
+ pprintf(p, "Player \"%s\" is unregistered and cannot receive messages.\n",
+ parray[p1].name);
+ return COM_OK; /* no need to removed */
+ }
+
+ if ((player_censored(p1, p)) && (parray[p].adminLevel == 0)) {
+ pprintf(p, "Player \"%s\" is censoring you.\n", parray[p1].name);
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+ }
+ if (player_add_message(p1, p, param[1].val.string)) {
+ pprintf(p, "Couldn't send message to %s. Message buffer full.\n",
+ parray[p1].name);
+ } else {
+ if (connected) {
+ pprintf(p1, "\n%s just sent you a message:\n", parray[p].name);
+ pprintf_prompt(p1, " %s\n", param[1].val.string);
+ }
+ }
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
+
+PUBLIC int com_messages(int p, param_list param)
+{
+ int start;
+ /* int end = -1; */
+
+ if (!parray[p].registered) {
+ pprintf (p, "Unregistered players may not send or receive messages.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ player_show_messages (p);
+ } else if (param[0].type == TYPE_WORD) {
+ if (param[1].type != TYPE_NULL)
+ return com_sendmessage(p, param);
+ else ShowMsgsBySender(p, param);
+ } else {
+ start = param[0].val.integer;
+ ShowMsgRange (p, start, start);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_clearmessages(int p, param_list param)
+{
+ int start;
+
+ if (player_num_messages(p) <= 0) {
+ pprintf(p, "You have no messages.\n");
+ return COM_OK;
+ }
+ if (param[0].type == TYPE_NULL) {
+ pprintf(p, "Messages cleared.\n");
+ player_clear_messages(p);
+ } else if (param[0].type == TYPE_WORD) {
+ ClearMsgsBySender(p, param);
+ } else if (param[0].type == TYPE_INT) {
+ start = param[0].val.integer;
+ ClrMsgRange (p, start, start);
+ }
+ return COM_OK;
+}
+
+PUBLIC int com_mailmess(int p, param_list param)
+{
+ char *buffer[1000];
+ char mdir[MAX_FILENAME_SIZE];
+ char filename[MAX_FILENAME_SIZE];
+ char subj[81], fname[MAX_FILENAME_SIZE];
+
+
+ if (!parray[p].registered) {
+ pprintf(p, "Only registered people can use the mailmess command.\n");
+ return COM_OK;
+ }
+ sprintf(filename, "%s.messages", parray[p].login);
+ sprintf(mdir, "%s/player_data/%c/", stats_dir, parray[p].login[0]);
+
+ if (search_directory(mdir, filename, buffer, 1000)) {
+ sprintf(subj, "Your FICS messages from server %s", fics_hostname);
+ sprintf(fname, "%s/%s", mdir, filename);
+ mail_file_to_user (p, subj, fname);
+ pprintf(p, "Messages sent to %s\n", parray[p].emailAddress);
+ } else {
+ pprintf(p, "You have no messages.\n");
+ }
+ return COM_OK;
+
+}
+
+PUBLIC int com_znotify(int p, param_list param)
+{
+ int p1, count = 0;
+
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (player_notified(p, p1)) {
+ if (!count)
+ pprintf(p, "Present company on your notify list:\n ");
+ pprintf(p, " %s", parray[p1].name);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ else
+ pprintf(p, "No one from your notify list is logged on.\n");
+
+ count = 0;
+ for (p1 = 0; p1 < p_num; p1++) {
+ if (player_notified(p1, p) && parray[p1].status == PLAYER_PROMPT) {
+ if (!count)
+ pprintf(p,
+ "The following players have you on their notify list:\n ");
+ pprintf(p, " %s", parray[p1].name);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, ".\n");
+ else
+ pprintf(p, "No one logged in has you on their notify list.\n");
+ return COM_OK;
+}
+
+PUBLIC int com_qtell(int p, param_list param)
+{
+ int p1;
+ char tmp[MAX_STRING_LENGTH];
+ char dummy[2];
+ char buffer1[MAX_STRING_LENGTH]; /* no highlight and no bell */
+ char buffer2[MAX_STRING_LENGTH]; /* no highlight and bell */
+ char buffer3[MAX_STRING_LENGTH]; /* highlight and no bell */
+ char buffer4[MAX_STRING_LENGTH]; /* highlight and and bell */
+ int i,count;
+/* FILE *fp; */
+
+ if (!in_list(p, L_TD, parray[p].name)) {
+ pprintf(p, "Only TD programs are allowed to use this command.\n");
+ return COM_OK;
+ }
+ strcpy(buffer1, ":\0");
+ strcpy(buffer2, ":\0");
+ strcpy(buffer3, ":\0");
+ strcpy(buffer4, ":\0");
+
+ sprintf(tmp, "%s", param[1].val.string);
+ for (i = 0, count = 0; ((tmp[i] != '\0') && (count < 1029));) {
+ if ((tmp[i] == '\\') && (tmp[i + 1] == 'n')) {
+ strcat(buffer1, "\n:");
+ strcat(buffer2, "\n:");
+ strcat(buffer3, "\n:");
+ strcat(buffer4, "\n:");
+ count += 2;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'b')) {
+ strcat(buffer2, "\007");
+ strcat(buffer4, "\007");
+ count++;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'H')) {
+ strcat(buffer3, "\033[7m");
+ strcat(buffer4, "\033[7m");
+ count += 4;
+ i += 2;
+ } else if ((tmp[i] == '\\') && (tmp[i + 1] == 'h')) {
+ strcat(buffer3, "\033[0m");
+ strcat(buffer4, "\033[0m");
+ count += 4;
+ i += 2;
+ } else {
+ dummy[0] = tmp[i];
+ dummy[1] = '\0';
+ strcat(buffer1, dummy);
+ strcat(buffer2, dummy);
+ strcat(buffer3, dummy);
+ strcat(buffer4, dummy);
+ count++;
+ i++;
+ }
+ }
+
+ if (param[0].type == TYPE_WORD) {
+/*
+ fp = fopen("/tmp/fics-log", "a");
+ fprintf(fp, "PLAYER \"%s\" - MESSAGE \"%s\"\n", param[0].val.word, param[1].val.string);
+ fclose(fp);
+*/
+ if ((p1 = player_find_bylogin(param[0].val.word)) < 0) {
+ pprintf(p, "*qtell %s 1*\n", param[0].val.word);
+ return COM_OK;
+ }
+ pprintf_prompt(p1, "\n%s\n", (parray[p1].highlight && parray[p1].bell) ? buffer4 :
+ (parray[p1].highlight && !parray[p1].bell) ? buffer3 :
+ (!parray[p1].highlight && parray[p1].bell) ? buffer2 :
+ buffer1);
+ pprintf(p, "*qtell %s 0*\n", parray[p1].name);
+
+ } else {
+ int p1;
+ int ch = param[0].val.integer;
+
+ if (ch == 0) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ if (ch < 0) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ if (ch >= MAX_CHANNELS) {
+ pprintf(p, "*qtell %d 1*\n", param[0].val.integer);
+ return COM_OK;
+ }
+ sprintf (tmp,"%d",param[0].val.integer);
+ for (p1 = 0; p1 < p_num ; p1++) {
+ if ((p1 == p) || (player_censored(p1, p)) || (parray[p1].status != PLAYER_PROMPT))
+ continue;
+ if (in_list(p1,L_CHANNEL,tmp))
+ pprintf_prompt(p1, "\n%s\n", (parray[p1].highlight && parray[p1].bell) ? buffer4 :
+ (parray[p1].highlight && !parray[p1].bell) ? buffer3 :
+ (!parray[p1].highlight && parray[p1].bell) ? buffer2 :
+ buffer1);
+ }
+ pprintf(p, "*qtell %d 0*\n", param[0].val.integer);
+ }
+ return COM_OK;
+}
+
+PUBLIC int on_channel(int ch, int p)
+{
+ char tmp[10]; /* 9 digits ought to be enough :) */
+
+ sprintf (tmp,"%d",ch);
+ return in_list(p, L_CHANNEL,tmp ); /* since needs ch converted to a string keep
+ hidden from view */
+}
+
+#if 0
+
+void WhichList(int p, char *partial, char **Full)
+{
+ int i, gotit = -1;
+ int slen = strlen(partial);
+ static char *MyList[] = {"notify", "censor", "channel", ""};
+
+ for (i=0; MyList[i][0] != '\0'; i++) {
+ if (strncmp(partial, MyList[i], slen))
+ continue;
+ if (gotit >= 0) {
+ pprintf(p, "Ambiguous list name.\n");
+ *Full = NULL;
+ return;
+ }
+ gotit = i;
+ }
+ if (gotit >= 0)
+ *Full = MyList[gotit];
+ else **Full = '\0';
+ return;
+}
+
+PUBLIC int com_plus(int p, param_list param)
+{
+ char *list;
+ int chan;
+ parameter *Param1 = ¶m[1];
+
+ WhichList (p, param[0].val.word, &list);
+
+ if (list == NULL) return COM_OK;
+
+ if (!strcmp(list, "notify"))
+ return notorcen (p, Param1, &parray[p].num_notify, MAX_NOTIFY,
+ parray[p].notifyList, "notify");
+ if (!strcmp(list, "censor"))
+ return notorcen (p, Param1, &parray[p].num_censor, MAX_NOTIFY,
+ parray[p].censorList, "censor");
+ if (!strcmp(list, "channel")) {
+ chan = atoi(param[1].val.word);
+ if (chan < 0) {
+ }
+
+ switch (channel_add(chan, p)) {
+ case 0: pprintf(p, "Channel %d turned on.\n", chan); break;
+ case 1: pprintf(p, "Channel %d is already full.\n", chan); break;
+ case 2: pprintf(p, "You are already on channel %d.\n", chan); break;
+ case 3: pprintf(p, "Maximum number of channels exceeded.\n"); break;
+ }
+ return COM_OK;
+ }
+ return com_addlist(p, param);
+}
+
+PUBLIC int com_minus(int p, param_list param)
+{
+ char *list;
+ int chan;
+ parameter *Param1 = ¶m[1];
+
+ WhichList (p, param[0].val.word, &list);
+
+ if (list == NULL) return COM_OK;
+
+ if (!strcmp(list, "notify"))
+ return unnotorcen (p, Param1, &parray[p].num_notify, MAX_NOTIFY,
+ parray[p].notifyList, "notify");
+ if (!strcmp(list, "censor"))
+ return unnotorcen (p, Param1, &parray[p].num_censor, MAX_CENSOR,
+ parray[p].censorList, "censor");
+ if (!strcmp(list, "channel")) {
+ chan = atoi(param[1].val.word);
+ if (on_channel(chan, p))
+ channel_remove(chan, p);
+ else
+ pprintf(p, "You are not on channel %d", chan);
+ return COM_OK;
+ }
+ return com_sublist(p, param);
+}
+#endif
blob - /dev/null
blob + c2c9ee86bad16c2c2971d066987033acc145dd0a (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/talkproc.h
+/* talkproc.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name yy/mm/dd Change
+ hersco and Marsalis 95/07/24 Created
+*/
+
+#ifndef _TALKPROC_H
+#define _TALKPROC_H
+
+#define MAX_CHANNELS 256
+
+extern int quota_time;
+
+extern int com_xtell();
+extern int com_shout();
+extern int com_cshout();
+/* extern int com_query(); */
+extern int com_it();
+extern int com_tell();
+extern int com_ptell();
+extern int com_say();
+extern int com_whisper();
+extern int com_kibitz();
+extern int com_censor();
+extern int com_uncensor();
+extern int com_notify();
+extern int com_unnotify();
+extern int com_channel();
+extern int com_inchannel();
+extern int com_sendmessage();
+extern int com_messages();
+extern int com_clearmessages();
+extern int com_mailmess();
+extern int com_znotify();
+extern int com_qtell();
+extern int on_channel(int, int);
+
+#endif /* _TALKPROC_H */
blob - /dev/null
blob + 2350becd01bea979e10b9069182acbf71d62ae7a (mode 644)
Binary files /dev/null and FICS.DIST/FICS/talkproc.o differ
blob - /dev/null
blob + 16ff015cb3f9c65a10c53ba79ca0f43ec415d4d1 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/utils.c
+/* utils.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "config.h"
+#if defined(SYSTEM_SUN4)
+/* #include <sys/vfs.h> */
+#endif
+
+/*
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+*/
+
+#include <string.h>
+
+#if defined(SGI)
+#else
+int gettimeofday(struct timeval * tp, struct timezone * tzp);
+#endif
+
+PUBLIC int count_lines(FILE *fp)
+{
+ int c, nl = 0;
+
+ while ((c = fgetc(fp)) != EOF)
+ if (c == '\n')
+ ++nl;
+
+ return nl;
+}
+
+PUBLIC int iswhitespace(int c)
+{
+ if ((c < ' ') || (c == '\b') || (c == '\n') ||
+ (c == '\t') || (c == ' ')) { /* white */
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+PUBLIC char *getword(char *str)
+{
+ int i;
+ static char word[MAX_WORD_SIZE];
+
+ i = 0;
+ while (*str && !iswhitespace(*str)) {
+ word[i] = *str;
+ str++;
+ i++;
+ if (i == MAX_WORD_SIZE) {
+ i = i - 1;
+ break;
+ }
+ }
+ word[i] = '\0';
+ return word;
+}
+
+PUBLIC char *eatword(char *str)
+{
+ while (*str && !iswhitespace(*str))
+ str++;
+ return str;
+}
+
+PUBLIC char *eatwhite(char *str)
+{
+ while (*str && iswhitespace(*str))
+ str++;
+ return str;
+}
+
+PUBLIC char *eattailwhite(char *str)
+{
+ int len;
+ if (str == NULL)
+ return NULL;
+
+ len = strlen(str);
+ while (len > 0 && iswhitespace(str[len - 1]))
+ len--;
+ str[len] = '\0';
+ return (str);
+}
+
+PUBLIC char *nextword(char *str)
+{
+ return eatwhite(eatword(str));
+}
+
+/* check_the_email_address function: */
+/*
+PUBLIC int check_emailaddr(char *email)
+{
+ int qbuflen;
+ char qabuf[5120];
+
+ if ((email = strchr(email, '@')) == NULL)
+ return 2;
+ email++;
+
+ res_init();
+ _res.options = (RES_INIT | RES_RECURSE);
+ if ((qbuflen = res_mkquery(QUERY, email, C_IN, T_ANY, NULL, 0, NULL, qabuf, sizeof(qabuf))) == -1)
+ return 1;
+
+ if (res_send(qabuf, qbuflen, qabuf, sizeof(qabuf)) == -1)
+ return 1;
+
+ return (_getshort(qabuf + 6) ? 0 : 2);
+}
+*/
+
+PUBLIC int mail_string_to_address(char *addr, char *subj, char *str)
+{
+ char com[1000];
+ FILE *fp;
+
+#ifdef SENDMAILPROG
+ sprintf(com, "%s\n", SENDMAILPROG);
+#else
+ sprintf(com, "%s -s \"%s\" %s", MAILPROGRAM, subj, addr);
+#endif
+ fp = popen(com, "w");
+ if (!fp)
+ return -1;
+#ifdef SENDMAILPROG
+ fprintf(fp, "To: %s\nSubject: %s\n%s", addr, subj, str);
+#else
+ fprintf(fp, "%s", str);
+#endif
+ pclose(fp);
+ return 0;
+}
+
+PUBLIC int mail_string_to_user(int p, char *subj, char *str)
+{
+
+ if (parray[p].emailAddress &&
+ parray[p].emailAddress[0] &&
+ safestring(parray[p].emailAddress)) {
+ return mail_string_to_address(parray[p].emailAddress, subj, str);
+ } else {
+ return -1;
+ }
+}
+
+PUBLIC int mail_file_to_address(char *addr, char *subj, char *fname)
+{
+ char com[1000];
+ char tmp[MAX_LINE_SIZE];
+ FILE *fp;
+ FILE *file_fp;
+
+#ifdef SENDMAILPROG
+ sprintf(com, "%s\n", SENDMAILPROG);
+#else
+ sprintf(com, "%s -s \"%s\" %s < %s&", MAILPROGRAM, subj, addr, fname);
+#endif
+ fp = popen(com, "w");
+ if (!fp)
+ return -1;
+#ifdef SENDMAILPROG
+ fprintf(fp, "To: %s\nSubject: %s\n", addr, subj);
+ file_fp = fopen(fname, "r");
+ if (!file_fp)
+ return -1;
+ while (!feof(file_fp)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, file_fp);
+ if (!feof(file_fp)) {
+ fputs(tmp, fp);
+ }
+ }
+ fclose(file_fp);
+
+#endif
+ pclose(fp);
+ return 0;
+}
+
+PUBLIC int mail_file_to_user(int p, char *subj, char *fname)
+{
+
+ if (parray[p].emailAddress &&
+ parray[p].emailAddress[0] &&
+ safestring(parray[p].emailAddress)) {
+ return mail_file_to_address(parray[p].emailAddress, subj, fname);
+ } else {
+ return -1;
+ }
+}
+
+
+/* Process a command for a user */
+PUBLIC int pcommand(int p, char *comstr,...)
+{
+ char tmp[MAX_LINE_SIZE];
+ int retval;
+ int current_socket = parray[p].socket;
+ va_list ap;
+ va_start(ap, comstr);
+
+ vsprintf(tmp, comstr, ap);
+ retval = process_input(current_socket, tmp);
+ if (retval == COM_LOGOUT) {
+ process_disconnection(current_socket);
+ net_close_connection(current_socket);
+ }
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC int pprintf(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE]; /* Make sure you can handle 10 lines worth of
+ stuff */
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 1);
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC void pprintf_dohightlight(int p)
+{
+ if (parray[p].highlight & 0x01)
+ pprintf(p, "\033[7m");
+ if (parray[p].highlight & 0x02)
+ pprintf(p, "\033[1m");
+ if (parray[p].highlight & 0x04)
+ pprintf(p, "\033[4m");
+ if (parray[p].highlight & 0x08)
+ pprintf(p, "\033[2m");
+}
+
+PUBLIC int pprintf_highlight(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE];
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+ pprintf_dohightlight(p);
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 1);
+ va_end(ap);
+ if (parray[p].highlight)
+ pprintf(p, "\033[0m");
+ return retval;
+}
+
+PUBLIC void sprintf_dohightlight(int p, char *s)
+{
+
+ if (parray[p].highlight & 0x01)
+ strcat(s, "\033[7m");
+ if (parray[p].highlight & 0x02)
+ strcat(s, "\033[1m");
+ if (parray[p].highlight & 0x04)
+ strcat(s, "\033[4m");
+ if (parray[p].highlight & 0x08)
+ strcat(s, "\033[2m");
+}
+
+PUBLIC int psprintf_highlight(int p, char *s, char *format,...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+ if (parray[p].highlight) {
+ sprintf_dohightlight(p, s);
+ retval = vsprintf(s + strlen(s), format, ap);
+ strcat(s, "\033[0m");
+ } else {
+ retval = vsprintf(s, format, ap);
+ }
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC int pprintf_prompt(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE]; /* Make sure you can handle 10 lines worth of
+ stuff */
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf_prompt buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 1);
+ net_send_string(parray[p].socket, parray[p].prompt, 1);
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC int pprintf_noformat(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE]; /* Make sure you can handle 10 lines worth of
+ stuff */
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf_noformat buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 0);
+ va_end(ap);
+ return retval;
+}
+
+
+/******************* grimm *************/
+/******************* added below *************/
+PUBLIC int psend_raw_file(int p, char *dir, char *file)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ char fname[MAX_FILENAME_SIZE];
+ int num;
+
+ if (dir)
+ sprintf(fname, "%s/%s", dir, file);
+ else
+ strcpy(fname, file);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -1;
+ while ((num = fread(tmp, sizeof(char), MAX_LINE_SIZE - 1, fp)) > 0) {
+ tmp[num] = '\0';
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int psend_file(int p, char *dir, char *file)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ char fname[MAX_FILENAME_SIZE];
+ int lcount = parray[p].d_height - 1;
+
+ if (parray[p].last_file)
+ rfree(parray[p].last_file);
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+
+ if (dir)
+ sprintf(fname, "%s/%s", dir, file);
+ else
+ strcpy(fname, file);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -1;
+ while (!feof(fp) && (--lcount > 0)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp)) {
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+ if (!feof(fp)) {
+ parray[p].last_file = strdup(fname);
+ parray[p].last_file_byte = ftell(fp);
+ pprintf(p, "Type [next] to see next page.\n");
+ }
+ fclose(fp);
+ return 0;
+}
+
+/*
+ * Marsalis added on 8/27/95 so that [next] does not
+ * appear in the logout process for those that have
+ * a short screen height. (Fixed due to complaint
+ * in Bug's messages).
+ */
+PUBLIC int psend_logoutfile(int p, char *dir, char *file)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ char fname[MAX_FILENAME_SIZE];
+
+ if (parray[p].last_file)
+ rfree(parray[p].last_file);
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+
+ if (dir)
+ sprintf(fname, "%s/%s", dir, file);
+ else
+ strcpy(fname, file);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -1;
+ while (!feof(fp)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp)) {
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int pmore_file(int p)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ int lcount = parray[p].d_height - 1;
+
+ if (!parray[p].last_file) {
+ pprintf(p, "There is no more.\n");
+ return -1;
+ }
+ fp = fopen(parray[p].last_file, "r");
+ if (!fp) {
+ pprintf(p, "File not found!\n");
+ return -1;
+ }
+ fseek(fp, parray[p].last_file_byte, SEEK_SET);
+
+ while (!feof(fp) && (--lcount > 0)) {
+ fgets(tmp, MAX_LINE_SIZE, fp);
+ if (!feof(fp)) {
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+ if (!feof(fp)) {
+ parray[p].last_file_byte = ftell(fp);
+ pprintf(p, "Type [next] to see next page.\n");
+ } else {
+ rfree(parray[p].last_file);
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+ }
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int psend_command(int p, char *command, char *input)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ int num;
+
+ if (input)
+ fp = popen(command, "w");
+ else
+ fp = popen(command, "r");
+ if (!fp)
+ return -1;
+ if (input) {
+ fwrite(input, sizeof(char), strlen(input), fp);
+ } else {
+ while (!feof(fp)) {
+ num = fread(tmp, sizeof(char), MAX_LINE_SIZE - 1, fp);
+ tmp[num] = '\0';
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+ pclose(fp);
+ return 0;
+}
+
+PUBLIC char *stolower(char *str)
+{
+ int i;
+
+ if (!str)
+ return NULL;
+ for (i = 0; str[i]; i++) {
+ if (isupper(str[i])) {
+ str[i] = tolower(str[i]);
+ }
+ }
+ return str;
+}
+
+PUBLIC int safechar(int c)
+{
+ if ((c == '>') || (c == '!') || (c == '&') || (c == '*') || (c == '?') ||
+ (c == '/') || (c == '<') || (c == '|') || (c == '`') || (c == '$'))
+ return 0;
+ return 1;
+}
+
+PUBLIC int safestring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if (!safechar(str[i]))
+ return 0;
+ }
+ return 1;
+}
+
+PUBLIC int alphastring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if (!isalpha(str[i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+PUBLIC int printablestring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if ((!isprint(str[i])) && (str[i] != '\t') && (str[i] != '\n'))
+ return 0;
+ }
+ return 1;
+}
+
+
+/*#if defined(SGI)
+#else*/
+/* This version of strdup must be used, or the count of allocs
+ in "uptime" will omit them. Maybe we change the name to
+ rstrdup and replace all calls, if the name is causing a conflict
+ with anyone's libraries. --mann
+*/
+PUBLIC char *strdup(const char *str)
+{
+ char *tmp;
+
+ if (!str)
+ return NULL;
+ tmp = rmalloc(strlen(str) + 1);
+ strcpy(tmp, str);
+ return tmp;
+}
+/*#endif*/
+
+PUBLIC char *hms_desc(int t)
+{
+static char tstr[80];
+int days, hours, mins, secs;
+
+ days = (t / (60*60*24));
+ hours = ((t % (60*60*24)) / (60*60));
+ mins = (((t % (60*60*24)) % (60*60)) / 60);
+ secs = (((t % (60*60*24)) % (60*60)) % 60);
+ if ((days==0) && (hours==0) && (mins==0)) {
+ sprintf(tstr, "%d sec%s",
+ secs, (secs==1) ? "" : "s");
+ } else if ((days==0) && (hours==0)) {
+/* sprintf(tstr, "%d min%s, %d sec%s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s"); */
+ sprintf(tstr, "%d min%s",
+ mins, (mins==1) ? "" : "s");
+ } else if (days==0) {
+ sprintf(tstr, "%d hr%s, %d min%s, %d "
+ "sec%s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ } else {
+ sprintf(tstr, "%d day%s, %d hour%s, %d minute%s "
+ "and %d second%s",
+ days, (days==1) ? "" : "s",
+ hours, (hours==1) ? "" : "s",
+ mins, (mins==1) ? "" : "s",
+ secs, (secs==1) ? "" : "s");
+ }
+ return tstr;
+}
+
+PUBLIC char *hms(int t, int showhour, int showseconds, int spaces)
+{
+ static char tstr[20];
+ char tmp[10];
+ int h, m, s;
+
+ h = t / 3600;
+ t = t % 3600;
+ m = t / 60;
+ s = t % 60;
+ if (h || showhour) {
+ if (spaces)
+ sprintf(tstr, "%d : %02d", h, m);
+ else
+ sprintf(tstr, "%d:%02d", h, m);
+ } else {
+ sprintf(tstr, "%d", m);
+ }
+ if (showseconds) {
+ if (spaces)
+ sprintf(tmp, " : %02d", s);
+ else
+ sprintf(tmp, ":%02d", s);
+ strcat(tstr, tmp);
+ }
+ return tstr;
+}
+
+PRIVATE char *strtime(struct tm * stm)
+{
+ static char tstr[100];
+
+#if defined (SGI)
+ strftime(tstr, sizeof(tstr), "%a %b %e, %H:%M %Z", stm);
+#else
+ strftime(tstr, sizeof(tstr), "%a %b %e, %k:%M %Z", stm);
+#endif
+ return (tstr);
+}
+
+PUBLIC char *fix_time(char *old_time) {
+
+ char day[5];
+ char month[5];
+ char date[5];
+ char new_time[20];
+ char i;
+
+ sscanf(old_time, "%s %s %s", day, month, date);
+
+ if (date[2] != ',') {
+ i = date[0];
+ date[0] = '0';
+ date[1] = i;
+ }
+ date[2] = '\0';
+
+ sprintf (new_time, "%s, %s %s", day, month, date);
+
+ return new_time;
+}
+
+PUBLIC char *strltime(time_t *clock)
+{
+ struct tm *stm = localtime(clock);
+ return strtime(stm);
+}
+
+PUBLIC char *strgtime(time_t *clock)
+{
+ struct tm *stm = gmtime(clock);
+ return strtime(stm);
+}
+
+/* This is used only for relative timeing since it reports seconds since
+ * about 5:00pm on Feb 16, 1994
+ */
+PUBLIC unsigned tenth_secs(void)
+{
+ struct timeval tp;
+ struct timezone tzp;
+
+ gettimeofday(&tp, &tzp);
+/* .1 seconds since 1970 almost fills a 32 bit int! So lets subtract off
+ * the time right now */
+ return ((tp.tv_sec - 331939277) * 10L) + (tp.tv_usec / 100000);
+}
+
+/* This is to translate tenths-secs time back into 1/1/70 time in full
+ * seconds, because vek didn't read utils.c when he programmed new ratings.
+ 1 sec since 1970 fits into a 32 bit int OK.
+*/
+PUBLIC int untenths(unsigned tenths)
+{
+ return (tenths / 10 + 331939277 + 0xffffffff / 10 + 1);
+}
+
+PUBLIC char *tenth_str(unsigned t, int spaces)
+{
+ return hms((t + 5) / 10, 0, 1, spaces); /* Round it */
+}
+
+#define MAX_TRUNC_SIZE 100
+
+/* Warning, if lines in the file are greater than 1024 bytes in length, this
+ won't work! */
+/* nasty bug fixed by mann, 3-12-95 */
+PUBLIC int truncate_file(char *file, int lines)
+{
+ FILE *fp;
+ int bptr = 0, trunc = 0, i;
+ char tBuf[MAX_TRUNC_SIZE][MAX_LINE_SIZE];
+
+ if (lines > MAX_TRUNC_SIZE)
+ lines = MAX_TRUNC_SIZE;
+ fp = fopen(file, "r");
+ if (!fp)
+ return 1;
+ while (!feof(fp)) {
+ fgets(tBuf[bptr], MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (tBuf[bptr][strlen(tBuf[bptr]) - 1] != '\n') { /* Line too long */
+ fclose(fp);
+ return -1;
+ }
+ bptr++;
+ if (bptr == lines) {
+ trunc = 1;
+ bptr = 0;
+ }
+ }
+ fclose(fp);
+ if (trunc) {
+ fp = fopen(file, "w");
+ for (i = 0; i < lines; i++) {
+ fputs(tBuf[bptr], fp);
+ bptr++;
+ if (bptr == lines) {
+ bptr = 0;
+ }
+ }
+ fclose(fp);
+ }
+ return 0;
+}
+
+/* Warning, if lines in the file are greater than 1024 bytes in length, this
+ won't work! */
+PUBLIC int lines_file(char *file)
+{
+ FILE *fp;
+ int lcount = 0;
+ char tmp[MAX_LINE_SIZE];
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return 0;
+ while (!feof(fp)) {
+ if (fgets(tmp, MAX_LINE_SIZE, fp))
+ lcount++;
+ }
+ fclose(fp);
+ return lcount;
+}
+
+PUBLIC int file_has_pname(char *fname, char *plogin)
+{
+ if (!strcmp(file_wplayer(fname), plogin))
+ return 1;
+ if (!strcmp(file_bplayer(fname), plogin))
+ return 1;
+ return 0;
+}
+
+PUBLIC char *file_wplayer(char *fname)
+{
+ static char tmp[MAX_FILENAME_SIZE];
+ char *ptr;
+ strcpy(tmp, fname);
+ ptr = rindex(tmp, '-');
+ if (!ptr)
+ return "";
+ *ptr = '\0';
+ return tmp;
+}
+
+PUBLIC char *file_bplayer(char *fname)
+{
+ char *ptr;
+
+ ptr = rindex(fname, '-');
+ if (!ptr)
+ return "";
+ return ptr + 1;
+}
+
+
+/* Hey, leave this code alone. "a" is always in network byte order,
+ which is big-endian, even on a little-endian machine. I fixed this
+ code to handle that correctly a while ago, and someone
+ gratuitiously changed it so that it would work correctly only on a
+ big-endian machine (like a Sun). I have now changed it back. --mann
+*/
+PUBLIC char *dotQuad(unsigned int a)
+{
+ static char tmp[20];
+ unsigned char *aa = (unsigned char *) &a;
+
+ sprintf(tmp, "%d.%d.%d.%d", aa[0], aa[1], aa[2], aa[3]);
+ return tmp;
+}
+
+PUBLIC int available_space(void)
+{
+#if defined(SYSTEM_NEXT)
+ struct statfs buf;
+
+ statfs(player_dir, &buf);
+ return ((buf.f_bsize * buf.f_bavail));
+#elif defined(SYSTEM_ULTRIX)
+ struct fs_data buf;
+
+ statfs(player_dir, &buf);
+ return ((1024 * buf.bfreen));
+#elif defined(SYSTEM_SUN4)
+/*
+ struct statfs buf;
+
+ statfs(player_dir, buf);
+ return (1024 * buf.f_bfree); */
+ return 100000000; /* Infinite space */
+#else
+ return 100000000; /* Infinite space */
+#endif
+}
+
+PUBLIC int file_exists(char *fname)
+{
+ FILE *fp;
+
+ fp = fopen(fname, "r");
+ if (!fp)
+ return 0;
+ fclose(fp);
+ return 1;
+}
+
+PUBLIC char *ratstr(int rat)
+{
+ static int on = 0;
+ static char tmp[20][10];
+
+ if (on == 20)
+ on = 0;
+ if (rat) {
+ sprintf(tmp[on], "%4d", rat);
+ } else {
+ sprintf(tmp[on], "----");
+
+ }
+ on++;
+ return tmp[on - 1];
+}
+
+PUBLIC char *ratstrii(int rat, int reg)
+{
+ static int on = 0;
+ static char tmp[20][10];
+
+ if (on == 20)
+ on = 0;
+ if (rat) {
+ sprintf(tmp[on], "%4d", rat);
+ } else {
+ if (reg) {
+ sprintf(tmp[on], "----");
+ } else {
+ sprintf(tmp[on], "++++");
+ }
+ }
+ on++;
+ return tmp[on - 1];
+}
+
+struct t_tree {
+ struct t_tree *left, *right;
+ char name; /* Not just 1 char - space for whole name */
+}; /* is allocated. Maybe a little cheesy? */
+
+struct t_dirs {
+ struct t_dirs *left, *right;
+ time_t mtime; /* dir's modification time */
+ struct t_tree *files;
+ char name; /* ditto */
+};
+
+PRIVATE char **t_buffer = NULL; /* pointer to next space in return buffer */
+PRIVATE int t_buffersize = 0; /* size of return buffer */
+
+/* fill t_buffer with anything matching "want*" in file tree t_tree */
+PRIVATE void t_sft(char *want, struct t_tree *t)
+{
+ if (t) {
+ int cmp = strncmp(want, &t->name, strlen(want));
+ if (cmp <= 0) /* if want <= this one, look left */
+ t_sft(want, t->left);
+ if (t_buffersize && (cmp == 0)) { /* if a match, add it to buffer */
+ t_buffersize--;
+ *t_buffer++ = &(t->name);
+ }
+ if (cmp >= 0) /* if want >= this one, look right */
+ t_sft(want, t->right);
+ }
+}
+
+/* delete file tree t_tree */
+PRIVATE void t_cft(struct t_tree **t)
+{
+ if (*t) {
+ t_cft(&(*t)->left);
+ t_cft(&(*t)->right);
+ rfree(*t);
+ *t = NULL;
+ }
+}
+
+/* make file tree for dir d */
+PRIVATE void t_mft(struct t_dirs *d)
+{
+ DIR *dirp;
+#ifdef USE_DIRENT
+ struct dirent *dp;
+#else
+ struct direct *dp;
+#endif
+ struct t_tree **t;
+
+ if ((dirp = opendir(&(d->name))) == NULL) {
+ fprintf(stderr, "FICS:mft() couldn't opendir.\n");
+ } else {
+ while ((dp = readdir(dirp))) {
+ t = &d->files;
+ if (dp->d_name[0] != '.') { /* skip anything starting with . */
+ while (*t) {
+ if (strcmp(dp->d_name, &(*t)->name) < 0) {
+ t = &(*t)->left;
+ } else {
+ t = &(*t)->right;
+ }
+ }
+ *t = rmalloc(sizeof(struct t_tree) + strlen(dp->d_name));
+ (*t)->right = (*t)->left = NULL;
+ strcpy(&(*t)->name, dp->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+}
+
+PUBLIC int search_directory(char *dir, char *filter, char **buffer, int buffersize)
+{
+/* dir = directory to search
+ filter = what to search for
+ buffer = where to store pointers to matches
+ buffersize = how many pointers will fit inside buffer */
+
+ static struct t_dirs *ramdirs = NULL;
+ struct t_dirs **i;
+ int cmp;
+ static char nullify = '\0';
+ struct stat statbuf;
+
+ t_buffer = buffer;
+ t_buffersize = buffersize;
+
+ if (!stat(dir, &statbuf)) {
+ if (filter == NULL) /* NULL becomes pointer to null string */
+ filter = &nullify;
+ i = &ramdirs;
+ while (*i) { /* find dir in dir tree */
+ cmp = strcmp(dir, &(*i)->name);
+ if (cmp == 0)
+ break;
+ else if (cmp < 0)
+ i = &(*i)->left;
+ else
+ i = &(*i)->right;
+ }
+ if (!*i) { /* if dir isn't in dir tree, add him */
+ *i = rmalloc(sizeof(struct t_dirs) + strlen(dir));
+ (*i)->left = (*i)->right = NULL;
+ (*i)->files = NULL;
+ strcpy(&(*i)->name, dir);
+ }
+ if ((*i)->files) { /* delete any obsolete file tree */
+ if ((*i)->mtime != statbuf.st_mtime) {
+ t_cft(&(*i)->files);
+ }
+ }
+ if ((*i)->files == NULL) { /* if no file tree for him, make one */
+ (*i)->mtime = statbuf.st_mtime;
+ t_mft(*i);
+ }
+ t_sft(filter, (*i)->files); /* finally, search for matches */
+ }
+ return (buffersize - t_buffersize);
+}
+
+PUBLIC int display_directory(int p, char **buffer, int count)
+/* buffer contains 'count' string pointers */
+{
+ int i;
+ multicol *m = multicol_start(count);
+
+ for (i = 0; (i < count); i++)
+ multicol_store(m, *buffer++);
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ return (i);
+}
blob - /dev/null
blob + 1d4fdaa644f47521e54fc6c6a6dcae300f61e49c (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/utils.c.orig
+/* utils.c
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "utils.h"
+#include "playerdb.h"
+#include "network.h"
+#include "rmalloc.h"
+#include "config.h"
+#if defined(SYSTEM_SUN4)
+/* #include <sys/vfs.h> */
+#endif
+
+/*
+#include <sys/types.h>
+#include <netinet/in.h>
+#include <arpa/nameser.h>
+#include <resolv.h>
+*/
+
+/* grimm */
+#if defined(SGI)
+#else
+/* char vsprintf(char *tmp, va_list format, va_list ap); */
+int gettimeofday(struct timeval * tp, struct timezone * tzp);
+#endif
+/* added for warnings */
+
+PUBLIC int count_lines(FILE *fp)
+{
+ int c, nl = 0;
+
+ while ((c = fgetc(fp)) != EOF)
+ if (c == '\n')
+ ++nl;
+
+ return nl;
+}
+
+PUBLIC int iswhitespace(int c)
+{
+ if ((c < ' ') || (c == '\b') || (c == '\n') ||
+ (c == '\t') || (c == ' ')) { /* white */
+ return 1;
+ } else {
+ return 0;
+ }
+}
+
+PUBLIC char *getword(char *str)
+{
+ int i;
+ static char word[MAX_WORD_SIZE];
+
+ i = 0;
+ while (*str && !iswhitespace(*str)) {
+ word[i] = *str;
+ str++;
+ i++;
+ if (i == MAX_WORD_SIZE) {
+ i = i - 1;
+ break;
+ }
+ }
+ word[i] = '\0';
+ return word;
+}
+
+PUBLIC char *eatword(char *str)
+{
+ while (*str && !iswhitespace(*str))
+ str++;
+ return str;
+}
+
+PUBLIC char *eatwhite(char *str)
+{
+ while (*str && iswhitespace(*str))
+ str++;
+ return str;
+}
+
+PUBLIC char *eattailwhite(char *str)
+{
+ int len;
+ if (str == NULL)
+ return NULL;
+
+ len = strlen(str);
+ while (len > 0 && iswhitespace(str[len - 1]))
+ len--;
+ str[len] = '\0';
+ return (str);
+}
+
+PUBLIC char *nextword(char *str)
+{
+ return eatwhite(eatword(str));
+}
+
+/* check_the_email_address function: */
+/*
+PUBLIC int check_emailaddr(char *email)
+{
+ int qbuflen;
+ char qabuf[5120];
+
+ if ((email = strchr(email, '@')) == NULL)
+ return 2;
+ email++;
+
+ res_init();
+ _res.options = (RES_INIT | RES_RECURSE);
+ if ((qbuflen = res_mkquery(QUERY, email, C_IN, T_ANY, NULL, 0, NULL, qabuf, sizeof(qabuf))) == -1)
+ return 1;
+
+ if (res_send(qabuf, qbuflen, qabuf, sizeof(qabuf)) == -1)
+ return 1;
+
+ return (_getshort(qabuf + 6) ? 0 : 2);
+}
+*/
+
+PUBLIC int mail_string_to_address(char *addr, char *subj, char *str)
+{
+ char com[1000];
+ FILE *fp;
+
+#ifdef SENDMAILPROG
+ sprintf(com, "%s\n", SENDMAILPROG);
+#else
+ sprintf(com, "%s -s \"%s\" %s", MAILPROGRAM, subj, addr);
+#endif
+ fp = popen(com, "w");
+ if (!fp)
+ return -1;
+#ifdef SENDMAILPROG
+ fprintf(fp, "To: %s\nSubject: %s\n%s", addr, subj, str);
+#else
+ fprintf(fp, "%s", str);
+#endif
+ pclose(fp);
+ return 0;
+}
+
+PUBLIC int mail_string_to_user(int p, char *subj, char *str)
+{
+
+ if (parray[p].emailAddress &&
+ parray[p].emailAddress[0] &&
+ safestring(parray[p].emailAddress)) {
+ return mail_string_to_address(parray[p].emailAddress, subj, str);
+ } else {
+ return -1;
+ }
+}
+
+PUBLIC int mail_file_to_address(char *addr, char *subj, char *fname)
+{
+ char com[1000];
+ char tmp[MAX_LINE_SIZE];
+ FILE *fp;
+ FILE *file_fp;
+
+#ifdef SENDMAILPROG
+ sprintf(com, "%s\n", SENDMAILPROG);
+#else
+ sprintf(com, "%s -s \"%s\" %s < %s&", MAILPROGRAM, subj, addr, fname);
+#endif
+ fp = popen(com, "w");
+ if (!fp)
+ return -1;
+#ifdef SENDMAILPROG
+ fprintf(fp, "To: %s\nSubject: %s\n", addr, subj);
+ file_fp = fopen(fname, "r");
+ if (!file_fp)
+ return -1;
+ while (!feof(file_fp)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, file_fp);
+ if (!feof(file_fp)) {
+ fputs(tmp, fp);
+ }
+ }
+ fclose(file_fp);
+
+#endif
+ pclose(fp);
+ return 0;
+}
+
+PUBLIC int mail_file_to_user(int p, char *subj, char *fname)
+{
+
+ if (parray[p].emailAddress &&
+ parray[p].emailAddress[0] &&
+ safestring(parray[p].emailAddress)) {
+ return mail_file_to_address(parray[p].emailAddress, subj, fname);
+ } else {
+ return -1;
+ }
+}
+
+
+/* Process a command for a user */
+PUBLIC int pcommand(int p, char *comstr,...)
+{
+ char tmp[MAX_LINE_SIZE];
+ int retval;
+ int current_socket = parray[p].socket;
+ va_list ap;
+ va_start(ap, comstr);
+
+ vsprintf(tmp, comstr, ap);
+ retval = process_input(current_socket, tmp);
+ if (retval == COM_LOGOUT) {
+ process_disconnection(current_socket);
+ net_close_connection(current_socket);
+ }
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC int pprintf(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE]; /* Make sure you can handle 10 lines worth of
+ stuff */
+ int retval;
+ va_list ap;
+ va_start(ap, format);
+
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 1);
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC void pprintf_dohightlight(int p)
+{
+ if (parray[p].highlight & 0x01)
+ pprintf(p, "\033[7m");
+ if (parray[p].highlight & 0x02)
+ pprintf(p, "\033[1m");
+ if (parray[p].highlight & 0x04)
+ pprintf(p, "\033[4m");
+ if (parray[p].highlight & 0x08)
+ pprintf(p, "\033[2m");
+}
+
+PUBLIC int pprintf_highlight(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE];
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+ pprintf_dohightlight(p);
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 1);
+ va_end(ap);
+ if (parray[p].highlight)
+ pprintf(p, "\033[0m");
+ return retval;
+}
+
+PUBLIC void sprintf_dohightlight(int p, char *s)
+{
+
+ if (parray[p].highlight & 0x01)
+ strcat(s, "\033[7m");
+ if (parray[p].highlight & 0x02)
+ strcat(s, "\033[1m");
+ if (parray[p].highlight & 0x04)
+ strcat(s, "\033[4m");
+ if (parray[p].highlight & 0x08)
+ strcat(s, "\033[2m");
+}
+
+PUBLIC int psprintf_highlight(int p, char *s, char *format,...)
+{
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+ if (parray[p].highlight) {
+ sprintf_dohightlight(p, s);
+ retval = vsprintf(s + strlen(s), format, ap);
+ strcat(s, "\033[0m");
+ } else {
+ retval = vsprintf(s, format, ap);
+ }
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC int pprintf_prompt(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE]; /* Make sure you can handle 10 lines worth of
+ stuff */
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf_prompt buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 1);
+ net_send_string(parray[p].socket, parray[p].prompt, 1);
+ va_end(ap);
+ return retval;
+}
+
+PUBLIC int pprintf_noformat(int p, char *format,...)
+{
+ char tmp[10 * MAX_LINE_SIZE]; /* Make sure you can handle 10 lines worth of
+ stuff */
+ int retval;
+ va_list ap;
+
+ va_start(ap, format);
+
+ retval = vsprintf(tmp, format, ap);
+ if (strlen(tmp) > 10 * MAX_LINE_SIZE) {
+ fprintf(stderr, "FICS: pprintf_noformat buffer overflow\n");
+ }
+ net_send_string(parray[p].socket, tmp, 0);
+ va_end(ap);
+ return retval;
+}
+
+
+/******************* grimm *************/
+/******************* added below *************/
+PUBLIC int psend_raw_file(int p, char *dir, char *file)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ char fname[MAX_FILENAME_SIZE];
+ int num;
+
+ if (dir)
+ sprintf(fname, "%s/%s", dir, file);
+ else
+ strcpy(fname, file);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -1;
+ while ((num = fread(tmp, sizeof(char), MAX_LINE_SIZE - 1, fp)) > 0) {
+ tmp[num] = '\0';
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int psend_file(int p, char *dir, char *file)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ char fname[MAX_FILENAME_SIZE];
+ int lcount = parray[p].d_height - 1;
+
+ if (parray[p].last_file)
+ rfree(parray[p].last_file);
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+
+ if (dir)
+ sprintf(fname, "%s/%s", dir, file);
+ else
+ strcpy(fname, file);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -1;
+ while (!feof(fp) && (--lcount > 0)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp)) {
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+ if (!feof(fp)) {
+ parray[p].last_file = strdup(fname);
+ parray[p].last_file_byte = ftell(fp);
+ pprintf(p, "Type [next] to see next page.\n");
+ }
+ fclose(fp);
+ return 0;
+}
+
+/*
+ * Marsalis added on 8/27/95 so that [next] does not
+ * appear in the logout process for those that have
+ * a short screen height. (Fixed due to complaint
+ * in Bug's messages).
+ */
+PUBLIC int psend_logoutfile(int p, char *dir, char *file)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ char fname[MAX_FILENAME_SIZE];
+
+ if (parray[p].last_file)
+ rfree(parray[p].last_file);
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+
+ if (dir)
+ sprintf(fname, "%s/%s", dir, file);
+ else
+ strcpy(fname, file);
+ fp = fopen(fname, "r");
+ if (!fp)
+ return -1;
+ while (!feof(fp)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp)) {
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int pmore_file(int p)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ int lcount = parray[p].d_height - 1;
+
+ if (!parray[p].last_file) {
+ pprintf(p, "There is no more.\n");
+ return -1;
+ }
+ fp = fopen(parray[p].last_file, "r");
+ if (!fp) {
+ pprintf(p, "File not found!\n");
+ return -1;
+ }
+ fseek(fp, parray[p].last_file_byte, SEEK_SET);
+
+ while (!feof(fp) && (--lcount > 0)) {
+ fgets(tmp, MAX_LINE_SIZE - 1, fp);
+ if (!feof(fp)) {
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+ if (!feof(fp)) {
+ parray[p].last_file_byte = ftell(fp);
+ pprintf(p, "Type [next] to see next page.\n");
+ } else {
+ rfree(parray[p].last_file);
+ parray[p].last_file = NULL;
+ parray[p].last_file_byte = 0L;
+ }
+ fclose(fp);
+ return 0;
+}
+
+PUBLIC int psend_command(int p, char *command, char *input)
+{
+ FILE *fp;
+ char tmp[MAX_LINE_SIZE];
+ int num;
+
+ if (input)
+ fp = popen(command, "w");
+ else
+ fp = popen(command, "r");
+ if (!fp)
+ return -1;
+ if (input) {
+ fwrite(input, sizeof(char), strlen(input), fp);
+ } else {
+ while (!feof(fp)) {
+ num = fread(tmp, sizeof(char), MAX_LINE_SIZE - 1, fp);
+ tmp[num] = '\0';
+ net_send_string(parray[p].socket, tmp, 1);
+ }
+ }
+ pclose(fp);
+ return 0;
+}
+
+PUBLIC char *stolower(char *str)
+{
+ int i;
+
+ if (!str)
+ return NULL;
+ for (i = 0; str[i]; i++) {
+ if (isupper(str[i])) {
+ str[i] = tolower(str[i]);
+ }
+ }
+ return str;
+}
+
+PUBLIC int safechar(int c)
+{
+ if ((c == '>') || (c == '!') || (c == '&') || (c == '*') || (c == '?') ||
+ (c == '/') || (c == '<') || (c == '|') || (c == '`') || (c == '$'))
+ return 0;
+ return 1;
+}
+
+PUBLIC int safestring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if (!safechar(str[i]))
+ return 0;
+ }
+ return 1;
+}
+
+PUBLIC int alphastring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if (!isalpha(str[i])) {
+ return 0;
+ }
+ }
+ return 1;
+}
+
+PUBLIC int printablestring(char *str)
+{
+ int i;
+
+ if (!str)
+ return 1;
+ for (i = 0; str[i]; i++) {
+ if ((!isprint(str[i])) && (str[i] != '\t') && (str[i] != '\n'))
+ return 0;
+ }
+ return 1;
+}
+
+
+/*#if defined(SGI)
+#else*/
+/* This version of strdup must be used, or the count of allocs
+ in "uptime" will omit them. Maybe we change the name to
+ rstrdup and replace all calls, if the name is causing a conflict
+ with anyone's libraries. --mann
+*/
+PUBLIC char *strdup(const char *str)
+{
+ char *tmp;
+
+ if (!str)
+ return NULL;
+ tmp = rmalloc(strlen(str) + 1);
+ strcpy(tmp, str);
+ return tmp;
+}
+/*#endif*/
+
+PUBLIC char *hms(int t, int showhour, int showseconds, int spaces)
+{
+ static char tstr[20];
+ char tmp[10];
+ int h, m, s;
+
+ h = t / 3600;
+ t = t % 3600;
+ m = t / 60;
+ s = t % 60;
+ if (h || showhour) {
+ if (spaces)
+ sprintf(tstr, "%d : %02d", h, m);
+ else
+ sprintf(tstr, "%d:%02d", h, m);
+ } else {
+ sprintf(tstr, "%d", m);
+ }
+ if (showseconds) {
+ if (spaces)
+ sprintf(tmp, " : %02d", s);
+ else
+ sprintf(tmp, ":%02d", s);
+ strcat(tstr, tmp);
+ }
+ return tstr;
+}
+
+PRIVATE char *strtime(struct tm * stm)
+{
+ static char tstr[100];
+
+#if defined (SGI)
+ strftime(tstr, sizeof(tstr), "%a %b %e, %H:%M %Z", stm);
+#else
+ strftime(tstr, sizeof(tstr), "%a %b %e, %k:%M %Z", stm);
+#endif
+ return (tstr);
+}
+
+PUBLIC char *strltime(time_t *clock)
+{
+ struct tm *stm = localtime(clock);
+ return strtime(stm);
+}
+
+PUBLIC char *strgtime(time_t *clock)
+{
+ struct tm *stm = gmtime(clock);
+ return strtime(stm);
+}
+
+/* This is used only for relative timeing since it reports seconds since
+ * about 5:00pm on Feb 16, 1994
+ */
+PUBLIC unsigned tenth_secs(void)
+{
+ struct timeval tp;
+ struct timezone tzp;
+
+ gettimeofday(&tp, &tzp);
+/* .1 seconds since 1970 almost fills a 32 bit int! So lets subtract off
+ * the time right now */
+ return ((tp.tv_sec - 331939277) * 10L) + (tp.tv_usec / 100000);
+}
+
+/* This is to translate tenths-secs time back into 1/1/70 time in full
+ * seconds, because vek didn't read utils.c when he programmed new ratings.
+ 1 sec since 1970 fits into a 32 bit int OK.
+*/
+PUBLIC int untenths(unsigned tenths)
+{
+ return (tenths / 10 + 331939277 + 0xffffffff / 10 + 1);
+}
+
+PUBLIC char *tenth_str(unsigned t, int spaces)
+{
+ return hms((t + 5) / 10, 0, 1, spaces); /* Round it */
+}
+
+#define MAX_TRUNC_SIZE 100
+
+/* Warning, if lines in the file are greater than 1024 bytes in length, this
+ won't work! */
+/* nasty bug fixed by mann, 3-12-95 */
+PUBLIC int truncate_file(char *file, int lines)
+{
+ FILE *fp;
+ int bptr = 0, trunc = 0, i;
+ char tBuf[MAX_TRUNC_SIZE][MAX_LINE_SIZE];
+
+ if (lines > MAX_TRUNC_SIZE)
+ lines = MAX_TRUNC_SIZE;
+ fp = fopen(file, "r");
+ if (!fp)
+ return 1;
+ while (!feof(fp)) {
+ fgets(tBuf[bptr], MAX_LINE_SIZE, fp);
+ if (feof(fp))
+ break;
+ if (tBuf[bptr][strlen(tBuf[bptr]) - 1] != '\n') { /* Line too long */
+ fclose(fp);
+ return -1;
+ }
+ bptr++;
+ if (bptr == lines) {
+ trunc = 1;
+ bptr = 0;
+ }
+ }
+ fclose(fp);
+ if (trunc) {
+ fp = fopen(file, "w");
+ for (i = 0; i < lines; i++) {
+ fputs(tBuf[bptr], fp);
+ bptr++;
+ if (bptr == lines) {
+ bptr = 0;
+ }
+ }
+ fclose(fp);
+ }
+ return 0;
+}
+
+/* Warning, if lines in the file are greater than 1024 bytes in length, this
+ won't work! */
+PUBLIC int lines_file(char *file)
+{
+ FILE *fp;
+ int lcount = 0;
+ char tmp[MAX_LINE_SIZE];
+
+ fp = fopen(file, "r");
+ if (!fp)
+ return 0;
+ while (!feof(fp)) {
+ if (fgets(tmp, MAX_LINE_SIZE, fp))
+ lcount++;
+ }
+ fclose(fp);
+ return lcount;
+}
+
+PUBLIC int file_has_pname(char *fname, char *plogin)
+{
+ if (!strcmp(file_wplayer(fname), plogin))
+ return 1;
+ if (!strcmp(file_bplayer(fname), plogin))
+ return 1;
+ return 0;
+}
+
+PUBLIC char *file_wplayer(char *fname)
+{
+ static char tmp[MAX_FILENAME_SIZE];
+ char *ptr;
+ strcpy(tmp, fname);
+ ptr = rindex(tmp, '-');
+ if (!ptr)
+ return "";
+ *ptr = '\0';
+ return tmp;
+}
+
+PUBLIC char *file_bplayer(char *fname)
+{
+ char *ptr;
+
+ ptr = rindex(fname, '-');
+ if (!ptr)
+ return "";
+ return ptr + 1;
+}
+
+
+/* Hey, leave this code alone. "a" is always in network byte order,
+ which is big-endian, even on a little-endian machine. I fixed this
+ code to handle that correctly a while ago, and someone
+ gratuitiously changed it so that it would work correctly only on a
+ big-endian machine (like a Sun). I have now changed it back. --mann
+*/
+PUBLIC char *dotQuad(unsigned int a)
+{
+ static char tmp[20];
+ unsigned char *aa = (unsigned char *) &a;
+
+ sprintf(tmp, "%d.%d.%d.%d", aa[0], aa[1], aa[2], aa[3]);
+ return tmp;
+}
+
+PUBLIC int available_space(void)
+{
+#if defined(SYSTEM_NEXT)
+ struct statfs buf;
+
+ statfs(player_dir, &buf);
+ return ((buf.f_bsize * buf.f_bavail));
+#elif defined(SYSTEM_ULTRIX)
+ struct fs_data buf;
+
+ statfs(player_dir, &buf);
+ return ((1024 * buf.bfreen));
+#elif defined(SYSTEM_SUN4)
+/*
+ struct statfs buf;
+
+ statfs(player_dir, buf);
+ return (1024 * buf.f_bfree); */
+ return 100000000; /* Infinite space */
+#else
+ return 100000000; /* Infinite space */
+#endif
+}
+
+PUBLIC int file_exists(char *fname)
+{
+ FILE *fp;
+
+ fp = fopen(fname, "r");
+ if (!fp)
+ return 0;
+ fclose(fp);
+ return 1;
+}
+
+PUBLIC char *ratstr(int rat)
+{
+ static int on = 0;
+ static char tmp[20][10];
+
+ if (on == 20)
+ on = 0;
+ if (rat) {
+ sprintf(tmp[on], "%4d", rat);
+ } else {
+ sprintf(tmp[on], "----");
+
+ }
+ on++;
+ return tmp[on - 1];
+}
+
+PUBLIC char *ratstrii(int rat, int reg)
+{
+ static int on = 0;
+ static char tmp[20][10];
+
+ if (on == 20)
+ on = 0;
+ if (rat) {
+ sprintf(tmp[on], "%4d", rat);
+ } else {
+ if (reg) {
+ sprintf(tmp[on], "----");
+ } else {
+ sprintf(tmp[on], "++++");
+ }
+ }
+ on++;
+ return tmp[on - 1];
+}
+
+struct t_tree {
+ struct t_tree *left, *right;
+ char name; /* Not just 1 char - space for whole name */
+}; /* is allocated. Maybe a little cheesy? */
+
+struct t_dirs {
+ struct t_dirs *left, *right;
+ time_t mtime; /* dir's modification time */
+ struct t_tree *files;
+ char name; /* ditto */
+};
+
+PRIVATE char **t_buffer = NULL; /* pointer to next space in return buffer */
+PRIVATE int t_buffersize = 0; /* size of return buffer */
+
+/* fill t_buffer with anything matching "want*" in file tree t_tree */
+PRIVATE void t_sft(char *want, struct t_tree *t)
+{
+ if (t) {
+ int cmp = strncmp(want, &t->name, strlen(want));
+ if (cmp <= 0) /* if want <= this one, look left */
+ t_sft(want, t->left);
+ if (t_buffersize && (cmp == 0)) { /* if a match, add it to buffer */
+ t_buffersize--;
+ *t_buffer++ = &(t->name);
+ }
+ if (cmp >= 0) /* if want >= this one, look right */
+ t_sft(want, t->right);
+ }
+}
+
+/* delete file tree t_tree */
+PRIVATE void t_cft(struct t_tree **t)
+{
+ if (*t) {
+ t_cft(&(*t)->left);
+ t_cft(&(*t)->right);
+ rfree(*t);
+ *t = NULL;
+ }
+}
+
+/* make file tree for dir d */
+PRIVATE void t_mft(struct t_dirs *d)
+{
+ DIR *dirp;
+ struct dirent *dp;
+ struct t_tree **t;
+
+ if ((dirp = opendir(&(d->name))) == NULL) {
+ fprintf(stderr, "FICS:mft() couldn't opendir.\n");
+ } else {
+ while ((dp = readdir(dirp))) {
+ t = &d->files;
+ if (dp->d_name[0] != '.') { /* skip anything starting with . */
+ while (*t) {
+ if (strcmp(dp->d_name, &(*t)->name) < 0) {
+ t = &(*t)->left;
+ } else {
+ t = &(*t)->right;
+ }
+ }
+ *t = rmalloc(sizeof(struct t_tree) + strlen(dp->d_name));
+ (*t)->right = (*t)->left = NULL;
+ strcpy(&(*t)->name, dp->d_name);
+ }
+ }
+ closedir(dirp);
+ }
+}
+
+PUBLIC int search_directory(char *dir, char *filter, char **buffer, int buffersize)
+{
+/* dir = directory to search
+ filter = what to search for
+ buffer = where to store pointers to matches
+ buffersize = how many pointers will fit inside buffer */
+
+ static struct t_dirs *ramdirs = NULL;
+ struct t_dirs **i;
+ int cmp;
+ static char nullify = '\0';
+ struct stat statbuf;
+
+ t_buffer = buffer;
+ t_buffersize = buffersize;
+
+ if (!stat(dir, &statbuf)) {
+ if (filter == NULL) /* NULL becomes pointer to null string */
+ filter = &nullify;
+ i = &ramdirs;
+ while (*i) { /* find dir in dir tree */
+ cmp = strcmp(dir, &(*i)->name);
+ if (cmp == 0)
+ break;
+ else if (cmp < 0)
+ i = &(*i)->left;
+ else
+ i = &(*i)->right;
+ }
+ if (!*i) { /* if dir isn't in dir tree, add him */
+ *i = rmalloc(sizeof(struct t_dirs) + strlen(dir));
+ (*i)->left = (*i)->right = NULL;
+ (*i)->files = NULL;
+ strcpy(&(*i)->name, dir);
+ }
+ if ((*i)->files) { /* delete any obsolete file tree */
+ if ((*i)->mtime != statbuf.st_mtime) {
+ t_cft(&(*i)->files);
+ }
+ }
+ if ((*i)->files == NULL) { /* if no file tree for him, make one */
+ (*i)->mtime = statbuf.st_mtime;
+ t_mft(*i);
+ }
+ t_sft(filter, (*i)->files); /* finally, search for matches */
+ }
+ return (buffersize - t_buffersize);
+}
+
+PUBLIC int display_directory(int p, char **buffer, int count)
+/* buffer contains 'count' string pointers */
+{
+ int i;
+ multicol *m = multicol_start(count);
+
+ for (i = 0; (i < count); i++)
+ multicol_store(m, *buffer++);
+ multicol_pprint(m, p, 78, 1);
+ multicol_end(m);
+ return (i);
+}
blob - /dev/null
blob + 901da9316c0cffc8cb9f1c28fead6493fbb84d97 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/utils.h
+/* utils.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include <stdio.h>
+#include "multicol.h"
+
+#define MAX_WORD_SIZE 1024
+
+/* Maximum length of an output line */
+#define MAX_LINE_SIZE 1024
+
+/* Maximum size of a filename */
+#ifdef FILENAME_MAX
+# define MAX_FILENAME_SIZE FILENAME_MAX
+#else
+# define MAX_FILENAME_SIZE 1024
+#endif
+
+#define SetFlag(VAR, FLAG) (VAR |= (FLAG))
+#define ClearFlag(VAR, FLAG) (VAR &= ~(FLAG))
+#define CheckFlag(VAR, FLAG) (VAR & (FLAG))
+
+extern int count_lines(FILE *);
+extern int iswhitespace( );
+extern char *getword( );
+/* Returns a pointer to the first whitespace in the argument */
+extern char *eatword( );
+/* Returns a pointer to the first non-whitespace char in the argument */
+extern char *eatwhite( );
+/* Returns a pointer to the same string with trailing spaces removed */
+extern char *eattailwhite( );
+/* Returns the next word in a given string >eatwhite(eatword(foo))< */
+extern char *nextword( );
+
+extern int check_emailaddr(char *);
+extern int mail_string_to_address();
+extern int mail_string_to_user();
+extern int mail_file_to_address();
+extern int mail_file_to_user();
+extern int pcommand(int, char *, ...);
+extern int pprintf(int, char *, ...);
+extern void pprintf_dohightlight(int);
+extern void sprintf_dohightlight(int,char *);
+extern int pprintf_highlight(int, char *, ...);
+extern int psprintf_highlight(int, char *, char *, ...);
+extern int pprintf_prompt(int, char *, ...);
+extern int pprintf_noformat(int, char *, ...);
+extern int psend_raw_file( );
+extern int psend_file( );
+extern int psend_logoutfile( );
+extern int pmore_file( );
+extern int pmail_file( );
+extern int psend_command( );
+extern char *fix_time(char *);
+extern char *stolower( );
+
+extern int safechar( );
+extern int safestring( );
+extern int alphastring( );
+extern int printablestring( );
+#if defined(SGI)
+#else
+/* extern char *strdup( ); */
+#endif
+
+extern char *hms_desc();
+extern char *hms();
+extern char *strltime();
+extern char *strgtime();
+extern unsigned tenth_secs();
+extern char *tenth_str();
+extern int untenths();
+
+extern int truncate_file();
+extern int lines_file();
+
+extern int file_has_pname();
+extern char *file_wplayer();
+extern char *file_bplayer();
+
+extern char *dotQuad();
+
+extern int available_space();
+extern int file_exists();
+extern char *ratstr();
+extern char *ratstrii();
+
+extern int search_directory(char *, char *, char **, int);
+extern int display_directory(int, char **, int);
+
+#endif /* _UTILS_H */
+
blob - /dev/null
blob + 68f042f294500ee0f8bcf191ad8ff10e58a4d3f9 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/utils.h.orig
+/* utils.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _UTILS_H
+#define _UTILS_H
+
+#include <stdio.h>
+#include "multicol.h"
+
+#define MAX_WORD_SIZE 1024
+
+/* Maximum length of an output line */
+#define MAX_LINE_SIZE 1024
+
+/* Maximum size of a filename */
+#ifdef FILENAME_MAX
+# define MAX_FILENAME_SIZE FILENAME_MAX
+#else
+# define MAX_FILENAME_SIZE 1024
+#endif
+
+#define SetFlag(VAR, FLAG) (VAR |= (FLAG))
+#define ClearFlag(VAR, FLAG) (VAR &= ~(FLAG))
+#define CheckFlag(VAR, FLAG) (VAR & (FLAG))
+
+extern int count_lines(FILE *);
+extern int iswhitespace( );
+extern char *getword( );
+/* Returns a pointer to the first whitespace in the argument */
+extern char *eatword( );
+/* Returns a pointer to the first non-whitespace char in the argument */
+extern char *eatwhite( );
+/* Returns a pointer to the same string with trailing spaces removed */
+extern char *eattailwhite( );
+/* Returns the next word in a given string >eatwhite(eatword(foo))< */
+extern char *nextword( );
+
+extern int check_emailaddr(char *);
+extern int mail_string_to_address();
+extern int mail_string_to_user();
+extern int mail_file_to_address();
+extern int mail_file_to_user();
+extern int pcommand(int, char *, ...);
+extern int pprintf(int, char *, ...);
+extern void pprintf_dohightlight(int);
+extern void sprintf_dohightlight(int,char *);
+extern int pprintf_highlight(int, char *, ...);
+extern int psprintf_highlight(int, char *, char *, ...);
+extern int pprintf_prompt(int, char *, ...);
+extern int pprintf_noformat(int, char *, ...);
+extern int psend_raw_file( );
+extern int psend_file( );
+extern int psend_logoutfile( );
+extern int pmore_file( );
+extern int pmail_file( );
+extern int psend_command( );
+
+extern char *stolower( );
+
+extern int safechar( );
+extern int safestring( );
+extern int alphastring( );
+extern int printablestring( );
+#if defined(SGI)
+#else
+/* extern char *strdup( ); */
+#endif
+
+extern char *hms();
+extern char *strltime();
+extern char *strgtime();
+extern unsigned tenth_secs();
+extern char *tenth_str();
+extern int untenths();
+
+extern int truncate_file();
+extern int lines_file();
+
+extern int file_has_pname();
+extern char *file_wplayer();
+extern char *file_bplayer();
+
+extern char *dotQuad();
+
+extern int available_space();
+extern int file_exists();
+extern char *ratstr();
+extern char *ratstrii();
+
+extern int search_directory(char *, char *, char **, int);
+extern int display_directory(int, char **, int);
+
+#endif /* _UTILS_H */
+
blob - /dev/null
blob + b348bb2862792d78c412dd72e7d6ddcc38112749 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/utils.o differ
blob - /dev/null
blob + b53664d1ede59fca11703823752c5da2dc431380 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/variable.c
+/* variable.c
+ * This is cludgy
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+ loon 95/03/17 added figure_boolean, use it :)
+ hersco 95/04/10 replaced figure_boolean with
+ set_boolean_var
+ DAV 95/19/11 moved variable command to here
+ added jprivate
+*/
+
+#include "stdinclude.h"
+
+#include "common.h"
+#include "variable.h"
+#include "playerdb.h"
+#include "utils.h"
+#include "ficsmain.h"
+#include "config.h"
+#include "rmalloc.h"
+#include "board.h"
+#include "command.h"
+#include "talkproc.h"
+#include "comproc.h"
+
+/* grimm */
+int SetValidFormula(int p, int which, char *val);
+/* added for warning */
+PRIVATE int set_boolean_var(int *var, char *val)
+{
+ int v = -1;
+
+ if (val == NULL)
+ return (*var = !*var);
+
+ if (sscanf(val, "%d", &v) != 1) {
+ stolower(val);
+ if (!strcmp(val, "off"))
+ v = 0;
+ if (!strcmp(val, "false"))
+ v = 0;
+ if (!strcmp(val, "on"))
+ v = 1;
+ if (!strcmp(val, "true"))
+ v = 1;
+ }
+ if ((v == 0) || (v == 1))
+ return (*var = v);
+ else
+ return (-1);
+}
+
+PRIVATE int set_open(int p, char *var, char *val)
+{
+ int v = set_boolean_var(&parray[p].open, val);
+
+ if (v < 0)
+ return VAR_BADVAL;
+ if (v > 0)
+ pprintf(p, "You are now open to receive match requests.\n");
+ else {
+ player_decline_offers(p, -1, PEND_MATCH);
+ player_withdraw_offers(p, -1, PEND_MATCH);
+ pprintf(p, "You are no longer receiving match requests.\n");
+ }
+ return VAR_OK;
+}
+
+PRIVATE int set_sopen(int p, char *var, char *val)
+{
+ int v = set_boolean_var(&parray[p].sopen, val);
+
+ if (v < 0)
+ return VAR_BADVAL;
+ pprintf(p, "sopen set to %d.\n", parray[p].sopen);
+
+ if (v > 0)
+ pprintf(p, "You are now open to receive simul requests.\n");
+ else
+ pprintf(p, "You are no longer receiving simul requests.\n");
+ player_decline_offers(p, -1, PEND_SIMUL);
+ return VAR_OK;
+}
+
+PRIVATE int set_ropen(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].ropen, val) < 0)
+ return VAR_BADVAL;
+ pprintf(p, "ropen set to %d.\n", parray[p].ropen);
+ return VAR_OK;
+}
+
+PRIVATE int set_rated(int p, char *var, char *val)
+{
+ if (!parray[p].registered) {
+ pprintf(p, "You cannot change your rated status.\n");
+ return VAR_OK;
+ }
+ if (set_boolean_var(&parray[p].rated, val) < 0)
+ return VAR_BADVAL;
+ pprintf(p, "rated set to %d.\n", parray[p].rated);
+ return VAR_OK;
+}
+
+PRIVATE int set_shout(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].i_shout, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_shout)
+ pprintf(p, "You will now hear shouts.\n");
+ else
+ pprintf(p, "You will not hear shouts.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_cshout(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].i_cshout, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_cshout)
+ pprintf(p, "You will now hear cshouts.\n");
+ else
+ pprintf(p, "You will not hear cshouts.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_kibitz(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].i_kibitz, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_kibitz)
+ pprintf(p, "You will now hear kibitzes.\n");
+ else
+ pprintf(p, "You will not hear kibitzes.\n");
+ return VAR_OK;
+}
+PRIVATE int set_kiblevel(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 9999))
+ return VAR_BADVAL;
+ parray[p].kiblevel = v;
+ pprintf(p, "Kibitz level now set to: %d.\n", v);
+ return VAR_OK;
+}
+
+PRIVATE int set_tell(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].i_tell, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_tell)
+ pprintf(p, "You will now hear tells.\n");
+ else
+ pprintf(p, "You will not hear tells.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_notifiedby(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].notifiedby, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].notifiedby)
+ pprintf(p, "You will now hear if people notify you, but you don't notify them.\n");
+ else
+ pprintf(p, "You will not hear if people notify you, but you don't notify them.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_pinform(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].i_login, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_login)
+ pprintf(p, "You will now hear logins/logouts.\n");
+ else
+ pprintf(p, "You will not hear logins/logouts.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_ginform(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].i_game, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_game)
+ pprintf(p, "You will now hear game results.\n");
+ else
+ pprintf(p, "You will not hear game results.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_private(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].private, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].private)
+ pprintf(p, "Your games will be private.\n");
+ else
+ pprintf(p, "Your games may not be private.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_jprivate(int p, char *var, char *val)
+{
+ if (!parray[p].registered) {
+ pprintf(p, "Unregistered players may not keep a journal.\n");
+ return VAR_OK;
+ }
+
+ if (set_boolean_var(&parray[p].jprivate, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].jprivate)
+ pprintf(p, "Your journal will be private.\n");
+ else
+ pprintf(p, "Your journal will not be private.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_automail(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].automail, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].automail)
+ pprintf(p, "Your games will be mailed to you.\n");
+ else
+ pprintf(p, "Your games will not be mailed to you.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_mailmess(int p, char *var, char *val)
+{
+ if (!parray[p].registered) {
+ pprintf(p, "Unregistered players may not receive messages.\n");
+ return VAR_OK;
+ }
+ if (set_boolean_var(&parray[p].i_mailmess, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].i_mailmess)
+ pprintf(p, "Your messages will be mailed to you.\n");
+ else
+ pprintf(p, "Your messages will not be mailed to you.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_pgn(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].pgn, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].pgn)
+ pprintf(p, "Games will now be mailed to you in PGN.\n");
+ else
+ pprintf(p, "Games will now be mailed to you in FICS format.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_bell(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].bell, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].bell)
+ pprintf(p, "Bell on.\n");
+ else
+ pprintf(p, "Bell off.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_highlight(int p, char *var, char *val)
+{
+/* if (set_boolean_var (&parray[p].highlight, val) < 0) return VAR_BADVAL;
+ */
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 15))
+ return VAR_BADVAL;
+
+ if ((parray[p].highlight = v)) {
+ pprintf(p, "Highlight is now style ");
+ pprintf_highlight(p, "%d", v);
+ pprintf(p, ".\n");
+ } else
+ pprintf(p, "Highlight is off.\n");
+ return VAR_OK;
+}
+
+PRIVATE int set_style(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 1) || (v > MAX_STYLES))
+ return VAR_BADVAL;
+ parray[p].style = v - 1;
+ pprintf(p, "Style %d set.\n", v);
+ return VAR_OK;
+}
+
+PRIVATE int set_flip(int p, char *var, char *val)
+{
+ if (set_boolean_var(&parray[p].flip, val) < 0)
+ return VAR_BADVAL;
+ if (parray[p].flip)
+ pprintf(p, "Flip on.\n");
+ else
+ pprintf(p, "Flip off.\n");
+ return VAR_OK;
+}
+/*
+PRIVATE int set_uscf(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 3000))
+ return VAR_BADVAL;
+ parray[p].uscfRating = v;
+ pprintf(p, "USCF Rating set to %d.\n", v);
+ return VAR_OK;
+}
+*/
+PRIVATE int set_time(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 240))
+ return VAR_BADVAL;
+ parray[p].d_time = v;
+ pprintf(p, "Default time set to %d.\n", v);
+ return VAR_OK;
+}
+
+PRIVATE int set_inc(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 0) || (v > 300))
+ return VAR_BADVAL;
+ parray[p].d_inc = v;
+ pprintf(p, "Default increment set to %d.\n", v);
+ return VAR_OK;
+}
+
+PRIVATE int set_height(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 5) || (v > 240))
+ return VAR_BADVAL;
+ parray[p].d_height = v;
+ pprintf(p, "Height set to %d.\n", v);
+ return VAR_OK;
+}
+
+PRIVATE int set_width(int p, char *var, char *val)
+{
+ int v = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ if (sscanf(val, "%d", &v) != 1)
+ return VAR_BADVAL;
+ if ((v < 32) || (v > 240))
+ return VAR_BADVAL;
+ parray[p].d_width = v;
+ pprintf(p, "Width set to %d.\n", v);
+ return VAR_OK;
+}
+
+PUBLIC char *Language(int i)
+{
+ static char *Lang[NUM_LANGS] = {"English", "Spanish", "French", "Danish"};
+ return Lang[i];
+}
+
+PRIVATE int set_language (int p, char *var, char *val)
+{
+ int i, len, gotIt = -1;
+
+ if (!val)
+ return VAR_BADVAL;
+ len = strlen(val);
+ for (i=0; i < NUM_LANGS; i++) {
+ if (strncasecmp(val, Language(i), len))
+ continue;
+ if (gotIt >= 0)
+ return VAR_BADVAL;
+ else gotIt = i;
+ }
+ if (gotIt < 0)
+ return VAR_BADVAL;
+ parray[p].language = gotIt;
+ pprintf(p, "Language set to %s.\n", Language(gotIt));
+ return VAR_OK;
+}
+
+PRIVATE int set_promote(int p, char *var, char *val)
+{
+ if (!val)
+ return VAR_BADVAL;
+ stolower(val);
+ switch (val[0]) {
+ case 'q':
+ parray[p].promote = QUEEN;
+ pprintf(p, "Promotion piece set to QUEEN.\n");
+ break;
+ case 'r':
+ parray[p].promote = ROOK;
+ pprintf(p, "Promotion piece set to ROOK.\n");
+ break;
+ case 'b':
+ parray[p].promote = BISHOP;
+ pprintf(p, "Promotion piece set to BISHOP.\n");
+ break;
+ case 'n':
+ case 'k':
+ parray[p].promote = KNIGHT;
+ pprintf(p, "Promotion piece set to KNIGHT.\n");
+ break;
+ default:
+ return VAR_BADVAL;
+ }
+ return VAR_OK;
+}
+
+PRIVATE int set_prompt(int p, char *var, char *val)
+{
+ if (!val) {
+ if (parray[p].prompt && (parray[p].prompt != def_prompt))
+ rfree(parray[p].prompt);
+ parray[p].prompt = def_prompt;
+ return VAR_OK;
+ }
+ if (!printablestring(val))
+ return VAR_BADVAL;
+ if (parray[p].prompt != def_prompt)
+ rfree(parray[p].prompt);
+ parray[p].prompt = (char *) rmalloc(strlen(val) + 2);
+ strcpy(parray[p].prompt, val);
+ strcat(parray[p].prompt, " ");
+ return VAR_OK;
+}
+
+int RePartner (int p, int new)
+{
+ int pOld;
+
+ if (p < 0)
+ return -1;
+ pOld = parray[p].partner;
+ if (parray[pOld].partner == p) {
+ if (new >= 0)
+ pprintf_prompt (pOld, "Your partner has just chosen a new partner.\n");
+ else
+ pprintf_prompt (pOld, "Your partner has just unset his/her partner.\n");
+ player_withdraw_offers (pOld, -1, PEND_BUGHOUSE);
+ player_decline_offers (pOld, -1, PEND_BUGHOUSE);
+ player_withdraw_offers (p, -1, PEND_BUGHOUSE);
+ player_decline_offers (p, -1, PEND_BUGHOUSE);
+ }
+ player_withdraw_offers(p, -1, PEND_PARTNER);
+ player_decline_offers(p, -1, PEND_PARTNER);
+ parray[pOld].partner = -1;
+ parray[p].partner = new;
+ return new;
+}
+
+PUBLIC int com_partner(int p, param_list param)
+{
+ int pNew;
+
+ if (param[0].type == TYPE_NULL) {
+ RePartner(p, -1);
+ return COM_OK;
+ }
+ /* OK, we're trying to set a new partner. */
+ pNew = player_find_part_login(param[0].val.word);
+ if (pNew < 0 || parray[pNew].status == PLAYER_PASSWORD
+ || parray[pNew].status == PLAYER_LOGIN) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", param[0].val.word);
+ return COM_OK;
+ }
+ if (pNew == p) {
+ pprintf(p, "You can't be your own bughouse partner.\n");
+ return COM_OK;
+ }
+ /* Now we know a legit partner has been chosen. Is an offer pending? */
+ if (player_find_pendfrom(p, pNew, PEND_PARTNER) >= 0) {
+ pprintf (p, "You agree to be %s's partner.\n", parray[pNew].name);
+ pprintf_prompt (pNew, "%s agrees to be your partner.\n", parray[p].name);
+ player_remove_request(pNew, p, PEND_PARTNER);
+
+ /* Make the switch. */
+ RePartner (p, pNew);
+ RePartner (pNew, p);
+ return COM_OK;
+ }
+ /* This is just an offer. Make sure a new partner is needed. */
+ if (parray[pNew].partner >= 0) {
+ pprintf(p, "%s already has a partner.\n", parray[pNew].name);
+ return COM_OK;
+ }
+ pprintf(pNew, "\n");
+ pprintf_highlight(pNew, "%s", parray[p].name);
+ pprintf(pNew, " offers to be your bughouse partner; ");
+ pprintf_prompt(pNew, "type \"partner %s\" to accept.\n", parray[p].name);
+ pprintf(p, "Making a partnership offer to %s.\n", parray[pNew].name);
+ player_add_request(p, pNew, PEND_PARTNER, 0);
+
+/* pprintf (p, "Command not implemented yet.\n"); */
+ return COM_OK;
+}
+
+PRIVATE int set_partner(int p, char *var, char *val)
+{
+#if 0
+ int p1 = parray[p].partner;
+
+ if (!val) {
+ RePartner (p, -1);
+ return VAR_OK;
+ }
+ if (!printablestring(val))
+ return VAR_BADVAL;
+ stolower(val);
+ p1 = player_find_part_login(val);
+ if (p1 < 0 || parray[p1].status == PLAYER_PASSWORD
+ || parray[p1].status == PLAYER_LOGIN) {
+ pprintf(p, "No user named \"%s\" is logged in.\n", val);
+ return VAR_OK;
+ }
+ if (p1 == p) {
+ pprintf(p, "You can't be your own bughouse partner!\n");
+ return VAR_OK;
+ }
+ parray[p].partner = p1;
+ pprintf(p, "Your bughouse partner is now %s.\n", parray[p1].name);
+ pprintf_prompt(p1, "%s just chose you for a bughouse partner.\n", parray[p].name);
+#endif
+ if (!val)
+ pprintf(p, "Command is obsolete; type \"partner\" to clear your partner\n");
+ else
+ pprintf(p, "Command is obsolete; type \"partner %s\" to change your partner\n", val);
+ return VAR_OK;
+}
+
+PRIVATE int set_busy(int p, char *var, char *val)
+{
+ if (!val) {
+ parray[p].busy[0] = '\0';
+ pprintf(p, "Your \"busy\" string was cleared.\n");
+ return VAR_OK;
+ }
+ if ((val) && (!printablestring(val)))
+ return VAR_BADVAL;
+ if (strlen(val) > 50) {
+ pprintf(p, "That string is too long.\n");
+ return VAR_BADVAL;
+ }
+ sprintf(parray[p].busy, "%s", val);
+ pprintf(p, "Your \"busy\" string was set to \" %s\"\n", parray[p].busy);
+ return VAR_OK;
+}
+
+/* this is really ugly */
+PRIVATE int set_plan(int p, char *var, char *val)
+{
+ int which;
+ int i;
+
+ if (val && !printablestring(val))
+ return VAR_BADVAL;
+ which = atoi(var); /* Must be an integer, no test needed */
+
+ if (which > MAX_PLAN)
+ return VAR_BADVAL;
+
+ if (which > parray[p].num_plan)
+ which = parray[p].num_plan + 1;
+
+ if (which == 0) { /* shove from top */
+ if (parray[p].num_plan >= MAX_PLAN) { /* free the bottom string */
+ if (parray[p].planLines[parray[p].num_plan - 1] != NULL)
+ rfree(parray[p].planLines[parray[p].num_plan - 1]);
+ }
+ if (parray[p].num_plan) {
+ for (i = (parray[p].num_plan >= MAX_PLAN) ? MAX_PLAN - 1 : parray[p].num_plan; i > 0; i--)
+ parray[p].planLines[i] = parray[p].planLines[i - 1];
+ }
+ if (parray[p].num_plan < MAX_PLAN)
+ parray[p].num_plan++;
+ parray[p].planLines[0] = ((val == NULL) ? NULL : strdup(val));
+ pprintf(p, "\nPlan variable %d changed to '%s'.\n", which+1, parray[p].planLines[which]);
+ pprintf(p, "All other variables moved down.\n");
+ return VAR_OK;
+ }
+ if (which > parray[p].num_plan) { /* new line at bottom */
+ if (parray[p].num_plan >= MAX_PLAN) { /* shove the old lines up */
+ if (parray[p].planLines[0] != NULL)
+ rfree(parray[p].planLines[0]);
+ for (i = 0; i < parray[p].num_plan; i++)
+ parray[p].planLines[i] = parray[p].planLines[i + 1];
+ } else {
+ parray[p].num_plan++;
+ }
+ parray[p].planLines[which - 1] = ((val == NULL) ? NULL : strdup(val));
+ pprintf(p, "\nPlan variable %d changed to '%s'.\n", which, parray[p].planLines[which-1]);
+ return VAR_OK;
+ }
+ which--;
+ if (parray[p].planLines[which] != NULL) {
+ rfree(parray[p].planLines[which]);
+ }
+ if (val != NULL) {
+ parray[p].planLines[which] = strdup(val);
+ pprintf(p, "\nPlan variable %d changed to '%s'.\n", which+1, parray[p].planLines[which]);
+ } else {
+ parray[p].planLines[which] = NULL;
+ if (which == parray[p].num_plan - 1) { /* clear nulls from bottom */
+ while ((parray[p].num_plan > 0) && (parray[p].planLines[parray[p].num_plan - 1] == NULL)) {
+ parray[p].num_plan--;
+ pprintf(p, "\nPlan variable %d cleared.\n", which+1);
+ }
+ } else if (which == 0) { /* clear nulls from top */
+ while ((which < parray[p].num_plan) && (parray[p].planLines[which] == NULL)) {
+ which++;
+ }
+ if (which != parray[p].num_plan) {
+ for (i = which; i < parray[p].num_plan; i++)
+ parray[p].planLines[i - which] = parray[p].planLines[i];
+ }
+ parray[p].num_plan -= which;
+ }
+ }
+ return VAR_OK;
+}
+
+PRIVATE int set_formula(int p, char *var, char *val)
+{
+ int which;
+ player *me = &parray[p];
+
+#ifdef NO_FORMULAS
+ pprintf(p, "Sorry -- not available because of a bug\n");
+ return COM_OK;
+#else
+ if (isdigit(var[1]))
+ which = var[1] - '1';
+ else
+ which = MAX_FORMULA;
+
+ if (val != NULL) {
+ val = eatwhite(val);
+ if (val[0] == '\0')
+ val = NULL;
+ }
+ if (!SetValidFormula(p, which, val))
+ return VAR_BADVAL;
+
+ if (which < MAX_FORMULA) {
+ if (val != NULL) {
+ while (me->num_formula < which) {
+ me->formulaLines[me->num_formula] = NULL;
+ (me->num_formula)++;
+ }
+ if (me->num_formula <= which)
+ me->num_formula = which + 1;
+ pprintf(p, "Formula variable f%d set to %s.\n",
+ which + 1, me->formulaLines[which]);
+ return VAR_OK;
+ }
+ pprintf(p, "Formula variable f%d unset.\n", which + 1);
+ if (which + 1 >= me->num_formula) {
+ while (which >= 0 && me->formulaLines[which] == NULL)
+ which--;
+ me->num_formula = which + 1;
+ }
+ } else {
+ if (me->formula != NULL)
+ pprintf(p, "Formula set to %s.\n", me->formula);
+ else
+ pprintf(p, "Formula unset.\n");
+ }
+ return VAR_OK;
+#endif
+}
+
+PUBLIC var_list variables[] = {
+ {"open", set_open},
+ {"simopen", set_sopen},
+ {"rated", set_rated},
+ {"ropen", set_ropen},
+ {"cshout", set_cshout},
+ {"shout", set_shout},
+ {"kibitz", set_kibitz},
+ {"kiblevel", set_kiblevel},
+ {"tell", set_tell},
+ {"notifiedby", set_notifiedby},
+ {"pinform", set_pinform},
+ {"i_login", set_pinform},
+ {"ginform", set_ginform},
+ {"i_game", set_ginform},
+ {"automail", set_automail},
+ {"mailmess", set_mailmess},
+ {"bell", set_bell},
+ {"pgn", set_pgn},
+ {"private", set_private},
+ {"jprivate", set_jprivate},
+ {"highlight", set_highlight},
+ {"style", set_style},
+ {"flip", set_flip},
+/* {"uscf", set_uscf},*/
+ {"prompt", set_prompt},
+ {"partner", set_partner},
+ {"promote", set_promote},
+ {"time", set_time},
+ {"inc", set_inc},
+ {"height", set_height},
+ {"width", set_width},
+ {"language", set_language},
+ {"busy", set_busy},
+ {"0", set_plan},
+ {"1", set_plan},
+ {"2", set_plan},
+ {"3", set_plan},
+ {"4", set_plan},
+ {"5", set_plan},
+ {"6", set_plan},
+ {"7", set_plan},
+ {"8", set_plan},
+ {"9", set_plan},
+ {"10", set_plan},
+ {"f1", set_formula},
+ {"f2", set_formula},
+ {"f3", set_formula},
+ {"f4", set_formula},
+ {"f5", set_formula},
+ {"f6", set_formula},
+ {"f7", set_formula},
+ {"f8", set_formula},
+ {"f9", set_formula},
+ {"formula", set_formula},
+ {NULL, NULL}
+};
+
+PRIVATE int set_find(char *var)
+{
+ int i = 0;
+ int gotIt = -1;
+ int len = strlen(var);
+
+ while (variables[i].name) {
+ if (!strncmp(variables[i].name, var, len)) {
+ if (len == strlen(variables[i].name)) {
+ return i;
+ } else if (gotIt >= 0) {
+ return -VAR_AMBIGUOUS;
+ }
+ gotIt = i;
+ }
+ i++;
+ }
+ if (gotIt >= 0) {
+ return gotIt;
+ }
+ return -VAR_NOSUCH;
+}
+
+PUBLIC int var_set(int p, char *var, char *val, int *wh)
+{
+ int which;
+
+ if (!var)
+ return VAR_NOSUCH;
+ if ((which = set_find(var)) < 0) {
+ return -which;
+ }
+ *wh = which;
+ return variables[which].var_func(p, (isdigit(*variables[which].name) ? var : variables[which].name), val);
+}
+
+PUBLIC int com_variables(int p, param_list param)
+{
+ int p1, connected;
+ int i;
+
+ if (param[0].type == TYPE_WORD) {
+ if (!FindPlayer(p, param[0].val.word, &p1, &connected))
+ return COM_OK;
+ } else {
+ p1 = p;
+ connected = 1;
+ }
+
+ pprintf(p, "Variable settings of %s:\n", parray[p1].name);
+/* if (parray[p1].fullName)
+ pprintf(p, " Realname: %s\n", parray[p1].fullName);
+ if (parray[p1].uscfRating)
+ pprintf(p, " USCF: %d\n", parray[p1].uscfRating);
+*/
+ pprintf(p, " time=%-3d inc=%-3d private=%d jprivate=%d Lang=%s\n",
+ parray[p1].d_time, parray[p1].d_inc, parray[p1].private,
+ parray[p1].jprivate, Language(parray[p1].language));
+ pprintf(p, " rated=%d ropen=%d open=%d simopen=%d\n",
+ parray[p1].rated, parray[p1].ropen, parray[p1].open, parray[p1].sopen);
+ pprintf(p, " shout=%d cshout=%d kib=%d tell=%d notifiedby=%d\n",
+ parray[p1].i_shout, parray[p1].i_cshout, parray[p1].i_kibitz, parray[p1].i_tell, parray[p1].notifiedby);
+ pprintf(p, " pin=%d gin=%d style=%-3d flip=%d kiblevel=%d\n",
+ parray[p1].i_login, parray[p1].i_game, parray[p1].style + 1, parray[p1].flip, parray[p1].kiblevel);
+ pprintf(p, " highlight=%d bell=%d auto=%d mailmess=%d pgn=%d\n",
+ parray[p1].highlight, parray[p1].bell, parray[p1].automail, parray[p1].i_mailmess, parray[p1].pgn);
+ pprintf(p, " width=%-3d height=%-3d\n",
+ parray[p1].d_width, parray[p1].d_height);
+ if (parray[p1].prompt && parray[p1].prompt != def_prompt)
+ pprintf(p, " Prompt: %s\n", parray[p1].prompt);
+ if (parray[p1].partner >= 0)
+ pprintf(p, " Bughouse partner: %s\n", parray[parray[p1].partner].name);
+
+#if 0
+ { /* added code to print channels */
+ int count = 0;
+ for (i = 0; i < MAX_CHANNELS; i++) {
+ if (on_channel(i, p1)) {
+ if (!count)
+ pprintf(p, "\n Channels:");
+ pprintf(p, " %d", i);
+ count++;
+ }
+ }
+ if (count)
+ pprintf(p, "\n");
+ }
+#endif /* Now use in [name] */
+/* if (parray[p1].numAlias && (p == p1)) {
+ pprintf(p, "\n Aliases:\n");
+ for (i = 0; i < parray[p1].numAlias; i++) {
+ pprintf(p, " %s %s\n", parray[p1].alias_list[i].comm_name,
+ parray[p1].alias_list[i].alias);
+ }
+ }
+*/
+ if (parray[p1].num_formula) {
+ pprintf(p, "\n");
+ for (i = 0; i < parray[p1].num_formula; i++) {
+ if (parray[p1].formulaLines[i] != NULL)
+ pprintf(p, " f%d: %s\n", i + 1, parray[p1].formulaLines[i]);
+ else
+ pprintf(p, " f%d:\n", i + 1);
+ }
+ }
+ if (parray[p1].formula != NULL)
+ pprintf(p, "\nFormula: %s\n", parray[p1].formula);
+
+ if (!connected)
+ player_remove(p1);
+ return COM_OK;
+}
blob - /dev/null
blob + 41e5a670410d8ae710600a9fab1660671821f937 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/variable.h
+/* variable.h
+ *
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _VARIABLE_H
+#define _VARIABLE_H
+
+typedef struct _var_list {
+ char *name;
+ int (*var_func)();
+} var_list;
+
+#define VAR_OK 0
+#define VAR_NOSUCH 1
+#define VAR_BADVAL 2
+#define VAR_AMBIGUOUS 3
+
+#define LANG_ENGLISH 0
+#define LANG_SPANISH 1
+#define LANG_FRENCH 2
+#define LANG_DANISH 3
+#define NUM_LANGS 4
+
+extern int var_set(int, char *, char *, int *);
+extern int com_time();
+extern int com_inc();
+extern int com_height();
+extern int com_width();
+extern int com_partner();
+extern char *Language();
+
+extern var_list variables[];
+
+extern int com_variables();
+
+#endif /* _VARIABLE_H */
blob - /dev/null
blob + 636233d2246ff79f3ee8bac91f4d9af7b74d1f07 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/variable.o differ
blob - /dev/null
blob + 8ca4633ddbb2722f0ff0725e8d9291010e6847c3 (mode 644)
--- /dev/null
+++ FICS.DIST/FICS/vers.c
+char SGS_VERS[]=""; char VERS_NUM[]="1.6.2"; char COMP_DATE[]="Thu Apr 6 20:31:51 EDT 2023";
blob - /dev/null
blob + df005acbe4ed94f44954f3c16b284a36a920f4e7 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/vers.h
+/* vers.h
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _VERS_H
+#define _VERS_H
+
+extern char SGS_VERS[];
+extern char VERS_NUM[];
+extern char COMP_DATE[];
+
+#endif /* _VERS_H */
blob - /dev/null
blob + df005acbe4ed94f44954f3c16b284a36a920f4e7 (mode 755)
--- /dev/null
+++ FICS.DIST/FICS/vers.h.orig
+/* vers.h
+ */
+
+/*
+ fics - An internet chess server.
+ Copyright (C) 1993 Richard V. Nash
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 2 of the License, or
+ (at your option) any later version.
+
+ This program 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 General Public License for more details.
+*/
+
+/* Revision history:
+ name email yy/mm/dd Change
+ Richard Nash 93/10/22 Created
+*/
+
+#ifndef _VERS_H
+#define _VERS_H
+
+extern char SGS_VERS[];
+extern char VERS_NUM[];
+extern char COMP_DATE[];
+
+#endif /* _VERS_H */
blob - /dev/null
blob + c5241b343daf8ea08aa3df48e4265274cb011775 (mode 644)
Binary files /dev/null and FICS.DIST/FICS/vers.o differ
blob - /dev/null
blob + 2ce1fb82372967c881cb498cbd29c7e3e92dc8e5 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/etiquette
+
+etiquette
+
+ETIQUETA
+
+El objetivo de FICS es proporcionar un medio amistoso para que los
+entusiastas del ajedrez juegen partidas y discutan temas de interes. A fin
+de promover una atmosfera amigable, FICS sigue algunas directrices y
+reglas de etiqueta sencillas. Los administradores de FICS tienen autoridad
+para advertir y, si es necesario, sancionar a los usuarios que violen
+dichas reglas.
+
+Los usuarios de FICS deben evitar hacer cualquier declaracion o comprome-
+terse en cualquier conducta que pueda ser considerada abusiva, ofensiva u
+obscena, especialmente con respecto a la nacionalidad, raza, religion u
+orientacion sexual. Evite que el tener diferencias de opinion se convierta
+en una secuela de ataques personales. Si quiere evitar escuchar las decla-
+raciones hechas por un usuario en particular, utilice el comando "censor".
+
+Los usuarios de FICS deben evitar las conductas abusivas que perjudiquen
+a FICS. Tales conductas incluyen: (a) disconectarse a fin de evitar perder
+una partida de ajedrez; (b) perder intencionalmente una partida a fin de
+inflar el puntaje de otro usuario; (c) usar un computador de ajedrez sin
+haberlo registrado como computador; (d) dejar a otras personas jugar
+partidas validas por puntaje utilizando su cuenta registrada.
+
+Es considerado buen comportamiento sostener las discusiones largas sobre
+un tema o problema particular usando los canales de FICS, en lugar de
+gritar ("shout"). Para este proposito han sido creados canales de topicos
+especiales (el archivo de ayuda "channel" tiene una lista). Puede haber
+ocasiones en las que se le pida que traslade su discusion a un canal.
+
+Vea tambien: abuser admins censor channel computers
+
+[Ultima modificacion: junio 26, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + c81afed9f7f71c8076cfdef67d06e3f38dfbf90a (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/ficsfaq
+
+ficsfaq
+
+PREGUNTAS DE OCURRENCIA FRECUENTE ACERCA DE FICS
+
+
+Los admins de este sitio pueden estar muy ocupados, asi que si usted
+encuentra un error (bug) o tiene preguntas, lea primero este archivo:
+
+1> Como me registro?
+ Lea el archivo de ayuda "register" -- "help register"
+
+2> Que es global (de red) vs. local ?
+ iene que ver con los puntajes distribuidos -- contacte a un admin si se
+ le presenta este error.
+
+3> Puedo tener mas de una cuenta?
+ Solo para jugar a la ciega, con/sin computador, para administrar o para
+ jugar en equipos.
+
+4> Puedo registrar mas de un computador?
+ Si.
+
+5> Puedo tener mas de una persona usando mi direccion electronica?
+ Si.
+
+6> Pueden varias personas compartir una cuenta para juegos en equipos?
+ Si, WEENIES es un ejemplo.
+
+7> Puedo ser un admin?
+ Lea el arcivo de ayuda "admin-new" -- "help admin-new".
+
+8> Puedo ayudar con la programacion?
+ Pregunte a Hawk [uno de los admins de aqui].
+
+9> Quien esta programando?
+ Dan/DAV/foxbat/grimm/hawk/Len/Mann/Shane, etc.
+ Gracias a Friar por algunos archivos de ayuda.
+ Y Cthulu (clong) por la base de datos ECO - proximamente.
+ Gracias a Richard Nash (red) y Michael Moore por el codigo del viejo
+ fics.
+
+10> Donde mas puedo jugar ajedrez GRATIS?
+ anemone.daimi.aau.dk 5000
+ arapaho.cse.ucsc.edu 5000
+ helium.daimi.aau.dk 5000
+ ics.onenet.net 5000
+ pitt.chess.edu 5000
+ Si usted sabe de mas sitios GRATUITOS, cuentenos!
+
+11> De donde consigo una interface?
+ pub/chess en ftp ics.onenet.net (use ftp-anonimo)
+
+12> De donde puedo conseguir el codigo mas reciente?
+ pub/chess/Unix en ftp ics.onenet.net (use ftp-anonimo)
+ Los archivos de ayuda estan en la version mas antigua FICS.tar.gz
+
+13> No me gusta el admin x. El admin y me esta tratando de mala manera.
+ Contacte a Sparky (onenet) y Hawk (helium).
+
+14> Darooha, arcsin y POTZY han venido a llevarse algo. Que hacer?
+ A veces, algunas personas fingen ser ellos.
+ No incurra en comportamiento abusivo contra ellos si entran al FICS.
+ Nuestro codigo es GNU - ellos pueden usar nuestras ideas y codigo en
+ ICC si quieren. Recuerde quien escribio este servidor en primer lugar.
+ [Nota del traductor: GNU es un proyecto del MIT para intercambiar
+ software libremente. Cualquiera puede tomar software de GNU y usarlo
+ como quiera -copiarlo, incorporarlo en sus programas, modificarlo,
+ distribuirlo-, dentro de los limites de la licencia publica de GNU.]
+
+15> Que es ICC?
+ No pregunte -- no hay publicidad gratuita -- usted paga $49 por jugar
+ ajedrez alli. :)
+
+16> Puedo gritar (shout) mensajes sobre ICC?
+ Si, seguro. Dada la eleccion de pagar $49 o $0. Yo elegiria la de $0.
+
+17> Deberia promocionar a FICS?
+ Si, hagalo. Procure sin embargo, no armar un lio en ICC. Si se conecta
+ a ICC, consulte el archivo de anuncios ("help ads"). Recuerde, las
+ hamburguesas Burger King son gratis. :)
+
+18> No puedo gritar (shout) !
+ Ya se ha registrado? Ha sido sancionado?
+
+19> No puedo jugar partidas validas por puntaje.
+ Han colocado usted y su oponente la variable "rated" en 1?
+ Tiene el error global (de red) vs. local?
+
+20> Como uso la cosa "-->Nombre mensaje" que he visto desplegada?
+ Use "it", "i" o ":" seguido del mensaje.
+
+21> Observo que ha resurgido el canal de las hormonas (51).
+ Si, pero solo se permite el uso de lenguaje decente. Este es un
+ servidor familiar. No diga cosas que no diria en frente de ninhos
+ pequenhos. Aunque tal vez si las diga. :)
+
+
+22> El tablero esta invertido (cabeza-abajo).
+ Problema del "flip" en el estilo 12 -- la vieja version de ZIICS y
+ SLICS se ven afectados por ello.
+
+23> No puedo coronar (promover un peon) - xboard -.
+ Intente e7e8 para una dama (reina).
+
+24> Como continuo un juego que fue aplazado?
+ Desafie ("match") al jugador nuevamente, y el servidor reiniciara el
+ juego si su oponente acepta.
+
+25> No puedo enrocar despues de devolver (cancelar) una jugada en la que
+ movi el rey.
+ Lo sabemos.
+
+26> Puedo enrocarme en jaque.
+ Si, sucedio una vez.
+
+27> "takeback" da informacion equivocada sobre la ultima jugada.
+ Un error.
+
+28> "simuls" no funciona.
+ Las simultaneas estuvieron fuera de servico algun tiempo. Deberian
+ funcionar bien ahora.
+
+29> Mi puntaje esta muy alto/bajo.
+ Debe haber un error en alguna parte.
+
+30> +alias/+censor etc. no funcionan.
+ Utilice alias/unalias y censor/uncensor por ahora.
+
+31> Tengo una vieja cuenta aqui, pero no recuerdo mi clave ...
+ Pida ayuda a un admin -- y tenga a mano su direccion electronica.
+
+34> "stats" da informacion inutil.
+ Lo sabemos.
+
+35> Hay variantes "salvajes" ?
+ Si ... y puntajes tambien.
+
+36> Zippy no quiere callarse, y grita mucho.
+ Utilice censor [nombre], cshout (equivalente a sshout en ICC) estara
+ listo proximamente.
+
+37> En cuantos canales puedo estar simultaneamente?
+ En tantos como quiera, pero no demasiados pues ello toma espacio de
+ archivos; teclee "help channel" para ver los canales predefinidos.
+ [Nota del traductor: canal 69 = canal latino; canal 73 = canal
+ espanhol. Con un poco de suerte, a traves de ellos puede obtener ayuda
+ en linea en espanhol].
+
+39> La informacion de "who" no aparece bien alineada.
+ Se arreglara proximamente.
+
+40> Como retiro un desafio ("match") ?
+ Escriba "withdraw".
+
+41> Estoy teniendo "lag" -- que puedo hacer?
+ Intente Ctrl-C para cancelar, o use "adjourn" para aplazar.
+ De otro modo, haga que su oponente le de mas tiempo con "moretime #",
+ donde # <= 600 segundos.
+ [Nota del traductor: "lag" (en espanhol, "demora" o "retardo") es la
+ diferencia entre el momento en que usted ingresa un comando o una
+ jugada y el momento en que el servidor le responde. Es una caracte-
+ ristica normal dentro del estado tecnologico actual de Internet,
+ aunque en algunos dias -y en algunos sitios- es peor que en otros].
+
+42> Repentinamente recibi el mensaje "connection closed".
+ a> Se bajo el servidor (shutdown)
+ b> Se cayo el servidor (crash) -tenganos paciencia-.
+ c> El servidor lo expulso por alguna razon
+ d> Usted armo algun lio
+
+43> Cuando duran los bajones (shutdowns) del servidor, y por que se
+ producen?
+ Alrededor de 10 segundos.
+ A veces necesitamos anhadir nuevo codigo, o corregir errores -por
+ favor, tenganos paciencia.
+
+44> Recibo caracteres no-desplegables / "delete" no funciona.
+ En reparacion.
+
+45> Donde puedo conseguir mas ayuda?
+ Siga estos pasos:
+ (a) Escriba "channel 1"
+ (b) Escriba "tell 1 help me!"
+ (c) Cuando sea suficiente, puede escribir "channel 1" para salir del
+ canal
+ [Nota del traductor: en los canales 69 (latino) y 73 (espanhol) puede
+ recibir ayuda en espanhol]
+
+46> Como detengo un archivo extenso que pasa de largo por mi pantalla?
+ Use Ctrl Q para detenerlo y Ctrl S para proseguir -- o use su barra de
+ "scroll".
+ Tambien "set height ##" determina cuantas lineas deben ser desplegadas
+ al tiempo.
+
blob - /dev/null
blob + cd075113b958dff822b26a6df36076bc7bd8da03 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/interface
+
+interface
+
+En este archivo de ayuda aparecen algunos detalles de las diversas inter-
+faces graficas. A menudo es dificil jugar ajedrez usando los tableros
+ASCII que genera el servidor. No son faciles de ver, y se ven afectados
+por otra informacion tal como los gritos (shouts).
+
+Las interfaces graficas le dan un tablero de ajedrez apropiado en el cual
+ver sus piezas, haciendo su ajedrez mas facil de jugar.
+
+Aqui hay un resumen:
+
+==========================================================================
+Interface Sistema Operativo y Modo Autor de la Localizacion
+Grafica de Conexion Requerido interface en ICL
+==========================================================================
+ZIICS # DOS, modem Zek pub/chess/DOS
+GIICS DOS, modem LLama pub/chess/DOS
+Monarc DOS, modem *Kevster pub/chess/DOS
+JIICS DOS, VGA, modem, mouse Peluri pub/chess/DOS
+NGIICS DOS, TCP/IP LLama pub/chess/DOS
+Raja MS Win3, modem *fischer pub/chess/Win3
+Gilchess MS Win3, modem Bloodrake pub/chess/Win3
+bludrake MS Win3, modem Bloodrake pub/chess/Win3
+SLICS # MS Win3, TCP/IP dfong pub/chess/Win3
+Toolkit ## MS Win3, TCP/IP y/o modem MaDHaTteR pub/chess/Win3
+WinBoard WinNT or W95, TCP/IP y/o mann pub/chess/Win3
+ modem
+PMICS OS/2, TCP/IP y/o modem woof pub/chess/DOS
+XBoard # Unix, X11R4, TCP/IP y/o mann pub/chess/X
+ modem
+xics Unix, X11R3 , TCP/IP *observer pub/chess/X
+cics TCP/IP y C, terminal *observer pub/chess/Unix
+ ASCII
+NeXTICS NeXT, TCP/IP y/o modem red pub/chess/NeXT
+MacICS Mac *douglas pub/chess/Macintosh
+E-ICS Mac, Modem *douglas pub/chess/Macintosh
+MacICS-TCP Mac, TCP/IP eew pub/chess/Macintosh
+Aics Amiga *fischer pub/chess/Amiga
+==========================================================================
+# Recomendado y popular
+## Aun no funciona bien en FICS.
+* No probado en FICS todavia.
+
+NB. Los handles de los autores pueden referirse a los handles de personas
+en el antiguo Aics. Algunos pueden ser de personas diferentes o no existir
+hoy en dia. La mayoria de las interfaces deberian trabajar; tanto los
+autores como los programadores de FICS les gustaria recibir informacion si
+usted tuviera problemas con alguna de ellas aqui.
+
+Mas adelante usted encontrara un listado que explica que interfaces corren
+en una configuracion en particular y en que directorio pueden encontrarse.
+En algunas hay breves comentarios de los usuarios o de los autores de las
+interfaces para ayudarlo a elegir.
+
+Si usted tiene preguntas o problemas ulteriores, por favor contacte a un
+admin.
+
+
+Instrucciones para Obtener una Interface
+----------------------------------------
+
+Cualquiera de las interfaces graficas mencionadas arriba puede encontrarse
+en el sitio ftp-anonimo chess.onenet.net (URL: ftp://chess.onenet.net/).
+La mayoria viene con algunas instrucciones. :-)
+
+Elija una, utilice ftp (help ftp-hints), Netscape o algun software similar
+para acceder a ella por Internet y transfierala a su sistema PC o estacion
+de trabajo local a traves de su metodo preferido (zmodem, kermit para la
+mayoria de conexiones telefonicas distintas de tcp/ip), desempaquetela (la
+mayoria utilizan software de compresion, o son auto-extractables), y por
+ultimo configurela. :-)
+
+
+Comentarios sobre las Interfaces
+--------------------------------
+
+Este listado describe las interfaces en un detalle ligermante mayor, con
+algunos comentarios de los usuarios/autores de las interfaces que pueden
+servir para ayudarlo a elegir.
+
+Si usted tiene preguntas o problemas ulteriores, por favor contacte a un
+admin.
+
+
+PC y compatibles (Usando DOS y modem): pub/chess/DOS
+----------------------------------------------------
+
+ZIICS por Zek:
+ Una muy popular interfce para el PC.
+
+ ZIICS requiere una coneccion normal por modem y un adaptador grafico
+ (VGA, EGA, CGA o Hercules). En VGA hay varios estilos de tableros, desde
+ 32 pixeles por escaque hasta 56 pixeles por escaque (casi llena toda la
+ pantalla verticalmente). Usted puede configurar los colores y las
+ funciones de los botones editando un archivo tipo texto.
+ [comentario de Zek]
+
+GIICS por LLama:
+
+JIICS por Peluri:
+ Necesitara VGA y un mouse para usar esta interface.
+
+Monarc por Kevster:
+
+
+PC y compatibles (Usando DOS y TCP/IP): pub/chess/DOS
+-----------------------------------------------------
+
+NGIICS por LLama:
+
+
+PC y compatibles (Usando Windows y modem): pub/chess/Win3
+---------------------------------------------------------
+
+Raja (elefante) de fischer:
+
+Gilchess por Azorduldu:
+
+bludrake por Bloodrake:
+
+
+PC y compatibles (Usando Windows y TCP/IP): pub/chess/Win3
+----------------------------------------------------------
+
+SLICS por dfong:
+
+Toolkit por MaDHaTteR:
+ Aun no funciona aqui correctamente, pero deberia hacerlo pronto.
+
+
+PC y compatibles (Usando Windows NT (o 95) y TCP/IP): pub/chess/Win3
+--------------------------------------------------------------------
+
+WinBoard por mann:
+ "finger mann" para obtener los ultimos detalles.
+
+
+PC y compatibles (OS/2 PM ): pub/chess/DOS
+------------------------------------------
+
+PMICS por woof:
+
+
+Unix (Xwindows): pub/chess/X
+----------------------------
+
+XBoard por mann:
+ Ciertamente la mejor de las interfaces UNIX, sigue siendo soportada para
+ trabajar aun mejor en FICS. A los usuarios de maquinas UNIX se les reco-
+ mienda ampliamente conseguir esta interface. Tambien es aconsejable para
+ usarla con GNUchess.
+ [comentario de DAV]
+
+ "finger mann" para obtener los ultimos detalles.
+
+xics por observer:
+
+
+Unix (terminal vt100): pub/chess/Unix
+-------------------------------------
+
+cics por observer:
+
+
+NeXT: pub/chess/NeXT
+--------------------
+
+NeXTICS por red:
+
+
+MAC: pub/chess/Macintosh
+------------------------
+
+MacICS por douglas:
+
+
+MAC (Modem): pub/chess/Macintosh
+--------------------------------
+
+E-ICS por douglas:
+
+
+MAC (TCP\IP): pub/chess/Macintosh
+---------------------------------
+
+MacTCP por eew:
+
+
+Amiga: pub/chess/Amiga
+----------------------
+
+Aics por fischer:
+ Podria no trabajar con KS2.0 y anteriores.
+
+Vea tambien: ftp-hints
+
+[Ultima modificacion: junio 16, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + 837b1a99ef3c885cc56f36a4f262401ebc65ac50 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro0
+
+intro0
+
+ B I E N V E N I D O
+
+ al
+
+ S E R V I D O R G R A T U I T O D E A J E D R E Z
+ D E I N T E R N E T (FICS)
+
+
+Hemos creado varios archivos de informacion para usuarios de este servidor
+de ajedrez. Los archivos describen diferentes caracteristicas del servidor
+y le dan algunas sugerencias sobre como esas caracteristicas pueden ayudar
+a disfrutar del ajedrez en internet. Aqui hay un directorio de archivos de
+informacion, con el tema que cubre cada uno:
+
+ Archivo Tema
+ ------- --------------------------------------------------
+ intro1 Informacion General
+ intro2 Comunicacion
+ intro3 Despliegue de Informacion
+ intro4 Definiendo sus Preferencias
+ intro5 Funciones Especiales
+ intro6 Partidas de Ajedrez
+ intro7 Haciendo Jugadas en una Partida de Ajedrez
+
+Para leer la informacion de uno de estos archivos , simplemente escriba
+"help intro#" usando el numero adecuado. Si despues de leer los archivos
+aun tiene preguntas, hay varias cosas que puede hacer. (1) Lea el archivo
+de ayuda del comando sobre el que tenga dudas ; su respuesta podria estar
+alli. (2) Contacte a otros usuarios, especialmente a los administradores
+del servidor (conocidos como "admins"); sus ayudas suelen ser muy utiles.
+
+Para leer un archivo de ayuda teclee "help [tema]", sin los parentesis
+cuadrados. Si el tema es un comando, el archivo de ayuda le dara infor-
+macion acerca del formato para ese comando. Es facil notar que se trata
+de un comando porque la pimera linea describe el formato ( "Uso" ). Las
+palabras en parentesis cuadrados designan parametros opcionales; incluir
+tales parametros afecta el modo en que se procesa el comando. En muchos
+casos un archivo de ayuda sugiere otros que usted seguramente querra leer.
+
+Algunos archivos son mas largos que una pantalla.Para continuar leyendo el
+archivo, teclee "next" o (su alias) "more". Cuantas lineas recibe usted de
+una vez depende del valor de su variable "height".
+
+Sus sugerencias sobre los archivos de informacion (y sobre los archivos de
+ayuda) son bienvenidas. Sientase libre de enviar un mensaje a HelpFiles
+("message helpfiles") con sus comentarios.
+
+Vea tambien: help next variables
+
+[Ultima modificacion: julio 1, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + a29530ce453d8c004cc17d31b91566ee064a0acb (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro1
+
+intro1
+
+INFORMACION GENERAL
+
+
+Internet tiene gran capacidad para conectar gente alrededor del mundo.
+Este servidor de ajedrez es una alternativa para los usuarios de la red
+que disfrutan del ajedrez. Otros servidores de ajedrez ( al menos los que
+nosotros conocemos ) se encuentran en el archivo "address". Entre otras
+cosas, un servidor de ajedrez permite a los usuarios jugar partidas unos
+con otros, asi como comunicarse entre si. El ( computador ) servidor de
+ajedrez esta programado para enviar las movidas y mensajes de cada jugador
+a los usuarios correctos. Tambien mantiene cierta informacion adicional.
+
+A fin de usar sus caracteristicas usted necesita ingresar ciertos co-
+mandos. Para listar dichos comandos escriba "help". Para conseguir una
+descripcion de un comando en particular, escriba "help [comando]" -- sin
+los parentesis cuadrados, por supuesto. NOTA: usted no tiene que escribir
+el comando entero a fin de usarlo o leer su archivo de ayuda; teclear las
+primeras letras funcionara en la mayoria de los casos.
+
+En general, los comandos hacen una de estas cuatro cosas: (a) envian un
+mensaje a uno o mas usuarios (ver intro2), (b) despliegan informacion para
+usted (ver intro3), (c) modifican uno de sus parametros/caracteristicas/
+funciones (ver intro4), o (d) hacen que el servidor realice alguna accion
+especial. Algunos comandos estan permitidos solo a los administradores del
+servidor ("admins") y no pueden ser empleados por los usuarios corrientes.
+
+Los nuevos usuarios podrian querer empezar con caracteristicas simples, y
+gradualmente aprender sobre las otras caracteristicas a medida que van
+avanzando. El servidor permite determinar como se quiere recibir cierta
+informacion. Por ejemplo, usted puede decidir como se muestra una posicion
+en una partida (ver style). Tambien puede fijar sus preferencias sobre los
+tipos de partidas de ajedrez que a usted le gustaria jugar, o los tipos de
+mensajes que recibe de otros (ver variables).
+
+Vea tambien: addresses intro2 intro3 intro4 intro5
+
+[Ultima modificacion: junio 11, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + b997794b4e19eaec0eb1ce67f9c74566bfa6715f (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro2
+
+intro2
+
+COMUNICACION
+
+
+Las comunicaciones entre usuarios son de dos tipos: (a) mensajes, y (b)
+peticiones. Los mensajes involucran basicamente conversaciones entre
+usuarios; el servidor simplemente transmite los mensajes. Las peticiones
+son diferentes por cuanto involucran el que el servidor haga algo acerca
+de o durante una partida de ajedrez.
+
+
+MENSAJES
+
+Suponga que usted quiere decir algo a uno o mas usuarios. Hay varios
+comandos que puede usar:
+
+ comando funcion
+ ------- --------------------------------------------
+ message Enviar a un usuario un mensaje para ser almacenado, aun
+ si el usuario no esta conectado en el momento
+ tell Hablar a un usuario, o a usuarios en un canal
+ xtell Hablar a un usuario, pero permitir la continuacion de la
+ conversacion con otro
+ channel Escuchar los tells enviados a un canal dado
+ say Hablar al usuario con el que usted esta jugando (o con el
+ que acaba de jugar una partida)
+ shout Hablar a todos los usuarios que estan abiertos a los
+ gritos (shouts)
+ cshout Hablar a todos los usuarios que estan abiertos a los
+ gritos (shouts); el mensaje debe ser sobre ajedrez
+ it Una clase especial de grito
+ kibitz Hablar a todos los jugadores y observadores de un juego
+ de ajedrez especifico
+ whisper Hablar a todos los observadores de una partida especifica
+ censor Evita que los mensajes de un usuario dado lleguen a usted
+
+Lea mas acerca de estos comnados en sus propios archivos de ayuda. Pero en
+general, "message" trabaja como una maquina contestadora, "tell" y "say"
+son como conversaciones normales uno-a-uno, "shout", "cshout" e "it" son
+para charlas en grupo y "kibitz" y "whisper" son para comentar una partida
+que se esta observando. Por favor, siga las indicaciones de etiqueta del
+servidor de ajedrez cuando utilice estos comandos.
+
+
+PETICIONES
+
+Los usuarios necesitan ponerse de acuerdo sobre las partidas que van a
+jugar. Tambien necesitan ponerse de acuerdo sobre diversas situaciones
+durante el juego de una partida. Las peticiones sirven como forma de
+alcanzar dichos acuerdos, asi como de realizar la accion acordada. Por
+ejemplo, los usuarios necesitan solicitar el inicio de una partida. Cuando
+ha habido acuerdo sobre las condiciones de juego, el servidor comienza una
+partida entre esos dos usuarios. Durante la misma, un jugador puede
+necesitar aplazarla; si se acuerda el aplazamiento, el servidor detiene el
+juego y lo graba, de modo que pueda ser reiniciado posteriormente. Lea
+intro6 para mas informacion sobre partidas de ajedrez y otras peticiones
+especiales.
+
+AYUDA UTIL: en ocasiones, muchos mensajes de varios usuarios llegaran a su
+pantalla. Para ayudarle a notar cuando un usuario le ha enviado un mensaje
+o solicitud a usted personalmente (en lugar de a todos los usurios de
+FICS), existe una variable llamada highlight que hace dichos mensajes mas
+evidentes (vea highlight).
+
+Vea tambien: etiquette intro6 [y los comandos individuales]
+
+[Ultima modificacion: junio 16, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + 7c813f01664f2238d2dab5980cf56de360c89ffc (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro3
+
+intro3
+
+
+DESPLIEGUE DE INFORMACION
+
+Hay varios comandos que pueden usarse para obtener informacion general:
+
+ comando informacion
+ ------- --------------------------------------------
+ allobservers lista todos los usuarios que observan una partida
+ best despliega los puntajes mas altos alcanzados en los varios
+ tipos de partidas (incluyendo computadores)
+ date fecha actual
+ games informa las partidas que se estan jugando en este momento
+ handle muestra los usuarios registrados con nombres que inician
+ con la letra o letras dadas
+ hbest despliega los puntajes mas altos alcanzados en los varios
+ tipos de partidas (excluyendo computadores)
+ help describe un comando, despliega informacion util, o lista
+ todos los comandos y los temas de los archivos de ayuda
+ alfabeticamente
+ hrank lista los usuarios y sus puntajes dentro del rango de
+ valores especificados (excluyendo computadores)
+ inchannel lista a todos los usuarios que estan escuchando un canal
+ de comunicacion dado
+ info lista los nombres de todos los archivos de ayuda que no
+ se refieren a comandos
+ llogons lista las ultimas 30 conexiones/desconexiones al servidor
+ rank lista los usuarios y puntajes dentro del rango de valores
+ especificado (incluyendo computadores)
+ statistics despliega informacion sobre uso del servidor
+ time hora actual
+ uptime cuanto tiempo ha estado corriendo el servidor desde su
+ ultimo arranque
+ who usuarios actualmente conectados
+
+Otros comandos despliegan informacion sobre usted a otro usuario y/o
+viceversa:
+
+ comando informacion
+ ------- --------------------------------------------
+ assess despliega como los puntajes suyo y de otro usuario
+ cambiarian si ambos jugaran una partida valida por puntos
+ eco despliega informacion sobre la apertura utilizada en una
+ partida
+ finger despliega informacion general sobre un usuario
+ history despliega informacion sobre las partidas recientes de un
+ usuario
+ hrank informa el puesto y puntaje de un jugador (excluyendo los
+ computadores)
+ logons lista las ultimas 10 conexiones de un usuario
+ pending informa las peticiones que han sido hechas a usted o por
+ usted y que todavia no han sido declinadas
+ rank informa el puesto y puntaje de un jugador (incluyendo los
+ computadores)
+ stored lista las partidas almacenadas por un usuario
+ variables despliega la preferencias y parametros actuales de un
+ usuario
+
+Vea tambien: [comandos individuales]
+
+[Ultima modificacion: junio 26, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + e19dfb4e7b5e7bcaa680167a232a818c4cee7549 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro4
+
+intro4
+
+DEFINIENDO SUS PREFERENCIAS
+
+
+Cada usuario tiene desde el comienzo ciertos valores y parametros por
+defecto, pero pueden cambiarse si se desea. Para cambiar los parametros
+se utiliza el comando "set"; usted puede ver sus parametros actuales o los
+de otro usuario, usando el comando "variables".
+
+Algunos parametros afectan la informacion que el servidor le transmitira a
+usted, como las comunicaciones de otros usuarios y las notificaciones de
+partidas que comienzan o de usuarios que llegan o se van. Otros parametros
+afectan las partidas de ajedrez, como los controles de tiempo por defecto,
+el si usted oye o no un timbre cuando se le envia una nueva posicion en el
+tablero, si debe enviarsele automaticamente un listado de las movidas de
+su partida cuando esta termina (o se aplaza), o incluso el formato usado
+para enviarle la posicion del tablero.
+
+Al cambiar estos parametros, usted puede crear la clase de atmosfera que
+le gustaria tener. Los parametros pueden cambiarse en cualquier momento,
+incluso varias veces durante una misma sesion. En su mayoria, los cambios
+que haga en sus parametros seran grabados luego de desconectarse, de modo
+que no tendra que volverlos a cambiar cada vez que ingrese al FICS.
+
+Su clave secreta (password) tambien es un parametro especial, aunque nunca
+se despliega en ninguna parte. Cuando usted se registra, se le asigna una
+clave de ingreso que usted puede cambiar en cualquier momento utilizando
+el comando password.
+
+Finalmente, el servidor le permite crear alias especiales para evitarle el
+teclear frases que usa a menudo. En lugar de escribir toda la frase, lo
+unico que tiene que hacer es teclear el alias.
+
+Vea tambien : aliases password set variables
+
+[Ultima modificacion: junio 16, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + a6c6bba01ddf59805103afe968e79abf14451013 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro5
+
+intro5
+
+FUNCIONES ESPECIALES
+
+
+Hay varios comandos que realizan funciones especiales mas alla de enviar
+mensajes a otros usuarios, desplegar informacion o modificar sus
+parametros. Aqui estan algunos de los mas utiles:
+
+
+ comando funcion
+ ------- --------------------------------------------
+ alias facilita la escritura de frases frecuentemente usadas
+ examine permite analizar un juego
+ mailmoves le envia las jugadas de la partida actual de un usuario
+ mailoldmoves le envia las jugadas de la ultima partida de un usuario
+ oldmoves le permite ver la ultima partida de un usuario
+ smoves despliega las jugadas de una partida guardada
+ sposition despliega la posicion final de una partida guardada
+
+Con el tiempo se iran agregando mas funciones.
+
+Vea tambien: [comandos individuales]
+
+[Ultima modificacion: junio 29, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + fafea36437dd016fd3102dab952c44527c92d22a (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro6
+
+intro6
+
+PARTIDAS DE AJEDREZ
+
+
+El proposito principal de este servidor de ajedrez es reunir usuarios que
+quieran jugar ajedrez. Entre otras cosas, el servidor permite contactar a
+otros usuarios para jugar partidas, valida que todos los movimientos sean
+legales, mantiene la posicion del tablero a medida que transcurre el
+juego, y actualiza los puntajes de los jugadores luego de cada partida.
+
+La manera basica de contactar a un usuario para jugar una partida es a
+traves del comando match. Hay un archivo de ayuda especial para el comando
+match, asi que no iremos en mucho detalle aqui. En seguida hay una lista
+de comandos sobre los que usted puede querer saber algo mas (recuerde que
+las peticiones estan dirigidas a su oponente, no al servidor, y que deben
+ser aceptadas por el para que tengan efecto):
+
+ comando funcion
+ ------- --------------------------------------------
+ match pedir a otro usuario jugar una partida
+ abort pedir que la partida sea cancelada
+ accpet aceptar una peticion de un usuario
+ adjourn pedir que la partida sea detenida y grabada para
+ continuarla en algun otro momento
+ decline declinar una peticion de un usuario
+ draw pedir que la partida sea declarada tablas
+ flag finalizar la partida porque su oponente se quedo sin
+ tiempo
+ moves hacer que FICS le envie las movidas de la partida que
+ usted esta jugando
+ pause pedir que la partida sea suspendida temporalmente, pero
+ sin aplazarla
+ promote decir a que pieza va a ser promovido un peon cuando
+ alcanza la octava fila
+ refresh mostrar la posicion actual del tablero
+ resign terminar la partida, dando a su oponente la victoria
+ say comunicarse con su actual (o ultimo) oponente
+ switch pedir a su oponente cambiar de lado (color)
+ takeback pedir a su oponente devolver (cancelar) una o mas jugadas
+ unpause pedir que una partida detenida con pause sea continuada
+ withdraw cancelar una peticion hecha por usted
+
+Es posible jugar partidas con mas de un usuario al tiempo, a semejanza de
+una exhibicion de simultaneas de un gran torneo de ajedrez. Si usted esta
+interesado en jugar contra otros en partidas simultaneas, lea el archivo
+"simuls".
+
+Vea tambien: match simuls [y los comandos individuales]
+
+[Ultima modificacion: junio 16, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + 9028410e54b92ec9bfe89f142614d706151fc663 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/intro7
+
+intro7
+
+HACIENDO JUGADAS EN UNA PARTIDA DE AJEDREZ
+
+
+Hay dos maneras de hacer jugadas durante una partida. Muchos usuarios
+tienen una interface grafica. En ese caso, el usuario mueve la pieza sobre
+el tablero grafico usando el mouse de su computador, y el software de la
+interface traduce este movimiento en notacion de ajedrez y lo envia al
+servidor para procesamiento. Lea el archivo de informacion de interfaces
+para obtener algunos detalles sobre interfaces graficas.
+
+Si no tiene una interface grafica, necesitara entrar sus jugadas usando un
+teclado. A fin de hacerlo, debe saber que clase de notacion utiliza el
+servidor de ajedrez. Los jugadores de ajedrez utilizan uno de dos sistemas
+notacionales diferentes: descriptivo o algebraico. El servidor entiende el
+algebraico unicamente (aunque tambien es capaz de comprender la version de
+computador de la notacion de ajedrez; ver mas abajo).
+
+En notacion algebraica, cada escaque tiene un unico nombre. Cada fila se
+numera del 1 al 8, siendo la primera fila del lado blanco la numero 1.
+Analogamente, cada columna se etiqueta desde la a hasta la h, siendo la
+primera columna de la izquierda del lado blanco la a. Asi, cada casilla
+tiene un nombre de fila y columna, mencionandose primero el de la columna.
+En notacion algebraica, cada pieza de ajedrez tiene su propio simbolo:
+ k = king = rey;
+ q = queen = reina o dama;
+ b = bishop = alfil;
+ n = knight = caballo;
+ r = rook = torre;
+ p = pawn = peon (aunque la "p" realmente no se utiliza).
+
+Aqui hay una muestra de una posicion de una partida, tal como se ve en el
+estilo 1 que es el estilo por defecto. En este ejemplo, el blanco esta en
+la parte inferior del tablero y el negro en la superior. Los simbolos de
+las piezas estan en letras mayusculas; el "*" significa que la pieza es
+negra.
+
+ ---------------------------------
+ 8 | | *R| | | *R| | *K| |
+ |---+---+---+---+---+---+---+---|
+ 7 | *P| | | *B| *P| *P| *B| *P|
+ |---+---+---+---+---+---+---+---|
+ 6 | | | | | | *N| *P| |
+ |---+---+---+---+---+---+---+---|
+ 5 | *Q| | | *P| | | B | |
+ |---+---+---+---+---+---+---+---|
+ 4 | | | | | | P | | |
+ |---+---+---+---+---+---+---+---|
+ 3 | | | N | B | P | | | |
+ |---+---+---+---+---+---+---+---|
+ 2 | P | P | | | Q | | P | P |
+ |---+---+---+---+---+---+---+---|
+ 1 | | | R | | | R | K | |
+ ---------------------------------
+ a b c d e f g h
+
+El rey negro (*K) esta en el escaque g8; el rey blanco (K) esta en el g1,
+y asi sucesivamente. Le toca mover al negro. Suponga que el negro quiere
+colocar el caballo (*N) en el escaque e4. La movida a entrar en notacion
+algebraica seria Ne4. Mover los peones es mas facil: usted no utiliza la
+"p" para la pieza, sino que simplemente da el escaque al cual el peon se
+va a mover. Suponga que el negro decide mover el peon (*P) del escaque h7
+al h6. La jugada a escribir seria h6. En muchas posiciones del tablero,
+varias piezas iguales (por ejemplo, dos torres o dos caballos) pueden
+moverse a la misma casilla. En este caso, usted debe indicar cual de las
+varias piezas quiere mover. Por ejemplo, suponga que el negro tiene
+caballos en c2 y e2, desde donde ambos pueden moverse a d4. Para mover el
+caballo de c2 a d4 usted podria escribir Ncd4, donde la "c" sirve para
+decir al servidor que caballo mover.
+
+En notacion algebraica, las capturas se denotan generalmente por "x".
+Suponga que el negro quiere capturar el peon blanco de b2 (P) con la torre
+de b8 (*R). El negro ingresaria el movimiento Rxb2. Sin embargo, el
+servidor tambien entenderia el simple Rb2 y comprenderia que hay una
+captura implicita. Asi que, para este servidor, usted puede ingresar la
+casilla en la cual la pieza va a capturar. Para hacer un enroque, utilice
+O-O si es el corto y O-O-O si se trata del largo.
+
+Muchos computadores requieren instrucciones muy explicitas de como mover
+las piezas. Esta notacion de computadores tiene el siguiente formato:
+ casilla_de_salida-casilla_de_llegada
+
+Por ejemplo, en la anterior posicion del tablero, mover la torre negra
+desde b8 hasta b2 se escribiria b8-b2. Nunca se utilizan simbolos para
+las piezas; solo se nombran las casillas. El servidor tambien entiende
+esta notacion de computador.
+
+En resumen, para mover una pieza durante una partida, ingrese la movida.
+Cada vez que usted o su oponente hacen una movida, el servidor actualiza
+la posicion del tablero y envia la nueva posicion tanto a su oponente como
+a usted mismo. Es asi de simple !
+
+Vea tambien: interfaces style
+
+[Ultima modificacion: junio 16, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + e0fedae9a8cffae10b05b2feb0a4ccf6753fdfbd (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/nota_acerca
+
+NOTA ACERCA DE LA TRADUCCION
+
+El espanhol no es un idioma uniforme entre todos los paises hispano-
+parlantes; como cualquier hablante nativo sabe, en Espanha se utilizan
+giros y expresiones virtualmente desconocidos en Hispanoamerica, y
+viceversa; entre los paises de esta ultima, por supuesto, tambien hay
+diferencias de mayor o menor importancia.
+
+A pesar de que en esta traduccion se ha procurado ser "neutral" en ese
+sentido, es seguro que existen sesgos en favor del uso que se da al idioma
+en America, especialmente en los paises andinos (estos sesgos se deben,
+logicamente, a la procedencia del autor de la traduccion: Colombia).
+
+En solo un caso dicho favorecimiento ha sido consciente: en el caso de
+tres terminos relacionados con computadores. Tales terminos son:
+
+ Ingles Traducido como
+
+ file archivo
+ interface interface
+ mouse mouse
+
+Es posible que un hablante espanhol encuentre mas natural traducir "file"
+por "fichero", "interface" por "interfaz" y "mouse" por "raton"; sin
+embargo, el traductor espera que, una vez hecha la aclaracion, la lectura
+de la version traducida no presente mayores dificultades.
+
+Una observacion final sobre acentuacion: a fin de facilitar la difusion de
+este archivo por cualquier tipo de sistema, no se han utilizado caracteres
+acentuados; tampoco se acudio a recursos de uso corriente, como escribir
+en mayUsculas las vocales acentuadas, ni con apo'strofes, por cuanto
+parecia evidente que tales recursos iban a entorpecer, mas que favorecer,
+la lectura del texto. Por tanto, las vocales van sin acentuar, y la letra
+del alfabeto espanhol que va entre la "n" y la "o" (y que aqui hay que
+describir por no poder llamarla por su nombre) se representa por la
+combinacion "nh": "enhe".
+
+ Spike -- julio 3, 1995
+
blob - /dev/null
blob + 917fcf4f4ed11144b07bdb79caacd43542266472 (mode 644)
--- /dev/null
+++ FICS.DIST/data/Spanish/register
+
+register
+
+ *** El registro por email ha sido automatizado! ***
+
+Para obtener una cuenta registrada, envie un mensaje a esta direccion:
+
+ chess@caissa.onenet.net
+
+... y utilice como asunto ("Subject"): "Fics Registration"
+
+Incluya una linea como la siguiente como texto de su mensaje (por favor,
+realice las sustituciones apropiadas como indican los marcadores <>):
+
+ fics_addplayer <seudonimo> "<Nombre Completo>" <edir.> <human|computer>
+
+(donde "edir" es su direccion electronica).
+Aqui hay un ejemplo que registraria a Sparky con su nombre y direccion
+electronica correctas:
+
+ Ej: fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net
+ o: fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net human
+
+
+NOTAS:
+
+(1) El nombre completo TIENE que estar entre comillas (").
+
+(2) Si se trata de una cuenta personal, no es necesario especificar 'human'.
+ Sin embargo, ES OBLIGATORIO usar 'computer' si se esta registrando un
+ computador en FICS (ver el archivo de ayuda "computers").
+
+(3) NO incluya los marcadores <> en su texto. Arriba se utilizaron solo para
+ indicar donde debe colocar informacion.
+
+(4) Por favor diganos si usted es un FM (Fide Master), IM (International
+ Master) o un GM (Grand Master).
+
+Vea tambien: computers
+
+[Ultima modificacion: junio 23, 1995 -- Friar
+ Version en espanhol: julio 3, 1995 -- Spike]
+
blob - /dev/null
blob + fdb6b081d5ddc2511a2e4582bac8a0a05fe4a2ab (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/accounts
+
+accounts
+
+These accounts were created in order to aid admins with their work. They
+shouldn't be used for any other purpose. Some of these accounts have admin
+status.
+
+ adjudicate - an account for adjudication requests
+ Bug - an account for bug reports
+ filter - an account to log filtered sites/reasons for filtering
+ Suggestion - an account for suggestions
+ vacation - an account for admin holiday notification
+ helpfiles - an account for help file updating requests
+
+If you need to use an account but don't know the password, ask an admin who
+does.
+
+[Last modified: December 25, 1995 -- Friar]
+
blob - /dev/null
blob + 80e3011fb8a02322726797de8d64725d8c2c66be (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/addaccounts
+addaccounts
+
+ This help file documents the rules for adding extra accounts for players.
+
+ The file is for the AFICS site, please feel free to modify the contents
+or admin names for your particular site.
+
+Types of account allowed:
+
+ playing account or | only 1 of these allowed per person
+ chatting account or | admins may have one of these in addition
+ playing/chatting account | to their normal account - see below.
+
+ - This is the default registered account.
+
+ blind account - for blindfold chess ONLY!
+
+ - may shout with it, but NOT to be used as
+ - an excuse to abuse/get round quota/get
+ - past censor lists etc.
+
+ - must use style 9 (although may set to
+ - another style to examine afterward)
+
+ team account - for team chess ONLY!
+ - see rules for blind accounts
+
+ - advise player not to let members other
+ - than from his/her site to use it as
+ - is responsible for their behaviour.
+ - this is not a hard fixed rule though.
+
+ computer account or | maximum 1 per player
+ 'cyborg' account | (more if automatic moving)
+
+ - non-automatic computers should NOT be
+ - used as a shouting mechanism (except for
+ - match pairings, greetings etc)
+
+ - A cyborg account is where the player is
+ - using a computer to analyse the moves,
+ - but a human is deciding which one to play.
+ - (can make a very strong player)
+
+ - Useful if computer specifications/house
+ - rules are placed in notes (eg no aborts)
+
+(any problems with the above three - remove immediately and comment the
+ player account)
+
+ admin account - may be used to play/chat
+
+ - advise to get a player account to save
+ - getting questions in the middle of a game
+
+ tester account - admins/programmers only.
+ - maximum of 2 per person (or more if only
+ - for a temporary period)
+
+ helper account - receives messages from players (eg bug)
+
+ - admins only, unless authorised by Sparky
+ - or sveshi (AFICS)
+ - do NOT put passwords in admin help files.
+
+1> Extra admins accounts.
+ Admins can have as many accounts as they wish as long as the above rules
+ are followed.
+
+2> Extra user accounts.
+
+ Must satisfy the following criterea:
+
+
+ 1> Is not currently being sanctioned (eg on abuser list)
+
+ 2> Comment file is clean or nearly clean (check the comments don't
+ assume because someone has more than one comment they have been
+ an abuser). Repeat offenders must be refused additional accounts.
+
+ 3> The player is not known to cause (much) trouble.
+
+ If in doubt please check with sveshi (AFICS) first.
+
+ Must put in comments list of the player applying for it the name and type
+ of account
+
+ Eg. addcomment FishFood DAV's blind account
+
+ Must add in the realname of the account, the handle of the player and what
+ type of account it is.
+
+ Finally add it to a list with +listname [name] if appropriate.
+
+ Do NOT revert an additional account to a player account without good reason
+ (eg old account was destroyed somehow). Check with sveshi (AFICS) if unsure..
+
+See ahelp: accounts, addplayer
+See help: addlist, sublist
+
+[Last modified 11/28/95 - DAV]
blob - /dev/null
blob + faadf3f0bd020ba51aebc8bddfa925a3524328b0 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/addcomment
+
+addcomment
+
+Usage: addcomment user comment
+RESTRICTED TO ADMINISTRATORS.
+
+ Places "comment" in the user's comments. If a user has comments, the number
+of comments is indicated to admins using the "finger" command. The comments
+themselves are displayed by the "showcomments" command.
+
+ Please add comments when action is taken regarding the user's account, such
+as admin actions, changes in settings or even complaints from other users.
+Comments provide a ready source of documentation and reference for all admins
+to review as needed.
+
+See ahelp: finger showcomment
+See help:
+
+[Last modified: September 14, 1995 -- Friar]
+
blob - /dev/null
blob + 6b162fb531cef68b6b62d103807a398242d11d2c (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/addplayer
+
+addplayer
+
+Usage: addplayer playername emailaddress realname
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds a local player to the server with the handle of "playername". For
+example:
+
+ addplayer Hawk u940456@daimi.aau.dk Henrik Gram
+
+If there is no email address, use "none". Settings can be revised using
+asetemail, asethandle ans asetname.
+
+See ahelp: asetemail asethandle asetrealname raisedead remplayer
+See help: register
+
+[Last modified: September 14, 1995 -- Friar]
+
blob - /dev/null
blob + de6887846b44bf4d062406308e71ef54c6c5663d (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/adjud_info
+
+adjud_info
+
+ Games should be adjudicated as a win for a player only if the game is an
+obvious (theoretical) win. For example, (a) K+R vs. K, or (b) up a queen in
+the middlegame. You may also grant a win due to time IF (1) the player
+requests a win on this basis and (2) the conditions (namely clocking settings)
+warrant it.
+
+ If the player seeks a draw, then the game should be dead equal in the
+endgame.
+
+ Abort adjudications are appropriate if the game has lasted only a few moves
+and neither player can speak of an advantage: i.e., 1. d4 d5, 2. c4 c6, 3. Nf3
+could be aborted. Games should *not* be aborted if one side has an advantage.
+For example, 1. d4 d5, 2. c4 e6, 3. c5 should *not* be adjudicated as an
+abort, especially if white wants the abort.
+
+ In rare cases, it might be necessary to adjudicate a game that is in
+progress. These occasions can occur when one opponent is a computer that
+either (a) fails to move, in which case an abort may be granted, or (b)
+continues play in a clearly drawn position, in which case a draw may be
+granted.
+
+ To list games for which adjudications have been requested, type "ahelp
+adjrequests".
+
+See ahelp: adjudicate
+See help: adjudication
+
+[Last modified: September 18, 1995 -- Friar]
+
blob - /dev/null
blob + 57d399cfc80ed3dda3931e00c57fd19520eb7cb0 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/adjudicate
+
+adjudicate
+
+Usage: adjudicate white_player black_player result
+RESTRICTED TO ADMINISTRATORS.
+
+ Adjudicates a game between white_player and black_player. The result is one
+of: abort, draw, white, black. "Abort" cancels the game (no win, loss or
+draw), "white" gives white_player the win, "black" gives black_player the win,
+and "draw" gives a draw. Both white_player and black_player will be notified
+by server messages concerning the adjudication.
+
+ In most cases, the game will be a stored (adjourned) game for which one
+opponent has made an adjudication request. To list games for which
+adjudications have been requested, type "ahelp adjrequests". However, there
+may be occasions when a game in progress needs to be adjudicated online --
+such as when a computer fails to move or cannot accept a draw in a clearly
+drawn position.
+
+ For guidelines about adjudications, see "adjud_info".
+
+See ahelp: adjud_info
+See help: adjourn adjudicate_request stored
+
+[Last modified: September 18, 1995 -- Friar]
+
blob - /dev/null
blob + c4ff054d426395b6788265752bf69b9aa6d08894 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/admin
+
+admin
+
+Usage: admin
+RESTRICTED TO ADMINISTRATORS.
+
+ This command toggles your admin symbol (*) on/off. This symbol appears in
+who listings.
+
+See ahelp:
+See help: who
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + 852a19aeeaa03c2fa8eb6664618757913ff3d334 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/admin_commands
+addcomment
+addplayer
+adjudicate
+ahelp
+admin
+anews
+announce
+annunreg
+asetv
+asetadmin
+asetblitz
+asetemail
+asethandle
+asetlight
+asetpasswd
+asetrealname
+asetstd
+asetwild
+chkip
+chkgame
+chkpl
+chksc
+chkts
+cmuzzle
+cnewsi
+cnewsf
+canewsi
+canewsf
+muzzle
+nuke
+pose
+asetmaxplayers
+quota
+raisedead
+remplayer
+rerank
+showcomment
+shutdown
+summon
blob - /dev/null
blob + bbcd9cef933dc1001e191f481dc3d9e2134e0696 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/admin_hierarchy
+0 "Normal User"
+5 "Authorized Helper Person" (DAV says no, we can't do this. Hmmm!)
+10 "Administrator"
+15 "Help File Librarian/Administrator"
+20 "Master Administrator"
+50 "Master Help File Librarian/Administrator"
+60 "Assistant Super User"
+100 "Super User"
blob - /dev/null
blob + 1dbc9db4ee03880ff7191d6c97d48cd621587782 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/ahelp
+
+ahelp
+
+Usage: ahelp [topic]
+RESTRICTED TO ADMINISTRATORS.
+
+ If a topic is specified, this command prints help on the given administrator
+topic. If topic is omitted, this command lists help files that only admins
+may read.
+
+See ahelp: admin_commands
+See help: admins
+
+[Last modified: July 1, 1995 -- Friar]
+
blob - /dev/null
blob + 6a4d319a44e45266f36cba4056cf515b380466b1 (mode 755)
--- /dev/null
+++ FICS.DIST/data/admin/amotd
+
+This is the admin motd. Type "help motd" to see the user motd.
+
+ Admin command helpfiles are shown by ahelp. Many don't have helpfiles yet.
+ "ahelp admin_commands" gives a list of all the admin commands.
+ Type "anews" for admin news. "anews all" to catch up if you forgot.
+__________________________________________________________________________
blob - /dev/null
blob + 08bf7bb879b33a36a4142d32ff2ffdd879038069 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/anews
+
+anews
+
+Usage: anews [#, all]
+RESTRICTED TO ADMINISTRATORS.
+
+ This command is used to display anews (admin news) entries. The entries are
+numbered. "Anews #" displays that anews item. "Anews all" will display all
+items. Anews items are created by the "canewsi" command with further
+information archived by the "canewsf" command.
+
+See ahelp: canewsf canewsi cnewsf cnewsi
+See help: motd_help news
+
+[Last modified: September 14, 1995 -- Friar]
+
blob - /dev/null
blob + dd9fa7500bb67f76c3fa77ecf105437cca0a1916 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/announce
+
+announce
+
+Usage: announce message
+RESTRICTED TO ADMINISTRATORS.
+
+ Broadcasts your message to all logged on users. Announcements reach all
+users and cannot be censored in any way (such as by "set shout 0").
+
+See ahelp: annunreg
+See help: shout
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + d468b45df87c6a9f99d54b419f21238ed3ac1bb0 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/annunreg
+
+annunreg
+
+Usage: annunreg message
+RESTRICTED TO ADMINISTRATORS.
+
+ Broadcasts your message to all logged on unregistered users, and admins,
+too. Announcements reach all unregistered users and admins and cannot be
+censored in any way (such as by "set shout 0").
+
+See ahelp: announce
+See help: shout
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + f199b16a35c38b2237462d66d0a45fe706a15af6 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetadmin
+
+asetadmin
+
+Usage: asetadmin player AdminLevel
+RESTRICTED TO ADMINISTRATORS.
+
+ Sets the admin level of the player with the following restrictions.
+ 1. You can only set the admin level of players lower than yourself.
+ 2. You can only set the admin level to a level that is lower than
+ yourself.
+
+ Levels
+ ------
+ 0 - Normal user. Almost everyone is admin level 0.
+ 10 - Administrator. This level allows you to execute administrator
+ commands.
+ 20 - Master Administrator. Allows you to make and break
+ administrators.
+ 100 - God. You can do anything.
+
+See ahelp: admin-hierarchy
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + e1112a861de22e614a28d020f6131f8475a80ff9 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetblitz
+
+asetblitz
+
+Usage: asetblitz handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for Blitz games. The
+parameters are self-explanatory: rating, # of wins, # of losses, # of draws,
+and ratings deviation.
+
+See ahelp: asetstd asetwild
+See help: glicko ratings
+
+[Last modified: July 17, 1995 -- Friar]
+
blob - /dev/null
blob + c1e580036653af15d2859bb430f89ca156b6e6d7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetemail
+
+asetemail
+
+Usage: asetemail player [address]
+RESTRICTED TO ADMINISTRATORS.
+
+ Sets the email address of the player to the address given. If the address
+is omited, then the player's email address is cleared. The person's email
+address is revealed to them when they use the "finger" command, but no other
+users -- except admins -- will have another player's email address displayed.
+
+See ahelp: finger
+See help: finger
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + cfb324a982461d0004bb66be26496563414e94d4 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asethandle
+
+asethandle
+
+Usage: asethandle oldname newname
+RESTRICTED TO ADMINISTRATORS.
+
+ This command changes the handle of the player from oldname to newname. The
+various player information, messages, logins, comments and games should be
+automatically transferred to the new account.
+
+See ahelp: asetpasswd
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + 97f795f0f2d587649bdc4a4b28a86b769da1c7c9 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetmaxplayer
+
+asetmaxplayer
+
+Usage: asetmaxplayer [n]
+RESTRICTED TO ADMINISTRATORS.
+
+ With an argument, this command raises or lowers the level at which logons
+from non-admins will be filtered. If an argument is supplied, it is checked
+to make sure it is both within the limits of the operating system and at least
+minimally safe. Without an argument, the command displays detailed
+information about the current limits.
+
+ The greater of max_connections-50 and 200 is a threshhold for triggering
+guest login restrictions. When the number of non-admin users is above that
+value, unregistered logins are turned away with a nice message.
+
+See ahelp:
+See help: limits
+
+[Last modified: October 9, 1995 -- Friar]
+
blob - /dev/null
blob + 7485e16bac8248d73c094890de0cd04cedecc7c1 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetpasswd
+
+asetpasswd
+
+Usage: asetpasswd player {password,*}
+RESTRICTED TO ADMINISTRATORS.
+
+ This command sets the password of the player to the password given. If '*'
+is specified then the player's account is locked, and no password will work
+until a new one is set by asetpasswd..
+
+ If the player is connected, he is told of the new password and the name of
+the admin who changed it, or likewise of his account status. An email message
+is mailed to the player's email address as well.
+
+See ahelp:
+See help: password
+
+[Last modified: July 1, 1995 -- Friar]
+
blob - /dev/null
blob + 10aa74cad0c0ac6bdaecfde66bf6693f8554607e (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetrealname
+
+asetrealname
+
+Usage: asetrealname user newname
+RESTRICTED TO ADMINISTRATORS.
+
+ This command sets the user's real name (as displayed to admins on finger
+notes) to "newname".
+
+See ahelp: finger
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + 2fa308083b3c38e66175c4d4b6d9a95f8e58fcaa (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetstd
+
+asetstd
+
+Usage: asetstd handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for Standard games.
+The parameters are self-explanatory: rating, # of wins, # of losses, # of
+draws, and ratings deviation.
+
+See ahelp: asetblitz asetwild
+See help: glicko ratings
+
+[Last modified: July 17, 1995 -- Friar]
+
blob - /dev/null
blob + b34106845261ea5d91aa4a2b7ea807257d727461 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetv
+
+asetv
+
+Usage: asetv user instruction
+RESTRICTED TO ADMINISTRATORS.
+
+ This command executes "set" instructions as if they had been made by the
+user indicated. For example, "asetv DAV shout 0" would set DAV's shout
+variable to 0.
+
+See ahelp: pose
+See help: set variables
+
+[Last modified: October 1, 1995 -- Friar]
+
blob - /dev/null
blob + daf28a781e3f13a9533db6595fba31e6bd8aa51b (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/asetwild
+
+asetwild
+
+Usage: asetwild handle rating won lost drew RD
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows admins to set a user's statistics for Wild games. The
+parameters are self-explanatory: rating, # of wins, # of losses, # of draws,
+and ratings deviation.
+
+See ahelp: asetblitz asetstd
+See help: glicko ratings
+
+[Last modified: July 17, 1995 -- Friar]
+
blob - /dev/null
blob + 819407fee266daa0e47fd346ca39fb31998391b4 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/ban
+
+ban
+
+Usage: [+,-,=]ban handle
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds to (+ban), removes from (-ban) or lists users on (=ban) the ban list.
+Users on the ban list cannot log onto the server. The user's account will
+still be active, however. As a result, autoregistration will screen out the
+user's email address and prevent additional accounts from being created from
+there, and the handle cannot be adopted by another user.
+
+ When you ban (or unban) a user, please leave a message in the player's
+comments file using the "addcom" command. You may also want to lock the
+account by "asetpasswd handle *".
+
+ Concerning when to ban a user, please refer to the admin guidelines that
+have been developed. See also help files on server conduct, such as abuser,
+etiquette and shout_abuse. It is also best to consult without admins abut the
+case in question. Documentation of user behavior is important.
+
+See ahelp: addcom asetpasswd filter
+See help: abuser etiquette lists shout_abuse showlists
+
+[Last modified: October 16, 1995 -- Friar]
+
blob - /dev/null
blob + fa2acd049dd8b869ef8a0fa210ef9a1c48eeefc3 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/buglist
+FICS bugs as of 7/22/95:
+
+The bugs followed by a (?) are not verified. They could be caused
+by some operator error or other anomoly. After verification by a
+few admins that they do not exist, they will be removed from the list.
+
+FIXED If you are observing a game and type moves it says that you are
+ not playing, observing, or examining a game.
+
+2. The ratings system needs to be verified for accuracy. Several
+ people have reported discrepencies. (E.g. According to the
+ formulas, RD can increase only due to the passage of time,
+ never because of playing a game. Yet sometimes people who
+ have just played play again and their RD increases. According
+ to Glickman, this must be a bug. (Courtesy fritzl))
+
+3. Draw by repetition being claim even though a position only came up
+ on time. (?)
+
+FIXED Some people stay logged into channels and notify lists even though
+ they are not logged in.
+
+FIXED Private games can be watched by repeated typing refresh.
+
+6. When challanged to a wild 5 game, after accepting, it becomes a
+ wild 0 game. Reported several times. (?)
+
+7. An ambiguity in the move list occurs when two rooks can capture on
+ the same square. (?)
+
+8. The width variable is not considered in who. Some reports even say
+ that it is not considered at all.
+
+9. History recognizes a stalemate as a win for the person who stalemated. (?)
+
+10. When you want to log in as an unregistered user, if you first choose
+ a handle which is already registered, the server tells you to hit
+ return and try again. But it doesn't let you try again! It
+ disconnects you instead.
+
+11. When loading a 2 12 rated game on move 19, an unrated untimed game
+ on move 1 comes up. (?)
+
+FIXED Even if kibitz is set to 0, you still hear kibitzes.
+
+13. The time and date that is sent with mailmoves is wrong. (?)
+
+FIXED When you offer an abort, your opponent is not told to type abort
+ to accept.
+
+15. Unregistered players can set stats and make notify lists and keep
+ a history, from login to login!
+
+16. Before the game the server reports "your new RD is x." However, after
+ the game, x does not correspond with your new RD.
+
+17. When someone makes the move "bc3" the server needs to check for Bishop
+ captures c3 or Pawn captures c3.
+
+FIXED Wins can be awarded on time even if there are no pieces left. (?)
+
+19. There are discrepencies in the 'assess' command's predictions. (?)
+
+FIXED Wild5 reverses the players ratings in the match challenge. (?)
+ (Has been report for other games too.)
+
+21. After mailing old moves, the server claims "No such game," but it
+ still mails the moves. (?)
+
+22. Someone sends a draw offer and then they move, which causes the
+ server to decline the draw. Then the person types decline
+ and it sends another draw offer. (?)
+
+23. When a player has two adjourned games, the 'accept' command tried to
+ load the other. The players are unable to play each other. (See
+ pdeck Jun 7) (?)
+
+24. A player cannot play 0 8 (or any other increment) because it parses as
+ untimed. (?)
+
+25. When a player is challenged to a normal match, and then a wild match by
+ a different person, if the normal game is accepted, the game becomes
+ a wild match with the person who challenged to the normal game. (?)
+
+26. If a player has been idle for example for 2:30 (2 hours 30 minutes),
+ when someone tells something to that person it says the player has
+ been idle for only 30 minutes (not 2:30).
+
+FIXED If you do 'sa' for say, it tries to simabort instead.
+
+28. With auto=1, drawn games are not sent. (?)
+
+[Last Modified: July 22, 1995 -- Marsalis]
+
+
blob - /dev/null
blob + 00dfe4bbe70e8ad0fa03d8bd3b08b7fd50f68099 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/canewsf
+
+canewsf
+
+Usage: canewsf # message
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows you to add additional information about an anews item
+that had previously been created using 'canewsi'. The '#' is the number of
+the news index and 'message' is the additional text. You can also modify a
+previous anews item description and thus update the anews item easily.
+
+See ahelp: canewsi
+See help: anews
+
+[Last modified: September 14, 1995 -- Friar]
+
blob - /dev/null
blob + 1d2a963b1f8ac58c319a55babe08b644b80b984b (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/canewsi
+
+canewsi
+
+Usage: canewsi message
+RESTRICTED TO ADMINISTRATORS.
+
+ This command adds a new item to the anews index. The message is limited to
+45 characters for formating purposes. In essence, the anews index works like
+a newspaper headline, giving admins enough information to know whether they
+should read the entire anews file for that item. A list of recent anews items
+is displayed by the 'anews' command.
+
+ After creating the anews item, the command reports the anews item number
+along with a reminder to create an anews file if necessary. This command
+replaced the 'createanews' command.
+
+See ahelp: canewsf
+See help: anews
+
+[Last modified: September 14, 1995 -- Friar]
+
blob - /dev/null
blob + 9dc2bb61219b61875a1174f4735d2190892b2ba7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/chkgame
+
+chkgame
+
+Usage: chkgame #
+RESTRICTED TO ADMINISTRATORS.
+
+ This command is a debugging tool primarlity, but might be useful for other
+occasions as well. The following information on a game is displayed:
+
+Current stored info for game # (garray[#]):
+Initial white time: # Initial white increment #
+Initial black time: # Initial black increment #
+Time of starting: DATE
+Game is: User1 (rating) vs. User2 (rating)
+White parray entry: # Black parray entry #
+Game is not bughouse or link to partner's game not found.
+ [versus bughouse links exist]
+Game is rated [or unrated]
+Game is not private [or is private]
+Games is of type blitz [or other type]
+## halfmove(s) have been made
+White's time # Black's time #
+The clock is [is not] ticking
+Game status: GAME_NEW [versus GAME_EXAMINE for instance]
+
+See ahelp:
+See help: games
+
+[Last modified: December 25, 1995 -- Friar]
+
blob - /dev/null
blob + 093c7c103c383277fa07407a57de94713833866d (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/chkip
+
+chkip
+
+Usage: chkip ip_address
+RESTRICTED TO ADMINISTRATORS.
+
+ This command returns the names and IPs of all users currently logged on from
+a given IP address. You can use the '*' wildcard in this command. For
+example:
+
+ chkip 129.1.*
+
+will give all users with IP's beginning with "129.1.1".
+
+See ahelp:
+See help:
+
+[Last modified: October 8, 1995 -- Friar]
+
blob - /dev/null
blob + d524cdc715e4c9eaca3b781b396b29d67cdb5e27 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/chkpl
+
+chkpl
+
+Usage: chkpl handle
+RESTRICTED TO ADMINISTRATORS.
+
+ This command displays server information about a given user. Items
+displayed are:
+
+ number X in parray of size Y
+ name
+ login
+ fullName
+ emailAddress
+ socket
+ registered
+ last_tell
+ last_channel
+ logon_time
+ adminLevel
+ muzzled
+ cmuzzled
+ network_player
+ thisHost
+ lastHost
+ num_notify
+ num_comments
+
+See ahelp: chkip
+See help: finger
+
+[Last modified: October 8, 1995 -- Friar]
+
blob - /dev/null
blob + 5bdc052842f9a6d4975e73658b0314a317ac0bc7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/chksc
+
+chksc
+
+Usage: chksc n
+RESTRICTED TO ADMINISTRATORS.
+
+ Shows which user is logged on to socket n.
+
+See ahelp:
+See help:
+
+[Last modified: October 11, 1995 -- Friar]
+
blob - /dev/null
blob + ae91d22d2ca2c4e4caebec9c51986136807cbde2 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/chkts
+
+chkts
+
+Usage: chkts
+RESTRICTED TO ADMINISTRATORS.
+
+ This command displays all current users who are using timeseal.
+
+See ahelp:
+See help: timeseal
+
+[Last modified: August 20, 1995 -- Friar]
+
blob - /dev/null
blob + fed8131989331873c388bca156ae10cf791d3c12 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/cmuzzle
+
+cmuzzle
+
+Usage: [=,-,=]cmuzzle
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds to (+cmuzzle), removes from (-cmuzzle) or lists users on (=cmuzzle) the
+cmuzzle list. Users on the cmuzzle list cannot use "cshout". Other forms of
+communication are not affected.
+
+ When you cmuzzle (or uncmuzzle) a user, please leave a message in the
+player's comments file using the "addcom" command. Documentation of user
+behavior is important.
+
+ Concerning when to cmuzzle a user, please refer to the admin guidelines that
+have been developed. See also help files on server conduct, such as abuser,
+etiquette and shout_abuse.
+
+See ahelp: addcom muzzle
+See help: etiquette lists shout shout_abuse
+
+[Last modified: October 16, 1995 -- Friar]
+
blob - /dev/null
blob + 54487b7701aa6bf30cdef6a6b58284f13e41f41a (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/cnewsf
+
+cnewsf
+
+Usage: cnewsf # message
+RESTRICTED TO ADMINISTRATORS.
+
+ This command allows you to add additional information about a news item
+that had previously been created using 'cnewsi'. The '#' is the number of the
+news index and 'message' is the additional text. You can also modify a
+previous news item description and thus update the news item easily.
+
+See ahelp: cnewsi
+See help: news
+
+[Last modified: August 20, 1995 -- Friar]
+
blob - /dev/null
blob + 5d7dad2b620d24849b595465eba4225b69143d59 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/cnewsi
+
+cnewsi
+
+Usage: cnewsi message
+RESTRICTED TO ADMINISTRATORS.
+
+ This command adds a new item to the news index. The message is limited to
+45 characters for formating purposes. In essence, the news index works like a
+newspaper headline, giving the user enough information to know whether they
+should read the entire news file for that item. After creating the news item,
+the command reports the news item number along with a reminder to create a
+news file if necessary. This command replaced the 'createnews' command.
+
+See ahelp: cnewsf
+See help: news
+
+[Last modified: August 20, 1995 -- Friar]
+
blob - /dev/null
blob + 0f279de9e4a4e1582045d1eaf94ca0493a6e585c (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/createanews
+
+createanews
+
+ This command has been superceded by the canewsi and canewsf commands.
+Please review those help files.
+
+See ahelp: anews canewsi canewsf
+See help: news
+
+[Last modified: September 14, 1995 -- Friar]
+
blob - /dev/null
blob + 833d7a091188a22daaabaa34825395611251c93f (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/filter
+
+filter
+
+Usage: [+,-,=]filter ip
+RESTRICTED TO ADMINISTRATORS.
+
+
+ This list bans unreg logins from a site where "ip" is a full or partial ip
+address. The number of levels in the "ip" affects how much filtering is made.
+An "ip" of 123.124.125.126 will ban a machine, 123.124.125 will ban the
+server, and 123.124 will probably ban the whole site. A special account has
+been established for documenting the need to filter logins: "filter".
+
+ When you filter a site, please leave a message in the filter account:
+"message filter <explanation>". To read the log of messages in this account,
+type "ahelp filtered".
+
+See ahelp: accounts lists
+See help:
+
+[Last modified: July 16, 1995 -- Friar]
+
blob - /dev/null
blob + 78f0d1e38d03e21038c882887f91756d98a43292 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/finger
+
+finger
+
+ Private, confidential information about a user is revealed to admins when
+they use the "finger" command. This information includes the player's real
+name, email address and whether the player has any comments attached to
+his/her account.
+
+See ahelp: showcomment
+See help: finger
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + 30e57f10e8d072d8d860f00e76cca0ac73695b9c (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/lists
+
+lists
+
+RESTRICTED TO ADMINISTRATORS.
+
+ There are several lists restricted to admin use. They are:
+
+ abuser for users who have abused server etiquette
+ cmuzzle prevents user from using cshouts
+ computer identifies user as a computer
+ filter prevents unreg logons from certain sites
+ fm adds FM label to a user
+ gm adds GM label to a user
+ im adds IM label to a user
+ muzzle prevents user from using shouts
+ quota limits frequency of a user's shouts
+
+ To add a user to one of these lists, use "+list_name". To remove a user,
+use "-list_name". And "=list_name" lists users on that list. For most lists,
+comments are automatically added to the user's file, and you may want to add
+one of your own comments as well in order to record your action and reasons.
+
+ Some lists are private, for admin reading only. Some can be read by all
+users. The "showlists" help file gives the security level for the lists.
+
+See ahelp: cmuzzle filter muzzle quota
+See help: abuser etiquette showlists
+
+[Last modified: June 26, 1995 -- Friar]
+
blob - /dev/null
blob + fe59becc0a79dbb2aec1e12bbd4a6e3310b0550a (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/muzzle
+
+muzzle
+
+Usage: [=,-,=]muzzle
+RESTRICTED TO ADMINISTRATORS.
+
+ Adds to (+muzzle), removes from (-muzzle) or lists users on (=muzzle) the
+muzzle list. Users on the muzzle list cannot use "shout" or "it". They can,
+however, use "tell" (including tells to channels).
+
+ When you muzzle (or unmuzzle) a user, please leave a message in the player's
+comments file using the "addcom" command. Documentation of user behavior is
+important.
+
+ Concerning when to muzzle a user, please refer to the admin guidelines that
+have been developed. See also help files on server conduct, such as abuser,
+etiquette and shout_abuse.
+
+See ahelp: addcom cmuzzle
+See help: etiquette lists shout shout_abuse
+
+[Last modified: October 16, 1995 -- Friar]
+
blob - /dev/null
blob + f51fe2e1135738b7412b533d0d60f88c1d34aa35 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/nuke
+
+nuke
+
+Usage: nuke user
+RESTRICTED TO ADMINISTRATORS.
+
+ This command disconnects the user from the server. The user is informed
+that she/he has been nuked by the admin named and a comment is automatically
+placed in the user's files (if she/he is a registered user, of course). Do
+not nuke someone for fun!
+
+See ahelp:
+See help: etiquette shout_abuse
+
+[Last modified: July 1, 1995 -- Friar]
+
blob - /dev/null
blob + 1ac9b8ab27bb2bc43d3b0cb041ccdb9741074de7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/pose
+
+pose
+
+Usage: pose user command
+RESTRICTED TO ADMINISTRATORS -- Super Users ONLY!!!
+
+ Executes 'command' as if it were typed by 'user'. This command goes beyond
+the "asetv" command because "asetv" relates only to variable settings while
+"pose" relates to ALL commands a user might execute.
+
+See ahelp: asetv
+See help:
+
+[Last modified: October 1, 1995 -- Friar]
+
blob - /dev/null
blob + 967a0df8b2cd0acf84a9d2a6c14421660ff4e102 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/projects
+Projects for FICS:
+
+Big projects:
+
+1. Set up commands for examine mode; allow examiners to add or remove pieces
+ to or from a position. Also allow users to clear the board except for
+ kings.
+
+2. Network many servers together.
+
+
+Medium projects:
+
+3. Rank information in RAM. UpdateRank takes too long.
+
+
+Smaller projects:
+
+4. Channel names (like "admin channel") instead of channel numbers
+ ("channel 0"). If we do this, I think we could seriously consider
+ eliminating the "shout" and "it" commands.
+
+5. Draw offers and aborts for adjourned games.
+
+6. On line registration. I don't see any reason not to allow this now that
+ we also have autoreg by e-mail.
+
+7. Apparently some limits are not checked; MAX_CHANNEL, MAX_ALIAS, probably
+ some others as well. We should fix this.
+
+Well, these are my immediate thoughts; feel free to add your own, or to
+program these.
+
+[Last modified: November 16, 1995 -- hersco]
+
blob - /dev/null
blob + cbf847de35869fb638b968bac5b4f440d7f443dc (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/quota
+
+quota
+
+Usage: quota [n]
+RESTRICTED TO ADMINISTRATORS.
+
+ The command sets the number of seconds (n) for the shout quota, which
+affects only those persons on the shout quota list. If no parameter (n) is
+given, the current setting is displayed.
+
+See ahelp: lists
+See help: it shout shout_abuse shout_quota
+
+[Last modified: June 23, 1995 -- Friar]
+
blob - /dev/null
blob + 6274371c342768df62dbf72fdfad11836177b472 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/raisedead
+
+raisedead
+
+Usage: raisedead oldname [newname]
+RESTRICTED TO ADMINISTRATORS
+
+ Restores an account that has been previously removed using "remplayer".
+The zombie files from which it came are removed. Under most circumstances,
+you restore the account to the same handle it had before (oldname). However,
+in some circumstances you may need to restore the account to a different
+handle, in which case you include "newname" as the new handle. After
+"raisedead", you may need to use the "asetpasswd" command to get the player
+started again as a registered user, especially if the account had been locked
+by setting the password to *.
+
+See ahelp: addplayer asethandle asetpasswd remplayer
+See help:
+
+[Last modified: July 1, 1995 -- Friar]
+
blob - /dev/null
blob + bd90ec7188e198705bd7ce0f58ad3081b51f28cb (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/register
+
+register
+
+
+ *** Email registration is now automated! ***
+
+
+To get a registered account, send a message to this address:
+
+ chess@caissa.onenet.net
+
+... and use as the Subject: "Fics Registration"
+
+Include a line like the following as the text of your message (please make the
+appropriate substitutions as indicated by the <>'s markers):
+
+ fics_addplayer <handle> "<First M. Last>" <email-address> <human|computer>
+
+Here is an example which would register Sparky with the correct name and email
+information:
+
+ Ex: fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net
+ or: fics_addplayer Sparky "Chris L. Petroff" chris@onenet.net human
+
+
+SPECIAL NOTES:
+
+(1) Quotation marks MUST be used around the name field.
+
+(2) If this is a human account, 'human' need not be specified. However,
+ 'computer' MUST be used if you are registering a computer on FICS (see
+ "computers" help file).
+
+(3) Do NOT include the <>'s markers in your text. They are used above only
+ to indicate where you need to place information.
+
+(4) Please tell us if you are an FM, IM or GM (master's titles for
+ international competition).
+
+
+See Also: computers
+
+[Last modified: June 23, 1995 -- Friar]
\ No newline at end of file
blob - /dev/null
blob + 0356697619e0948ae7bc79b8f48e132936cb8131 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/remplayer
+
+remplayer
+
+Usage: remplayer name
+RESTRICTED TO ADMINISTRATORS.
+
+ Removes an account. A copy of its files are saved under .rem.* which can
+be found in the appropriate directory (useful in case of an accident).
+
+ The account's details, messages, games and logons are all saved as 'zombie'
+files. These zombie accounts are not listed in handles or totals. Although a
+handle may have been removed, it is not possible for another user to register
+with this handle -OR- to register for a new account using email registration.
+The autoregister program checks for regular as well as remplayered accounts.
+
+ Please do not use this command unless necessary, such as for multiple
+accounts or inappropriate handles. To stop a player from having access to an
+account, it may be preferable to use the "asetpasswd" command instead.
+
+See also: addplayer asetpasswd raisedead
+
+[Last modified: October 17, 1995 -- Friar]
+
blob - /dev/null
blob + 0b4ea93138d5d010798f75bed1bd185d12d5f102 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/rerank
+
+rerank
+
+Usage: rerank name
+RESTRICTED TO ADMINISTRATORS.
+
+ Use this command to reset a player's rank if there has been a calculation
+error.
+
+See ahelp:
+See help: best hbest hrank rank
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + f9234737f12a5e0fd7406a54e8283a5c65d5f7bc (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/server_com
+
+SERVER COMMANDS [taken from ONENET chess site]
+
+ The following text is displayed when you telnet to ics.onenet.net and log in
+through the admin doorway.
+
+/~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~\
+| It's BACK!! ;-> Sveshi's Power-Admin command set: Commands now defined: |
+| |
+| 'ckemail' - search for anything you like in the address database. |
+| (will show matches for any part of email, realname) |
+| 'ckname' - search for A NAME (two words) in the address database. |
+| 'cklog' - search connect log for a player. |
+| 'host' - Tells you an alpha host name from the numeric. |
+| 'players' - gives last 24 autoregister attempts. |
+| 'uscf' - Searches for the USCF rating of a person (two words) |
+| 'fide' - Searches for the ELO rating of a person (two words) |
+| 'icswho' - Print name and email info for a player handle |
+| |
+~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
+
+Friar's notes
+-------------
+ The commands are typed at the server prompt. They may come in handy when
+trying to verify certain user information or dealing with problem situations,
+such as duplicate accounts or whether a user is a titled chess master.
+
+
+Usage Result
+______________________ _____________________________________________
+
+ckemail string Hits for 'string' in address database
+ckname name1 name2 Hits for 'name1 name2' in address database
+cklog user_handle Lists connect log for user_handle
+host ip_number Provides alpha name for IP address
+players Lists last 24 autoregister attempts
+uscf name1 name2 USCF rating for 'name1 name 2'
+fide name1 name2 FIDE rating for 'name1 name 2'
+icswho user_handle Real_name and email address for user_handle
+
+[Last update: September 24, 1995 -- Friar]
blob - /dev/null
blob + 2572caa44b3c5688a19c35e938396e0734478c5e (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/showcomment
+
+showcomment
+
+Usage: showcomment user
+RESTRICTED TO ADMINISTRATORS.
+
+ This command will display all of the comments added to the user's account.
+
+See ahelp: addcomment
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + a68a8e59de7a720619cdc8f78e79da8087ceea78 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/shutdown
+
+shutdown
+
+Usage: shutdown [now,cancel,time,die] [comment]
+RESTRICTED TO ADMINISTRATORS.
+
+ This command shuts down the server, but with different consequences. If the
+parameter is omitted or is 'now' then the server is immediately halted cleanly
+(including games being saved). If a time is given then a countdown commences
+and the server is halted when time is up; "time" is given in seconds (not
+minutes). If 'cancel' is given then the countdown is stopped. If the
+parameter is 'die', the server will be halted immediately without saving
+games; this version can be useful for debugging purposes, but users will need
+to be warned in advance because the consequences differ from a normal,
+announced shutdown.
+
+ You can add an optional comment to this command. If there is a comment, it
+will be displayed to users each time the countdown is updated. Having a
+comment is a useful way to explain the reason for the shutdown and cut down on
+the number of questions admins will have to answer about the shutdown.
+
+ Using "announce" may be useful during a coutdown so that users can be
+informed of special information, such as how long the shutdown will last.
+
+See ahelp: announce
+See help:
+
+[Last modified: December 25, 1995 -- Friar]
+
blob - /dev/null
blob + 4845e339d8026143fe2d2d8ec68e8db26dd9ef30 (mode 644)
--- /dev/null
+++ FICS.DIST/data/admin/summon
+
+summon
+
+Usage: summon player
+RESTRICTED TO ADMINISTRATORS.
+
+ This command gives a beep and a message to the player indicating that you
+want to talk with him/her. The command is useful for waking someone up, for
+example a sleepy admin or an ignorant player.
+
+See ahelp:
+See help:
+
+[Last modified: June 22, 1995 -- Friar]
+
blob - /dev/null
blob + cf0acfa357b200a16aab87b400dfa4d20d003082 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/deflection-79
+W: Kg1 Qc2 Rc8 Bg2 Ne4 Pa6 d4 g3
+B: Kh7 Qf5 Rb4 Re7 Pg7 h6
blob - /dev/null
blob + 8350d888c2f692d822c446ca54e101f4d0f7895f (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/discovery-70
+B: Kc8 Qc7 Rd8 Re8 Bd7 Ne5 Nh4 Pa7 b6
+W: Ke1 Qb3 Rb1 Rg1 Bc1 Bf1 N32 Pa3 d3 f6 f5 g4 h2
blob - /dev/null
blob + 4cba62e325d1fb7f38f913402d98500b15aeae70 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/discovery-71
+W: Kf3 Rd1 Re6 Ne4 Pa4 f6 f4
+B: Kf8 Re2 Rh2 Ne8 Pa5 c5 g6
blob - /dev/null
blob + 0bbd5926759435fda925602c1e37bb8eb1c9bb9f (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/double-threat-49
+B: Kg4 Rf6 Be4 Pb6 g2
+W: Kg1 Re1 Ba5 Pa4 b5 c3
blob - /dev/null
blob + 6d62e2d735023433a2b9e8cd5b25c6dc6fefdaff (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/fork-48
+W: Kg1 Qc7 Rc1 Re1 Pa2 b3 f2 g3 h2
+B: Ke8 Qd7 Rf8 Bb7 Be7 Pa6 d6 g6 h7
blob - /dev/null
blob + 1c3dd7466d0cfdacba88ccf1d85649b6d6f6d708 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/fork-50
+B: Ke7 Rh3 Bd4 Pa5 e6 f7 g6
+W: Kf4 Rc8 Bb5 Pa4 e5
blob - /dev/null
blob + a1793418f51c2b673e13233a9a0d6f64522ddafe (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-attack-15
+W: Kf3 Rd8 Rh8 Bg4 Pa4 e3 g5
+B: Kg6 Rc7 Rf7 Bb4 Pa7 b6 f4 g7
blob - /dev/null
blob + 39f9bcb99edc5e57596238c932bfbac6d2fe4eb7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-attack-16
+W: Ka1 Rd1 Rf1 Nc3 Ne4 Pa3 b2 d5 g4
+B: Ke5 Rb8 Rb3 Be7 Na5 Pa6 c4 g6
blob - /dev/null
blob + 1d66d5b6ff6334e6f358d270103facdad431c5e5 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-attack-17
+W: Kb1 Qb4 Rf1 Bh4 Nc5 Pa2 b2 c2 e5 g4 h3
+B: Ke8 Qh6 Ra8 Be6 Nb6 Pa4 c7 c6 d5 g7 h7
blob - /dev/null
blob + a556d9c5bb9c254ab9cc909abc722063f509a1d4 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-attack-18
+W: Kg1 Qf4 Rb1 Bc5 Pd4 e6 f3 g4 h2
+B: Kc4 Qd5 Rc8 Bb7 Pc7 c3
blob - /dev/null
blob + 83546771399be393896fb30da81c4c6b2d9787e5 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-attack-19
+B Kg6 Qf1 Pa5 d5 e6 h6
+W: Kg4 Rc3 Be5 Nc5 Pf3 g3
blob - /dev/null
blob + 8bca3b2115fa4b5941fd22ccf39914b7cc83adc7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-net-01
+B: Kh8 Qg5 Rd8 Rh7 Ne2 Nh4 Pa6 b7 d6 e5 f4
+W: Kh2 Qc1 Rc3 Rg1 Bh1 Nf2 Pa5 b4 d5 e4 f3 h3
blob - /dev/null
blob + 82324c6cf158ac433a07924fbd9fca9886258dd4 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-net-02
+W: Kb1 Qd8 Rd1 Pb3 e4 f3 g4 h4
+B: Kg7 Qe3 Rc4 Nf6 Pa5 b4 e5 g6 h7
blob - /dev/null
blob + 6ffa41bcc8970f6f817869ea1c9893cdc77c693b (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-net-03
+B: Kd8 Qd2 Ra8 Rb8 Nf6 Pa5 c7 c5 d6 e5 f7 g7 h7
+W: Kg1 Qc6 Ra1 Rf1 Ba4 Pa3 b2 c4 d5 e4 f4 g2 h4
blob - /dev/null
blob + 0d75e44e6dfd393605f00b75b608f466aa9e6c76 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-net-04
+B: Kh7 Qc1 Re2 Ng4 Pc6 e6 f7 g6 h5
+W: Kg3 Qa7 Rc3 Bg1 Pa2 b4 c2 e4 h4
blob - /dev/null
blob + 22ebbee18699fac22a3032b3d416ec67ea85fcaf (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/mating-net-05
+B: Kg8 Qd4 Be3 Nd2 Pa7 b7 e7 g6 h7
+W: Kg3 Qb5 Ra1 Nc3 Pa2 e4 g4 g2 h4
blob - /dev/null
blob + 5f3c3a46e6aa73afb11602471505c9d17d55fadd (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/overload-75
+W: Kc1 Qe5 Rg6 Be6 Nc3 Pa3 b2 e3 f2 h4
+B: Kf8 Qe7 Rh8 Rh5 Na6 Pa7 b6 c6
blob - /dev/null
blob + 8678d87a6379e2405cd78279000c6fa517949734 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/pin-60
+W: Kg1 Qh7 Rh1 Bd4 Pa2 d5 e4 f2 g2
+B: Kf7 Qa6 Rf8 Bc4 Bg7 Pa7 b7 f6 g6
blob - /dev/null
blob + 8a50585dc1c16eee5fdc487eab99f9d6b89fcbc7 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/pin-62
+W: Kg1 Qc7 Rd1 Bc5 Bh3 Pb6 e4 f2 g3 h2
+B: Kg8 Qa6 Rb8 Rd8 Bd3 Pa5 e5 f6 g7 h7
blob - /dev/null
blob + 01e42a1f604556e71f598feafe7af4c16de86e57 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/pin-overload-61
+W: Kg1 Rc1 Re1 Bf4 Nd5 Ne5 Pd4 f2 g2 h2
+B: Kd8 Ra8 Re8 Bb3 Be7 Nd6 Pa6 b7 c7 f7 g7 h7
blob - /dev/null
blob + 8a86e2d62f2ef863085d07608cc7918e0340999e (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/promotion-96
+W: Kh1 Rb1 Ba5 Bg2 Ne4 Pd3 d5 g3 h2
+B: Kg8 Re8 Bg7 Nc8 Nd4 Pe5 f5 g6 h7
blob - /dev/null
blob + d85c001610cfa73dc2e00f606dbaa7d7d3c79a8b (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/remove-guard-76
+W: Kg1 Qf3 Ra1 Rb5 Bb2 Bc4 Pa2 b3 e2 f2 g3 h2
+B: Kg8 Qe7 Rc6 Rd8 Bc5 Na6 Pa7 b7 f7 g6 h7
blob - /dev/null
blob + e6eba17bdeec05ee3b32c25593a670c3e812912a (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/shut-off-90
+W: Ke3 Be6 Pa2 d7 f6 g4 h2
+B: Kf8 Rd6 Pa6 b6 g6 h6
blob - /dev/null
blob + 445ed5b8f218846a18cd6a4edac7d1f8b26135c4 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/simplification-89
+W: Kh1 Qd8 Rd1 Pd7 e4 g2 h3
+B: Kh7 Qf4 Be5 Ph6
blob - /dev/null
blob + f4e9a8394e17550121bdb3cc476e7bf2fa219700 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/chessercizes/skewer-69
+W: Kg4 Rh3 Nb6 Pa2 b4 c5 e6 f5
+B: Ke8 Rc7 Nd5 Pa6 b5 c6 f6 g5
blob - /dev/null
blob + edd030add08689a1a187f2038494ee58aad07758 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/knight
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 82b044b7e40c62a592324e3e848bac0a3ad4e0ca (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/knight-and-move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 87a0cd8ce2e0c483dc0fa324d228ad339edbba12 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/pawn
+W: P a2 b2 c2 d2 e2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 87d3899366ea2cc3774cec269b7816e54e76a7f9 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/pawn-and-move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + db477c6d2859b5cd97388bfe1e022622f7f2d81d (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/queen
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 9addeeb3c86945105449475443dbd34d7e19e84a (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/queen-and-move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 K e8
blob - /dev/null
blob + a7f6684d6d8c719e335cd5c7ec96cfb95ff5205b (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/rook
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 9f2c3c1ef1b0d11d54f8d57bfe12e583b5183c35 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/material-odds/rook-and-move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 354cbe4e27abf1d7302bc611401e7ecf6f484031 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/misc/little-game
+# This is Wild7 on ICC.
+W: P a2 b2 c2 K d1
+B: P f7 g7 h7 K e8
blob - /dev/null
blob + dcf3febaa99a725d9784abaff87386cb537f047e (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/double-d-pawn
+W: P a2 b2 c2 d4 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d5 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 974fd077f2745d0a4b269760511ca7b650a5b2d8 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/double-e-pawn
+W: P a2 b2 c2 d2 e4 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e5 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
+
blob - /dev/null
blob + bff23a331544df745e446a7814501bdd04ed37a1 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/giouco-piano
+B: P a7 b7 c7 d7 e5 f7 g7 h7 R a8 h8 N c6 g8 B c8 f8 Q d8 K e8
+W: P a2 b2 c2 d2 e4 f2 g2 h2 R a1 h1 N b1 f3 B c1 c4 Q d1 K e1
blob - /dev/null
blob + a3995795cb7396f73dab08c79614c5f4e7e28dd3 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambita
+W: P a2 b2 c2 d2 e4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 f4 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + eb5472fc9e96595dbd4a769d7efbb7dd98d508bb (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambita-be7
+W: P a2 b2 c2 d2 e4 g2 h2 R a1 h1 N b1 f3 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 f4 f7 g7 h7 R a8 h8 N b8 g8 B c8 e7 Q d8 K e8
blob - /dev/null
blob + d1369d890e16551a9f254592b51ed996a86e4612 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambita-fischer
+W: P a2 b2 c2 d2 e4 g2 h2 R a1 h1 N b1 f3 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d6 f4 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 71f993b0fdefad51a038e91d825d4feaf7072f88 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambita-nc6
+W: P a2 b2 c2 d2 e4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 f4 f7 g7 h7 R a8 h8 N c6 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + ef2376952028a2a815a6a161ec4694dbfd3341c3 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambita-schallop
+W: P a2 b2 c2 d2 e4 g2 h2 R a1 h1 N b1 f3 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 f4 f7 g7 h7 R a8 h8 N b8 f6 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 412e79b66502dbe49270012ab7dd67033d2f77dc (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambitd-bc5
+W: P a2 b2 c2 d2 e4 f4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e5 f7 g7 h7 R a8 h8 N b8 g8 B c8 c5 Q d8 K e8
blob - /dev/null
blob + 7c8c948a9db138b201f5287eca9f0c03357aa841 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambitd-d6
+W: P a2 b2 c2 d2 e4 f4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d6 e5 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + e5b73e0699b750cd58197c846b60bd351003ddfb (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambitd-falkbeer
+W: P a2 b2 c2 d2 e4 f4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d5 e5 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + dd0f49e2c5ce2027496520f5bf275091a5d0ce94 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambitd-nf6
+W: P a2 b2 c2 d2 e4 f4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e5 f7 g7 h7 R a8 h8 N b8 f6 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 32503c31bed2a0b49ec2b428a84f48de74d1ac79 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/kings-gambitd-nimzo
+W: P a2 b2 c2 d2 d5 f4 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c6 e5 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + 09ea3917115d5b6ab0c2e2c3498448e7994029e9 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/openings/ruy-lopez
+W: P a2 b2 c2 d2 e4 f2 g2 h2 R a1 h1 N b1 f3 B c1 b5 Q d1 K e1
+B: P a6 b7 c7 d7 e5 f7 g7 h7 R a8 h8 N c6 g8 B c8 f8 Q d8 K e8
+
blob - /dev/null
blob + 7e1b8f7eaf465a6d207f87958f39df9a94899e1b (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/pawns/pawns-only
+# Game with pawns only...
+# Whichever color is listed first is on move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 K e8
+
blob - /dev/null
blob + 2c88ec8a350eae1cdd304260c041895331822fdf (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/standard/standard
+# This is the standard game
+# Whichever color is listed first is on move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
+
blob - /dev/null
blob + b03543bb20751cceaef48f637d0f9d879f77465b (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/std.board
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
blob - /dev/null
blob + fe30582f31c96c8fa5c0da1643cc5b2449b2c004 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/test/bugpos
+B: Pa7 b6 e6 g5 Rh7 Kh6 Qe2
+W: P a3 b4 f2 g2 h3 Rd1 d4 Qf8 h8 Kg1
blob - /dev/null
blob + ef13177298bf034f5776a99f09e567390888fb73 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/0
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q e8 K d8
+
blob - /dev/null
blob + 448ea8a601dea9bafbcbe7060f6000f83284f4f9 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/1
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 N b1 c1 Q d1 K e1 B f1 g1 R h1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 B b8 c8 K d8 Q e8 N f8 g8 R h8
blob - /dev/null
blob + 155a7073081c8f064dc5b6a8f7200374b8dee3af (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/2
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 N b1 B c1 d1 N e1 K f1 R g1 Q h1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 N b8 B c8 d8 N e8 K f8 R g8 Q h8
blob - /dev/null
blob + 7d6fb7bd5c598bad5e5ccb2b35675c0c9e121ef6 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/3
+W: P a2 b2 c2 d2 e2 f2 g2 h2 N a1 b1 B c1 d1 Q e1 K f1 Q g1 h1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 N a8 b8 B c8 d8 Q e8 K f8 Q g8 h8
blob - /dev/null
blob + d3c08884870ebe81a4ac63cf3a7c59d479263acb (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/4
+W: P a2 b2 c2 d2 e2 f2 g2 h2 B a1 R b1 Q c1 K d1 Q e1 B f1 g1 N h1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 K a8 B b8 c8 R d8 B e8 N f8 Q g8 h8
blob - /dev/null
blob + 0eb7c2fa378026b66e24306943ff83b909baa10c (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/5
+W: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q e8 K d8
+B: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q e1 K d1
+
blob - /dev/null
blob + 3e3e25deb2767c41484d391eedeeb99c1d0917c8 (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/8
+W: P a4 b4 c4 d4 e4 f4 g4 h4 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a5 b5 c5 d5 e5 f5 g5 h5 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
+
blob - /dev/null
blob + 2c88ec8a350eae1cdd304260c041895331822fdf (mode 644)
--- /dev/null
+++ FICS.DIST/data/boards/wild/bughouse
+# This is the standard game
+# Whichever color is listed first is on move
+W: P a2 b2 c2 d2 e2 f2 g2 h2 R a1 h1 N b1 g1 B c1 f1 Q d1 K e1
+B: P a7 b7 c7 d7 e7 f7 g7 h7 R a8 h8 N b8 g8 B c8 f8 Q d8 K e8
+
blob - /dev/null
blob + 3314120d1c8617df30b410a09022c6aab5acb5db (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/changes.txt
+
+To long001.idx:
+
+Changed:
+
+ KGA: bishop's gambit, Chigorin's attack/Gifford variation
+ KGA: bishop's gambit, Chigorin's attack (Gifford variation)
+
+ Santasiere's folly
+ Santasiere's Folly
+
+ Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein)
+ Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system)
+
+ Ruy Lopez: closed (8...Na5)
+ Ruy Lopez: closed (9...Na5)
+
+ All occurences of "defence" to "defense"
+ All occurences of "manoevre" to "maneuver"
+ All occurences of "centre" to "center"
+
+Added:
+
+ Queen's pawn: London system
+ d2d4 g8f6 c1f4
blob - /dev/null
blob + 9cfbbea70ba66a50c261028211abc51cde3502bd (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/eco000.idx
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+E84
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+B99*
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+B65*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+B67*
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+B69*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+B64*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+B68*
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+B79*
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+B78*
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D64*
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+D65*
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+D67*
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D66*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+D63*
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+D54*
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+D69*
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+D68*
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+B99
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+B85
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D96*
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D95*
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+D98*
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D97*
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+E36*
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+E37*
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+B49
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+E23*
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E22*
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D81*
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+E35*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+E39*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E38*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+E34*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+E33*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E32*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B48
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B47
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+D19*
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+C98
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+C99
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+C97
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+D68
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+E19*
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+D69
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A98*
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+E09*
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+E96
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D65
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+A64*
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+A75*
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E57*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+E63
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C93
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C89
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+C91
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+C92
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C90
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+C96
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E59*
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E58*
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A99*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+E69
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A63
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E55
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/3P1NP1/PPN2PBP/R1BQR1K1 b - -
+A79*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+A77*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+A78*
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+D67
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D64
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+D66
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+E09
+r1bq1rk1/pp1nbppp/4pn2/2Pp2B1/2P5/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D62
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+E29
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+A39
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+E97*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+E94*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+A73*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+A76*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 b - -
+A74*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+B64
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+B65
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+E66*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+A39*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+E65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+A95*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+A89*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+A88*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+A97*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+E18*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+E63*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+A63*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+D88
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E66
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+B77
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+E79
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+B74
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+E69*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E68*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+E55*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+E54*
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+E59
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+E56
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+E58
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+E57
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E56*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+B85*
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+E98
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A89
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E83
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+E97
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E93
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+E95
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+E68
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+D63
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D60
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D61
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+E07
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+E08
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+E99
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E67
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+E29*
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+E49*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+D86*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A37
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+B38
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+B37
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E77*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E73*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+A26*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+B25
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+B26
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E48*
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E47*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A67*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+B25*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+A26
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C64
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+C27*
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+C51
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C53
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C28*
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+C52
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+C87
+r1bqk2r/1pp1bppp/p1p2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C85
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C84
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+C86
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+C88
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+D87*
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+C06*
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+E23
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A38*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+A38
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+A37*
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B35
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+B39
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+E78*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+A69*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+E93*
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+D34
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E92*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E91*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A72*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A71*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E64*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+E67*
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+D34*
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A62*
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+B73
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D47*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+E53*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+E52*
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D46*
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+D48*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+D42*
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+D49*
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+B59*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B58*
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B83*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B92*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B84*
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+B87*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B57*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B88*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B86*
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E33
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C49*
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C49
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+C54
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C48*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D17*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D16*
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+D18*
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+B66
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C79
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C78
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C77
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C80
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+D48
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+D49
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+C59
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+C06
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+D52
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D46
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+D47
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+A33
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+A29*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+A28*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+A27*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E42*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+E44*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+E45*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E62*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+D33*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D38*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E21*
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D24*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D40*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D43*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D15*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D37*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D90*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+A54*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D41*
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+A61*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+A33*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B60
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B57
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B58
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D42
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E51*
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E50*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+D45*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D94*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+A55*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E90*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A70*
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+B59
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B62
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B63
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B89
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+B88
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A68*
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B91*
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B81*
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+B19*
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C04
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C47*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B07*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+B45*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+B47*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+B56*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+B70*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+B80*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+B46*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+B90*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B43*
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C66
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+C58
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B71*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B82*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B93*
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A55
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D51
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E03
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+C09*
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+C04*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C48
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C65
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B11*
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+C57
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C55
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+A28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+A29
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+C47
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C46*
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C67
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+C56
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B46
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C74
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C72
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C71
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C69
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C68
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C70
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+C19*
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+C18*
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+C73
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+E25*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E27*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E24*
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E26*
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E28*
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B17
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B45
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B44
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A19*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+A18*
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B31
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A36*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+A23*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+A24*
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+B36
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B34
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+A36
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A35*
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A35
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A34*
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B32
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+B24
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+A25*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B30
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+A21*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+A17*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A16*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B33
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E20*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+D32*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+D31*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D35*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A85*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+E61*
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+D85*
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E72*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E71*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E41*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+E43*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E46*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E40*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+D33
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+B14*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C09
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+A42*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+E70*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+A65*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+A59*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+E81*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E80*
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E76*
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A66*
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D07
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+C17*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+C16*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+C15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+B15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C10*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C11*
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+D09
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C62
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+B16*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B18*
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+B17*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B08*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+C08*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+C07*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C03*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C05*
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B24*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C60
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C50
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+A27
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A25
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B23*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C46
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C26*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C44
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C25*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+C45
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+C22
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C61
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C63
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C29*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+E99*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+E98*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+A64
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E95*
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+A78
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+C98*
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+C99*
+r1bqr1k1/ppn2pbp/3p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 w - -
+A79
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+E96*
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+B79
+r2q1rk1/p3n1pp/3bbp2/3pp1B1/N7/6P1/PP2PPBP/R2Q1RK1 w - -
+D89*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+D88*
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+B78
+r2q1rk1/pp2ppbp/6p1/n7/3PP1b1/3BBP2/P3N1PP/R2Q1RK1 b - -
+D89
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+B74*
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+B73*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+E75*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E74*
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+B26*
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+B68
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+C83
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+B69
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+E79*
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+B49*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+B35*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B89*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+B67
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+C81
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+C82
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+D57*
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B61
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+E89*
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E86*
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D39*
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+E13*
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D44*
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D92*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D91*
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+B39*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D93*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+D58*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+D56*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D52*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+D55*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+D60*
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+D59*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+B48*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B72*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B60*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B62*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B94*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B95*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+B76*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+B75*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+B98*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+B96*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+B97*
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+C76
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+C75
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+B19
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+E31*
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E30*
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D82*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+D53*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D50*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+D51*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D80*
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D83*
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+D84*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E88*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+E87*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E85*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+E82*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+E83*
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D01*
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+C12*
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+C14*
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A83*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+C13*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+B77*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+E84*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+D99*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+B61*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B63*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+B66*
+r3kb1r/ppq2ppp/2n1pn2/2p5/2pP2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+D62*
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+D61*
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+D36*
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+A75
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+A94*
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+E19
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E18
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+D19
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+D98
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+D99
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+E45
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+E13
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E16
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E17
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+D29
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A59
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D12
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+D18
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+D17
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+D14*
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+D14
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+B38*
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+B05
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D03*
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B52
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+B11
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B18
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+E03*
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E02*
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+C14
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B97
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B53*
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C22*
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+A99
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A97
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+A98
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+D29*
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+D28*
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+D84
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+D57
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C81*
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+C86*
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+E08*
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A74
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+C95
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C94
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D59
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D58
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E82
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E52
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+A93*
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+E39
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+A14*
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A95
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+A94
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A88
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D78
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+E74
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E65
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E64
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+E78
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+B76
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+D78*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+E07*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+D77*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+A96*
+rnbq1rk1/pp2ppbp/5np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 b - -
+D75*
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+D74*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D79*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D79
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+D76*
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+D87
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D75
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E88
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E86
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+A73
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+A72
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+A68
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+A62
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E89
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+E75
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+C83*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C82*
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+D27*
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E54
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E53
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+A96
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+A93
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D56
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+D54
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D55
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D76
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+E91
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+E81
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+E77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+D83
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D93
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+D95
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+D73
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+D97
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D74
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+E87
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E85
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+E94
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E92
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+E51
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+E48
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+E49
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C56*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+E46
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+E50
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+E47
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+E28
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+E27
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C67*
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+C66*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2N2/1PP1BPPP/R1BQK2R b KQ -
+C85*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+C69*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+C80*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+C78*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+C84*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+C79*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+C72*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+A92
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E01*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+A90*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+A91*
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+D71*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C17
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+C18
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A42
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C15
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C16
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+C38
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C24*
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C23*
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C35
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B98
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E44
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E43
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C51*
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C52*
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C53*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+C74*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+C75*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E42
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E41
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E38
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+E26
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+D72*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+C19
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+B75
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+E16*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+E05*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E04*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+E06*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D73*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+A92*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+A87*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+E17*
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+A67
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+A71
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+E31
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+C76*
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+E25
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C54*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D53
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C13
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+A14
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E06
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E05
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+D72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+E62
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+E90
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+E80
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+E72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+E71
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+E73
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+E76
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D91
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D92
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+D96
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D94
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+D71
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+D86
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B42*
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+E37
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C12
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D38
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E34
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+E36
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D39
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E35
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+C73*
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+B55*
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+E30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+E22
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+E40
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+E21
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+E20
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+E32
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E11
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+E24
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C55*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C50*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+C61*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C65*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C60*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+C62*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+C63*
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C64*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B31*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+B52*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B51*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+C68*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+C77*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+C70*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+C71*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C57*
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+C58*
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+C38*
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+A91
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+C59*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+A87
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A08*
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+E70
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B94
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+B91
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B92
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B90
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B93
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B95
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+B96
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+B84
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+D28
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+D27
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+A58
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+B87
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+E14
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E12
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+E15
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A47
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+A12*
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A57
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A23
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+A19
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A60
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+A32
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+A31
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A56
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A09*
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B29
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+B16
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B72
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B70
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B71
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+D09*
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E15*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D15
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+D16
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B56
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E11*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D23*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+D21*
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+A31*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+D11*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+E12*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E10*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+B14
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D13*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D13
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A32*
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A70
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+A66
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+A61
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D45
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D43
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D44
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+D36
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+B55
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A65
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B86
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+B81
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B83
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B80
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B82
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D26*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D25*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+D22*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D41
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D40
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D12*
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E14*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+B36*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+B37*
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+B07
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+B08
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D80
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+D82
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+D81
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D90
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+A49*
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D85
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A53
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+B09
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B04
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+D01
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+D03
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D04
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D02*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+A47*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A46*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A48*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D24
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D25
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D23
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+A54
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D50
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D37
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D35
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+E01
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D05*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D05
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D04*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C11
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C05
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D26
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E04
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E02
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+C32
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+B05*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+B04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B32*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C43*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+C29
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+B44*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B34*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C45*
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B54*
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+B41*
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A24
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+A18
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A17
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+E10
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+E00
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+C24
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+B30*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A22
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+B50*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+B40*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+B29*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B27*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+B28*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A51
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C43
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C44*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C26
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+C41*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C42*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C42
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C40*
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+A52
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C27
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+C39*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+A90
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C36*
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+C37*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+C34*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+C35*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+A85
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+A86
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+A83
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+E61
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+E60
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A48
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+A49
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A07*
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A16
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A15
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A50
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+A46
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A06*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A45
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B02
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A05*
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A05
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A04*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+B03
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B43
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+B42
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B41
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B28
+rnbqkbnr/1pp1pppp/p7/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D22
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A01*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B22*
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B40
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+A44
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A11
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B12
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B10
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A34
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A30*
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A30
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A43
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+B23
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+B22
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+B27
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+A20*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B20
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+A11*
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+A13*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A15*
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A10*
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A86*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E00*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+A12
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D11
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D10
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+B15
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+B51
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B50
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B54
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+B53
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+D20*
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+A52*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+A57*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A60*
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A56*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+D07*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+D10*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+D30*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D06*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+D08*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A51*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A84*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+A53*
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A50*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+E60*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+A08
+rnbqkbnr/pp2pppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+B13
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+A58*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D32
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C07
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+C08
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A81*
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A41
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A09
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A43*
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+D06
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D02
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+D00*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D00
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B01
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A80*
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A03
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+A41*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A45*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A06
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A07
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A40*
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+A44*
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D21
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D20
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C41
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+D31
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D30
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C10
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+C03
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C02
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C21*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+B03*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+B13*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C01*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+C01
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C02*
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C36
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D08
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+C31
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A82*
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+B12*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+B09*
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C32*
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+C39
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C37
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A13
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C00
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+C23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A21
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+B20*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A20
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+B01*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C40
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+C20*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C20
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+C30
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+B10*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+C00*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+B02*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+B06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+B00*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+C21
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+C34
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+C33
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C33*
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+C31*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C30*
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A84
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+A81
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A03*
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A80
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+A82
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A02*
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B06
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A10
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A40
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+B00
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A02
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+A01
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A04
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq -
+A00*
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A00
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+C93*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C92*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+C94*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+C89*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+C90*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A76
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+A77
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+A69
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+C95*
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C91*
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+C97*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+C96*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+C88*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+C87*
blob - /dev/null
blob + 9cfbbea70ba66a50c261028211abc51cde3502bd (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/eco999.idx
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+E84
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+B99*
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+B65*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+B67*
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+B69*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+B64*
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+B68*
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+B79*
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+B78*
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D64*
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+D65*
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+D67*
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+D66*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+D63*
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+D54*
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+D69*
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+D68*
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+B99
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+B85
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D96*
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D95*
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+D98*
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D97*
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+E36*
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+E37*
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+B49
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+E23*
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E22*
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D81*
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+E35*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+E39*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E38*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+E34*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+E33*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E32*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B48
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B47
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+D19*
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+C98
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+C99
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+C97
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+D68
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+E19*
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+D69
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A98*
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+E09*
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+E96
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D65
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+A64*
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+A75*
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E57*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+E63
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C93
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C89
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+C91
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+C92
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+C90
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+C96
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E59*
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E58*
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+A99*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+E69
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A63
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+E55
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/3P1NP1/PPN2PBP/R1BQR1K1 b - -
+A79*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+A77*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+A78*
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+D67
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+D64
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+D66
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+E09
+r1bq1rk1/pp1nbppp/4pn2/2Pp2B1/2P5/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D62
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+E29
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+A39
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+E97*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+E94*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+A73*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+A76*
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 b - -
+A74*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+B64
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+B65
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+E66*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+A39*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+E65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+A95*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+A89*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+A88*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+A97*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+E18*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+E63*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+A63*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+D88
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E66
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+B77
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+E79
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+B74
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+E69*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E68*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+E55*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+E54*
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+E59
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+E56
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+E58
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+E57
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E56*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+B85*
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+E98
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A89
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E83
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+E97
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E93
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+E95
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+E68
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+D63
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D60
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+D61
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+E07
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+E08
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+E99
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E67
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+E29*
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+E49*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+D86*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A37
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+B38
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+B37
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E77*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E73*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+A26*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+B25
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+B26
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E48*
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E47*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A67*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+B25*
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+A26
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C64
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+C27*
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+C51
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C53
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C28*
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+C52
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+C87
+r1bqk2r/1pp1bppp/p1p2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C85
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C84
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+C86
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+C88
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+D87*
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+C06*
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+E23
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+A38*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+A38
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+A37*
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B35
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+B39
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+E78*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+A69*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+E93*
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+D34
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E92*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+E91*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A72*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+A71*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E64*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+E67*
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+D34*
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A62*
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+B73
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D47*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+E53*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+E52*
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D46*
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+D48*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+D42*
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+D49*
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+B59*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B58*
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B83*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B92*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B84*
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+B87*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B57*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B88*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B86*
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E33
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C49*
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C49
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+C54
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C48*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D17*
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D16*
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+D18*
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+B66
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C79
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C78
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C77
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C80
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+D48
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+D49
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+C59
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+C06
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+D52
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D46
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+D47
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+A33
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+A29*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+A28*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+A27*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E42*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+E44*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+E45*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E62*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+D33*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D38*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E21*
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D24*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D40*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D43*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+D15*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D37*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D90*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+A54*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D41*
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+A61*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+A33*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B60
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B57
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B58
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+D42
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+E51*
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E50*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+D45*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D94*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+A55*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E90*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A70*
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+B59
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B62
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B63
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+B89
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+B88
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+A68*
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B91*
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B81*
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+B19*
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C04
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C47*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B07*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+B45*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+B47*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+B56*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+B70*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+B80*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+B46*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+B90*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B43*
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C66
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+C58
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B71*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+B82*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B93*
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A55
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D51
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E03
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+C09*
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+C04*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+C48
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C65
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B11*
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+C57
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C55
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+A28
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+A29
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+C47
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C46*
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+C67
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+C56
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B46
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+C74
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C72
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C71
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+C69
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C68
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C70
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+C19*
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+C18*
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+C73
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+E25*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E27*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E24*
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+E26*
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+E28*
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B17
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B45
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B44
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A19*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+A18*
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B31
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A36*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+A23*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+A24*
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+B36
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B34
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+A36
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A35*
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A35
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A34*
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B32
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+B24
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+A25*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B30
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+A21*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+A17*
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A16*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B33
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E20*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+D32*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+D31*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D35*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A85*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+E61*
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+D85*
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E72*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E71*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+E41*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+E43*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+E46*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E40*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+D33
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+B14*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+C09
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+A42*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+E70*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+A65*
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+A59*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+E81*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E80*
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+E76*
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+A66*
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D07
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+C17*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+C16*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+C15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+B15*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C10*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C11*
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+D09
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C62
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+B16*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+B18*
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+B17*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+B08*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+C08*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+C07*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C03*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+C05*
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B24*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C60
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+C50
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+A27
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A25
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B23*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C46
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C26*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C44
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C25*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+C45
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+C22
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C61
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+C63
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C29*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+E99*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+E98*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+A64
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+E95*
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+A78
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+C98*
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+C99*
+r1bqr1k1/ppn2pbp/3p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 w - -
+A79
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+E96*
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+B79
+r2q1rk1/p3n1pp/3bbp2/3pp1B1/N7/6P1/PP2PPBP/R2Q1RK1 w - -
+D89*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+D88*
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+B78
+r2q1rk1/pp2ppbp/6p1/n7/3PP1b1/3BBP2/P3N1PP/R2Q1RK1 b - -
+D89
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+B74*
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+B73*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+E75*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+E74*
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+B26*
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+B68
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+C83
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+B69
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+E79*
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+B49*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+B35*
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B89*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+B67
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+C81
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+C82
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+D57*
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+B61
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+E89*
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E86*
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+D39*
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+E13*
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+D44*
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D92*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+D91*
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+B39*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+D93*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+D58*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+D56*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+D52*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+D55*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+D60*
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+D59*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+B48*
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+B72*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+B60*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+B62*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+B94*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+B95*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+B76*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+B75*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+B98*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+B96*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+B97*
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+C76
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+C75
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+B19
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+E31*
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+E30*
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D82*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+D53*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D50*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+D51*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+D80*
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D83*
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+D84*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+E88*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+E87*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+E85*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+E82*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+E83*
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D01*
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+C12*
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+C14*
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A83*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+C13*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+B77*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+E84*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+D99*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+B61*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+B63*
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+B66*
+r3kb1r/ppq2ppp/2n1pn2/2p5/2pP2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+D62*
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+D61*
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+D36*
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+A75
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+A94*
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+E19
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E18
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+D19
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+D98
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+D99
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+E45
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+E13
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E16
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E17
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+D29
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A59
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D12
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+D18
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+D17
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+D14*
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+D14
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+B38*
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+B05
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D03*
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+B52
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+B11
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+B18
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+E03*
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E02*
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+C14
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B97
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B53*
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C22*
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+A99
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A97
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+A98
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+D29*
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+D28*
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+D84
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+D57
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C81*
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+C86*
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+E08*
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A74
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+C95
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+C94
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D59
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+D58
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E82
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E52
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+A93*
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+E39
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+A14*
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A95
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+A94
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+A88
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D78
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+E74
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+E65
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+E64
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+E78
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+B76
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+D78*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+E07*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+D77*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+A96*
+rnbq1rk1/pp2ppbp/5np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 b - -
+D75*
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+D74*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D79*
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D79
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+D76*
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+D87
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D75
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E88
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E86
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+A73
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+A72
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+A68
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+A62
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+E89
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+E75
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+C83*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+C82*
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+D27*
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+E54
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+E53
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+A96
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+A93
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D56
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+D54
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D55
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+D76
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+E91
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+E81
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+E77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+D83
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+D93
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+D95
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D77
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+D73
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+D97
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+D74
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+E87
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+E85
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+E94
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+E92
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+E51
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+E48
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+E49
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C56*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+E46
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+E50
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+E47
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+E28
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+E27
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+C67*
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+C66*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2N2/1PP1BPPP/R1BQK2R b KQ -
+C85*
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+C69*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+C80*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+C78*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+C84*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+C79*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+C72*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+A92
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E01*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+A90*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+A91*
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+D71*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C17
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+C18
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A42
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C15
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C16
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+C38
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C24*
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C23*
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C35
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+B98
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E44
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E43
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C51*
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C52*
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C53*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+C74*
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+C75*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+E42
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+E41
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E38
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+E26
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+D72*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+C19
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+B75
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+E16*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+E05*
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+E04*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+E06*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+D73*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+A92*
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+A87*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+E17*
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+A67
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+A71
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+E31
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+C76*
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+E25
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+C54*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+D53
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C13
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+A14
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E06
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+E05
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+D72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+E62
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+E90
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+E80
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+E72
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+E71
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+E73
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+E76
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D91
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+D92
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+D96
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D94
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+D71
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+D86
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+B42*
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+E37
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+C12
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D38
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E34
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+E36
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D39
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+E35
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+C73*
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+B55*
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+E30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+E22
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+E40
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+E21
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+E20
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+E32
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E11
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+E24
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C55*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C50*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+C61*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+C65*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C60*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+C62*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+C63*
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+C64*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B31*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+B52*
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B51*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+C68*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+C77*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+C70*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+C71*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+C57*
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+C58*
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+C38*
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+A91
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+C59*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+A87
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A08*
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+E70
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+B94
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+B91
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B92
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B90
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B93
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+B95
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+B96
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+B84
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+D28
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+D27
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+A58
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+B87
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+E14
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+E12
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+E15
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A47
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+A12*
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A57
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A23
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+A19
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+A60
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+A32
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+A31
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A56
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A09*
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B29
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+B16
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+B72
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B70
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B71
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+D09*
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E15*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D15
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+D16
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B56
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+E11*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D23*
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+D21*
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+A31*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+D11*
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+E12*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E10*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+B14
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D13*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D13
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A32*
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+A70
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+A66
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+A61
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+D45
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D43
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+D44
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+D36
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+B55
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+A65
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+B86
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+B81
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+B83
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+B80
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+B82
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D26*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D25*
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+D22*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D41
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+D40
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+D12*
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+E14*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+B36*
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+B37*
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+B07
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+B08
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D80
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+D82
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+D81
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D90
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+D70
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+A49*
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D85
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A53
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+B09
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+B04
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+D01
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+D03
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D04
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D02*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+A47*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A46*
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A48*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D24
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D25
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D23
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+A54
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+D50
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+D37
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D35
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+E01
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+D05*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+D05
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D04*
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+C11
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C05
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+D26
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+E04
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+E02
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+C32
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+B05*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+B04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B32*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C43*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+C29
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+B44*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+B34*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+B33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C45*
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+B54*
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+B41*
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+A24
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+A18
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A17
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+E10
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+E00
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+C24
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+B30*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+A22
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+B50*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+B40*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+B29*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B27*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+B28*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+A51
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C43
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C44*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+C26
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+C41*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C42*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C42
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C40*
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+A52
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+C27
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+C39*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+A90
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C36*
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+C37*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+C34*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+C35*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+A85
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+A86
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+A83
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+E61
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+E60
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+A48
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+A49
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A07*
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A16
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A15
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A50
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+A46
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A06*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A45
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B02
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A05*
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A05
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A04*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+B03
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+B43
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+B42
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+B41
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B28
+rnbqkbnr/1pp1pppp/p7/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+D22
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A01*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B22*
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B40
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+A44
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A11
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B12
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B10
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A34
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A30*
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A30
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A43
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+B23
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+B22
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+B27
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+A20*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B20
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+B21
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+A11*
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+A13*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A15*
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A10*
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+D70*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+A86*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+E00*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+A12
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D11
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D10
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+B15
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+B51
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+B50
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+B54
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+B53
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+D20*
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+A52*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+A57*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+A60*
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A56*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+D07*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+D10*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+D30*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D06*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+D08*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+A51*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A84*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+A53*
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A50*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+E60*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+A08
+rnbqkbnr/pp2pppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+B13
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+A58*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+D32
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+C07
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+C08
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A81*
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A41
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+A09
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A43*
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+D06
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+D02
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+D00*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+D00
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B01
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A80*
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A03
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+A41*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A45*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+A06
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+A07
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A40*
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+A44*
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+D21
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D20
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+C41
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+D31
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D30
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+C10
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+C03
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C02
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C21*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+B03*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+B13*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+C01*
+rnbqkbnr/ppp2ppp/8/3p4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+C01
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+C02*
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C36
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+D08
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+C31
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+A82*
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+B12*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+B09*
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+C32*
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+C39
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+C37
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A13
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C00
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+C23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+A21
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+B20*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+A20
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+B01*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+C25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+C40
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+C20*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C20
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+C30
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+B10*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+C00*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+B02*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+B06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+B00*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+C21
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+C34
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+C33
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+C33*
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+B21*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+C31*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+C30*
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+A84
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+A81
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A03*
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+A80
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+A82
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A02*
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+B06
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+A10
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+A40
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+B00
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+A02
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+A01
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+A04
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR b KQkq -
+A00*
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+A00
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+C93*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C92*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+C94*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+C89*
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+C90*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+A76
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+A77
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+A69
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+C95*
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+C91*
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+C97*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+C96*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+C88*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+C87*
blob - /dev/null
blob + da5570c6c02c87d140f4dd73c7c9d894b382ec3a (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/fen.doc
+
+Opening classification uses modified FEN notation, i.e. the halfmove and
+fullmove numbers are dropped since these are irrelvant for opening positions.
+
+---
+
+16.1.1: History
+
+FEN is based on a 19th century standard for position recording designed by the
+Scotsman David Forsyth, a newspaper journalist. The original Forsyth standard
+has been slightly extended for use with chess software by Steven Edwards with
+assistance from commentators on the Internet. This new standard, FEN, was
+first implemented in Edwards' SAN Kit.
+
+16.1.2: Uses for a position notation
+
+Having a standard position notation is particularly important for chess
+programmers as it allows them to share position databases. For example,
+there exist standard position notation databases with many of the classical
+benchmark tests for chessplaying programs, and by using a common position
+notation format many hours of tedious data entry can be saved. Additionally,
+a position notation can be useful for page layout programs and for confirming
+position status for e-mail competition.
+
+Many interesting chess problem sets represented using FEN can be found at the
+chess.uoknor.edu ftp site in the directory pub/chess/SAN_testsuites.
+
+
+16.1.3: Data fields
+
+FEN specifies the piece placement, the active color, the castling
+availability, the en passant target square, the halfmove clock, and the
+fullmove number. These can all fit on a single text line in an easily
+read format. The length of a FEN position description varies somewhat
+according to the position. In some cases, the description could be eighty
+or more characters in length and so may not fit conveniently on some
+displays. However, these positions aren't too common.
+
+A FEN description has six fields. Each field is composed only of non-blank
+printing ASCII characters. Adjacent fields are separated by a single ASCII
+space character.
+
+
+16.1.3.1: Piece placement data
+
+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.
+
+
+16.1.3.2: Active color
+
+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.
+
+
+16.1.3.3: Castling availability
+
+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.
+
+
+16.1.3.4: En passant target square
+
+The fourth field is the en passant target square. If there is no en passant
+target square then the single character symbol "-" appears. If there is an
+en passant target square then is represented by a lowercase file character
+immediately followed by a rank digit. Obviously, the rank digit will be "3"
+following a white pawn double advance (Black is the active color) or else be
+the digit "6" after a black pawn double advance (White being the active
+color).
+
+An en passant target square is given if and only if the last move was a pawn
+advance of two squares. Therefore, an en passant target square field may have
+a square name even if there is no pawn of the opposing side that may
+immediately execute the en passant capture.
+
+
+16.1.3.5: Halfmove clock
+
+The fifth field is a nonnegative integer representing the halfmove clock.
+This number is the count of halfmoves (or ply) since the last pawn advance
+or capturing move. This value is used for the fifty move draw rule.
+
+
+16.1.3.6: Fullmove number
+
+The sixth and last field is a positive integer that gives the fullmove number.
+This will have the value "1" for the first move of a game for both White and
+Black. It is incremented by one immediately after each move by Black.
+
+
+16.1.4: Examples
+
+Here's the FEN for the starting position:
+
+rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1
+
+And after the move 1. e4:
+
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq e3 0 1
+
+And then after 1. ... c5:
+
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq c6 0 2
+
+And then after 2. Nf3:
+
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq - 1 2
+
+For two kings on their home squares and a white pawn on e2 (White to move)
+with thirty eight full moves played with five halfmoves since the last pawn
+move or capture:
+
+4k3/8/8/8/8/8/4P3/4K3 w - - 5 39
blob - /dev/null
blob + a370e2eaab8b30a2ee439e6ddc00db3fa2805782 (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/long001.idx
+1q3rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy) *
+1r2kb1r/p1pq2pp/Q1n5/3npp2/6b1/P2PPN2/1P3PPP/RNB1KB1R b KQk -
+Sicilian: Najdorf, Poisoned pawn variation *
+1rb2rk1/pp3ppp/5q2/3P4/1n6/2P1Q3/PP3PPP/RN2KB1R w KQ -
+Scotch: Gottschall variation
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+King's Indian: S\"amisch, Panno main line
+1rbq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Ruban variation
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+English: closed, 5.Rb1 *
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3PN/PPPP1PBP/R1BQK2R b KQk -
+English: closed, 5.Rb1 Taimanov variation *
+1rbqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQk -
+two knights defense: Colman variation
+2bqkbnr/r4ppp/p1npp3/1p6/4P3/1BN2N2/PP2QPPP/R1B2RK1 w k -
+Sicilian: Smith-Morra gambit, Chicago defense
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+Sicilian: Najdorf, 7...Be7 main line *
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7 *
+2kr1b1r/pppq2pp/2n1bp2/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, Yugoslav attack, Rauser variation *
+2kr1b1r/pppq2pp/2n2n2/2Pp1p2/3Pp3/2N1P3/PP1NQPPP/R1B2RK1 b - -
+French: classical, St\a hlberg variation *
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6 *
+2kr1b1r/pppq2pp/2n5/3Npp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq2pp/2n5/3npp2/4P1b1/2NP1N2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4 *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7 *
+2kr3r/pp2bppp/2nqbn2/3pp1B1/8/1NN3P1/PPP1PPBP/R2Q1RK1 w - -
+Gr\"unfeld: Russian, Keres variation *
+2kr3r/ppp2ppp/1bn1bPq1/6N1/2ppNPP1/8/PPP4P/R1BQR1K1 w - -
+two knights: Max Lange attack, Berger variation
+2kr3r/pppb1ppp/2n1q2n/1Bb1p3/8/2NP1N2/PPP2PPP/R1BQR1K1 w - -
+Center game: Kupreichik variation *
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+Sicilian: dragon, Yugoslav attack, 12.h4 *
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O *
+2kr3r/pppqbppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP2B1PP/R2Q1RK1 w - -
+Alekhine's defense: four pawns attack, Tartakower variation
+2kr3r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Grigoriev variation *
+2kr3r/ppq1nppp/2nbp3/3p4/3P2b1/5N2/PPP1BPPP/R1BQRNK1 w - -
+QGD: exchange, chameleon variation *
+2krr3/pppq1ppp/1bn5/3n4/QPN1p1b1/P2PPN2/1B3PPP/R3KB1R w KQ -
+Sicilian: Najdorf, Ivkov variation *
+2r1kb1r/1pq2ppp/p1n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack (with Rc1) *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation *
+2r1kb1r/ppq2ppp/2n1pn2/2ppN3/3P2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation *
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, main line *
+2rq1rk1/pp2ppbp/2n2np1/2Pp4/3P2b1/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Bogolyubov variation *
+2rq1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/1PN1BN2/P3BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Stoltz variation *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, Bd3 line, 11.O-O *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/8/2P1PB1P/PP1N1PP1/R1BQ1RK1 w - -
+QGD: Petrosian variation *
+2rqk2r/pp3pp1/2n1pn2/2bp3p/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line, Janowski variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/1P4b1/2P1PN2/P2NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, fianchetto variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 b k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2n1pn2/3p4/1b1P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Capablanca variation *
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2nbpn2/3p4/3P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Pillsbury attack *
+2rqk2r/pp3ppp/4pn2/2bpn3/3N4/2P1P3/PP1NQPPP/R1B2RK1 w k -
+QGD: Orthodox defense, Bd3 line, Alekhine variation *
+2rqkb1r/pp1bpppp/2n2n2/2pp4/Q2P4/2P1PN2/PP1N1PPP/R1B1KB1R w KQk -
+QGD: Rochlin variation *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, 7.Rc1 *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/P3PN2/1PPNBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Swiss (Henneberger) variation *
+2rqkb1r/pp3ppp/2n1pn2/3p4/3p2b1/P3PN2/1PPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Swiss, Karlsbad variation *
+2rqkb1r/pp3ppp/4pn2/3p4/3P4/1P2B2P/P1P1QPP1/RN3RK1 b k -
+QGD: Tartakower variation *
+2rqkbnr/pp3ppp/2n1p3/2p2b2/2pP4/4BNP1/PP2PPBP/RN1Q1RK1 b k -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation *
+2rqkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w k -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation *
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+QGD: Anti-neo-orthodox variation *
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical, 13.de *
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical variation *
+4rrk1/pppb2pp/2np1q2/2b2P2/4Q3/2N4B/PPPPNP1P/R1B1K2R w KQ -
+KGA: Muzio gambit, Paulsen variation *
+5rk1/5ppp/p1pbr3/1p1n3q/P2P2b1/1BPQB1P1/1P1N1P1P/R3R1K1 w - -
+Ruy Lopez: Marshall, main line, Spassky variation
+5rk1/ppq2ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar) *
+N1bk1b1r/p2pq2p/1pnn2p1/3Qpp2/8/1B6/PPPP1PPP/R1B1K1NR w KQ -
+Vienna: `Frankenstein-Dracula' variation
+N1bk3r/pp1p1ppp/2n2n2/8/1b6/P4B1q/1PPN1P1P/R1BQK2R b KQ -
+Scotch: Berger variation
+r1b1k1nr/ppp2ppp/1bn5/3p4/4P2q/2NN4/PPPP1PPP/R1BQKB1R w KQkq -
+Vienna: Adams' gambit *
+r1b1k1nr/ppp2ppp/2n5/q3P3/1b6/2N2N2/PPPB1PPP/R2QKB1R b KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack
+r1b1k1nr/pppp1ppp/1b6/8/3qPP2/1PNN2P1/P2PQ2P/n1BK1B1R b kq -
+Vienna: `Frankenstein-Dracula' variation *
+r1b1k1nr/pppp1ppp/1b6/nP2N1q1/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Hirschbach variation
+r1b1k1nr/pppp1ppp/1bn5/8/4P2q/3N4/PPPPBPPP/RNBQK2R b KQkq -
+Vienna game *
+r1b1k1nr/pppp1ppp/2n2q2/1Nb5/4P3/4B3/PPP2PPP/RN1QKB1R b KQkq -
+Scotch: Blumenfeld attack
+r1b1k1nr/pppp1ppp/2n5/1N6/1b2P2q/8/PPPB1PPP/RN1QKB1R b KQkq -
+Scotch game
+r1b1k1nr/ppppqppp/1bn5/4p1B1/2BPP3/2P2N2/PP3PPP/RN1QK2R b KQkq -
+Giuoco Piano: Mestel variation
+r1b1k1nr/ppppqppp/1bn5/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: center-holding variation
+r1b1k1nr/ppppqppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Boden variation
+r1b1k1nr/ppppqppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano: close variation
+r1b1k1nr/pppq1ppp/1b6/n3N3/2B1P3/BQP5/P4PPP/RN3RK1 b kq -
+Evans gambit: Levenfish variation
+r1b1k2r/1pp1qppp/pbnp1n2/4p3/P1BPP3/2P2N1P/1P3PP1/RNBQR1K1 b kq -
+Giuoco Piano: Tarrasch variation
+r1b1k2r/1pp2ppp/p1n5/2bpq3/3NP3/2P1K3/PPN3PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Leonhardt variation *
+r1b1k2r/1pq1bppp/p1nppn2/8/P2NPP2/2N5/1PP1B1PP/R1BQ1R1K b kq -
+Sicilian: Scheveningen, classical, Mar\'oczy system
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+Sicilian: Najdorf, 7...Be7 main line
+r1b1k2r/2q1bppp/p2p1n2/npp1p3/P2PP3/2P2N2/1PB2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, Balla variation
+r1b1k2r/p1q2pp1/2pb1n1p/n3N3/3Pp3/8/PPPBBPPP/RN1QK2R b KQkq -
+two knights defense: Knorre variation
+r1b1k2r/pp1n1ppp/2p1pn2/q2p2B1/1bPP4/2N1P3/PPQN1PPP/R3KB1R b KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation
+r1b1k2r/pp3ppp/1qn1p3/2bp4/6n1/5NP1/PPPNPPBP/R1BQ1RK1 w kq -
+Gr\"unfeld: Pachman variation *
+r1b1k2r/pp3ppp/3b1q2/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Stahlberg variation *
+r1b1k2r/ppp1qppp/5n2/4p1B1/2BnP3/2N5/PPP3PP/R2Q1RK1 b kq -
+Giuoco piano: Holzhausen attack
+r1b1k2r/ppp2ppp/2N5/1B1pP3/4n2q/8/PPP2bPP/RNBQ1K1R w kq -
+Two knights defense, Keidanz variation
+r1b1k2r/ppp3p1/2np1q1p/2b1pP2/2B5/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+KGD: classical, Svenonius variation *
+r1b1k2r/pppp1ppp/1bn5/8/4n2q/2NN4/PPPPBPPP/R1BQK2R w KQkq -
+Vienna: Alekhine variation *
+r1b1k2r/pppp1ppp/2n2q2/2b5/3NP3/4K3/PPP1N1PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Polerio defense *
+r1b1k2r/ppppnp1p/2n4b/4q3/2B2p2/2NP1Q2/PPPB2PP/4RRK1 b kq -
+KGA: Muzio gambit, Paulsen variation
+r1b1k2r/ppppnppp/2n2q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R b KQkq -
+Scotch: Paulsen attack
+r1b1k2r/ppppnppp/2n2q2/2b5/3NP3/2P1B3/PP1Q1PPP/RN2KB1R b KQkq -
+Scotch: Blackburne attack
+r1b1k2r/ppppnppp/2n2q2/2b5/4P3/2P1B3/PPN2PPP/RN1QKB1R b KQkq -
+Scotch: Meitner variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/1QN2N2/P4PPP/R1BR2K1 b kq -
+Evans gambit: compromised defense, Potter variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/BQN2N2/P4PPP/R4RK1 b kq -
+Evans gambit: compromised defense, Paulsen variation
+r1b1kb1r/1pp3pp/p1n2n2/5pq1/2BPp3/2N1PP2/PP1N2PP/R1BQ1RK1 b kq -
+French: Steinitz, Brodsky-Jones variation *
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b kq -
+Sicilian: Scheveningen, classical
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6
+r1b1kb1r/2p1nppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Qkq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation *
+r1b1kb1r/p1q2pp1/2p2n1p/n3N3/4p3/8/PPPPBPPP/RNBQK2R w KQkq -
+two knights defense: G\"oring variation
+r1b1kb1r/p1q2ppp/2p2n2/n3p1N1/8/3B1Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Paoli variation
+r1b1kb1r/pp1n1ppp/2p1p3/q2n2B1/3P4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation
+r1b1kb1r/pp1n1ppp/2p1pB2/q2p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, Capablanca variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q2P2B1/3P4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, 7.cd
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p4/2PP4/2N2N2/PP1BPPPP/2RQKB1R b Kkq -
+QGD: Rochlin variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q5B1/2pP4/2N1P3/PP1N1PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation
+r1b1kb1r/pp1p1ppp/1qn1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R w KQkq -
+English: symmetrical, Geller variation
+r1b1kb1r/pp1p1ppp/4pn2/1Bp5/3nPq2/2N2N2/PPPP1PPP/R1BQR1K1 w kq -
+English: four knights, Stean variation *
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kb1r/pp2pppp/1qn2n2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation
+r1b1kb1r/pp2pppp/1qnp1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Benk\"o variation
+r1b1kb1r/pp2pppp/2n2n2/q1pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Flohr variation *
+r1b1kb1r/pp2pppp/2n2n2/q2p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/4PNP1/PPP2PBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Botvinnik variation *
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Qb3 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+Gr\"unfeld: Russian, Smyslov variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/1P3NP1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Levenfish variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2N2NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Byrne (Simagin) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2P2NP1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Russian variation with e4 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/N4NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Prins variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/P4NP1/1PP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation *
+r1b1kb1r/pp3ppp/2n5/2pqp3/8/3P1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation *
+r1b1kb1r/ppppq1pp/2n2n2/3Q4/8/5N2/PPP1PPPP/RNB1KB1R w KQkq -
+Queen's pawn: Englund gambit
+r1b1kb1r/ppppq1pp/2n2n2/4N1B1/3Pp3/8/PPP2PPP/RN1QKB1R w KQkq -
+Vienna gambit: Kaufmann variation *
+r1b1kb1r/ppppqppp/5n2/1B2N3/3nPP2/2N5/PPPP2PP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation
+r1b1kb1r/ppq1pppp/2n2n2/1Bpp4/8/2NPPN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation *
+r1b1kb1r/ppq2ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Stoltz variation *
+r1b1kb1r/ppqp1ppp/2B1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+English: four knights, Romanishin variation *
+r1b1kbnr/1p2pppp/p1q5/2pp4/1P6/4PN2/P1PP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Adorjan gambit *
+r1b1kbnr/1p2pppp/p1q5/2pp4/3P4/2N1PN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Botvinnik variation *
+r1b1kbnr/1p2pppp/p1q5/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, main line *
+r1b1kbnr/1pp2ppp/p1pq4/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Bronstein variation
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3 *
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2 *
+r1b1kbnr/1pq2ppp/p3p3/2ppN3/3PP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, San Remo variation *
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/2p2ppp/p1p5/3p2q1/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, poisoned pawn variation *
+r1b1kbnr/p1p2ppp/2p5/3pN1q1/3Pp3/4P2P/PPP2PP1/RNBQ1K1R w kq -
+French: MacCutcheon, Duras variation *
+r1b1kbnr/p1pp1ppp/1pn5/8/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation
+r1b1kbnr/pp1qpppp/2np4/1B6/3QP3/5N2/PPP2PPP/RNB1K2R w KQkq -
+Sicilian: Chekhover, Zaitsev variation
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6 *
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Spielmann variation *
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kbnr/pp2pppp/2nq4/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Mikenas attack *
+r1b1kbnr/pp3ppp/1qn1p3/2ppP3/3P4/2PB1N2/PP3PPP/RNBQK2R b KQkq -
+French: advance, Milner-Barry gambit
+r1b1kbnr/ppp1pppp/2n5/3q4/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Marshall gambit
+r1b1kbnr/ppp1pppp/2n5/7q/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Novosibirsk opening *
+r1b1kbnr/ppp1qppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Balogh variation
+r1b1kbnr/ppp2ppp/2n5/1B1p2q1/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Russian variation *
+r1b1kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPN1PPP/RNBQKB1R w KQkq -
+French: Steinitz, Gledhill attack *
+r1b1kbnr/ppp2ppp/2n5/3p4/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Zukertort defense
+r1b1kbnr/ppp3pp/2n2q2/3pN3/3PpP2/8/PPP3PP/RNBQKB1R w KQkq -
+Vienna gambit: Heyde variation *
+r1b1kbnr/ppp3pp/2n5/5pq1/2BPp3/4P3/PP1N1PPP/RNBQK2R w KQkq -
+French: Steinitz, Bradford attack *
+r1b1kbnr/pppnq2p/8/4Npp1/3Q1P2/8/PPP3PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, Charousek variation *
+r1b1kbnr/pppp1Npp/8/8/4q3/5n2/PPPPBP1P/RNBQKR2 w Qkq -
+Blackburne shilling gambit
+r1b1kbnr/pppp1p1p/2n5/4N3/2B1Pppq/8/PPPP2PP/RNBQ1K1R w kq -
+KGA: Herzfeld gambit
+r1b1kbnr/pppp1p1p/5q2/4n3/2B1PQ2/2N5/PPPP2PP/R1B2RK1 w kq -
+Vienna: Hamppe-Muzio, Dubois variation
+r1b1kbnr/pppp1ppp/2n2q2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Goldman (Spielmann) variation *
+r1b1kbnr/pppp1ppp/2n5/1B2p1q1/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Vienna: Zhuravlev countergambit *
+r1b1kbnr/pppp1ppp/2n5/1N6/4P2q/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Horwitz attack
+r1b1kbnr/pppp1ppp/2n5/8/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Boden defense
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Scotch: Steinitz variation
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Pulling counter-attack
+r1b1kbnr/pppp1ppp/2n5/8/4P2q/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Fraser attack
+r1b1kbnr/pppp2pp/2n2q2/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit: Paulsen attack *
+r1b1kbnr/pppp2pp/2n2q2/4N3/3PpP2/8/PPP3PP/RNBQKB1R b KQkq f3
+Vienna gambit: Bardeleben variation *
+r1b1kbnr/ppppq1pp/2n5/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Rubinstein variation *
+r1b1kbnr/ppppqppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Vinogradov variation
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed *
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Pir\'c variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, 4...c5 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, 4...Nc6 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical variation *
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov (Bastrikov) variation
+r1b1kbnr/ppqppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Flohr variation
+r1b2knr/pppp3p/2n2qP1/2b1p2Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Fraser variation *
+r1b2rk1/1p2qp1p/2n1pn2/pBbpN1p1/5B2/2P1P3/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch, S\"amisch variation *
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch variation, main line *
+r1b2rk1/1pp1qppp/2n2n2/p1bPp3/8/2PP1N2/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Nimzovich, Sozin variation *
+r1b2rk1/1pq1bppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R3QRK1 w - -
+Sicilian: Scheveningen, classical main line
+r1b2rk1/2q1bppp/p1np1n2/1pP1p3/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, Rauzer attack
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, 12...Nc6
+r1b2rk1/2q1bppp/p1pp1n2/np2p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Rossolimo defense
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, 12...c5d4
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Chigorin defense
+r1b2rk1/5ppp/p1pb4/1p1n4/3P4/1BP3Pq/PP3P1P/RNBQR1K1 w - -
+Ruy Lopez: Marshall, main line, 14...Qh3
+r1b2rk1/p1q2ppp/2n2n2/3pp3/N7/1B1P4/PPPB1bPP/R2Q1KNR w - -
+Evans gambit: Fraser-Mortimer attack *
+r1b2rk1/p4ppp/1qB2n2/2bp4/3P4/2N5/PPP2PPP/R1BQK2R b KQ -
+Giuoco Piano: Bernstein variation *
+r1b2rk1/p4ppp/2n2n2/q1bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR w KQ -
+Evans gambit: Fraser attack *
+r1b2rk1/pp1n1ppp/2p1pn2/q2p4/1bPP3B/2N1P3/PPQN1PPP/R3KB1R b KQ -
+QGD: Cambridge Springs defense, Argentine variation
+r1b2rk1/pp1nqppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2Q1RK1 w - -
+Ruy Lopez: open, Malkin variation *
+r1b2rk1/pp1nqppp/2n1p3/3pP3/2pP1P2/2N2N2/PPPQ2PP/2KR1B1R w - -
+French: classical, St\a hlberg variation
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Orthodox defense, Bd3 line, 11.O-O
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BPN3/4PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Alekhine variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/1Q3RK1 b - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy)
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PPQ2PPP/5RK1 b - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar)
+r1b2rk1/pp2nppp/2pq1n2/3pp1B1/1b2P2N/1BNP4/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Blake variation
+r1b2rk1/pp2ppbp/1qnp1np1/4P3/3N1P2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Zollner gambit
+r1b2rk1/pp2ppbp/2nq1np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Botvinnik variation *
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 9.Qxc3 *
+r1b2rk1/pp2qppp/1bn2n2/4p3/1P6/P1NPP3/R4PPP/2BQKBNR b K -
+Sicilian: Smith-Morra gambit, Chicago defense *
+r1b2rk1/pp2qppp/2n1pn2/2bp4/2P1P3/2NB1N2/PP2QPPP/R1B2RK1 b - -
+QGD: Semi-Tarrasch, Levenfish variation
+r1b2rk1/pp2qppp/2nb1n2/2p1p3/2BP4/2N1PN2/PP2QPPP/R1B2RK1 w - -
+QGD: Semi-Tarrasch, Levenfish variation *
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical, 13.de
+r1b2rk1/ppp1qppp/2n2n2/1B1pp3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 w - -
+Four knights: Alatortsev variation
+r1b2rk1/ppp1qppp/2np1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Metger unpin
+r1b2rk1/pppp2pp/2n5/2b1pq2/4N3/5Q2/PPPP1P1P/R1B1KBNR b KQ -
+Vienna: Hamppe-Muzio, Dubois variation *
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with Qc2 *
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, main line *
+r1b3nr/ppppkBpp/1b6/nP2N1qQ/4P3/8/P1PP1PPP/RNB1K2R b KQ -
+Evans gambit declined, V\'asquez variation
+r1b3r1/ppp2k1p/1b6/nP2B1q1/3PP3/8/P1PN1PPP/R2QK2R b KQ -
+Evans gambit declined, Pavlov variation
+r1bB1rk1/pp3ppp/8/4p3/3nn3/3P4/PPP1KbPP/R2Q1BNR w - -
+Scotch: Sea-cadet mate *
+r1bk1bnr/2p2ppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation *
+r1bk2nr/pppp1Qpp/1b6/nP2q3/2B1P3/8/PBPP1PPP/RN2K2R b KQ -
+Evans gambit declined, Hicken variation
+r1bk2nr/pppp1ppp/2n3q1/1N6/8/8/PPPNBPPP/R2Q1RK1 w - -
+Scotch: Rosenthal variation
+r1bk2nr/ppppq1pp/2n5/2b1PP1Q/8/8/PPPP2PP/RNBK1BNR b - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation *
+r1bnk2r/ppppnppp/5q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R w KQkq -
+Scotch: Paulsen, Gunsberg defense
+r1bq1b1r/ppn3pp/2p1k3/3np3/2BPQ3/P1N5/1PP2PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Leonhardt variation
+r1bq1b1r/ppp1n1pp/4k3/3np3/2B5/2N2Q2/PPPP1PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Polerio defense
+r1bq1b1r/ppp2kp1/2n5/1B1p1PPp/3Qn3/5N2/PPP2P1P/RNB1K2R w KQ -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/3P4/2N5/PPP2PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Zukertort defense *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/8/1PN5/P1PP1PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation *
+r1bq1k1r/2p2ppp/p4n2/1pbPR1N1/3n4/1B6/PPPP1PPP/RNBQ2K1 w - -
+Ruy Lopez: Rabinovich variation
+r1bq1k1r/pp2nppp/2n5/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit: Ne2 variation *
+r1bq1knr/pp3p1p/2n3p1/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit *
+r1bq1knr/ppp3pp/2n5/2bp1P1Q/4p1P1/3P4/PPP2PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Grimm attack *
+r1bq1knr/ppp3pp/2n5/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R b KQ -
+KGA: bishop's gambit, classical defense *
+r1bq1knr/ppp4p/2n3p1/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1knr/pppp3p/2n3p1/2b1pP1Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1r1k/1pp1b1pp/2n5/p2npp2/8/P1NPPN2/1PQ1BPPP/R1B1K2R w KQ -
+Sicilian: Scheveningen, classical, Mar\'oczy system *
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+King's Indian: orthodox, 7...Nbd7, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/P1N1PN2/1PQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+Benoni: fianchetto, 11...Re8 *
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+Benoni: classical with ...a6 and 10...Bg4 *
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9...a6, 10.a4 *
+r1bq1rk1/1p2ppbp/2np1np1/p7/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, Byrne variation
+r1bq1rk1/1p2ppbp/2np1np1/p7/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Alekhine variation
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+QGD Slav: Dutch variation *
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd *
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Panno variation
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Panno formation
+r1bq1rk1/1pp2ppp/1bn5/p2PN3/1P1P4/P7/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Berger variation *
+r1bq1rk1/1ppnbppp/p3pn2/3P2B1/3P4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, Swiss, Karlsbad variation
+r1bq1rk1/1ppnbppp/p3pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense, Swiss (Henneberger) variation
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Smyslov defense
+r1bq1rk1/2p1bppp/2np1n2/pp2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (9...a5) variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1P4/4p3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall, Herman Steiner variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall counter-attack
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.d4
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.h3
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed (with ...d6)
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BPP1N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Pilnik variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/2P2N2/PPBP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Lutikov variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/PBP2N2/1P1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Suetin variation
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed (9...Na5)
+r1bq1rk1/2pnbppp/p1np4/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP2N/1BP4P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, Simagin variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer, Borisenko variation
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, 7...O-O
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w - -
+Ruy Lopez: Worrall attack, sharp line
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 8.c3
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, anti-Marshall 8.a4
+r1bq1rk1/3nbppp/p2p4/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (...Nd7) defense
+r1bq1rk1/4bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Borisenko defense
+r1bq1rk1/4bppp/p1p5/1p1nR3/3P4/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, main line, 12.d2d4
+r1bq1rk1/4bppp/p1p5/1p1nR3/8/1BP5/PP1P1PPP/RNBQ2K1 w - -
+Ruy Lopez: Marshall counter-attack, 11...c6
+r1bq1rk1/4bppp/p2p1n2/npp1p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed (10...c5)
+r1bq1rk1/4bppp/ppnppn2/8/2P1P3/N1N5/PP2BPPP/R1BQ1RK1 w - -
+Sicilian, Sz\'en, hedgehog variation
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line *
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3 *
+r1bq1rk1/5ppp/p2b4/1p1p4/3P4/2P1R3/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, Kevitz variation
+r1bq1rk1/p1p2ppp/2pp1n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Svenonius variation *
+r1bq1rk1/p1pnbppp/1p3n2/1B1p2B1/3P4/2N1PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Capablanca variation
+r1bq1rk1/p1pnbppp/1p3n2/3p2B1/3P4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Pillsbury attack
+r1bq1rk1/p1ppbppp/8/2p1P3/3B4/2N5/PPP1QPPP/R3R1K1 w - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation
+r1bq1rk1/p2nbppp/1pp1pn2/3p4/P1PP4/5NP1/1PQ1PPBP/RNBR2K1 b - -
+Catalan: closed, Zagoryansky variation
+r1bq1rk1/p2nbppp/2p1pn2/1p4B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, fianchetto variation
+r1bq1rk1/p2pppbp/1pn2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with b3 *
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack *
+r1bq1rk1/p3nppp/2p5/2bpp3/8/1P4P1/P1PQPPBP/RNB2RK1 b - -
+Gr\"unfeld: exchange, Larsen variation *
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with b3 *
+r1bq1rk1/p4ppp/2n2n2/2bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit *
+r1bq1rk1/p4ppp/2n2n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Morphy attack *
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical main line
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 9...Nbd7
+r1bq1rk1/pp1n1pp1/2p1pb1p/8/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Petrosian variation
+r1bq1rk1/pp1n1ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, St. Petersburg variation *
+r1bq1rk1/pp1n1ppp/1bp5/3P4/1PN1p1n1/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation, Karpov gambit *
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation
+r1bq1rk1/pp1n1ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7
+r1bq1rk1/pp1n2pp/2n1pp2/2bpP3/5PQ1/P1N2N2/1PP3PP/R1B1KB1R w KQ -
+French: Steinitz, Brodsky-Jones variation
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 w - -
+Benoni: classical, 11.f3 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+Benoni: classical, 9...Re8, 10.Nd2 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+Benoni: classical with ...Re8 and ...Na6 *
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP3P/2N1PN2/PP3PP1/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Janowski variation
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver
+r1bq1rk1/pp1nbppp/2p1p3/3p2B1/2PPn3/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack (with Rc1)
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/1P3NP1/P1Q1PPBP/RNB2RK1 b - -
+Catalan: closed, Qc2 & b3
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/2NQ1NP1/PP2PPBP/R1B2RK1 b - -
+Catalan: closed, Botvinnik variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+Catalan: closed, main line
+r1bq1rk1/pp1nbppp/2p4n/3pp1N1/2BPPP2/2P5/PP4PP/RNBQ1RK1 w - -
+Philidor: Hanham, Berger variation
+r1bq1rk1/pp1nbppp/2pp1n2/8/P1BpP3/2N2N2/1PP1QPPP/R1B2RK1 w - -
+Philidor: Nimzovich, Sozin variation
+r1bq1rk1/pp1nbppp/4pn2/2pP2B1/3P4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein)
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+Nimzo-Indian: S\"amisch, main line
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+English: symmetrical, hedgehog system *
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1PN2NP1/P2PPPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with b3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2NP1NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d4
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+English: Symmetrical, Keres defense *
+r1bq1rk1/pp2b1pp/2n2n2/2pp4/4pB2/1N2PP2/PPP1B1PP/RN1Q1RK1 b - -
+Alekhine's defense: four pawns attack, Korchnoi variation *
+r1bq1rk1/pp2bppp/2n1pn2/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQR1K1 b - -
+R\'eti: King's Indian attack, French variation
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+QGD: Tarrasch, Prague variation, 9.Bg5
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, Normal position
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation) *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b - -
+King's Indian: orthodox, Donner variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+King's Indian: orthodox variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7 *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9.O-O *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+Benoni: classical, 9...Re8 *
+r1bq1rk1/pp2bppp/2np1n2/4p1B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/1BN1B3/PPP3PP/R2QK2R b KQ -
+Sicilian: Sozin, Fischer variation
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/3ppn2/6B1/3nPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/n1n5/2p1p3/8/PPNPPN2/4BPPP/R1BQ1RK1 b - -
+Sicilian, Sz\'en, hedgehog variation *
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav Panno *
+r1bq1rk1/pp2ppbp/2n2np1/2pp2B1/8/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, Simagin variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d4 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav, 7.O-O *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2PP1NP1/PP2PPBP/RN1Q1RK1 b - -
+King's Indian: fianchetto, Larsen system *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+Dutch: Leningrad, main variation with Nc6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+Dutch: Leningrad, main variation with c6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+Dutch: Ilyin-Genevsky variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 7.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Panno variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+QGD: Tarrasch, Prague variation, Normal position *
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+Benoni: fianchetto, 9...Nbd7 *
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd
+r1bq1rk1/pp2ppbp/2np1np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d3 *
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav Panno
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+Sicilian: dragon, Yugoslav attack, 9.Bc4
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+King's Indian: Four pawns attack, main line
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/2KR3R b - -
+Sicilian: dragon, classical, Grigoriev variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R4RK1 b - -
+Sicilian: dragon, classical, Richter variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1BP2/PPPQ2PP/2KR1B1R b - -
+Sicilian: dragon, Yugoslav attack, Rauser variation
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+Sicilian: dragon, classical, 9.Nb3
+r1bq1rk1/pp2ppbp/5np1/n7/2BP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+QGD: Tarrasch, R\'eti variation *
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical main line *
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation, 8.e4 *
+r1bq1rk1/pp3ppp/2B2n2/2b1N3/3p4/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller (Therkatz) attack *
+r1bq1rk1/pp3ppp/2B2n2/2bpN3/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano *
+r1bq1rk1/pp3ppp/2N2n2/1Bbp4/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano: Greco variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP2QPPP/RNB2RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc *
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd
+r1bq1rk1/pp3ppp/2n2n2/2bp4/N7/5NP1/PP2PPBP/R1BQ1RK1 b - -
+QGD: Tarrasch, R\'eti variation
+r1bq1rk1/pp3ppp/2nbpn2/1BPp4/8/2N1PN2/PPP2PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Ragozin variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/1P2PN2/P4PPP/RNBQ1RK1 b - -
+Nimzo-Indian: 4.e3, Keres variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6 *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7 *
+r1bq1rk1/pp3ppp/2nbpn2/2pp2B1/3P4/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Smyslov defense *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+QGD: Semi-Tarrasch, symmetrical variation *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+QGD: Semi-Tarrasch, symmetrical variation
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/3P1B2/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Flohr defense *
+r1bq1rk1/pp3ppp/3b4/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQ -
+QGD semi-Slav: Meran, Sozin variation *
+r1bq1rk1/pp4bp/2nppnp1/2p5/2P1PPPP/2N5/PP2B3/R1BQK1NR b KQ -
+King's Indian: Six pawns attack
+r1bq1rk1/ppbn1Npp/2p2n2/8/1PBPp3/P1N1B3/2P2PPP/R2Q1RK1 b - -
+Ruy Lopez: open, Dilworth variation *
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6 *
+r1bq1rk1/ppp1bppp/2n1pn2/8/3PN3/P5N1/1PP1BPPP/R1BQK2R w KQ -
+French: Winawer, Alekhine gambit, Alatortsev variation
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1P1N1PPP/R1BQKB1R b KQ -
+Sicilian: Scheveningen, classical, Nd7 system *
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1PQ2PPP/RNB1KB1R b KQ -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1
+r1bq1rk1/ppp1nppN/3p4/3P4/2B1R3/8/PP3PPP/R2Q2K1 b - -
+Giuoco Piano: Therkatz-Herzog variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Pillsbury variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b1PP3/2N2N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: Alatortsev variation *
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical, Mar\'oczy system *
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with Nc6
+r1bq1rk1/ppp1ppbp/2n2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Byrne (Simagin) variation
+r1bq1rk1/ppp1ppbp/2n3p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's improved variation
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nc6
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, 6...Nc6
+r1bq1rk1/ppp1ppbp/n2p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Kazakh variation
+r1bq1rk1/ppp1ppbp/n4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Prins variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation)
+r1bq1rk1/ppp2ppp/1b1p1n2/4p3/N3P3/3P1B2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation
+r1bq1rk1/ppp2ppp/2Bp1n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights *
+r1bq1rk1/ppp2ppp/2n1pn2/8/1bpP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Ragozin variation
+r1bq1rk1/ppp2ppp/2n2n2/1B1pp3/4P3/2PP1N2/P1P2PPP/R1BQ1RK1 w - -
+Four knights: Svenonius variation
+r1bq1rk1/ppp2ppp/2n2n2/3Pp3/1b6/2NP1N2/PPPB1PPP/R2QKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Wolf variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2QK2R b KQ -
+Ruy Lopez: Berlin defense, hedgehog variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Showalter variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: double Ruy Lopez *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: symmetrical variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical variation
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Mar\'oczy system
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/4P3/2PP1N2/P1P2PPP/R1BQR1K1 b - -
+Four knights: Janowski variation
+r1bq1rk1/ppp2ppp/3p1b2/n3p3/4P3/1B1P1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation *
+r1bq1rk1/ppp3pp/2n2P2/2bp1PB1/8/2p5/PPP2P1P/R2QKBNR w KQ -
+Vienna: Pierce gambit, Rushmere attack *
+r1bq1rk1/ppp3pp/2n5/1B1p1p2/1b2p3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Bardeleben variation *
+r1bq1rk1/pppn1pb1/3p3p/3Pp1pn/2P1P2P/2N2NB1/PP2BPP1/R2QK2R b KQ -
+King's Indian: Petrosian system, Keres variation
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, main line
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation, 8.e4
+r1bq1rk1/pppn1ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation *
+r1bq1rk1/pppnbBpp/3p1n2/4p1N1/3PP3/2N5/PPP2PPP/R1BQK2R b KQ -
+Philidor: Nimzovich, L\"arobok variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/1QN1PN2/PP3PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rauzer variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, 7.Rc1
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Orthodox defense
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rubinstein variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2NBPN2/PP3PPP/R2QK2R b KQ -
+QGD: Orthodox defense, Botvinnik variation
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Catalan: closed, 6...Nbd7
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+Catalan: closed, 7.Qc2
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P1P1/2N2P2/PP2B2P/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, main line
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nd7
+r1bq1rk1/pppnppbp/5np1/6N1/2BP4/1QN1P3/PP3PPP/R1B1K2R b KQ -
+Gr\"unfeld: Pachman variation
+r1bq1rk1/pppp1ppp/1bn2n2/1B2p3/3PP3/2P2N2/PP3PPP/RNBQ1RK1 w - -
+Ruy Lopez: classical defense, Benelux variation
+r1bq1rk1/pppp1ppp/2B2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Nimzovich (Paulsen) variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2P3/1b1P1P2/2N5/PPP3PP/R1BQ1RK1 w - -
+Four knights: Bardeleben variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: double Ruy Lopez
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2b2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Nimzovich (Paulsen) variation *
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2bP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights
+r1bq1rk1/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQ -
+Four knights: Rubinstein counter-gambit, Henneberger variation *
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/2BPP3/2P5/P4PPP/RNBQ1RK1 b - -
+Evans gambit: Richardson attack
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Knorre variation *
+r1bq1rk1/pppp1ppp/2n5/1B1P4/1b2p3/5N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Gunsberg counter-attack
+r1bq1rk1/pppp1ppp/2n5/3Np3/1bB1n3/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Marshall variation *
+r1bq1rk1/pppp1ppp/5n2/1B2P3/1b1p4/2N5/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Gunsberg counter-attack *
+r1bq1rk1/pppp1ppp/5n2/1Bb1N3/3nP3/2N5/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Marshall variation
+r1bq1rk1/pppp1ppp/5n2/4n1N1/1bB5/8/PB3PPP/RN1Q1RK1 w - -
+Scotch gambit: Hanneken variation
+r1bq1rk1/pppp2pp/2n2n2/2b1pPP1/8/2N5/PPPP1P1P/R1BQKBNR w KQ -
+Vienna: Hamppe-Muzio gambit *
+r1bq2k1/pp3p1p/5n2/2b1r1p1/3p4/3P1B2/PPP1NPPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller, bayonet attack *
+r1bq3r/pp3pkp/2n2np1/4p3/2Pp4/3P1NP1/4PPBP/RN1Q1RK1 w - -
+Benk\"o gambit: main line *
+r1bq3r/ppp2k1p/2n3p1/2Qp4/3pP3/8/PPP2PPP/RNB1K2R w KQ -
+Scotch gambit: Cochrane-Shumov defense
+r1bq3r/ppp3pp/5k2/3pN3/1n1Pn3/1Q3P2/PP4PP/RN2K2R b KQ -
+Giuoco Piano: Krause variation
+r1bqk1nr/1ppp1ppp/p1n5/2b1p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Classical defense deferred
+r1bqk1nr/1ppp1ppp/p1n5/4p3/Bb2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense deferred
+r1bqk1nr/1ppp1ppp/pbn5/4p3/PPB1P3/2N2N2/2PP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Showalter variation
+r1bqk1nr/2pp1ppp/p1n5/1pb1p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Graz variation
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, main line *
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3, Botvinnik system *
+r1bqk1nr/p1pp1ppp/2n5/bp2p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Leonhardt variation
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: exchange, classical variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/1P2P3/P2N1PPP/RNBQKB1R b KQkq -
+French: Tarrasch, Botvinnik variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqk1nr/pp1nbppp/2pp4/4P3/2B1P3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Steiner variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p2P2/2B1P3/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+Sicilian: Grand Prix attack, Schofman variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk1nr/pp1p1pbp/2n3p1/1Bp1p3/1P2P3/5N2/P1PP1PPP/RNBQR1K1 b kq -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system *
+r1bqk1nr/pp1p1pbp/4p1p1/2p5/3nP3/3PB1P1/PPP1NPBP/R2QK1NR b KQkq -
+Sicilian: closed, Smyslov variation
+r1bqk1nr/pp1p1ppp/2n5/2b5/2pNp3/3PP3/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation *
+r1bqk1nr/pp1pppbp/2N3p1/8/8/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+English: ultra-symmetrical variation *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: ultra-symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2NPB3/PPP2PPP/R2QKBNR b KQkq -
+English, Tr\"oger defense *
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Rubinstein system *
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7
+r1bqk1nr/pp1pppbp/2n3p1/8/8/1N4P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Czech defense *
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, 6.Be2 *
+r1bqk1nr/pp2b3/2n5/2p1pppp/2P5/2NPPNP1/PP4BP/R1BQ1RK1 w kq -
+King's Indian: Six pawns attack *
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Be2 *
+r1bqk1nr/pp2ppbp/2n3p1/2pp4/5P2/2PP1N2/PPQ1P1PP/RNB1KB1R b KQkq -
+Dutch: Hort-Antoshin system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+English: closed system (without ...d6) *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+Sicilian: closed
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+Sicilian: closed, 6.Be3
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4PP2/2NP2P1/PPP3BP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP1NPBP/R1BQK2R w KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik)
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+English: Botvinnik system *
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4PP2/2NP2P1/PPP3BP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik)
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5 *
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 *
+r1bqk1nr/pp3ppp/2nbp3/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: Dus-Khotimirsky variation *
+r1bqk1nr/pp3ppp/8/1Pb1p3/1nPp4/3P1N2/4PPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack *
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Taimanov variation *
+r1bqk1nr/ppp1bp1p/2n5/3pp1p1/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Chinese variation *
+r1bqk1nr/ppp1bpp1/2n5/3pp2p/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: bayonet (Mariotti) attack *
+r1bqk1nr/ppp1bppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc defense *
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Kotov variation
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+English: Botvinnik system
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+Sicilian: closed *
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/ppp2ppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 b kq -
+Evans gambit: Ulvestad variation
+r1bqk1nr/ppp2ppp/1b1p4/n5B1/2BPP3/2N2N2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: G\"oring attack
+r1bqk1nr/ppp2ppp/1bnp4/4p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Lasker defense
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/2N2N2/P4PPP/R1BQ1RK1 b kq -
+Evans gambit: Morphy attack
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: normal variation
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: LaBourdonnais variation
+r1bqk1nr/ppp2ppp/2n1p3/8/3Pp3/P1N5/1PP2PPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit, Kan variation
+r1bqk1nr/ppp2ppp/2n5/2bpp3/1PB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans counter-gambit
+r1bqk1nr/ppp2ppp/2n5/2bpp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Holmov system *
+r1bqk1nr/ppp2ppp/2nb4/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Swiss variation *
+r1bqk1nr/ppp2ppp/2np4/b3p1B1/2BPP3/2P2N2/P4PPP/RN1QK2R b KQkq -
+Evans gambit: Sokolsky variation
+r1bqk1nr/ppp2ppp/2np4/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 w kq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/1QP2N2/P4PPP/RNB1K2R b KQkq -
+Evans gambit: Tartakower attack
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b7/2BpP3/1QP2N2/P4PPP/RNB2RK1 b kq -
+Evans gambit: Waller attack
+r1bqk1nr/ppp2ppp/3b4/3pn3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Alekhine gambit *
+r1bqk1nr/ppp2ppp/8/2bp4/8/2P2P2/PP3PPP/RNBQKB1R w KQkq -
+Caro-Kann: Forg\'acs variation *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik) *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 *
+r1bqk1nr/ppp3pp/1b1p1p2/n7/2BPP3/2N1BN2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: Steinitz variation
+r1bqk1nr/ppp3pp/2n5/2bppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation *
+r1bqk1nr/pppn1ppp/3p4/2b1p3/4PP2/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+KGD: classical, Hanham variation
+r1bqk1nr/pppp1Bpp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Jerome gambit
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+English: closed, 5.Rb1
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+English: closed system (without ...d6)
+r1bqk1nr/pppp1ppp/1bn5/1B2p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Charousek variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/1PB1P3/5N2/PBPP1PPP/RN1QK2R b KQkq -
+Evans gambit declined, Cordel variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/PPB1P3/5N2/2PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined, 5.a4
+r1bqk1nr/pppp1ppp/2n5/1B2p3/1b2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: classical defense, 4.c3
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical (Cordel) defense
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Giuoco Pianissimo
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b3N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch game
+r1bqk1nr/pppp1ppp/2n5/2b5/4P3/1N6/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Potter variation
+r1bqk1nr/pppp1ppp/2n5/4p3/1bB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/1N6/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Romanishin variation
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Scotch: G\"oring gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bB1P3/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bBpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/b3P3/2B5/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit: Cochrane variation
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 b kq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b7/2B1P3/2p2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: compromised defense
+r1bqk1nr/pppp1ppp/2nb4/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Stone-Ware variation
+r1bqk1nr/pppp1ppp/8/1Bb1p3/1P1nP3/5N2/P1PP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: classical defense, Zaitsev variation
+r1bqk1nr/pppp2pp/2n5/1Bb1pp2/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cordel gambit
+r1bqk1nr/pppp2pp/2n5/1Bb2P2/4p3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+KGA: bishop's gambit, Paulsen attack *
+r1bqk1nr/pppp2pp/2n5/2b1p1N1/2B1Pp2/3P4/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo: Dubois variation
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Jaenisch variation *
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KGA: bishop's gambit, Bogolyubov variation *
+r1bqk1nr/ppppbppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Lucena defense
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: 5...Be7
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Hungarian defense
+r1bqk1nr/ppppbppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Romanishin variation
+r1bqk1nr/ppppbppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Benima defense
+r1bqk1nr/ppppbppp/2n5/8/4P3/2P1Q3/PP3PPP/RNB1KBNR w KQkq -
+Center game: Charousek variation
+r1bqk1nr/ppppbppp/8/n3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Cordel variation
+r1bqk2r/1p1p1ppp/p1n1pn2/8/1bPNP3/2N5/PPB2PPP/R1BQK2R b KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: closed, Averbach variation
+r1bqk2r/1pp1bppp/p5n1/3pn3/8/2N1PN2/PPP1BPPP/R1BQ1RK1 b kq -
+French: Winawer, Alekhine gambit, Alatortsev variation *
+r1bqk2r/1ppn1p1p/p4b1Q/1B6/8/2N2N2/PP1P1PPP/n1BK3R w kq -
+Scotch: Berger variation *
+r1bqk2r/1ppp1ppp/p1n2n2/2b1p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: M\"oller defense
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Exchange variation doubly deferred (DERLD)
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, center attack
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed defense
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: Worrall attack
+r1bqk2r/1pppbppp/p1n5/4P3/B2pn3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, Basque gambit (North Spanish variation)
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/3PP3/1B3N2/PPP2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, 7...d6, 8.d4
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w kq -
+Ruy Lopez: Worrall attack, solid line
+r1bqk2r/2pp1ppp/2n2n2/ppb1p3/4P3/PBN5/1PPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Showalter variation *
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Wing attack
+r1bqk2r/4bppp/p2p1n2/1pp5/3QP3/1B6/PPP2PPP/RNB1R1K1 w kq -
+Ruy Lopez: Noah's ark trap
+r1bqk2r/4nppp/p1pb4/2ppp3/2P5/1PN1P3/P2P1PPP/R1BQNRK1 b kq -
+Nimzo-Indian: S\"amisch, Capablanca variation *
+r1bqk2r/5ppp/p1n1pn2/1pb1P3/2B5/5N2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, Furman variation
+r1bqk2r/p1ppbppp/2p5/4Pn2/8/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Cordel variation
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Spassky variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/1P4P1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's lesser variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/2N3P1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's improved variation *
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+Nimzo-Indian: e3, H\"ubner variation *
+r1bqk2r/pnppbppp/2p5/4P3/2P5/5N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Zukertort variation
+r1bqk2r/pnppbppp/2p5/4P3/3N4/8/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Winawer attack
+r1bqk2r/pnppbppp/2p5/4P3/8/1P3N2/P1P1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Pillsbury variation
+r1bqk2r/pp1n1ppp/2p1pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Romih variation
+r1bqk2r/pp1n1ppp/2pbpn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Chigorin defense
+r1bqk2r/pp1n1ppp/3bpn2/2pp4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav: Semmering variation *
+r1bqk2r/pp1n1ppp/3bpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD: Stonewall variation *
+r1bqk2r/pp1nbppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Bogolyubov variation
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/1NN1P3/PP3PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Leningrad variation *
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, closed variation, main line *
+r1bqk2r/pp1p1ppp/2n1p3/2P5/1bP5/1QN2N2/PP1nPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation
+r1bqk2r/pp1p1ppp/2n1p3/2n5/1bP5/1QN2N2/PP1BPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, San Remo variation
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6
+r1bqk2r/pp1p1ppp/2nNpn2/8/1b2P3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov, American attack
+r1bqk2r/pp1p1ppp/2nb1n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+English: Queens Indian, Romanishin variation *
+r1bqk2r/pp1p2pp/2n1p3/2n2p2/1bP5/2N2NP1/PPQBPP1P/R3KB1R b KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2PN/PPP2PBP/R1BQK2R b KQkq -
+English: closed, Taimanov variation *
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+English: closed, Hort variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical variation
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/6P1/PPP2PBP/RNBQK2R b KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation *
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+Sicilian: accelerated fianchetto, Breyer variation
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack *
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, Florentine gambit *
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, with Be2 and Nf3 *
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+Benoni: four pawns attack, main line *
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: Symmetrical, Keres defense
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Petrosian system *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+King's Indian: Petrosian system, main line *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/4p3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Andersson variation *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/P2pP3/3P1NP1/1PP2PBP/RNBQ1RK1 b kq -
+King's Indian: Petrosian system, Stein variation *
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: classical variation *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: 6.Be2 *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/N2P1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: Kazakh variation *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7
+r1bqk2r/pp2bppp/2nppn2/8/2BNP3/2N1B3/PPP1QPPP/R3K2R b KQkq -
+Sicilian: Velimirovi\'c attack
+r1bqk2r/pp2bppp/2nppn2/8/3NPP2/2N1BQ2/PPP3PP/R3KB1R b KQkq -
+Sicilian: Scheveningen, Tal variation
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Pomar system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: fianchetto, Yugoslav system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: anti-Queen's Indian system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nc6 *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nd7 *
+r1bqk2r/pp2ppbp/2n2np1/3p2B1/2PP4/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Tarrasch, Wagner variation *
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7 *
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: fianchetto variation *
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+Sicilian: dragon, classical, 8.O-O
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R3K2R b KQkq -
+Sicilian: dragon, classical, Amsterdam variation
+r1bqk2r/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical, Nottingham variation
+r1bqk2r/pp2ppbp/2np2pn/8/2P1P3/8/PPN1BPPP/RNBQK2R w KQkq -
+Sicilian: accelerated fianchetto, Simagin variation
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran variation *
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 7.Bc4 *
+r1bqk2r/pp3ppp/2n2n2/1Bb1p3/8/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Scotch: G\"oring gambit, Bardeleben variation *
+r1bqk2r/pp3ppp/2n2n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Greco's attack *
+r1bqk2r/pp3ppp/2nb1n2/1P1pp3/8/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Pir\'c variation *
+r1bqk2r/pp3ppp/2nb1n2/3p4/1PP1p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, old main line *
+r1bqk2r/pp3ppp/2nb1n2/3pp3/1PP5/P3PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran *
+r1bqk2r/pp3ppp/2nb1n2/4p3/1PPp4/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Reynolds' variation *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...c5 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...b6 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/2P1PN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Romih variation *
+r1bqk2r/pp3ppp/2nbpn2/1P1p4/8/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation) *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 6.Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQK2R b KQkq -
+QGD semi-Slav: Bogolyubov variation *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2PBPN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Chigorin defense *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD semi-Slav: stonewall defense *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/2P1PN2/PB1N1PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Meran, Wade variation *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, 8...a6 *
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch, 7.Bd3 *
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+Nimzo-Indian: e3, H\"ubner variation
+r1bqk2r/pp3ppp/3b1n2/3P2N1/1n2p3/P3P3/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Rabinovich variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2N3/P3PN2/5PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Sozin variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation *
+r1bqk2r/ppb2ppp/2n5/1Bpnp3/8/P1N1PN2/1P1P1PPP/R1BQK2R w KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation *
+r1bqk2r/ppp1bpp1/5n1p/3P4/2P1p3/5N2/PPP1QPPP/RNB1K2R w KQkq -
+two knights defense: Mar\'oczy variation
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3 *
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical system, 5.Be2 *
+r1bqk2r/ppp1bppp/2n5/1B1pp3/3Pn3/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation
+r1bqk2r/ppp1bppp/2n5/3np3/4P3/2NP1N2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Boleslavsky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: classical *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: modern Scheveningen *
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.Be2 *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Opo\v censky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bqk2r/ppp1bppp/2n5/3p4/2PPn3/3B1N2/PP3PPP/RNBQ1RK1 b kq -
+Petrov: classical attack, Jaenisch variation
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Chigorin variation
+r1bqk2r/ppp1bppp/2n5/4p3/4P3/2nP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky, Louma variation *
+r1bqk2r/ppp1npbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik) *
+r1bqk2r/ppp1nppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 w kq -
+Evans gambit: Paulsen variation
+r1bqk2r/ppp1nppp/3p1b2/3P4/2B1R1P1/5N2/PP3P1P/R1BQ2K1 b kq -
+Giuoco Piano: M\"oller, bayonet attack
+r1bqk2r/ppp2pbp/2np2pn/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Taimanov variation
+r1bqk2r/ppp2pp1/5n1p/2bP4/2P1p3/8/PPPNQPPP/RNB1K2R b KQkq -
+two knights defense: Yankovich variation
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Sozin with ...a6 and ...b5 *
+r1bqk2r/ppp2ppp/2n1pn2/3p4/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Botvinnik variation
+r1bqk2r/ppp2ppp/2n2n2/2bpP3/2Bp4/2P2N2/PP3PPP/RNBQK2R w KQkq d6
+Giuoco Piano
+r1bqk2r/ppp2ppp/2n2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Schlechter variation *
+r1bqk2r/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPB1PPP/R2QKB1R w KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack *
+r1bqk2r/ppp2ppp/2n5/1B1pP3/1b1Pn3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: Anderssen variation
+r1bqk2r/ppp2ppp/2n5/2b5/4p3/2PP1NP1/P3PP1P/R1BQKB1R w KQkq -
+Sicilian: Magnus Smith trap *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/1QNP1N2/PP2PPPP/R1B1KB1R b KQkq -
+Sicilian: Sozin, Benk\"o variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, not Scheveningen *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Sozin, Leonhardt variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Sozin attack *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Lipnitzky attack *
+r1bqk2r/ppp2ppp/2n5/3np1N1/1bBP4/8/PPP2PPP/RNBQK2R w KQkq -
+two knights defense: Pincus variation
+r1bqk2r/ppp2ppp/2n5/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Venice attack *
+r1bqk2r/ppp2ppp/2n5/3np3/1b6/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation *
+r1bqk2r/ppp2ppp/2n5/3p4/2BP4/1Qb2N2/P4PPP/R1B2RK1 w kq -
+Giuoco Piano: Bernstein variation
+r1bqk2r/ppp2ppp/2n5/3p4/2BPn3/B1P2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Steinitz variation
+r1bqk2r/ppp2ppp/2n5/3pp3/2PPn3/P3P3/1PQ2PPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, San Remo variation
+r1bqk2r/ppp2ppp/2n5/3pp3/4P1n1/3P1N2/PPPNBbPP/R1BQ1RK1 w kq -
+Philidor: Nimzovich, L\"arobok variation *
+r1bqk2r/ppp2ppp/2nb4/1B1np3/4P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin, Jaffe variation *
+r1bqk2r/ppp2ppp/2np1n2/2b1p1B1/2B1P3/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+Giuoco Pianissimo: Canal variation
+r1bqk2r/ppp2ppp/2np1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Italian four knights variation *
+r1bqk2r/ppp2ppp/2np1n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Romanovsky variation *
+r1bqk2r/ppp2ppp/2nppn2/8/1bPP4/2N2N2/PPQ1PPPP/R1B1KB1R w KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation
+r1bqk2r/ppp2ppp/3p1n2/4p1B1/2BnP3/8/PPP2PPP/RN1Q1RK1 w kq -
+Giuoco piano
+r1bqk2r/ppp3p1/2n5/2bppPPp/4n2P/7B/PPPP1P1R/RNBQK1N1 w Qkq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation *
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Bd3 *
+r1bqk2r/pppn1ppp/4pn2/3p2B1/1bPP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Manhattan variation
+r1bqk2r/pppn1ppp/5n2/2bP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, Eliskases variation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3P4/2N1PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Reversed Philidor formation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Inverted Hanham *
+r1bqk2r/pppp1p2/5n1p/4p1p1/2BnPP1B/8/PPP3PP/RN1Q1RK1 b kq -
+Giuoco piano: Rosentreter variation
+r1bqk2r/pppp1pbp/2n3pn/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR w Kkq -
+English: closed, 5.Rb1 Taimanov variation
+r1bqk2r/pppp1pp1/5n1p/4n3/2PN3B/2P5/P3PPPP/R2QKB1R w KQkq -
+English: Nenarokov variation
+r1bqk2r/pppp1ppp/1b5n/nP2N3/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Lange variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...Nc6
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: double Ruy Lopez *
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: double Ruy Lopez
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Spanish, classical defense
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/3PBN2/PPP2PPP/RN1QK2R b KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Beverwijk variation
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense *
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Boden-Kieseritsky gambit *
+r1bqk2r/pppp1ppp/2n2n2/2b1P3/2Bp4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p1N1/2B1P3/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Wilkes Barre (Traxler) variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/1PB1P3/2P2N2/P2P1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Bird's attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano: four knights variation *
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo: Italian four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1PP2/2P5/PP1PQ1PP/RNB1K1NR b KQkq -
+Bishop's opening: Lopez gambit
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Italian variation *
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Rubinstein counter-gambit *
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Schlechter variation
+r1bqk2r/pppp1ppp/2n2n2/4N3/1b1PP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, Krause variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Spanish variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N3P1/PPPPNP1P/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Ruy Lopez: Schliemann defense, Berger variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish, classical defense *
+r1bqk2r/pppp1ppp/2n2n2/4p3/2P5/2b1PN2/PPQP1PPP/R1B1KB1R w KQkq -
+English: four knights, Romanishin variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Keres variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Four knights: Ranken variation *
+r1bqk2r/pppp1ppp/2n2n2/8/1bB1P3/2N2N2/PP3PPP/R1BQK2R w KQkq -
+Scotch: G\"oring gambit, Bardeleben variation
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/2N2N2/PP3PPP/R1BQK2R b KQkq -
+Giuoco Piano: Greco's attack
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/5N2/PP3PPP/RNBQ1K1R b kq -
+Giuoco Piano: Cracow variation
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: four knights (Tarrasch) variation *
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation *
+r1bqk2r/pppp1ppp/2n4n/2b3NQ/2BpP3/8/PPP2PPP/RNB1K2R b KQkq -
+Scotch gambit: Vitzhum attack
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack, Krause variation
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+two knights: Max Lange attack, Steinitz variation
+r1bqk2r/pppp1ppp/2n5/2bBP3/8/2p2NK1/PP4PP/RNBQ3R b kq -
+Giuoco Piano: Ghulam Kassim variation
+r1bqk2r/pppp1ppp/2n5/2bPp3/4n3/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+Ponziani: Fraser defense
+r1bqk2r/pppp1ppp/2n5/3P4/2B1n3/2b2N2/PP3PPP/R1BQ1RK1 b kq -
+Giuoco Piano: M\"oller (Therkatz) attack
+r1bqk2r/pppp1ppp/2n5/3np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation *
+r1bqk2r/pppp1ppp/2n5/8/1bBP4/2n2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano: Greco variation
+r1bqk2r/pppp1ppp/2n5/8/2BP4/B1b2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Aitken variation
+r1bqk2r/pppp1ppp/2n5/8/2BPn3/2b2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano
+r1bqk2r/pppp2pp/2n2n2/1Bb1pQ2/4P3/8/PPPP1PPP/RNB1K1NR w KQkq -
+KGD: Norwalde variation, B\"ucker gambit *
+r1bqk2r/pppp2pp/2n2n2/2b1p3/2P2p2/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: Grand Prix attack, Schofman variation *
+r1bqk2r/pppp2pp/2n2n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: MacDonnell gambit *
+r1bqk2r/pppp2pp/2n5/3Npp2/1b2n3/5N2/PPPPQPPP/R1B1KB1R w KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation *
+r1bqk2r/ppppbppp/2n2n2/3Np3/4P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2 *
+r1bqk2r/ppppbppp/2n5/1B2P3/4n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Minckwitz variation
+r1bqk2r/ppppbppp/2n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open Berlin defense, 5...Be7
+r1bqk2r/ppppbppp/2n5/4P3/2Bpn3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Hungarian defense: Tartakower variation
+r1bqk2r/ppppbppp/2nn4/4N2Q/8/1BN5/PPPP1PPP/R1B1K2R b KQkq -
+Vienna: Alekhine variation
+r1bqk3/ppp3p1/2n5/2bppP2/4n1P1/2PP4/PP3P2/RNBQK1NB w KQq -
+KGA: Greco gambit *
+r1bqkb1r/1p1n1ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical, Nd7 system
+r1bqkb1r/1p1ppppp/p1n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Marini variation *
+r1bqkb1r/1p2nppp/p1n1p3/2pp4/3P4/3BPN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: Simagin variation *
+r1bqkb1r/1p2pp1p/2n3p1/p1np4/4PB2/2P2N2/PPQN1PPP/R3KB1R b KQkq -
+QGD Slav: Carlsbad variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp2B1/8/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Steiner variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Czech defense *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: Soultanb\'eieff variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav accepted: Alapin variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P1PN2/PP3PPP/RN1QKB1R b KQkq -
+QGD Slav: Wiesbaden variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Krause attack *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Dutch variation *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Dutch, Lasker variation *
+r1bqkb1r/1p3ppp/2n2n2/p1Ppp1B1/8/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Smyslov variation *
+r1bqkb1r/1p3ppp/p1n1pn2/3p4/2P1P3/N1N5/PP3PPP/R1BQKB1R w KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6
+r1bqkb1r/1pp1nppp/p1B5/3pP3/8/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer, Alekhine gambit *
+r1bqkb1r/1pp2ppp/2P2n2/1p6/3Pp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Rauzer variation *
+r1bqkb1r/1pp2ppp/p1n5/3pP3/8/2N1P3/PPP2PPP/R1BQK1NR b KQkq -
+French: Winawer, Alekhine gambit, Kan variation *
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B1P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Morphy defense, Duras variation
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred (Russian defense)
+r1bqkb1r/1ppn1ppp/p3pn2/8/3P4/6P1/PPQ1PPBP/RNB1K1NR b KQkq -
+Catalan: open, Alekhine variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Ranken variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred)
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Gunsberg variation *
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: four knights (Tarrasch) variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Anderssen variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: 5.O-O
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Morphy defense
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB1K2R b KQkq -
+Ruy Lopez: Wormald (Alapin) attack
+r1bqkb1r/1ppp1ppp/p1n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Rosenthal variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 6.d4
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Knorre variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open (Tarrasch) defense
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Tartakower variation
+r1bqkb1r/1ppp1ppp/p1n5/8/B2pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Riga variation
+r1bqkb1r/1pppnppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense deferred
+r1bqkb1r/2p1nppp/p7/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Zukertort variation
+r1bqkb1r/2p2ppp/p1n5/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 8.de
+r1bqkb1r/2p2ppp/p1n5/1p1pp3/2PPn3/1B3N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Harksen gambit
+r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: ...b5 & ...d6
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, positional main line *
+r1bqkb1r/2p2ppp/p1pp4/4p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation
+r1bqkb1r/2p2ppp/p7/1p1p4/P2pn3/1BN5/1PP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Berger variation
+r1bqkb1r/2p2ppp/p7/1p1pp3/P2nn3/1B3N2/1PP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Schlechter defense
+r1bqkb1r/2p3pp/p1p5/3pPp2/4n3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation
+r1bqkb1r/2pp1ppp/p1n5/1p1Pp3/B3n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Richter variation
+r1bqkb1r/2pp1ppp/p1n5/1p2N3/B2Pn3/8/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Friess attack
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/3Pn3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 7.Bb3
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 6.d4 b5
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, 8...a6
+r1bqkb1r/3n1ppp/p1p1pn2/8/1p1PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Pir\'c variation
+r1bqkb1r/3n1ppp/p3p3/1N2P3/3p2n1/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Rabinovich variation
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation
+r1bqkb1r/3n1ppp/p3pn2/1pp1P3/3P4/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, old main line
+r1bqkb1r/3n1ppp/p3pn2/1pp5/3PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran
+r1bqkb1r/3n1ppp/p3pn2/1ppP4/4P3/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Reynolds' variation
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Sveshnikov variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B1Q2/PP3PPP/R1B1K2R b KQkq -
+QGD semi-Slav: Meran, Stahlberg variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B4/PP3PPP/R1BQ1RK1 b kq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Chelyabinsk variation
+r1bqkb1r/5ppp/p3pn2/1N2n3/3p4/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/p1p2ppp/2n2n2/1p1Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Ulvestad variation
+r1bqkb1r/p1p2ppp/8/1p1np3/3nN3/2P5/PP1P1PPP/RNBQKB1R b KQkq -
+two knights defense: Fritz, Gruber variation
+r1bqkb1r/p1pn1ppp/1p2pn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Zukertort variation *
+r1bqkb1r/p1pp1ppp/2p2n2/4P3/8/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Mieses variation
+r1bqkb1r/p1pp1ppp/2p2n2/8/4P3/8/PPPN1PPP/R1BQKB1R b KQkq -
+Scotch: Tartakower variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N2Q2/PP3PPP/R3KB1R b KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N3P1/PP3P1P/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran variation
+r1bqkb1r/p2n1ppp/2p1pn2/8/1p1P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation)
+r1bqkb1r/p3pp1p/2pp1np1/4P3/2B5/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Magnus Smith trap
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/p4pp1/2p2n1p/n3p3/8/7N/PPPPBPPP/RNBQK2R b KQkq -
+two knights defense: Steinitz variation
+r1bqkb1r/p4ppp/2n1pn2/1ppp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Makogonov variation *
+r1bqkb1r/p4ppp/2p2n2/3pp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: modern exchange variation *
+r1bqkb1r/p4ppp/2p2n2/n3p1N1/8/8/PPPPBPPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Bogolyubov variation
+r1bqkb1r/p4ppp/5n2/np2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQkq -
+two knights defense: Blackburne variation
+r1bqkb1r/pp1n1ppp/2n1p3/2PpP3/5P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+French: Steinitz variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P1P2/2N1BN2/PPP3PP/R2QKB1R b KQkq -
+French: Steinitz, Boleslavsky variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, closed variation
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+French: Tarrasch, closed variation, main line
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: 5...c6
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/4PN2/PP1N1PPP/R2QKB1R b KQkq -
+QGD: Capablanca variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/P1N1P3/1P3PPP/R2QKBNR b KQkq -
+QGD: Capablanca anti-Cambridge Springs variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Alekhine variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 5...Nd7
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PPQ2PPP/R1B1KB1R b KQkq -
+QGD semi-Slav: Stoltz variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 6.Bd3
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD Slav
+r1bqkb1r/pp1n1ppp/2p1pn2/3pN3/2PP4/2N1P3/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 7.Bc4
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/2PP4/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD Slav: Semmering variation
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PNP1/PP3P1P/RNBQKB1R b KQkq -
+QGD: Spielmann variation *
+r1bqkb1r/pp1npp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R w KQkq -
+Sicilian: dragon, Levenfish; Flohr variation
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Nimzovich (knight's tour) variation *
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: Nd2 variation *
+r1bqkb1r/pp1npppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Bogo-Indian defense, Gr\"unfeld variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+QGD: Albin counter-gambit, Janowski variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP1QPPP/R1B1KBNR b KQkq -
+QGD: Albin counter-gambit, Balogh variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, Alapin variation *
+r1bqkb1r/pp1npppp/5n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Breyer variation *
+r1bqkb1r/pp1p1Npp/2p1nn2/8/2B1P3/8/PPP2PPP/RNBQ1RK1 b kq -
+Scotch: Cochrane variation
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, 4.e3 *
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+English: symmetrical variation
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Nimzovich variation *
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation
+r1bqkb1r/pp1p1ppp/2n5/2ppP3/3P4/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit
+r1bqkb1r/pp1p1ppp/n1p2n2/8/2PNp3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+Sicilian: 2.c3, Heidenfeld variation *
+r1bqkb1r/pp1pnppp/2p2n2/1B2N3/4P3/3P4/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, kingside fianchetto *
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+English: Nimzo-English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p3B1/4P3/3P4/PPP2PPP/RN1QKBNR b KQkq -
+English, Smyslov defense *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: symmetrical, four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, four knights system
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+English: three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Queens Indian formation *
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/8/PPP1PPPP/RNBQKB1R w KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkb1r/pp1ppppp/2n5/2p1P3/1P4n1/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Bellon gambit *
+r1bqkb1r/pp1ppppp/2n5/2pnP3/8/N1P2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: 2.c3, Heidenfeld variation
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system) *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2 *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: Reshevsky variation *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation *
+r1bqkb1r/pp2nppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Kramer system *
+r1bqkb1r/pp2pp1p/2n2np1/2Pp4/3P4/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation *
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Tarrasch, Prague variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/1QN1PN2/PP1P1PPP/R1B1KB1R b KQkq -
+English: symmetrical, Geller variation *
+r1bqkb1r/pp2pp1p/2np1np1/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation
+r1bqkb1r/pp2pp1p/3p1np1/8/2PQP3/2N5/PP3PPP/R1B1KB1R w KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation
+r1bqkb1r/pp2pppp/2n2n2/1Bp1N3/2Pp4/4P3/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: three knights, Euwe variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bp5/2Pp4/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights, Korchnoi variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+QGD: Chigorin defense, Janowski variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav, Noteboom variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav accepted *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Semi-Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/1QP2N2/PP2PPPP/RNB1KB1R b KQkq -
+QGD Slav: S\"uchting variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Old Indian: Ukrainian variation, 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2ppP3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Bradley Beach variation *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, 5.cd *
+r1bqkb1r/pp2pppp/2n2n2/3p4/3P1B2/2PB4/PP3PPP/RN1QK1NR b KQkq -
+Caro-Kann: exchange, Rubinstein variation
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Benoni defense *
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: symmetrical variation *
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Capablanca variation *
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin, not Scheveningen
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: classical
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian
+r1bqkb1r/pp2pppp/5n2/n2P2B1/2p5/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense
+r1bqkb1r/pp3p1p/2n2np1/2Ppp3/3P4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation *
+r1bqkb1r/pp3ppp/1nn1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R w KQkq -
+French: Tarrasch, Leningrad variation
+r1bqkb1r/pp3ppp/2Np1n2/4p3/4P3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky, Louma variation
+r1bqkb1r/pp3ppp/2Nppn2/6B1/4P3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Richter attack
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD: Semi-Tarrasch, 7.Bd3
+r1bqkb1r/pp3ppp/2n1p3/2pp4/3Pn3/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system *
+r1bqkb1r/pp3ppp/2n1p3/3p4/3PnB2/4P3/PP1N1PPP/RN1QKB1R b KQkq -
+QGD Slav: Amsterdam variation *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5 *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5 *
+r1bqkb1r/pp3ppp/2n1pn2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 5.e3 (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5...Nd7 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/P1P1PN2/1P3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PN4/4P3/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch with e3 *
+r1bqkb1r/pp3ppp/2n1pn2/3p4/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: exchange variation *
+r1bqkb1r/pp3ppp/2n2n2/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: G\"oring gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Pp4/1P2p3/2P2N2/P3PPPP/RNBQKB1R w KQkq -
+QGD Slav: Tolush-Geller gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Slav gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/P4N2/1PP1PPPP/RNBQKB1R w KQkq -
+QGA, Bogolyubov variation *
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Prague variation
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: main line *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Nf3 *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/Q1P5/3P2P1/PP2PPBP/RNB1K1NR b KQkq -
+Pterodactyl defense *
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: classical with e4 and Nf3 *
+r1bqkb1r/pp3ppp/2np1n2/4p3/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Boleslavsky variation
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3
+r1bqkb1r/pp3ppp/2nppn2/1B4B1/3NP3/2N5/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, 6...e6
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2NQ4/PPP2PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Keres variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/4P3/1NN5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Sozin, 7.Be3
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Leonhardt variation
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: modern Scheveningen
+r1bqkb1r/pp3ppp/n1n5/2p1p3/3P4/P1N1PN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit *
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, dynamic line *
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: four pawns attack *
+r1bqkb1r/ppp1nppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit *
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/4B3/PP4PP/RN1QKBNR b KQkq -
+Alekhine's defense: four pawns attack, 7.Be3
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6
+r1bqkb1r/ppp2Npp/2n5/3np3/2B5/8/PPPP1PPP/RNBQK2R b KQkq -
+two knights defense: Fegatello attack
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, fianchetto variation *
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation *
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Keres attack *
+r1bqkb1r/ppp2p1p/2n5/3p2p1/Q3nB2/2P2N2/PP2PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Gr\"unfeld variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3p2B1/Q7/5N2/PPP1PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Lasker variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical, h3 system *
+r1bqkb1r/ppp2pp1/2n4p/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Adams attack *
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+Caro-Kann: classical, 7...Nd7 *
+r1bqkb1r/ppp2pp1/5nn1/3p4/7p/2P3BP/PP1NPPP1/R2QKBNR w KQkq -
+Caro-Kann: classical, Spassky variation *
+r1bqkb1r/ppp2ppp/2Bp1n2/4p3/4P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, Guimard main line
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+French: Reversed Philidor formation
+r1bqkb1r/ppp2ppp/2n2n2/3Pp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, 4...exd4 *
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: exchange, Bogolyubov variation
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/Q3P3/8/PPP2PPP/RN2KBNR b KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q3P3/8/PPP2PPP/RNB1KBNR w KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q4B2/5N2/PPP1PPPP/RN2KB1R b KQkq -
+Scandinavian defense *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Scotch variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Improved Hanham variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+Inverted Hanham
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/2PP2P1/PP2PPBP/RNBQK1NR b KQkq -
+Robatsch defense: two knights, Suttles variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: two knights variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Leonhardt variation
+r1bqkb1r/ppp2ppp/2n5/1B1n4/4p3/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Sicilian: Pin, Koch variation *
+r1bqkb1r/ppp2ppp/2n5/1B1np3/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin variation (Sicilian counter-attack) *
+r1bqkb1r/ppp2ppp/2n5/1B1pp3/4n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Scotch, Krause variation *
+r1bqkb1r/ppp2ppp/2n5/1B2p3/8/2NnPN2/PP1P1PPP/R1BQK2R w KQkq -
+Sicilian: Taimanov, American attack *
+r1bqkb1r/ppp2ppp/2n5/3np1N1/2BP4/8/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Lolli attack
+r1bqkb1r/ppp2ppp/2n5/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Steinitz variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+Sicilian: Taimanov (Bastrikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, modern variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+Sicilian: dragon variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Nc3 *
+r1bqkb1r/ppp2ppp/2n5/3p4/2Bpn3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+two knights defense: Canal variation
+r1bqkb1r/ppp2ppp/2n5/4P3/2BP2n1/4p3/PPP3PP/RNBQK1NR w KQkq -
+Philidor: Philidor counter-gambit, Berger variation *
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/2P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Duras variation
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, 4.O-O, d6
+r1bqkb1r/ppp2ppp/2np1n2/4p3/2P5/1PN1P3/P2P1PPP/R1BQKBNR w KQkq -
+Amsterdam attack
+r1bqkb1r/ppp2ppp/4pn2/4N3/3P4/8/PPP2PPP/R1BQKB1R b KQkq -
+French: Rubinstein, Capablanca line
+r1bqkb1r/ppp2ppp/5n2/3Pp1N1/2Bn4/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Fritz variation
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Belgrade gambit *
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Three knights: Steinitz, Rosenthal variation *
+r1bqkb1r/ppp2ppp/5n2/3p4/2PPp3/2N5/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit *
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2B1P3/PPP2PPP/RN1QKBNR b KQkq -
+French: Fort Knox variation *
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/3P4/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Kieseritsky variation
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense
+r1bqkb1r/ppp2ppp/5n2/nB1Pp1N1/8/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/ppp2ppp/6nn/3p4/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Flohr variation *
+r1bqkb1r/ppp2ppp/8/3p4/4n3/4PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Rubinstein, Capablanca line *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/4p3/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.e5 *
+r1bqkb1r/ppp3pp/2n2n2/3p4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Euwe defense *
+r1bqkb1r/ppp3pp/2n2n2/3ppP2/6P1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Pierce gambit *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/2P5/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+Pirc: Austrian attack, dragon formation *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Pirc: Austrian attack *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP1NPP1P/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish; Flohr variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, Levenfish variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.f4 *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.f4 *
+r1bqkb1r/ppp4p/3p1nN1/8/3np2Q/8/PPP2PPP/RNB1KB1R w KQkq -
+Vienna gambit, Wurzburger trap *
+r1bqkb1r/pppn1ppp/2np4/1B2p3/3PP3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Chigorin variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2NBP3/PP3PPP/R1BQK1NR b KQkq -
+Old Indian: Dus-Khotimirsky variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Old Indian: main line
+r1bqkb1r/pppn1ppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Philidor: Improved Hanham variation
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR b KQkq -
+QGD
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Nbd7
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+French: Tarrasch, open variation, main line *
+r1bqkb1r/pppn1ppp/5n2/3p4/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: exchange, S\"amisch variation
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Guimard main line *
+r1bqkb1r/pppn1ppp/5n2/4N3/4p3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Sokolsky variation *
+r1bqkb1r/pppn1ppp/8/4p3/8/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Tartakower variation *
+r1bqkb1r/pppp1ppp/2n1pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Kevitz variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, 4.O-O
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense
+r1bqkb1r/pppp1ppp/2n2n2/1B6/3pP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Nyholm attack
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Belgrade gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/4P3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Schultze-M\"uller gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Nimzovich attack *
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: two knights, 3...Bg4 *
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Italian variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense (Modern bishop's opening)
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, Nimzovich variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, 4.e3
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: four knights system
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+English: four knights, kingside fianchetto
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+English: four knights, Capablanca variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/P1N2N2/1P1PPPPP/R1BQKB1R b KQkq -
+English: four knights, Marini variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/5N2/PPP1BPPP/RNBQK2R b KQkq -
+Tayler opening
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Three knights: Steinitz variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Jaenisch counter-attack
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Four knights: Gunsberg variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Three knights: Winawer defense (Gothic defense) *
+r1bqkb1r/pppp1ppp/2n2n2/6N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense, Perreux variation
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Dubois-R\'eti defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2PPp3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+English: Bradley Beach variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Schmidt variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3pP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Four knights: Scotch, 4...exd4
+r1bqkb1r/pppp1ppp/2n2n2/8/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: Berger variation
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, open variation
+r1bqkb1r/pppp1ppp/2n5/2n1P3/3N4/8/PPP1QPPP/RNB1KB1R w KQkq -
+Petrov: modern attack, Bardeleben variation
+r1bqkb1r/pppp1ppp/2n5/4p3/4n3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Schultze-M\"uller gambit *
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2nn4/1B2P3/8/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, l'Hermet variation
+r1bqkb1r/pppp1ppp/2nn4/4p2Q/3P4/1BN5/PPP2PPP/R1B1K1NR b KQkq -
+Vienna: Adams' gambit
+r1bqkb1r/pppp1ppp/2nn4/4p3/B2P4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, Showalter variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3NP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Four knights: Rubinstein counter-gambit, Henneberger variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Three knights: Schlechter variation *
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Rubinstein counter-gambit
+r1bqkb1r/pppp1ppp/5n2/4p3/3nP3/2N2N2/PPPPBPPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Hamppe-Allgaier gambit *
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2NP4/PPP2P1P/R1BQKBNR b KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation *
+r1bqkb1r/pppp2p1/2n5/4pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Blackburne gambit *
+r1bqkb1r/pppp2pp/2n2n2/4N3/3Pp3/8/PPP1BPPP/RNBQK2R b KQkq -
+Vienna gambit: Breyer variation *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Quaade gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pp2/2B1P3/3P4/PPPN1PPP/R1BQK1NR b KQkq -
+KGD: classical, Hanham variation *
+r1bqkb1r/ppppnp1p/2n3p1/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense
+r1bqkb1r/ppppnppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: chameleon variation *
+r1bqkb1r/ppppnppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: R\'eti variation
+r1bqkb1r/ppppnppp/5n2/1B2p3/4P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation
+r1bqkb1r/ppppnppp/8/1B6/3pP3/8/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Bird's defense, Paulsen variation
+r1bqkb1r/pppppppp/2n2n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Kevitz-Trajkovich defense
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/1pp2ppp/p1n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, 5.a3 *
+r1bqkbnr/1pp2ppp/p1np4/4p3/B1P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: modern Steinitz defense, 5.O-O
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Keres variation
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: exchange variation, 5.O-O
+r1bqkbnr/1pp3pp/p1np4/4pp2/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Romanovsky variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Gligori\'c variation
+r1bqkbnr/1ppp1p1p/p1n3p1/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto defense deferred
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: exchange variation
+r1bqkbnr/1ppp1ppp/p1n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Mengarini variation *
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez
+r1bqkbnr/1ppp1ppp/p7/4p3/B2nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense deferred
+r1bqkbnr/1ppp2pp/p1n5/4pp2/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense deferred
+r1bqkbnr/1ppppppp/p1n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Battambang opening *
+r1bqkbnr/2p2ppp/2p5/p2p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, Smyslov variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+French: Winawer, advance, 6...Ne7 *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PPQ2PPP/RNB1K1NR b KQkq -
+French: Winawer, classical variation *
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation
+r1bqkbnr/2p2ppp/p1pp4/4p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation
+r1bqkbnr/2p3pp/p1pp1p2/4p3/3PP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation
+r1bqkbnr/2pp1ppp/p1n5/1p2p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Caro variation
+r1bqkbnr/2pp1ppp/p7/np2p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN1P2/4P3/PP4PP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN4/4P3/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch, Keres variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/1P2PN2/P2P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p2p4/1pp5/3QP3/1B6/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: Noah's ark trap
+r1bqkbnr/6pp/p1p1pp2/3p4/2PN4/4P3/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, Botvinnik variation *
+r1bqkbnr/p1pp1ppp/2n5/1p6/Q7/8/PPP1PPPP/RNB1KBNR w KQkq -
+Scandinavian, Mieses-Kotr\v c gambit *
+r1bqkbnr/p2p1ppp/1pn1p3/2p5/4P3/2NP1N2/PPP2PPP/R1BQKB1R b KQkq -
+Amsterdam attack *
+r1bqkbnr/p3pppp/2p5/2p5/2Pp1P2/6P1/PP1PP2P/RNBQK1NR b KQkq -
+Beefeater defense *
+r1bqkbnr/pp1n1ppp/2pp4/4p1N1/2BPP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Kmoch variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Philidor: Hanham, Schlechter variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Delmar variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Krause variation
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Steinitz variation
+r1bqkbnr/pp1p1p1p/2n3p1/2p1p3/2P4P/2NP4/PP2PPP1/R1BQKBNR b KQkq -
+Sicilian: Gloria variation *
+r1bqkbnr/pp1p1ppp/2n1p3/1N6/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Mikenas-Carls, Sicilian variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2N1PN2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Mikenas-Carls, Kevitz variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls variation *
+r1bqkbnr/pp1p1ppp/2n5/2p5/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls, Flohr variation *
+r1bqkbnr/pp1p1ppp/2n5/4p3/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation
+r1bqkbnr/pp1ppp1p/2N3p1/8/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, exchange variation
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+English: Bremen, Smyslov system *
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6)
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+English: Bremen, reverse dragon *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Bremen system, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2PP4/PP3PPP/RNBQKBNR b KQkq -
+English, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Carls' Bremen system *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+English: Bremen system with ...g6 *
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, modern variation
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6)
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+English, Kramnik-Shirov counterattack *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Sicilian: closed
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+English: Sicilian reversed *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Sicilian: closed, 2...Nc6
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Sicilian: chameleon variation
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Sicilian: Grand Prix attack
+r1bqkbnr/pp1ppppp/2n5/2p5/8/2NP2P1/PPP1PP1P/R1BQKBNR b KQkq -
+Venezolana opening
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/8/7Q/2N5/PPP1PPPP/R1B1KBNR b KQkq -
+Novosibirsk opening
+r1bqkbnr/pp2p1pp/2n2p2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Kmoch variation *
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system *
+r1bqkbnr/pp2pp1p/2n5/2pp2p1/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Spike gambit *
+r1bqkbnr/pp2ppp1/2np4/2p4p/2P1P3/2N3P1/PP1P1P1P/R1BQKBNR w KQkq -
+Sicilian: Gloria variation
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/1P2P3/P1P2PPP/RNBQKBNR b KQkq -
+QGD: Alapin variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+QGD: Charousek (Petrosian) variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+QGD: 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGD: 3...Nf6 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/P3P3/1PP2PPP/RNBQKBNR b KQkq -
+QGD: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3PP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+QGD Slav: Winawer counter-gambit *
+r1bqkbnr/pp2pppp/2n5/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Old Indian: Ukrainian variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5B2/3P1N2/PPP1PPPP/RN1QKB1R b KQkq -
+Old Indian: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch defense, Rubinstein variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/6PN/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense: Bladel variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Modern defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian defense, 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/3P4/3p4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit *
+r1bqkbnr/pp2pppp/2n5/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense, 4.cd ed *
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: exchange variation *
+r1bqkbnr/pp2pppp/2n5/3p4/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich variation
+r1bqkbnr/pp2pppp/2n5/3p4/3p4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange variation *
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Zaitsev system *
+r1bqkbnr/pp2pppp/8/n2P4/1Pp5/8/P4PPP/RNBQKBNR b KQkq b3
+QGD: Tarrasch defense, Tarrasch gambit *
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian with e4 & g3 *
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Makagonov system (5.h3) *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: 4.e3 c5 *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: Fischer variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 *
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+French: advance, Paulsen attack
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation
+r1bqkbnr/pp3ppp/2n5/2P1p3/1PPp4/5N2/P3PPPP/RNBQKB1R b KQkq -
+QGA: Linares variation *
+r1bqkbnr/pp3ppp/2n5/2Ppp3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense, Alekhine variation *
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Czech Benoni: King's Indian system *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6 *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, open variation, main line
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6 *
+r1bqkbnr/pp3ppp/2n5/2ppp3/3P4/2P1P3/PP3PPP/RNBQKBNR w KQkq -
+QGD: semi-Slav, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/2ppp3/5P2/3P2P1/PPP1P1BP/RNBQK1NR b KQkq -
+Modern defense: Averbakh system, Randspringer variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+Modern defense: Averbakh system, Kotov variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Modern defense: Averbakh system *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+King's Indian: 4.e4 *
+r1bqkbnr/pp3ppp/2n5/3p4/2pP4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation
+r1bqkbnr/pp3ppp/2n5/3p4/2pPP3/2N2NP1/PP3P1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation
+r1bqkbnr/pp3ppp/2n5/3pp3/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Benoni: 6.e4 *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+Benk\"o gambit: 7.e4 *
+r1bqkbnr/pp3ppp/2np4/1N2p3/4P3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, 5...O-O *
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: S\"amisch variation *
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Four pawns attack *
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: pawn storm variation *
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Mikenas variation *
+r1bqkbnr/ppnppppp/2p5/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+de Bruycker defense
+r1bqkbnr/ppp1pp1p/2n5/3p2p1/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch, Spielmann gambit *
+r1bqkbnr/ppp1pp1p/2np2p1/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Venezolana opening *
+r1bqkbnr/ppp1pppp/2n5/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: Anti-Veresov *
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Chigorin defense
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Chigorin variation
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Chigorin variation *
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Bogolyubov variation
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/3P2P1/PP2PP1P/RNBQKBNR b KQkq -
+Old Benoni: Schmid's system *
+r1bqkbnr/ppp1pppp/2n5/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Chigorin defense, Janowski variation
+r1bqkbnr/ppp1pppp/2n5/8/Q1Pp4/5N2/PP1PPPPP/RNB1KB1R b KQkq -
+Woozle defense *
+r1bqkbnr/ppp2p1p/2n3p1/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Sveshnikov system *
+r1bqkbnr/ppp2p1p/2n5/3pP1p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Tartakower variation *
+r1bqkbnr/ppp2p1p/2np4/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R w KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, 6.h4 *
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Guimard variation
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPPQ1PPP/RNB1K1NR b KQkq -
+French: Winawer, Petrosian variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation *
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Q4/2N5/PPP1PPPP/R1B1KBNR w KQkq -
+KP: Nimzovich defense, Marshall gambit *
+r1bqkbnr/ppp2ppp/2n5/3p4/Q3P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Scandinavian: Anderssen counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pP3/8/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/1P1P4/2P5/P3PPPP/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Marshall variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Bogolyubov variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P3P1/PP2PP1P/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze system *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Paulsen variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Lemberg counter-gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Fyfe gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2P5/PPNPPPPP/R1BQKBNR b KQkq -
+de Bruycker defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2PP1N2/PP2PPPP/RNBQKB1R b KQkq -
+Pirc: Ufimtsev-Pytel variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Pirc defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense *
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD: Albin counter-gambit, Alapin variation
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit, 5.g3
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: old Steinitz defense
+r1bqkbnr/ppp2ppp/3p4/8/3QP3/3B4/PPP2PPP/RNB1K2R b KQkq -
+Scotch: Ghulam Kassim variation
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Bronstein-Larsen variation *
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/3Q4/4P3/PPP2PPP/RNB1KBNR b KQkq -
+French: Frere (Becker) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: classical variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+Caro-Kann: Steinitz variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPPN1PPP/R1BQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp3pp/2n2p2/3pP3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Rasa-Studier gambit *
+r1bqkbnr/ppp3pp/2n2p2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Steinitz variation
+r1bqkbnr/ppp3pp/2n2p2/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Janowski variation
+r1bqkbnr/ppp3pp/2n5/3p1p2/3Pp2P/2P3P1/PP2PPB1/RNBQK1NR b KQkq -
+Robatsch defense: Gurgenidze variation *
+r1bqkbnr/ppp3pp/2n5/3ppP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Steinitz gambit *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Austrian attack *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Pseudo-Austrian attack *
+r1bqkbnr/ppp3pp/2n5/5p2/2pPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp3pp/2np4/3Ppp2/4P3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Ponziani counter-gambit, Schmidt attack
+r1bqkbnr/ppp3pp/2np4/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/ppp3pp/2np4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit, Steinitz variation *
+r1bqkbnr/ppp3pp/6n1/3p1p2/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Mar\'oczy attack *
+r1bqkbnr/pppn1ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Hanham variation
+r1bqkbnr/pppn1ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open, 4.ed ed *
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P1P2/4P3/PPP3PP/RNBQKBNR b KQkq -
+French: Tarrasch, Haberditz variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/1QP5/PP2PPPP/RNB1KBNR b KQkq -
+Caro-Kann: Edinburgh variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+French: Tarrasch, Guimard variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: 3.Nd2 *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Tarrasch *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqkbnr/pppn2pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Keres variation *
+r1bqkbnr/pppnpppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Valencia opening *
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense
+r1bqkbnr/pppp1p1p/2n3p1/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Three knights: Steinitz, Rosenthal variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: closed, Korchnoi variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Steinitz variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Paulsen variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Paulsen-Mieses variation *
+r1bqkbnr/pppp1p1p/2n5/1B2p1p1/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Brentano defense
+r1bqkbnr/pppp1p1p/2n5/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Neumann defense
+r1bqkbnr/pppp1p1p/2n5/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R b KQkq -
+Vienna: Hamppe-Allgaier gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Blachly gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/3PPp2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+Vienna: Pierce gambit
+r1bqkbnr/pppp1p1p/2n5/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, Holloway defense
+r1bqkbnr/pppp1p1p/2n5/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQ1RK1 b kq -
+Vienna: Hamppe-Muzio gambit
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez (Spanish opening)
+r1bqkbnr/pppp1ppp/2n5/1B6/3pP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch: Relfsson gambit (`MacLopez')
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Mayet defense
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Dresden opening
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: three knights system
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian: closed, 2...Nc6 *
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Sicilian reversed
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1ppp/2n5/4p3/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Scandinavian variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Vienna: Fyfe gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Three knights game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen variation
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game, Max Lange defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna game, Max Lange defense
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+Ponziani opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna: Falkbeer variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPPBPPP/RNBQK2R b KQkq -
+Inverted Hungarian
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+Konstantinopolsky opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Vienna game *
+r1bqkbnr/pppp1ppp/2n5/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+r1bqkbnr/pppp1ppp/2n5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Maurian defense
+r1bqkbnr/pppp1ppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqkbnr/pppp1ppp/2n5/8/2Q1P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Hall variation
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch game
+r1bqkbnr/pppp1ppp/2n5/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: S\"amisch attack *
+r1bqkbnr/pppp1ppp/2n5/8/3P4/4p3/PPPNPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Spielmann variation *
+r1bqkbnr/pppp1ppp/2n5/8/3PPp2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Vienna: Steinitz gambit
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+Center game
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Scotch: G\"oring gambit
+r1bqkbnr/pppp1ppp/2n5/8/4P3/4Q3/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Paulsen attack
+r1bqkbnr/pppp1ppp/2n5/8/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/8/8/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Scandinavian: Pytel-Wade variation *
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense
+r1bqkbnr/pppp1ppp/8/4n3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Irish (Chicago) gambit
+r1bqkbnr/pppp1ppp/8/4p3/3nP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Lolli variation
+r1bqkbnr/pppp1ppp/8/nB2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Pollock defense
+r1bqkbnr/pppp2pp/2n2p2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Nuremberg variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: Schliemann defense, Berger variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense
+r1bqkbnr/pppp2pp/2n5/4Np2/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian: Fraser defense
+r1bqkbnr/pppp2pp/2n5/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Keres (Mason-Steinitz) gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Rousseau gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+r1bqkbnr/pppp2pp/2n5/4pp2/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Pelikan variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Milner-Barry variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Winawer defense (Gothic defense)
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani counter-gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/5p2/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: l'Hermet variation
+r1bqkbnr/pppp3p/2n5/4Ppp1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird's opening, Swiss gambit *
+r1bqkbnr/ppppp1pp/2n2p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP: Neo-Mongoloid defense
+r1bqkbnr/ppppp1pp/2n5/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP: Colorado counter
+r1bqkbnr/pppppppp/2n5/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense
+r1bqkbnr/pppppppp/2n5/8/3PP3/2P5/P4PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense, Wheeler gambit
+r1bqkbnr/pppppppp/2n5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Dunst (Sleipner,Heinrichsen) opening *
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Dunst (Sleipner, Heinrichsen) opening *
+r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Lemming defense
+r1bqkbnr/pppppppp/n7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Durkin's attack *
+r1bqnrk1/p2p1ppp/1pn1p3/2p5/2PPP3/P1PB4/4NPPP/R1BQK2R w KQ -
+Nimzo-Indian: S\"amisch, Capablanca variation
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, main line *
+r1bqnrk1/pp2b2p/2n2p2/2p1p1p1/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack *
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1 *
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 11...Re8
+r1bqr1k1/p1p2ppp/2pp1n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Janowski variation *
+r1bqr1k1/pp1n1ppp/2p2n2/b2pp3/4P3/P1NP1N2/1PP1BPPP/R2QBRK1 b - -
+Ruy Lopez: Kecskem\'et variation *
+r1bqr1k1/pp1n1ppp/2pb1n2/3pN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Berger variation *
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1 *
+r1bqr1k1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky, Winter variation *
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 b - -
+Benoni: classical, 11.f3
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+Benoni: classical with ...Re8 and ...Na6
+r1bqr1k1/ppb2pp1/2p1nn1p/3pp3/NPP1P3/P2P1NP1/2QBBP1P/R3R1K1 b - -
+Ruy Lopez: closed, Chigorin, Yugoslav system *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin, 12...Nc6 *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P2P1N2/1B1NBPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1PPpP1P1/P2P1N2/2Q1BP1P/RNB1K2R b KQ -
+Ruy Lopez: closed, Leonhardt variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1Pp1P3/P1NP1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, Rauzer attack *
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, 12...c5d4 *
+r1bqr1k1/ppp2ppp/2n2n2/2bPN3/3P4/2N5/PPP2PPP/R1BQKB1R w KQ -
+two knights defense: Canal variation *
+r1bqr1k1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2Q1RK1 b - -
+Ruy Lopez: Berlin defense, Tarrasch trap *
+r1bqr1k1/ppp2ppp/2n2n2/4N3/3PpP2/P1P5/2P3PP/R1BQKB1R w KQ -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation *
+r1bqr1k1/ppp2ppp/2np1n2/8/1bB1P3/2N1Q2N/PPPB1PPP/2KR3R b - -
+Center game: Kupreichik variation
+r1bqr1k1/ppp2ppp/8/2PPn3/2B2Qn1/2N1Bp2/PPP2PPP/R3K2R w KQ -
+two knights: Max Lange attack, Marshall variation *
+r1bqr1k1/ppp2ppp/8/2PPn3/5Qn1/2N1Bp2/PPP2PPP/R3KB1R b KQ -
+two knights: Max Lange attack, Rubinstein variation *
+r1bqr1k1/ppp2ppp/8/3pn3/3Q4/P1P1B3/1PP2PPP/R3KB1R b KQ -
+Four knights: Spielmann variation *
+r1bqr1k1/ppp4p/8/2PPnpp1/6n1/1BN1BpQ1/PPP2PPP/2KR3R b - -
+two knights: Max Lange attack, Berger variation *
+r1bqr1k1/pppn1pbp/3p1np1/4p3/2PP4/2N1PN2/PP2BPPP/R1BQ1RK1 w - -
+R\'eti: King's Indian attack, French variation *
+r1bqr1k1/pppp1ppp/2n2n2/3NpQ2/1bP5/4PN2/PP1P1PPP/R1B1KB1R b KQ -
+English: four knights, Stean variation
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7, main line *
+r1bqrnk1/ppp1bppp/5n2/3p2B1/3P4/2NBP3/PPQ1NPPP/2KR3R b - -
+QGD: exchange, chameleon variation
+r1br2k1/p1q1ppbp/1pn2np1/2pp4/1P1P4/2P1PN2/PB1NBPPP/R2Q1RK1 b - -
+Catalan: closed, Spassky gambit *
+r1br2k1/p3ppbp/1pn2np1/2pq4/8/PP1PPN2/1B1NBPPP/R2QK2R b KQ -
+English: symmetrical, hedgehog, flexible formation *
+r1br2k1/p4ppp/1qn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Potter variation *
+r1br2k1/pp2qppp/1bn1pn2/3p4/1PP5/P2BPN2/1B1N1PPP/R2QK2R b KQ -
+QGA: classical, Smyslov variation *
+r1br2k1/ppq2ppp/2n1pn2/2P5/1P1p4/P3PN2/1BQ2PPP/R3KB1R b KQ -
+QGA: classical, Flohr variation *
+r1q2rk1/pp2ppbp/2npbnp1/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 12.h4
+r2n1rk1/ppp1qppp/3p1n2/1B2p1B1/3PP1b1/2P2N2/P1P2PPP/R2QR1K1 w - -
+Four knights: symmetrical, Capablanca variation
+r2q1bnr/ppp1kBpp/3p4/3NN3/4P3/8/PP3PPP/R1Bb1RK1 b - -
+Scotch: Sea-cadet mate
+r2q1knr/pppb1Bpp/1b1p4/n7/3PP3/2N2N2/P1Q2PPP/R1B2RK1 b - -
+Evans gambit: Fraser-Mortimer attack
+r2q1rk1/1b1nbppp/p2p1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation)
+r2q1rk1/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP1NQPPP/R1B2RK1 b - -
+Ruy Lopez: open, Malkin variation
+r2q1rk1/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, Bogolyubov variation
+r2q1rk1/2p1bppp/p1npbn2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Kholmov variation
+r2q1rk1/2p1bppp/p3b3/1p1pn3/3Nn3/1BP5/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: open, Breslau variation
+r2q1rk1/2p2ppp/p1n1b3/1pbpP3/8/2P2N2/PPBN1nPP/R1BQ1RK1 w - -
+Ruy Lopez: open, Dilworth variation
+r2q1rk1/3nbppp/bpp1pn2/p2p4/2PP4/1P3NP1/PBQNPPBP/R4RK1 w - -
+Catalan: closed, Sokolsky variation
+r2q1rk1/p1p2ppp/2pp1n2/4p3/1b2P1b1/2NP1N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: symmetrical, Metger unpin *
+r2q1rk1/p3bppp/1pn1bn2/2pp2B1/3P4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Stoltz variation
+r2q1rk1/p3n1pp/2p1bp2/3pp1B1/N1P5/6P1/PP2PbBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Seville variation *
+r2q1rk1/p3n1pp/3bbp2/3pp3/N7/4B1P1/PP2PPBP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3 *
+r2q1rk1/p3n1pp/3bbp2/4p3/N2p4/4B1P1/PP2PPBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Sokolsky variation *
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd *
+r2q1rk1/p4ppp/2n1bn2/2bpp3/N7/1B1P1P2/PPP3PP/R1BQK1NR w KQ -
+Evans gambit: Steinitz variation *
+r2q1rk1/p4ppp/2n2n2/2bpp3/N5b1/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: G\"oring attack *
+r2q1rk1/p4ppp/b1B2n2/2bp4/8/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Aitken variation *
+r2q1rk1/p4ppp/b1p2n2/2bpN3/3P4/2N5/PPP2PPP/R1BQK2R w KQ -
+Giuoco Piano: Steinitz variation *
+r2q1rk1/pb1nbppp/2p1pn2/1p1p4/2PP4/1PN2NP1/P1Q1PPBP/R1BR2K1 w - -
+Catalan: closed, Spassky gambit
+r2q1rk1/pp1bbppp/2nppn2/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line with Nb3
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, 9...Bd7
+r2q1rk1/pp2b1pp/2n1bn2/2pp4/4pB2/1NN1P3/PPPQBPPP/2KR3R b - -
+Alekhine's defense: four pawns attack, Tartakower variation *
+r2q1rk1/pp2bpp1/2n2n1p/2pp1b2/5B2/1NNP2P1/PP2PPBP/R2Q1RK1 w - -
+Alekhine's defense: exchange, Karpov variation *
+r2q1rk1/pp2bppp/2n1bn2/3p2B1/2pP4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Bogolyubov variation
+r2q1rk1/pp2bppp/2npbn2/2p3B1/4P3/2N2N2/PPP1BPPP/R2QR1K1 b - -
+Philidor: Berger variation
+r2q1rk1/pp2pBbp/6p1/n1p5/3PP1b1/2P1BP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Seville variation
+r2q1rk1/pp2ppbp/1nnp2p1/5b2/2PP1B2/2N2N1P/PP2BPP1/R2Q1RK1 b - -
+Alekhine's defense: exchange, Karpov variation
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, 9.Bg5 *
+r2q1rk1/pp2ppbp/3p1np1/n4P2/2b1P3/1NNBB3/PPP3PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Spielmann variation
+r2q1rk1/pp2ppbp/4b1p1/n2P4/4P3/3BBP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Sokolsky variation
+r2q1rk1/pp2ppbp/4b1p1/n7/3PP3/3BBP2/P3N1PP/R2Q1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3
+r2q1rk1/pp2ppbp/5np1/n2p1P2/4P3/1NNPB3/PP4PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Bernard defense
+r2q1rk1/pp4pp/1nnpb3/4p3/N2P1p2/5NP1/PP2PPBP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Bernard defense *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPBNP1/PP2PPBP/R1Q2RK1 b - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPPN2/PP1BBPPP/R2Q1RK1 w - -
+Sicilian: modern Scheveningen, main line with Nb3 *
+r2q1rk1/ppp1b1pp/2n1b3/3n1p2/4p3/1QNP1NP1/PP2PPBP/R1B2RK1 w - -
+Sicilian: dragon, classical, Zollner gambit *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: modern Scheveningen, main line *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R w KQ -
+Sicilian: Scheveningen, classical *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, 9.Nb3 *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b - -
+Sicilian: dragon, classical, Alekhine variation *
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+Sicilian: dragon, classical, 8.O-O *
+r2q1rk1/ppp1ppbp/1nn3p1/8/3PP1b1/2NQBN2/PP2BPPP/2KR3R b - -
+Gr\"unfeld: Russian, Keres variation
+r2q1rk1/ppp1ppbp/2np1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation
+r2q1rk1/ppp1ppbp/2np1np1/8/2PP2b1/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Simagin variation
+r2q1rk1/ppp2ppp/1bnp4/1B2p2n/3PP1b1/2PQ1N2/PP2NPPP/R1B2RK1 b - -
+Four knights: symmetrical, Blake variation *
+r2q1rk1/ppp2ppp/2n2n2/3pp3/1b2P1b1/2NP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Bernstein variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/2NPBN2/PPP2PPP/R2Q1RK1 b - -
+Four knights: symmetrical, Tarrasch variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Pillsbury variation *
+r2q1rk1/ppp2ppp/2npbn2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Tarrasch variation
+r2q1rk1/ppp3pp/1nnbb3/2B1p3/N4p2/3P1NP1/PP2PPBP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Spielmann variation *
+r2q1rk1/ppp3pp/2n5/2bNp3/4P1b1/5N2/PPP1QPPP/R1B1K2R w KQ -
+Giuoco piano: Holzhausen attack *
+r2q1rk1/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQR1K1 w - -
+Ruy Lopez: Berlin defense, Tarrasch trap
+r2q1rk1/pppnbppp/8/8/1n6/2N3Q1/PPPP1PPP/R1BK2NR b - -
+Scotch: Rosenthal variation *
+r2q2k1/pp3ppp/8/2b1r3/3p4/3P4/PPP1NPPn/R1BQ1RK1 w - -
+Giuoco Piano: Therkatz-Herzog variation *
+r2qbrk1/1pp1bppp/p1np1n2/4p3/B2PP3/2P2N2/PP1N1PPP/R1BQR1K1 w - -
+Ruy Lopez: Kecskem\'et variation
+r2qk1nr/pp2bppp/2n1b3/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Semi-Averbakh system *
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, main line *
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, 6...c5 *
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Averbakh system *
+r2qk1nr/pp4pp/2nbbp2/2ppp3/8/P1PP1NP1/1P2PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, Byrne variation *
+r2qk1nr/ppp1npbp/3pb1p1/3Np3/2P5/4P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: closed, Smyslov variation *
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Hort variation
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.Be3 *
+r2qk1nr/ppp2ppp/1bnp4/8/2BPP1b1/2N2N2/P4PPP/R1BQ1RK1 w kq -
+Evans gambit
+r2qk1nr/ppp2ppp/1bnp4/8/Q1BPP1b1/2N2N2/P4PPP/R1B2RK1 b kq -
+Evans gambit: Fraser attack
+r2qk1nr/ppp2ppp/2nb4/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Tarrasch variation *
+r2qk1nr/ppp2ppp/2np4/2b5/2BpP1b1/2P2N2/PP3PPP/RNBQ1RK1 w kq -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack
+r2qk1nr/ppp2ppp/2np4/b3p3/2BPP1b1/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Alapin-Steinitz variation
+r2qk1nr/pppb1ppp/2nb4/1B1p4/2PQ4/4P3/PP3PPP/RNB1K1NR w KQkq -
+French: Winawer, Kondratiyev variation *
+r2qk1nr/pppb1ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Sanders-Alapin variation
+r2qk2r/1b1n1ppp/p2bpn2/1pp5/3P4/1BN1PN2/PP2QPPP/R1BR2K1 w kq -
+QGA: classical, Smyslov variation
+r2qk2r/1b1nbppp/pp1ppn2/8/2PQ4/1PN2NP1/P3PPBP/R1BR2K1 w kq -
+English: symmetrical, hedgehog, flexible formation
+r2qk2r/1bppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: Trajkovi\'c counter-attack
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/2P1n3/1B3N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack, Adam variation
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, classical defense
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQR1K1 b kq -
+Ruy Lopez: open, 9...Be7, 10.Re1
+r2qk2r/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP2QPPP/RNB1K2R w KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation
+r2qk2r/2p1nppp/p3b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 w kq -
+Ruy Lopez: open, Motzko attack, Nenarokov variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, St. Petersburg variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Italian variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 b kq -
+Ruy Lopez: open, Motzko attack
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6
+r2qk2r/p1pn1ppp/8/3pp3/Np2b1Q1/1B6/PPP2K1P/R1B3R1 w kq -
+Evans gambit declined, Pavlov variation *
+r2qk2r/pp1bppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: Opo\v censky variation *
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+King's Indian: Four pawns attack, main line *
+r2qk2r/pp2bpp1/2n2nb1/2p1p2p/3pP1PN/3P3P/PPPN1PB1/R1BQ1RK1 w kq -
+King's Indian: Petrosian system, Keres variation *
+r2qk2r/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Gligori\'c-Taimanov system *
+r2qk2r/pp3ppp/2n1pn2/3p1b2/1b1P1B2/1QN1PN2/PP3PPP/R3KB1R w KQkq -
+QGD Slav: exchange, Trifunovi\'c variation
+r2qk2r/pp3ppp/2nbp3/3p4/3Pn1b1/1P3N2/PBP1BPPP/RN1Q1RK1 w kq -
+QGD: Pillsbury attack *
+r2qk2r/pp3ppp/2nbpn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Botvinnik variation *
+r2qk2r/ppp1b1pp/2n5/3p1p2/2PPn1b1/3B1N2/PP3PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Krause variation
+r2qk2r/ppp1b1pp/2n5/3p1p2/3Pn1b1/2PB1N2/PP1N1PPP/R1BQR1K1 b kq -
+Petrov: classical attack, Berger variation
+r2qk2r/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Nottingham variation *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, classical attack *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qk2r/ppp2p1p/2n1bPp1/2b3N1/2pp4/8/PPP2PPP/RNBQR1K1 w kq -
+two knights: Max Lange attack, Loman defense
+r2qk2r/ppp2pPp/2n1b3/2b5/2pp4/5N2/PPP2PPP/RNBQR1K1 b kq -
+two knights: Max Lange attack, Schlechter variation
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4 *
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, 7.Be3 *
+r2qk2r/ppp2ppp/2n5/3np3/1b4b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation *
+r2qk2r/ppp2ppp/2np1n2/2b1p3/2B1P1b1/2NP1N2/PPP2PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Canal variation *
+r2qk2r/ppp2ppp/2np1n2/2b5/2B1Pp2/2NP1Q1P/PPP3P1/R1B1K2R w KQkq -
+KGD: classical, Svenonius variation
+r2qk2r/ppp3pp/1bn1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w kq -
+Sicilian: Sozin, Fischer variation *
+r2qk2r/ppp3pp/2n5/3p1p2/2PPn1bb/3B1N2/PP3PPP/RNBQR1K1 w kq -
+Petrov: classical attack, Mar\'oczy variation
+r2qk2r/pppbbppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Showalter variation
+r2qk2r/pppbbppp/2np1n2/1B2p1B1/3PP3/2N2N2/PPP2PPP/R2Q1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Bernstein variation
+r2qk2r/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: Berlin defense, hedgehog variation
+r2qkb1r/1bpp1ppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Archangelsk (counterthrust) variation
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/1QP1P3/P4PPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Junge variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/2P1P3/P3QPPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Koomen variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/PP6/2P1P3/5PPP/RNBQK1NR b KQkq -
+QGD: semi-Slav, Abrahams variation *
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7
+r2qkb1r/1p3ppp/p1npbn2/4p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Bird variation
+r2qkb1r/1ppbnppp/p1np4/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 8...Be6
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPPN1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 9.c3
+r2qkb1r/2p2ppp/p1n1b3/1pn1P1N1/3p4/1BP5/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation, Karpov gambit
+r2qkb1r/2p2ppp/p1n1b3/1pnpP3/8/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Berlin variation
+r2qkb1r/2p2ppp/p1pp1n2/4p3/3PP1b1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation
+r2qkb1r/p2b1ppp/5n2/1B1pp3/Q7/4P3/PP3PPP/RNB1K2R b KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation *
+r2qkb1r/p3pppp/2p5/2pn3b/4N3/5N1P/PPPP1PP1/R1BQK2R b KQkq -
+English: Nenarokov variation *
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, main line *
+r2qkb1r/pb1n1ppp/2p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Wade variation
+r2qkb1r/pp1b1ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Opo\v censky variation *
+r2qkb1r/pp1bppp1/5n1p/1BpP4/4p3/2N5/PPP1QPPP/R3K1NR b KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation *
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2
+r2qkb1r/pp1n1ppp/2n1p3/2Pp4/Q5b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation *
+r2qkb1r/pp1n1ppp/4pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca variation *
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox main line *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6 *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Ruban variation *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, Panno formation *
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin, Vienna variation *
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+Queen's Indian: 4.Nc3, main line *
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: 5.Bg5 dc *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+QGD: classical variation (5.Bf4) *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bf4 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation *
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bg5 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Smyslov system *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5 *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD: exchange, S\"amisch variation *
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Uhlmann variation *
+r2qkb1r/pp2pppp/2n2nb1/2pp4/6PN/1P2P2P/PBPP1P2/RN1QKB1R b KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation *
+r2qkb1r/pp2pppp/n1p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Dutch, Lasker variation
+r2qkb1r/pp2pppp/n1p2n2/8/P1pPP1b1/2N2N2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Smyslov variation
+r2qkb1r/pp3p1p/2n3p1/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation *
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Breyer variation *
+r2qkb1r/pp3ppp/2n1bn2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Larsen variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with Bf4 & e3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bh4 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN1P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Neo-orthodox variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QGD: 6.Nf3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QGD: Orthodox defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4Pb1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bxf6 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P4/2P1Pb2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, Capablanca variation *
+r2qkb1r/pp3ppp/2n1pn2/2ppN2b/3P4/4P2P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Lasker defense *
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5 *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2N2b1/2P1P3/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2p2b1/2P1PN2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, 7.cd *
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/6b1/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran) *
+r2qkb1r/pp3ppp/2n2n2/2pp4/3P2b1/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Wagner variation
+r2qkb1r/pp3ppp/2n2n2/2ppp3/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Alekhine variation *
+r2qkb1r/pp3ppp/2n2n2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Zinnowitz variation *
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical, 8.Bg5 *
+r2qkb1r/pp3ppp/2n5/2Pp3P/1P2n3/2P1Pp1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: Ekstrom variation *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P1Np1n1/2P1P2P/P4P2/RNBQKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P2p1n1/2P1PN1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: anti-Meran gambit *
+r2qkb1r/ppp1p1pp/1nn1p3/2P5/3P2b1/5N2/PP4PP/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation
+r2qkb1r/ppp2ppp/1nn5/4p3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, 6.Be3 *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Byrne (English) attack *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.Bg5 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/4p3/6b1/2nPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Richter attack *
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan, Chelyabinsk variation *
+r2qkb1r/ppp2ppp/n1n5/4p3/4P1b1/P1NPBN2/1P3PPP/R2QKB1R b KQkq -
+Sicilian: Pelikan, Bird variation *
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+Sicilian: Sveshnikov variation *
+r2qkb1r/ppp3pp/2n1bn2/3p1p2/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Steinitz, Boleslavsky variation *
+r2qkb1r/ppp3pp/2n1bn2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Be3 *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 7...O-O *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, Yugoslav attack *
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky variation *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+Sicilian: Najdorf, 7...Be7 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 7.f4 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+Sicilian: Najdorf, 7...Qb6 *
+r2qkb1r/pppb1ppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack
+r2qkb1r/pppb1ppp/2n2n2/1B6/Q3p3/2N5/PPP2PPP/R1B1K1NR w KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack *
+r2qkb1r/pppb1ppp/2np1n2/1B6/3pP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Wolf variation
+r2qkb1r/pppn2p1/8/3pNbPp/3Pn3/8/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation *
+r2qkbnr/1p3ppp/p1n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca anti-Cambridge Springs variation *
+r2qkbnr/1pp2pp1/p1p5/4p2p/4P1b1/5N1P/PPPP1PP1/RNBQ1RK1 w kq -
+Ruy Lopez: exchange variation, Alapin gambit
+r2qkbnr/1pp3pp/p1np4/4pb2/B7/2P2N2/PP1P1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Siesta, Kopayev variation
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r2qkbnr/pp1b1ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Euwe variation
+r2qkbnr/pp1nppp1/2p3bp/7P/3P4/5NN1/PPP2PP1/R1BQKB1R b KQkq -
+Caro-Kann: classical, Spassky variation
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+Caro-Kann: classical, 7...Nd7
+r2qkbnr/pp2pppp/2n5/1Bp4b/1PPp4/4PN1P/P2P1PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit *
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, main line *
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Leningrad variation *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: Harrwitz attack *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: 4.Bf4 *
+r2qkbnr/pp2pppp/2n5/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Been-Koomen variation *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QGD: 4.Bg5 Be7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Bg5 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+QGD: 4.Bg5 Nbd7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Stockholm variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/1Q2PN2/PP3PPP/RNB1KB1R b KQkq -
+QGD: Canal (Venice) variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+QGD: exchange, positional line, 5...c6 *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line *
+r2qkbnr/pp3ppp/2n1p3/1Bpp4/3P2b1/4PN2/PPPN1PPP/R1BQK2R b KQkq -
+QGD: Manhattan variation *
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Gr\"unfeld gambit *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD: 5...c6 *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 b kq -
+QGD: 4.Bg5 Be7, 5.e3 O-O *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkbnr/pp3ppp/2n1p3/2ppN3/3P2b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+QGD: Lasker variation *
+r2qkbnr/pp3ppp/2n5/2P5/N2p2b1/5N2/PP2PPPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation *
+r2qkbnr/pp3ppp/2n5/2pp4/Q2P2b1/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation *
+r2qkbnr/pp3ppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: accelerated Averbakh system *
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+Gr\"unfeld: Gr\"unfeld gambit accepted *
+r2qkbnr/pp3ppp/8/3pn3/8/8/PPP1NPPP/RNBQK2R b KQkq -
+Bishop's opening: Lisitsyn variation
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.d5 c6 *
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: S\"amisch, orthodox, 7.d5 *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, double fianchetto variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, 6...Nc6 *
+r2qkbnr/ppp1p1pp/2n2p2/3p4/3P1Bb1/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Richter variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P1B2/5b2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Veresov variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Richter-Veresov attack *
+r2qkbnr/ppp2p1p/2P5/8/2BP1pb1/2N2p2/PPP3PP/R1BQ1RK1 b kq -
+Vienna: Pierce gambit, Rushmere attack
+r2qkbnr/ppp2pp1/2n5/3p3p/2PPp1b1/4P3/PP1NBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQ1RK1 b kq -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQK2R w KQkq -
+French: Albin-Alekhine-Ch\^atard attack *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4PP2/PPPNB1PP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/P3P3/1PPNBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation *
+r2qkbnr/ppp2pp1/2n5/3pP2p/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Alekhine variation *
+r2qkbnr/ppp2ppp/2n1b3/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Janowski variation *
+r2qkbnr/ppp2ppp/2n1b3/3p4/3Pp3/1P2P3/P1P1BPPP/RNBQK1NR b KQkq -
+French: classical, Frankfurt variation *
+r2qkbnr/ppp2ppp/2n1b3/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Henneberger variation *
+r2qkbnr/ppp2ppp/2n5/1B1p3b/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Bernstein variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3P2b1/4Pp1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3Pp1b1/4PN2/PPP2PPP/RNBQK2R w KQkq -
+French: MacCutcheon, advance variation *
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+French: MacCutcheon variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+French: exchange, Bogolyubov variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+French: exchange, Svenonius variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp1b1/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+French: classical, Vistaneckis (Nimzovich) variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+French: classical variation *
+r2qkbnr/ppp2ppp/2n5/3pN3/3Pp1b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+French: classical, Tartakower variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/1P3N2/P1PPP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Nimzovich variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/2P2N2/PP1PP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Burn variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Staunton's line *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+French: classical *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P4/4Pb2/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen variation *
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Byrne variation *
+r2qkbnr/ppp2ppp/2npb3/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English, Tr\"oger defense
+r2qkbnr/ppp2ppp/8/3p4/1n1Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Alapin variation *
+r2qkbnr/ppp3pp/2n2p2/3pP3/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Lasker variation *
+r2qkbnr/ppp3pp/2n5/3p1p2/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Steinitz variation *
+r2qkbnr/pppb1ppp/2B5/3p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Bogolyubov variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/3Pp3/4P2P/PPPN1PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Tartakower variation *
+r2qkbnr/pppb1ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, fingerslip variation *
+r2qkbnr/pppb1ppp/2n5/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Caro variation
+r2qkbnr/pppb1ppp/2np4/1B2p3/2PPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation
+r2qkbnr/pppb2pp/2npP3/1B3p2/3p4/5N2/PPP2PPP/RNBQK2R b KQkq -
+KGD: Falkbeer, Morphy gambit *
+r2qkbnr/pppnpppp/8/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+R\'eti: King's Indian attack, Keres variation
+r2qr1k1/p1p2ppp/2p2n2/3pp1B1/1b2P1b1/3P1N2/PPP1QPPP/R2N1RK1 b - -
+Four knights: symmetrical, Capablanca variation *
+r2qr1k1/p1p2ppp/5n2/1p1P3b/Q5P1/2N1Bn1P/PPP1KP2/R4B1R w - -
+two knights defense: Yurdansky attack *
+r2qr1k1/ppp1bppp/2n2n2/4p3/2P3b1/2NPBN2/PP2BPPP/R2Q1RK1 w - -
+Philidor: Berger variation *
+r2r2k1/ppq2ppp/2n1pn2/2bp4/2P5/2N1PN1P/PP1BQPP1/R4RK1 b - -
+QGD: Lasker defense, Russian variation *
+r3k1nr/ppp1qppp/2n5/4P3/1bPp4/5N1P/PP1BPPP1/R2QKB1R w KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation
+r3k2r/p2q1ppp/5n2/3pp3/1b6/4P3/PP3PPP/RNBQ1RK1 w kq -
+QGD: Semi-Tarrasch, Kmoch variation *
+r3k2r/ppp1qppp/2n1b3/2bnp3/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Velimirovi\'c attack *
+r3k2r/ppp2ppp/2n1bP2/2b2qN1/2ppN3/8/PPP2PPP/R1BQR1K1 b kq -
+two knights: Max Lange attack, Marshall variation
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 9...Bd7 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+Sicilian: dragon, Yugoslav attack, 9.Bc4 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, Byrne variation *
+r3k2r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Amsterdam variation *
+r3k2r/ppq1ppbp/2N3p1/2pp4/6n1/1P2P3/PBPP1PPP/RN1Q1RK1 w kq -
+Bogo-Indian defense, Monticelli trap *
+r3kb1r/1b3ppp/p2ppn2/qpn1P1B1/3N4/1BN5/PPPQ1PPP/2KRR3 b kq -
+Sicilian: Najdorf, Ivkov variation
+r3kb1r/1bq2ppp/p3pn2/1p1P4/2p5/2N1PN2/PPQ2PPP/R1BR2K1 w kq -
+QGA: classical, Flohr variation
+r3kb1r/1pp2ppp/p1p1b3/3q4/3PN3/8/PPP2PPP/R1BQR1K1 w kq -
+Four knights: Spielmann variation
+r3kb1r/5ppp/b3pn2/1p1qN1B1/3p4/3B4/PP2QPPP/R4RK1 b kq -
+QGD semi-Slav: Meran, Rellstab attack
+r3kb1r/p4ppp/1qp1pn2/3p4/3P4/3Q3P/PPP2PP1/RNB2RK1 b kq -
+QGD: Lasker defense, Bernstein variation *
+r3kb1r/pp1Npppp/1qn2n2/1Bp5/2p5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation *
+r3kb1r/pp1b1ppp/nq2pn2/3p4/3P1B2/4PN2/PP3PPP/RNQ1KB1R w KQkq -
+QGD Slav: Landau variation *
+r3kb1r/pp1bpppp/1qn2n2/1Bp5/2N5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, San Remo variation *
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Panno main line *
+r3kb1r/pp1qpppp/2np1n2/2p5/3PP3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit
+r3kb1r/pp2pppp/1qn2n2/2pp4/3P4/2P1PQ1P/PP3PP1/RNB1KB1R w KQkq -
+QGD/QGD semi-Slav: Hastings variation *
+r3kb1r/pp2pppp/2n2n2/2pq4/3P2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation *
+r3kb1r/pp2pppp/2n5/q1p5/1n1PP1b1/P4N2/1P3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Krause variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/2P5/6P1/PP1NPPBP/RN1Q1RK1 b kq -
+Gr\"unfeld defense: Smyslov, Yugoslav variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+Gr\"unfeld defense: Smyslov, main line *
+r3kb1r/pp3ppp/1qn1pn2/1B1p1b2/3P1B2/2N1PN2/PP3PPP/R2QK2R b KQkq -
+QGD Slav: exchange, Trifunovi\'c variation *
+r3kb1r/pp3ppp/1qn1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rauzer variation *
+r3kb1r/pp3ppp/2n2q2/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation *
+r3kb1r/ppp1q1pp/2n5/3n4/1P2p1b1/P3PN2/2Q2PPP/RNB1KB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation *
+r3kb1r/ppp2ppp/2n1bP2/5qN1/2ppN3/8/PPP2PPP/R1BQR1K1 w kq -
+two knights: Max Lange attack, Rubinstein variation
+r3kb1r/ppp2ppp/2nq4/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Keres variation *
+r3kb1r/ppp3pp/2n1bq2/3npp2/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen, Tal variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/6P1/P2PPN1P/1P2BP2/RNBQK2R b KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/8/P2PPN1P/1PQ1BPP1/RNB1K2R b KQkq -
+Sicilian: Najdorf, Browne variation *
+r3kb1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQ1BPPP/RNB1K2R b KQkq -
+Sicilian: Najdorf variation *
+r3kb1r/pppq1ppp/2n1b3/3np3/8/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, English variation *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQK2R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 *
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rubinstein variation *
+r3kb1r/ppq2ppp/2n1pn2/2ppN3/3P4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, Teichmann variation *
+r3kb1r/ppq2ppp/2n1pn2/3p4/2Pp2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein) *
+r3kb1r/ppqbpp1p/2n2np1/1Bp5/2N2P2/2N1P3/PP1P2PP/R1BQK2R w KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp3b/Q2P4/2P1PN2/PP1N1PPP/R1B2RK1 w kq -
+QGD: Cambridge Springs defense, Argentine variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1K2R w KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation *
+r3kb1r/ppqn1ppp/2p2n2/4pb2/P1NP4/2N3P1/1P2PP1P/R1BQKB1R w KQkq -
+QGD Slav: Carlsbad variation
+r3kbnr/1ppb1ppp/p1p5/8/3NP3/8/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: exchange, Alekhine variation
+r3kbnr/p1pb1ppp/2p5/3pN1q1/3Pp3/4P1PP/PPP2P2/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation, 8...g6 *
+r3kbnr/pp1qpppp/8/2ppP3/2P3b1/6P1/PP2PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: Lundin variation *
+r3kbnr/ppp2pp1/2n5/1B1p2qP/3P4/4P3/PPP2Pp1/RNBQK1R1 w Qkq -
+French: MacCutcheon, Grigoriev variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen-Richter variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Pollock variation *
+r3kbnr/pppq1ppp/2n1b3/3pp3/8/2PP1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Pirc: 150 attack *
+r3kbnr/pppq1ppp/2n5/1B1p4/Q7/4PP2/PPP2P1P/RNB1K2R b KQkq -
+French: MacCutcheon, Bogolyubov variation *
+r3kbnr/pppq1ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Rubinstein variation *
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line, 6.Qc2 *
+r3qrk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ1BPPP/R1B2RK1 b - -
+Sicilian: Scheveningen, classical main line *
+r3r1k1/1p1n1p1p/1bpqb1p1/p2p2B1/1P1N3Q/P1PBR3/5PPP/5RK1 b - -
+Ruy Lopez: Marshall, main line, Spassky variation *
+r3r1k1/2qbbp1p/p2p1np1/npp1p3/3PP3/2P1NN1P/PPB2PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, Yugoslav system
+r3r1k1/ppp1qppp/2n5/3b4/2P1p3/8/P1PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation *
+r4b1r/ppp1kp2/2n1bN1p/q5p1/1P1p3B/5N2/P1P2PPP/R2QR1K1 b - -
+two knights defense: Yurdansky attack
+r4rk1/2pqb1pp/p1n1p3/1p1pP3/4R3/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: open, Tarrasch trap
+r4rk1/2pqbppp/p1n1b3/3pP3/2B1n3/5N2/PP2QPPP/RNBR2K1 w - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation
+r4rk1/p4ppp/bqn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Paulsen variation *
+r4rk1/pbqnppbp/1p3np1/2pp4/P2P4/BPP1PN2/3NBPPP/R2Q1RK1 b - -
+Catalan: closed, Sokolsky variation *
+r4rk1/pp1bqpp1/2n1pn1p/2p5/2BP4/2N1PN2/PPQ2PPP/R2R2K1 w - -
+QGD: Lasker defense, Russian variation
+r4rk1/pp2ppbp/3p1np1/q4P2/4P1P1/2N1B3/PPP1Q2P/R4RK1 b - -
+Sicilian: dragon, classical, Stockholm attack
+r4rk1/pp2qppp/3b4/3P4/1P1Qn1b1/B3PN2/5PPP/R3KB1R w KQ -
+QGD semi-Slav: Meran, Rellstab attack *
+r4rk1/ppp1q2p/2n1b3/4p1p1/Q4p2/3P1NP1/PP2PPBP/R4RK1 w - -
+Sicilian: dragon, classical, Stockholm attack *
+r4rk1/ppp3pp/2n1bq2/4pP2/8/5Q2/PPPP1K1P/RNB2BNR w - -
+KGA: Lolli gambit, Young variation *
+r4rk1/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Richter variation *
+r4rk1/ppq1ppbp/2n2np1/2pp4/3P1Pb1/2P1PN2/PP2B1PP/RNB1QRK1 w - -
+Dutch: stonewall: Chekhover variation *
+r5nr/pp2k2p/2n2p2/2N1p2q/3pP3/3P2P1/PPP2PBP/RNB2RK1 b - -
+King's Indian: S\"amisch, orthodox, Bronstein variation *
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+Benoni: classical with ...a6 and 10...Bg4
+rn1q1rk1/4ppbp/3p1np1/2pP4/4P3/2N2NP1/PP3PKP/R1BQ3R b - -
+Benk\"o gambit: main line
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Ba3 *
+rn1q1rk1/pb1pbppp/1p2pn2/8/2PN4/1P1BP3/PB3PPP/RN1Q1RK1 b - -
+Queen's Indian: Averbakh variation
+rn1q1rk1/pb3ppp/1p1bp3/2pn4/8/1P2PN2/PB1PBPPP/RN1Q1RK1 w - -
+Queen's Indian: Averbakh variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP1NPPP/R1BQK2R b KQ -
+Evans gambit: Paulsen variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Ulvestad variation *
+rn1q1rk1/pb3ppp/8/1Bb5/4N1n1/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Scotch gambit: Hanneken variation *
+rn1q1rk1/pbp1bppp/1p3n2/3pN1B1/3P4/2NBP3/PP3PPP/R2QK2R b KQ -
+QGD: Pillsbury attack
+rn1q1rk1/pbpp1ppp/1p2p3/6N1/2PP4/2n3P1/PPQ1PPBP/R3K2R b KQ -
+Bogo-Indian defense, Monticelli trap
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+Queen's Indian: old main line, 9.Qxc3
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Queen's Indian: Euwe variation
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Queen's Indian: old main line, 7.Nc3
+rn1q1rk1/pp1nppbp/6p1/2p5/3PP1b1/1QN1BN2/PP3PPP/R3KB1R w KQ -
+Gr\"unfeld defense: Smyslov, Yugoslav variation
+rn1q1rk1/pp2ppbp/2p2np1/3p1b2/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Flohr defense
+rn1q1rk1/pp2ppbp/2p2np1/3p4/2PP2b1/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Smyslov defense
+rn1q1rk1/pp2ppbp/2pp1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Larsen system
+rn1q1rk1/pp2ppbp/4bnp1/2Pp4/2P2B2/2N1P3/PP3PPP/2RQKBNR w K -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation
+rn1q1rk1/pp3ppp/2p1p3/5b2/PbBPn1P1/2N1PN2/1P2QP1P/R1B2RK1 b - -
+QGD Slav: Dutch, S\"amisch variation
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+QGD Slav: Dutch variation, main line
+rn1q1rk1/ppp1b1pp/1n2pp2/4Pb2/2PP4/2N2N2/PP2B1PP/R1BQ1RK1 w - -
+Alekhine's defense: four pawns attack, Korchnoi variation
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Smyslov variation
+rn1q1rk1/ppp2ppp/3b4/3p4/2PPn1b1/3B1N2/PP3PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Tarrasch variation
+rn1q1rk1/ppp2ppp/8/2bNp3/4P1b1/3P1N2/PPP2PPP/R1BQK2R b KQ -
+Giuoco piano *
+rn1q1rk1/ppp2ppp/8/2bP1b2/4nPP1/5N2/PPP1Q2P/RNB1KB1R w KQ -
+KGD: Falkbeer, Tarrasch variation
+rn1q1rk1/ppp3pp/8/2bNpp1b/4P1P1/5N1P/PPPP1P2/R1BQK2R w KQ -
+Giuoco piano: Rosentreter variation *
+rn1q1rk1/ppp3pp/8/3P1p2/3Pn1b1/3B1N2/PP3PPb/RNBQR1K1 w - -
+Petrov: classical attack, Marshall trap
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+Gr\"unfeld defense: Smyslov, main line
+rn1qk1nr/pb3ppp/8/2b1p3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: Schlechter defense *
+rn1qk1nr/pb3ppp/8/2b1p3/8/8/PPPPQPPP/RNB1KBNR b KQkq -
+Danish gambit: Collijn defense *
+rn1qk1nr/pp1bppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch-Indian, Alekhine variation *
+rn1qk1nr/pp3ppp/2pb4/3p1b2/3P4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Caro-Kann: exchange, Rubinstein variation *
+rn1qk1nr/ppp1ppbp/3p2p1/8/2PPP1b1/5N2/PP3PPP/RNBQKB1R w KQkq -
+Robatsch defense: Rossolimo variation
+rn1qk1nr/ppp2ppp/8/2b1p3/Q3P1b1/2P2N2/PP1P2PP/RNB1KB1R b KQkq -
+KGD: classical, Marshall attack
+rn1qk2r/1bpp1ppp/1p2pn2/p7/1bPP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Yates variation
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation
+rn1qk2r/p4ppp/2p2n2/2bpp3/B3P1b1/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Sokolsky variation *
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: symmetrical, hedgehog system
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, main line
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: Capablanca variation
+rn1qk2r/pbpp1ppp/5n2/1pb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Cordel variation *
+rn1qk2r/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP1BPPBP/R2QK2R b KQkq -
+Queen's Indian: Opo\v censky variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R b KQkq -
+Queen's Indian: anti-Queen's Indian system
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Riumin variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b kq -
+Queen's Indian: old main line, 6.O-O
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: 5.Bg2 Be7
+rn1qk2r/pp1bppbp/5np1/1Bpp4/P7/1P2PN2/1BPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Yates variation *
+rn1qk2r/pp1bppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: Riumin variation *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Paulsen attack *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/5Q2/PPPPNPPP/R1BNK2R b KQkq -
+Scotch: Paulsen, Gunsberg defense *
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+QGD Slav: Dutch variation
+rn1qk2r/pp3ppp/2p2n2/2bpp3/4P1b1/1BN5/PPPPQPPP/R1B1K1NR w KQkq -
+Giuoco Piano: Mestel variation *
+rn1qk2r/ppp2ppp/3pbn2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation *
+rn1qk2r/ppp2ppp/8/2bP1b2/4nP2/5N2/PPP1Q1PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, main line, 7...Bf5
+rn1qk2r/ppp3p1/8/2bpP1Pp/4b3/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Cook variation *
+rn1qk2r/pppbbppp/8/3pP3/N3n3/2PB1N1P/P1Q2PP1/R1B1K2R w KQkq -
+two knights defense: Knorre variation *
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 8...Bb7
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N3P1/PP3P1P/R1BQ1KNR b kq -
+Benk\"o gambit
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N5/PP2NPPP/R1BQ1K1R b kq -
+Benk\"o gambit: Ne2 variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benk\"o gambit: fianchetto variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benk\"o gambit: Nd2 variation
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benk\"o gambit: 7.e4
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto)
+rn1qkb1r/pb1p1ppp/1p2pn2/2p5/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+English: Wimpey system *
+rn1qkb1r/pb1p1ppp/1p3n2/2pp2N1/2P5/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: B\"urger variation
+rn1qkb1r/pb1p1ppp/1p3n2/2pp4/2P4N/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: Rubinstein variation
+rn1qkb1r/pb1ppppp/1p3n2/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Capablanca's variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: New York (London) defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+English: Bled variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Queen's Indian: Marienbad system
+rn1qkb1r/pb1ppppp/1p3n2/8/2PQ4/5NP1/PP2PPBP/RNB1K2R b KQkq -
+Queen's Indian: Marienbad system, Berg variation
+rn1qkb1r/pbpp1p2/1p2p2p/6pn/2PP4/2N2NB1/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2NB1N2/PP1P1PPP/R1BQK2R b KQkq -
+English: Queens Indian, Romanishin variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 Bb7
+rn1qkb1r/pp1bpppp/5n2/1Bpp4/8/4PN2/PPPPQPPP/RNB1K2R b KQkq -
+Bogo-Indian defense, Nimzovich variation *
+rn1qkb1r/pp1n1ppp/4p3/3pNb2/3P4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD Slav: Amsterdam variation
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: New York (London) defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: London defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 Bf5
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Capablanca's variation
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: Torre defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p4/6b1/5NP1/PPPPPPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Yugoslav variation
+rn1qkb1r/pp2pppp/2p2n2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav: Krause attack
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+QGD Slav: Dutch variation
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Czech defense
+rn1qkb1r/pp2pppp/2p2n2/8/P1pP2b1/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Steiner variation
+rn1qkb1r/pp2pppp/2pp4/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Flohr variation
+rn1qkb1r/pp2pppp/5n2/1Bpp4/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Vienna variation *
+rn1qkb1r/pp2pppp/5n2/2p5/1PPp2b1/4PN2/P2P1PPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation *
+rn1qkb1r/pp2pppp/5n2/2pp1b2/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Miles variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN1P/PPP2PP1/RNBQKB1R b KQkq -
+QGD: Capablanca-Duras variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD *
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: exchange variation
+rn1qkb1r/pp2pppp/5n2/8/1PPp2b1/5N1P/P2P1PP1/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit, Spielmann variation *
+rn1qkb1r/pp3ppp/2p1pn2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Wiesbaden variation
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3 *
+rn1qkb1r/ppn2ppp/2p1b3/4p3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Meitner variation *
+rn1qkb1r/ppp1pppp/1n1p4/3PP3/2P3b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Vitolins attack
+rn1qkb1r/ppp1pppp/1n1p4/4Pb2/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation
+rn1qkb1r/ppp1pppp/3p1n2/5b2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Janowski variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/2PP2b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Alekhine variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N1P/PPP2PP1/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Panov variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation, 4...Bg4
+rn1qkb1r/ppp1pppp/4bn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Flohr variation
+rn1qkb1r/ppp1pppp/5B2/3p1b2/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack, Veresov variation
+rn1qkb1r/ppp1pppp/5n2/3p1b2/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's bishop game *
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: London system *
+rn1qkb1r/ppp1pppp/5n2/3p1bB1/3P4/2N2P2/PPP1P1PP/R2QKBNR b KQkq -
+Richter-Veresov attack, Richter variation
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Torre attack (Tartakower variation) *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/8/2pP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Janowsky-Larsen variation
+rn1qkb1r/ppp2ppp/4b3/4p3/1nB5/2N2Q2/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch: Blumenfeld attack *
+rn1qkb1r/ppp2ppp/5n2/3pp3/2P3b1/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack, Wagner gambit *
+rn1qkb1r/ppp2ppp/8/3pP3/4n1b1/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Vienna gambit: Kaufmann variation
+rn1qkb1r/ppp3p1/8/3ppbPp/3Pn3/5N2/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense *
+rn1qkb1r/pppb1ppp/8/1B2p2Q/1n6/2N5/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch game *
+rn1qkbnr/1bpp1ppp/p7/1P6/3Q4/8/PP2PPPP/RNB1KBNR w KQkq -
+Sicilian: wing gambit, Marienbad variation *
+rn1qkbnr/1pp2ppp/p3p3/3P4/2B3b1/4PN2/PP3PPP/RNBQK2R b KQkq -
+QGA: Alekhine defense, Alatortsev variation
+rn1qkbnr/p1pppppp/bp6/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Guatemala defense
+rn1qkbnr/pp1b1ppp/4P3/1Bp5/4p3/8/PPP2PPP/RNBQK1NR b KQkq -
+QGD: Albin counter-gambit, Lasker trap *
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7
+rn1qkbnr/pp2pppp/2p3b1/8/3P1P2/6N1/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: classical, Mar\'oczy attack
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+Caro-Kann: classical, 6.h4
+rn1qkbnr/pp2pppp/2p3b1/8/3P4/6NN/PPP2PPP/R1BQKB1R b KQkq -
+Caro-Kann: classical, Flohr variation
+rn1qkbnr/pp2pppp/2p5/3p4/2P3b1/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Caro-Kann: two knights, 3...Bg4
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: classical variation
+rn1qkbnr/pp2pppp/8/2p2bN1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Rubinstein variation *
+rn1qkbnr/pp2pppp/8/2pp4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Neo-Indian (Seirawan) attack *
+rn1qkbnr/pp3ppp/2p1p3/3pPb2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+Caro-Kann: advance, Short variation
+rn1qkbnr/pp4pp/4b3/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R w KQkq -
+Alekhine's defense: four pawns attack, 7.Be3 *
+rn1qkbnr/ppp1pppp/3p4/8/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Old Indian: Tartakower (Wade) variation
+rn1qkbnr/ppp1pppp/3p4/8/4P1b1/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+R\'eti: Wade defense
+rn1qkbnr/ppp1pppp/4b3/8/2p5/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+R\'eti accepted: Keres variation
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit *
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Grau (Sahovic) defense
+rn1qkbnr/ppp1pppp/8/3p1b2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn, Mason variation *
+rn1qkbnr/ppp1pppp/8/3p1b2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: London system *
+rn1qkbnr/ppp1pppp/8/3p4/2P3b1/8/PP1PPPBP/RNBQK1NR b KQkq -
+Grob: Fritz gambit
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Queen's pawn: Anti-Veresov
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/8/PPP1PPPP/RNBQKBNR w KQkq -
+Levitsky attack (Queen's bishop attack) *
+rn1qkbnr/ppp1pppp/8/3p4/5Pb1/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, 2.Bg5 variation *
+rn1qkbnr/ppp1pppp/8/3p4/6b1/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening) *
+rn1qkbnr/ppp1pppp/8/8/2Pp2b1/8/PP1PPPBP/RNBQK1NR w KQkq -
+Grob: Romford counter-gambit
+rn1qkbnr/ppp2ppp/2b1p3/8/3PN3/5N2/PPP2PPP/R1BQKB1R w KQkq -
+French: Fort Knox variation
+rn1qkbnr/ppp2ppp/3p4/4p3/2P3b1/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English, Smyslov defense
+rn1qkbnr/ppp2ppp/4b3/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Alapin variation *
+rn1qkbnr/ppp2ppp/8/3p4/5p2/6PB/PPPPP2P/RNBQK2R w KQkq -
+Amar gambit
+rn1qkbnr/pppb1ppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R w KQkq -
+Philidor: Boden variation
+rn2k2r/pbpp1ppp/8/2b1p3/Np2Q3/1B6/PPPP1qPP/R1BK2NR w kq -
+Evans gambit declined, Hicken variation *
+rn2k2r/pp4pp/1q3p2/1N1pN3/3Pn3/5K2/PPP3PP/R1BQ3R w kq -
+Giuoco Piano: Krause variation *
+rn2kb1r/pp1q1ppp/2p1b3/3np3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Blackburne attack *
+rn2kb1r/pp2pppp/2p2n2/q3Nb2/3P2P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Scandinavian defense, Gr\"unfeld variation
+rn2kb1r/pp3ppp/2p1q3/1N6/3p4/5Q2/PP3PPP/1RB2RK1 b kq -
+Scotch: Gottschall variation *
+rn2kb1r/ppp1pppp/5n2/q4b2/3P4/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian defense
+rn2kb1r/ppp1pppp/5n2/q7/3P2b1/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Scandinavian defense, Lasker variation
+rn2kbnr/pp1b1ppp/1q2p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Wade variation
+rn2kbnr/pp1qpppp/3p4/2p5/2P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation
+rn2kbnr/ppp2ppp/8/q3p3/3P2b1/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation
+rn3rk1/p1p1qpp1/1p2b2p/3p4/3P4/4PN2/PP3PPP/2RQKB1R w K -
+QGD: Tartakower variation
+rn3rk1/p4ppp/bqp5/2b1p3/N3n3/1B6/PPPQ1PPP/R1B1K1NR w KQ -
+Evans gambit: Levenfish variation *
+rnb1k1nr/p3qppp/2p1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Koomen variation
+rnb1k1nr/p4ppp/1qp1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Junge variation
+rnb1k1nr/pp1pq1pp/2p5/2b1pp2/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Bishop's opening: Lopez gambit *
+rnb1k1nr/pp2ppbp/3p2p1/q1p5/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Pterodactyl defense
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4 *
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Qa4 *
+rnb1k1nr/pp3ppp/2p5/2PP4/2B4q/5p2/PPP2PPP/RNBQ1RK1 b kq -
+Bishop's opening: Pratt variation *
+rnb1k1nr/pp3ppp/4p3/2pq4/1b1P4/2NB4/PPPB1PPP/R2QK1NR b KQkq -
+French: Winawer, Kondratiyev variation
+rnb1k1nr/ppp2pbp/3p4/4P1p1/2BP1p1q/2N5/PPP3PP/R1BQ1KNR b kq -
+KGA: bishop's gambit, Grimm attack
+rnb1k1nr/ppp2ppp/3b4/3B4/4Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bor\'en-Svenonius variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1P2q/2N2Qp1/PPPP3P/R1B2KNR b kq -
+KGA: bishop's gambit, Fraser variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1Pp1q/2N3P1/PPPP3P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k1nr/pppp1ppp/8/2b1p1q1/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: del Rio variation
+rnb1k1nr/pppp1ppp/8/2b5/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Greco variation
+rnb1k1nr/pppp1ppp/8/4p3/1bB1Pq2/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGD: Norwalde variation, B\"ucker gambit
+rnb1k1nr/ppppqppp/1b1P4/4p3/2B1P3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano: Eisinger variation
+rnb1k1nr/pppq1ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, Petrosian variation
+rnb1k1nr/ppq1ppbp/6p1/3p4/8/P3PN2/1PPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, Alekhine variation *
+rnb1k1nr/ppq2ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, classical variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P1NPPP/R1B1KB1R b KQq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P2PPP/R1BK1BNR b q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation
+rnb1k2r/1pq1bpp1/p2ppn1p/8/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, Browne variation
+rnb1k2r/1pq1bppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf variation
+rnb1k2r/2q1bp1p/p2p1n2/1ppPp1p1/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 w kq -
+Ruy Lopez: closed, Leonhardt variation
+rnb1k2r/p1pp1ppp/8/4p3/Np2n1Qq/1B6/PPPPKbPP/R1B3NR w kq -
+Evans gambit declined, V\'asquez variation *
+rnb1k2r/p4ppp/1qp2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Tartakower attack *
+rnb1k2r/pp2ppbp/5np1/2pq4/8/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+Queen's Indian: Marienbad system, Berg variation *
+rnb1k2r/pp2qppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2QK2R b KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation *
+rnb1k2r/pp3ppp/4p3/q7/1b1PP3/5N2/P2B1PPP/R2QKB1R w KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation
+rnb1k2r/ppp1qppp/5n2/2p1P3/3p4/5N1P/PPP1BPP1/R1BQK2R b KQkq -
+two knights defense: Mar\'oczy variation *
+rnb1k2r/ppp1qppp/5n2/3P4/1bBp4/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Bishop's opening: Urusov gambit, Panov variation
+rnb1k2r/ppp2p1p/4pp2/q7/1b1P4/2N5/PPPQ1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Bogolyubov variation
+rnb1k2r/ppp2p1p/5n2/3qN3/1b1P1ppP/2N5/PPP2KP1/R1BQ1B1R b kq -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation
+rnb1k2r/ppp2ppp/1b6/3qp3/1PP5/P2P4/5PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Noah's ark trap *
+rnb1k2r/ppp2ppp/3b4/3qp3/8/3P4/PPP2PPP/R1BQKBNR w KQkq -
+Scotch: Ghulam Kassim variation *
+rnb1k2r/ppp2ppp/5n2/3qp3/1b6/2NP4/PP1QPPPP/R1B1KBNR b KQkq -
+Sicilian: Chekhover, Zaitsev variation *
+rnb1k2r/ppp2ppp/8/2bPp3/2B3nq/2N4N/PPPP1PPP/R1BQK2R w KQkq -
+Scotch gambit: Vitzhum attack *
+rnb1k2r/ppp2ppp/8/3Pp3/2qP4/2N3P1/PPP2K1P/R1BQ3R b kq -
+Scotch gambit: Cochrane-Shumov defense *
+rnb1k2r/ppp2ppp/8/3np3/8/P1P5/1PPB1PPP/R3KBNR b KQkq -
+Ruy Lopez: exchange, Alekhine variation *
+rnb1k2r/ppp2ppp/8/3q4/4nP2/8/PPPNQbPP/RNBK1B1R b kq -
+KGD: Falkbeer, Alapin variation
+rnb1k2r/ppp3p1/3q1n2/2bppP1p/6P1/3P3P/PPP2PB1/RNBQK1NR w KQkq -
+KGA: Philidor gambit, Schultz variation *
+rnb1k2r/pppnqppp/4p3/1N1pP3/3P4/8/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Alapin variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P1P2/2N5/PPP3PP/R2QKBNR b KQkq -
+French: classical, Steinitz variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Pollock variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPPQ1PPP/R3KBNR b KQkq -
+French: classical, Rubinstein variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2NB4/PPP2PPP/R2QK1NR b KQkq -
+French: classical, Tarrasch variation
+rnb1k2r/pppnqppp/8/2p1P3/2Bp4/5N1P/PPP2PP1/R1BQK2R w KQkq -
+two knights defense: Yankovich variation *
+rnb1k2r/pppp1ppp/3b1q2/8/N3P1n1/2P2N2/P1Q2PPP/R1B1KB1R w KQkq -
+two knights defense: Paoli variation *
+rnb1k2r/pppp1ppp/5q2/8/NP2P1n1/5N2/P4PPP/R1BQKB1R b KQkq -
+two knights defense: Blackburne variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/1RBQKB1R b Kkq -
+two knights defense: Colman variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+two knights defense: Bogolyubov variation *
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N3P1/PPP4P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N5/PPP3PP/R1BQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1k2r/ppppqppp/4pn2/8/1bPP4/5N2/PP1BPPPP/RN1QKB1R w KQkq -
+Bogo-Indian defense, Nimzovich variation
+rnb1k2r/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Wormald (Alapin) attack *
+rnb1kb1N/ppp3pp/5n2/3p4/2B1p3/8/PPPP1PqP/RNBQKR2 w Qkq -
+Latvian: Behting variation
+rnb1kb1r/1p3ppp/p2ppn2/6B1/3NPP2/q1N5/P1PQ2PP/1R2KB1R w Kkq -
+Sicilian: Najdorf, Poisoned pawn variation
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Qb6
+rnb1kb1r/1pq2ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnb1kb1r/2q2ppp/p3pn2/1p2P1B1/3N4/2N5/PPP1Q1PP/R3KB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Ponziani: Leonhardt variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Ponziani: Steinitz variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+Ponziani: Caro variation *
+rnb1kb1r/pp1p2pp/2p2n2/q3p1B1/2B1P3/8/PPP2PPP/RN1QK1NR w KQkq -
+KGD: classical, Marshall attack *
+rnb1kb1r/pp1ppppp/5n2/q1pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Woozle defense
+rnb1kb1r/pp2pppp/1qp2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav: S\"uchting variation
+rnb1kb1r/pp2pppp/5n2/q1Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA: Mannheim variation *
+rnb1kb1r/pp3pp1/2p1pq1p/3p4/2PP4/1QN2N2/PP2PPPP/R3KB1R b KQkq -
+QGD/QGD semi-Slav: Hastings variation
+rnb1kb1r/pp3ppp/1q2pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Canal (Venice) variation
+rnb1kb1r/ppp1pppp/5n2/8/3q4/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Queen's pawn: Englund gambit *
+rnb1kb1r/ppp1q1pp/5n2/4Np2/2Bp1B2/8/PPP2PPP/RN1QK2R b KQkq -
+KGD: Falkbeer, main line, 7...Bf5 *
+rnb1kb1r/ppp1q2p/5n2/4Npp1/2Bp1B2/8/PPP2PPP/RN1Q1RK1 b kq -
+KGD: Falkbeer, Tarrasch variation *
+rnb1kb1r/ppp1qppp/5n2/3PN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Steinitz variation *
+rnb1kb1r/ppp1qppp/8/3n4/2N1p3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: modern attack, Bardeleben variation *
+rnb1kb1r/ppp2p1p/3p3n/4N3/2BPPppq/8/PPP3PP/RNBQ1K1R w kq -
+KGA: Salvio gambit, Anderssen counter-attack
+rnb1kb1r/ppp2ppp/5n2/3qN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, main line *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian, Chekhover variation *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PPPB1PPP/RN1QKBNR b KQkq -
+Philidor: Boden variation *
+rnb1kb1r/ppp2ppp/5n2/4N3/3qp3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Rellstab variation *
+rnb1kb1r/ppp2ppp/8/3NP2q/8/3P1Nn1/PPP4P/R1BQKB1R b KQkq -
+Vienna gambit, Wurzburger trap
+rnb1kb1r/ppp3pp/8/3q1p2/4nPP1/8/PPPNQ2P/R1B1KBNR b KQkq -
+KGD: Falkbeer, Charousek variation
+rnb1kb1r/pppp1p1p/7n/4N3/2BPP1pq/5p2/PPP3PP/RNBQ1K1R w kq -
+KGA: Silberschmidt gambit
+rnb1kb1r/pppp2p1/8/4pq1p/8/3B1N1P/PPPP1K2/RNBQ3R b kq -
+KGA: Allgaier, Horny defense *
+rnb1kb1r/ppppqppp/5n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Cozio (Lasker) attack *
+rnb1kb1r/ppq1p1pp/2pp1n2/5p2/2PP4/2N3P1/PP2PPBP/R1BQK1NR w KQkq -
+Dutch: Hort-Antoshin system
+rnb1kbnr/p1pp1ppp/8/1p6/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnb1kbnr/pp1ppppp/8/q1p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Stiletto (Althouse) variation
+rnb1kbnr/pp2pppp/1qp5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+Caro-Kann: Edinburgh variation
+rnb1kbnr/pp2pppp/8/3q4/1p6/P7/1BPP1PPP/RN1QKBNR b KQkq -
+Sicilian: wing gambit, Marienbad variation
+rnb1kbnr/pp3ppp/2p1q3/4p3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Center game: Charousek variation *
+rnb1kbnr/ppp1pp1p/3q4/3p2p1/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch, Von Pretzel gambit *
+rnb1kbnr/ppp1pppp/3q4/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation *
+rnb1kbnr/ppp1pppp/3q4/8/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scandinavian: Pytel-Wade variation
+rnb1kbnr/ppp1pppp/8/q7/1P6/2N5/P1PP1PPP/R1BQKBNR b KQkq -
+Scandinavian, Mieses-Kotr\v c gambit
+rnb1kbnr/ppp1q1pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, R\'eti variation *
+rnb1kbnr/ppp1q1pp/8/4Np2/3p4/8/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Charousek gambit *
+rnb1kbnr/ppp2p1p/8/3B2p1/4Pp1q/6P1/PPPP3P/RNBQ1KNR b kq -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation)
+rnb1kbnr/ppp2ppp/4p3/3q4/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Frere (Becker) variation
+rnb1kbnr/ppp2ppp/4q3/4p3/5P2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Center game: l'Hermet variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Center game: Berger variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Paulsen attack *
+rnb1kbnr/ppp2ppp/8/2q1p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Hall variation *
+rnb1kbnr/ppp2ppp/8/3p2q1/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich variation *
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/3qp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Scandinavian: Anderssen counter-attack
+rnb1kbnr/ppp3pp/3p1q2/8/3Pp3/4N3/PPP2PPP/RNBQKB1R b KQkq -
+Latvian: Nimzovich variation
+rnb1kbnr/pppp1B1p/8/4q3/5p2/5Q2/PPPP2PP/RNB2RK1 b kq -
+KGA: double Muzio gambit
+rnb1kbnr/pppp1p1p/8/4N3/2B1P1pq/5p2/PPPP2PP/RNBQ1K1R w kq -
+KGA: Cochrane gambit
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/5Q2/PPPP2PP/RNB2KNR b kq -
+KGA: bishop's gambit, classical defense, Cozio attack
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Greco defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Napoleon's opening *
+rnb1kbnr/pppp1ppp/5q2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Norwalde variation
+rnb1kbnr/pppp1ppp/8/4p3/4P2q/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Patzer opening *
+rnb1kbnr/pppp2pp/5q2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Breyer gambit *
+rnb1kbnr/ppppq1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Carrera (Basman) gambit *
+rnb1kbnr/ppppq2p/8/4Np2/2BPPppP/8/PPP3P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation
+rnb1kbnr/ppppqp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense
+rnb1kbnr/ppppqp1p/8/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, From defense
+rnb1kbnr/ppppqp1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Kling and Horwitz counter-attack
+rnb1kbnr/ppppqppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Gunderam defense
+rnb1kbnr/ppppqppp/8/4p3/4PP2/6P1/PPPP3P/RNBQKBNR w KQkq -
+KGD: Keene's defense
+rnb1kbnr/ppppqppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Chigorin variation *
+rnb1kbnr/ppppqppp/8/8/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Collijn defense
+rnb1kbnr/ppq1pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Fajarowicz, Steiner variation *
+rnb1kbnr/ppq1pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+Queen's pawn: Mengarini attack *
+rnb1kbnr/ppqppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Quinteros variation
+rnb1qrk1/pp2b1pp/2p1pn2/3p1pB1/2PP4/2N2NP1/PPQ1PPBP/R4RK1 b - -
+Dutch: stonewall: Chekhover variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+Dutch: Ilyin-Genevsky variation with b3
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Ilyin-Genevsky variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQR1K1 b - -
+Dutch: Ilyin-Genevsky, Winter variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+Dutch: Ilyin-Genevsky variation with Qc2
+rnb1r1k1/ppp2ppp/1b6/3qp3/1PP5/P2P1N2/4BPPP/R1BQK2R b KQ -
+Ruy Lopez: Noah's ark trap *
+rnb2bnr/pppp1k1p/5q2/8/4Pp2/2N1BQ2/PPP3PP/R4RK1 b - -
+KGA: Lolli gambit, Young variation
+rnb2knr/pppp2pp/5q2/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, classical defense, Cozio attack *
+rnb2rk1/p1p1qppp/1p3n2/8/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Pillsbury variation *
+rnb2rk1/p1pqppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQ1RK1 w - -
+Gr\"unfeld: exchange, Larsen variation
+rnb2rk1/p1q1ppbp/1p3np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Qc2 & b3 *
+rnb2rk1/p4ppp/1qp2n2/2bPp3/B7/2NP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Waller attack *
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+QGA: classical, 8...Bb7 *
+rnb2rk1/pp2qppp/1b3n2/2p1N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, Howell attack, Adam variation *
+rnb2rk1/pp2qppp/4pn2/2bp4/1PP5/P3PN2/5PPP/RNBQKB1R b KQ -
+QGA: classical, 7...b5 *
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, 7.Qe2 *
+rnb2rk1/pp2qppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation
+rnb2rk1/pp2qppp/5n2/2b5/1PB1p3/P1N1PN2/5PPP/R1BQK2R w KQ -
+QGA: classical, Furman variation *
+rnb2rk1/pp2qppp/5n2/2p5/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Zukertort variation *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, Motzko attack *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P3B3/2P1NPPP/R2QK2R b KQ -
+Ruy Lopez: open, Motzko attack, Nenarokov variation *
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+Gr\"unfeld: Gr\"unfeld gambit accepted
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+QGD: Lasker defense, main line
+rnb2rk1/ppp1qpp1/4p2p/3p4/2PPn3/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Lasker defense, Teichmann variation
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Howell attack *
+rnb2rk1/ppp1qppp/5n2/3pN3/1b1PP3/2N5/PPP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation *
+rnb2rk1/ppp1qppp/5n2/8/4pN2/2P5/P1PPBPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Cordel variation *
+rnb2rk1/ppp1qppp/8/3n4/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Winawer attack *
+rnb2rk1/ppp2pbp/3p2p1/3Pp3/2n1P2Q/2N2P2/PP2K2P/R5NR w - -
+King's Indian: S\"amisch, orthodox, Bronstein variation
+rnb2rk1/ppp2pp1/3q3p/3p4/3P4/1QP1PN2/P4PPP/R3KB1R w KQ -
+QGD: Lasker defense, Bernstein variation
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/2N5/PPPP1P1P/R1BQKBNR b KQ -
+KGA: Muzio gambit, Holloway defense *
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, From defense *
+rnb2rk1/pppp2pp/5q2/5P2/4Q3/8/PPPP1b1P/RNB1KBNR w KQ -
+KGA: double Muzio gambit *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Worrall attack, sharp line *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Worrall attack, solid line *
+rnb2rk1/ppppqppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Tartakower variation *
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Worrall attack *
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+Catalan: closed, 7.Qc2 *
+rnbk1b1r/pppnqBpp/8/4Np2/3Q4/8/PPP2PPP/RNB1K2R w KQ -
+KGD: Falkbeer, Alapin variation *
+rnbk1bnr/pppp2pp/8/8/2B1pp1q/2N5/PPPPQ1PP/R1BK2NR w - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation
+rnbq1bnr/ppp3k1/7p/3B4/3PPppP/8/PPP3P1/RNBQK2R b KQ -
+KGA: Allgaier, Urusov attack
+rnbq1bnr/ppp3k1/7p/4B3/2BPp1pP/8/PPP3P1/RN1QK2R b KQ -
+KGA: Allgaier, Cook variation
+rnbq1bnr/pppp1k2/7p/8/2B1PppP/8/PPPP2P1/RNBQK2R b KQ -
+KGA: Allgaier, Walker attack
+rnbq1bnr/pppp1k2/7p/8/3PPppP/8/PPP3P1/RNBQKB1R b KQ -
+KGA: Allgaier, Thorold variation
+rnbq1bnr/pppp1k2/7p/8/4PppP/2N5/PPPP2P1/R1BQKB1R b KQ -
+KGA: Allgaier, Blackburne gambit
+rnbq1bnr/pppp1kpp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQ -
+KGA: Tumbleweed gambit *
+rnbq1bnr/pppppkpp/5p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQ -
+Fried fox defense
+rnbq1bnr/pppppkpp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQ -
+Hammerschlag (Fried fox/Pork chop opening) *
+rnbq1k1r/pp3ppp/5n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Cracow variation *
+rnbq1k1r/ppp2Bpp/8/4N2Q/1b1Pp3/2n5/PPP2PPP/R1B1K2R b KQ -
+Two knights defense, Keidanz variation *
+rnbq1k1r/ppp2pp1/4p2p/3pP3/3Pn1Q1/2P5/P1P2PPP/R1B1KBNR b KQ -
+French: MacCutcheon, Duras variation
+rnbq1k1r/ppp3pp/5P2/2bpp1PQ/4n3/7N/PPPP1P1P/RNB1KB1R b KQ -
+KGA: Silberschmidt gambit *
+rnbq1k1r/ppp3pp/8/2bppPPQ/4n3/3P3N/PPP2P1P/RNB1KB1R b KQ -
+KGA: Salvio gambit, Anderssen counter-attack *
+rnbq1k1r/pppp2pp/5P2/2b1p1PQ/4n3/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: Cochrane gambit *
+rnbq1k1r/pppp2pp/8/2b1pPPQ/4n3/2N5/PPPP1P1P/R1B1KBNR b KQ -
+KGA: Herzfeld gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/1P6/8/P1PP1PPP/RNB1KBNR b KQ -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/2B5/8/PPPP1PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Greco variation *
+rnbq1knr/pppp2pp/8/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: bishop's gambit, classical defense *
+rnbq1knr/pppp2pp/8/2b1pP1Q/8/2N5/PPPP1PPP/R1B1KBNR b KQ -
+KGA: bishop's gambit, Boden defense *
+rnbq1knr/pppp2pp/8/4pP1Q/3b4/3B4/PPP2PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Bor\'en-Svenonius variation *
+rnbq1knr/pppp3p/6p1/4pP1Q/3b2P1/8/PPP2P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation) *
+rnbq1r1k/p1p4P/5n2/2bpp2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+Bishop's opening: Four pawns' gambit *
+rnbq1r1k/pppp3P/5n2/2b1p2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+KGA: Cunningham, three pawns gambit *
+rnbq1rk1/1p2ppbp/p1pp1np1/8/2PPP3/2NBBP2/PP4PP/R2QK1NR w KQ -
+King's Indian: S\"amisch, Byrne variation
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...a6, 10.a4
+rnbq1rk1/1p3ppp/4pn2/p1bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Rubinstein variation *
+rnbq1rk1/1pp1ppbp/p4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation
+rnbq1rk1/1pp2pbp/3p1np1/p2Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, Stein variation
+rnbq1rk1/1pp2ppp/1b3n2/p2NN3/1P1PP3/P7/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Schlechter defense *
+rnbq1rk1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Wing attack *
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, 10.d4
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer defense
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, double fianchetto variation
+rnbq1rk1/p1p1ppbp/1p3np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Levenfish variation
+rnbq1rk1/p1p1ppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's lesser variation
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...b6
+rnbq1rk1/p1pp1ppp/4pn2/1p6/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Adorjan gambit
+rnbq1rk1/p1pp1ppp/5n2/1p1Np3/1bB1P3/8/PPPP1PPP/R1BQK1NR w KQ -
+Ruy Lopez: classical defense, Zaitsev variation *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR w KQ -
+Evans gambit *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall, Botwinnik variation *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: Euwe variation *
+rnbq1rk1/p4ppp/1p2pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Keres variation
+rnbq1rk1/p4ppp/2P2n2/2b1p3/B7/2N5/PPPP1PPP/R1BQK1NR b KQ -
+Evans gambit: compromised defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp1B1/B3P3/2NP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit: Alapin-Steinitz variation *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/4P3/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: Lasker defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPPB1PPP/R2QK1NR b KQ -
+Evans gambit: Sanders-Alapin variation *
+rnbq1rk1/p4ppp/2p5/2bpp3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Evans gambit: Richardson attack *
+rnbq1rk1/p4ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: normal variation *
+rnbq1rk1/pp1p1ppp/2p2n2/b7/4PB2/P1NP4/1PP3PP/R2QKBNR w KQ -
+Ruy Lopez: Siesta, Kopayev variation *
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Pir\'c variation
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+English: Neo-Catalan declined *
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: stonewall with Nc3
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+Dutch: stonewall with Ba3
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with c6
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O c6
+rnbq1rk1/pp2ppbp/2p2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, 6...c5
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav, 7.O-O
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto, Yugoslav system
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, with Be2 and Nf3
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R b KQ -
+King's Indian: Four pawns attack, dynamic line
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+Sicilian: dragon, Yugoslav attack, 7...O-O
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: stonewall variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O c6 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+Catalan: closed, 6...Nbd7 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: classical variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQ -
+Queen's Indian: old main line, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2ppN3/5P2/4P3/PPPPB1PP/RNBQ1RK1 b - -
+Dutch defense, Alekhine variation *
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O, main line *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O, main line
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6 *
+rnbq1rk1/pp2ppbp/5np1/8/2pN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc *
+rnbq1rk1/pp2ppbp/6p1/2Pn4/8/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Spassky variation
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox, 7.d5 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Donner variation
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+Benoni: classical without 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+Benoni: four pawns attack
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+Benoni: fianchetto variation
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, Florentine gambit
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack
+rnbq1rk1/pp3ppp/1b3n2/2ppN3/1P1PP3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Harksen gambit *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+Ruy Lopez: open, classical defense *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, 9.c3 *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+Ruy Lopez: open, Italian variation *
+rnbq1rk1/pp3ppp/1bp2n2/8/1PNPp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, Berlin variation *
+rnbq1rk1/pp3ppp/2p2n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack, Krause variation *
+rnbq1rk1/pp3ppp/2p2n2/2bPp1B1/2B5/2NP4/PPP2PPP/R2QK1NR b KQ -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/1b2P3/1BN2N2/PPPP1PPP/R1BQ1RK1 b - -
+Ruy Lopez: classical defense, Benelux variation *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/2P5/2NP1N2/PP1QPPPP/R3KB1R w KQ -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit *
+rnbq1rk1/pp3ppp/2p2n2/b2PN3/4p3/P1N5/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, Basque gambit (North Spanish variation) *
+rnbq1rk1/pp3ppp/3b1n2/2ppN1B1/3P4/3B4/PPP2PPP/RN1Q1RK1 b - -
+Petrov: classical attack, Tarrasch variation *
+rnbq1rk1/pp3ppp/3b1n2/2ppN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Jaenisch variation *
+rnbq1rk1/pp3ppp/3b4/2pnp3/8/P2PPNP1/1P3P1P/RNBQKB1R b KQ -
+Sicilian: Kan, Gipslis variation *
+rnbq1rk1/pp3ppp/3b4/2ppN3/3PB3/8/PPP2PPP/RNBQ1RK1 b - -
+Petrov: modern attack, Trifunovi\'c variation *
+rnbq1rk1/pp3ppp/4p3/1B6/3PP3/5N2/P2Q1PPP/R3K2R b KQ -
+QGD: Semi-Tarrasch, Kmoch variation
+rnbq1rk1/pp3ppp/4p3/2pn4/3P4/P1P1PP2/6PP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch, Botvinnik variation
+rnbq1rk1/pp3ppp/4pn2/2bP4/8/4PN2/PP3PPP/RNBQKB1R b KQ -
+QGA: classical, Steinitz variation *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R w KQ -
+QGA: classical variation, 6.O-O *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QGA: classical, 6...a6 *
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...c5
+rnbq1rk1/pp3ppp/5n2/2bpp3/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Geller variation *
+rnbq1rk1/pp4pp/2p5/2bppp2/3PP1n1/2P4N/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Hanham, Berger variation *
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: classical variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Dutch: stonewall, Botwinnik variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Dutch: stonewall with Nc3
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: stonewall variation
+rnbq1rk1/ppp1bpp1/4p2p/3p4/2PPn2B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Lasker defense
+rnbq1rk1/ppp1bpp1/4pB1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bxf6
+rnbq1rk1/ppp1bpp1/4pn1p/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Neo-orthodox variation
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bh4
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+QGD: Anti-neo-orthodox variation
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQ -
+QGD: 4.Bg5 Be7, 5.e3 O-O
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: 6.Nf3
+rnbq1rk1/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Mason variation
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6
+rnbq1rk1/ppp1ppbp/3p1np1/4P3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQ -
+Pirc: Austrian attack, 6.e5
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Zinnowitz variation
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1B3/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Semi-Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1BN2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Larsen variation
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+King's Indian: S\"amisch, 5...O-O
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+King's Indian: Four pawns attack, 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PP3/6P1/PPP1NPBP/RNBQK2R b KQ -
+R\'eti: King's Indian attack, Pachman system *
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N1BN2/PPP3PP/R2QKB1R b KQ -
+Pirc: Austrian attack, 6.Be3
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+Pirc: Austrian attack
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+Pirc: Austrian attack, 6.Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/1PPP4/2N1PN2/P4PPP/R1BQKB1R b KQ -
+Gr\"unfeld: Makogonov variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/2RQKBNR b K -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+Gr\"unfeld: Gr\"unfeld gambit
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+Gr\"unfeld with Bf4 & e3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld with e3 & Qb3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP1B1PPP/R2QKB1R b KQ -
+Gr\"unfeld: Opo\v censky variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+Gr\"unfeld with e3 & Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O
+rnbq1rk1/ppp1ppbp/5np1/3p4/5P2/2P3PN/PP1PP1BP/RNBQK2R b KQ -
+Dutch: Leningrad, Basman system *
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld: Russian variation with e4
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+King's Indian: S\"amisch, orthodox, 7.d5
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Petrosian system
+rnbq1rk1/ppp2pbp/3p1np1/4P3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Andersson variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2QK2R b KQ -
+King's Indian: Gligori\'c-Taimanov system
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: classical variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+King's Indian: Pomar system
+rnbq1rk1/ppp2pbp/4pnp1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Botvinnik variation
+rnbq1rk1/ppp2ppp/1b3n2/3pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 7.Bb3 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, 8...Be6 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 8.de *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P7/2P1NPPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Zukertort variation *
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQ1RK1 b - -
+Petrov: classical attack, Mason variation *
+rnbq1rk1/ppp2ppp/3bpn2/3p4/2PP4/P1N1P3/1P2NPPP/R1BQKB1R w KQ -
+Nimzo-Indian: Simagin variation
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3, Botvinnik system
+rnbq1rk1/ppp2ppp/5P2/2b4Q/2pp4/2P5/PP3PPP/RNB1K1NR w KQ -
+Bishop's opening: Pratt variation
+rnbq1rk1/ppp2ppp/5n2/2b1p3/4p3/2PP4/PP1NBPPP/R1BQK1NR w KQ -
+Philidor: Hanham, Steiner variation *
+rnbq1rk1/ppp2ppp/5n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R b KQ -
+two knights: Max Lange attack, Steinitz variation *
+rnbq1rk1/ppp2ppp/5n2/2bP4/2B1p3/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack *
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQ -
+Philidor: Hanham, Krause variation *
+rnbq1rk1/ppp2ppp/5n2/3Pp3/1b6/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, Nyholm attack *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/2N5/PPPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: open Berlin defense, 5...Be7 *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, Rosenthal variation *
+rnbq1rk1/ppp2ppp/5n2/3pN3/4P3/P1PP4/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation *
+rnbq1rk1/ppp2ppp/5n2/3pp1B1/4P3/P1PP1N2/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation *
+rnbq1rk1/ppp2ppp/5n2/3pp3/1b2P3/2NP4/PPPN1PPP/R1BQKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Chigorin variation *
+rnbq1rk1/ppp2ppp/5n2/4N3/1b2p3/2N5/PPPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Minckwitz variation *
+rnbq1rk1/ppp2ppp/5n2/8/1b2p3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, l'Hermet variation *
+rnbq1rk1/ppp2ppp/5n2/b2PN3/8/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Riga variation *
+rnbq1rk1/ppp2ppp/5n2/b2p4/4P3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, Showalter variation *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, 6.d4 b5 *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 6.d4 *
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, center attack *
+rnbq1rk1/ppp2ppp/5n2/b3N3/1P1pP3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Richter variation *
+rnbq1rk1/ppp2ppp/8/2b1p3/8/2P1NN2/PP1P1nPP/R1BQKB1R w KQ -
+Scotch: Cochrane variation *
+rnbq1rk1/ppp2ppp/8/3pb3/2PPn3/3B4/PP3PPP/RNBQ1RK1 w - -
+Petrov: modern attack, Trifunovi\'c variation
+rnbq1rk1/ppp2ppp/8/b2pN3/1P2n3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Friess attack *
+rnbq1rk1/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQ -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation
+rnbq1rk1/pppp1pp1/5n1p/4p1B1/4P2P/P1P5/1PP2PP1/R2QKBNR b KQ -
+Ruy Lopez: exchange variation, Alapin gambit *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPP1PPP/R2QKB1R b KQ -
+Ruy Lopez: Archangelsk (counterthrust) variation *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: ...b5 & ...d6 *
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+Nimzo-Indian: Reshevsky variation
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+Nimzo-Indian: 4.e3 O-O
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, open variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, 4.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, 4.O-O, d6 *
+rnbq1rk1/pppp1ppp/5n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Beverwijk variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR b KQ -
+Ruy Lopez: exchange, Gligori\'c variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: exchange variation, 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1PQ4/1PP2PPP/R1B1KBNR b KQ -
+Ruy Lopez: exchange, Bronstein variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Exchange variation doubly deferred (DERLD) *
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open (Tarrasch) defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/2B1P3/P1N2N2/1PPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: M\"oller defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: closed defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred (Russian defense) *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: modern Steinitz defense, 5.O-O *
+rnbq1rk1/pppp1ppp/8/3Pp3/1b6/8/PPPPNPPP/R1BQKB1R b KQ -
+Ruy Lopez: Bird's defense, Paulsen variation *
+rnbq1rk1/pppp2p1/8/2b2PPp/3pn3/3B1N2/PPP2P1P/RNBQK2R w KQ -
+KGA: Kieseritsky, Rice gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR w KQ -
+KGA: Hanstein gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/3P4/8/PPP2P1P/RNBQKBNR b KQ -
+KGA: Muzio gambit, Brentano defense *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQ -
+KGA: Muzio gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, Kling and Horwitz counter-attack *
+rnbq1rk1/ppppb1pp/4p3/5p2/2PPn3/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch defense, Alekhine variation
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+Dutch defense
+rnbq1rk1/ppppppbp/5np1/6B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQ -
+R\'eti: King's Indian attack, Yugoslav variation *
+rnbq2k1/pp1p1ppp/1bp5/8/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack, 11...c6 *
+rnbq2k1/pp3ppp/1bp5/3p4/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, main line, 12.d2d4 *
+rnbq2k1/pp3ppp/1bp5/4r3/1P1Pp3/P1N1P3/2PQB1PP/R4RK1 w - -
+Ruy Lopez: open, Tarrasch trap *
+rnbq2k1/pp3ppp/2p1r3/3p4/1P1P4/P2B4/5PPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, Kevitz variation *
+rnbq2k1/pppp1ppp/1b6/3N4/1PBpr1n1/P4N2/2P2PPP/R1BQ1K1R b - -
+Ruy Lopez: Rabinovich variation *
+rnbq3r/pp4pp/2P2nk1/8/2Bbp3/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Ghulam Kassim variation *
+rnbq3r/pppp1k2/3b1n1p/8/4PQ1P/8/PPPP2P1/RNB1KB1R w KQ -
+KGA: Allgaier, Horny defense
+rnbqk1n1/pppp1p1r/7b/4N2p/2BPPppP/2N5/PPP3P1/R1BQK2R b KQq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation
+rnbqk1nb/pp3p2/2pp4/4N1p1/2BPPp2/2N5/PPP3P1/R1BQK3 b Qkq -
+KGA: Greco gambit
+rnbqk1nr/1p1p1ppp/p3p3/2b5/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Polugaievsky variation
+rnbqk1nr/5ppp/2p1p3/pp6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Abrahams variation
+rnbqk1nr/p1p1bppp/1p2p3/3pP3/3P4/2N1B3/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Frankfurt variation
+rnbqk1nr/p1pp1ppp/8/1pb1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Wing gambit *
+rnbqk1nr/p1pp2pp/8/1Bb1pp2/4P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: MacDonnell double gambit *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P1Q1/8/PPPP1PPP/RNB1K1NR b KQkq -
+Bishop's opening: del Rio variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis counter-gambit *
+rnbqk1nr/pp1pp2p/6p1/2pP1p2/2P5/2P5/P3PPPP/R1BQKBNR w KQkq -
+Beefeater defense
+rnbqk1nr/pp1ppp1p/6pb/2p5/2P1P3/5N2/PP1P1PPP/RNBQKB1R w KQkq -
+Sicilian: Acton extension
+rnbqk1nr/pp1pppbp/8/2p3B1/3P4/8/PPP1PPPP/RN1QKBNR w KQkq -
+Grob: Fritz gambit *
+rnbqk1nr/pp1pppbp/8/2pP2B1/8/8/PPP1PPPP/RN1QKBNR b KQkq -
+Grob: Romford counter-gambit *
+rnbqk1nr/pp2bppp/2p5/3p4/3PpB2/2P1P3/PP3PPP/RN1QKBNR w KQkq -
+Caro-Kann: advance, Short variation *
+rnbqk1nr/pp2ppb1/2p3p1/3pP2p/3P1P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+Robatsch defense: Gurgenidze variation
+rnbqk1nr/pp2ppbp/2pp2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Robatsch defense: two knights, Suttles variation
+rnbqk1nr/pp2ppbp/6p1/1Bpp4/5P2/4PN2/PPPP2PP/RNBQK2R b KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: closed *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+King's Indian: 3.g3, counterthrust variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd *
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, Russian variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, advance, Bogolyubov variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/P1N5/1PP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, 5.a3
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/3pP3/1P6/2p2N2/1PP2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, Rauzer variation
+rnbqk1nr/ppp1bppp/3p4/4p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Philidor: Steinitz variation
+rnbqk1nr/ppp1bppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Charousek (Petrosian) variation
+rnbqk1nr/ppp1bppp/4p3/3pP1B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Vistaneckis (Nimzovich) variation
+rnbqk1nr/ppp1p1bp/3p2p1/5p2/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Randspringer variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Modern defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Modern defense: Averbakh system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Robatsch defense: two knights variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Robatsch defense: Geller's system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Robatsch defense: Pseudo-Austrian attack
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqk1nr/ppp2p1p/3b4/6p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird: From gambit, Lasker variation
+rnbqk1nr/ppp2pb1/3p3p/6p1/2BPPp1P/3Q1N2/PPP3P1/RNB1K2R b KQkq -
+KGA: Philidor gambit, Schultz variation
+rnbqk1nr/ppp2ppp/1b1p4/8/2P1p3/1N6/PP1PPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Kmoch variation *
+rnbqk1nr/ppp2ppp/3b4/3Pp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit: Maroczy gambit
+rnbqk1nr/ppp2ppp/3b4/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Schlechter variation *
+rnbqk1nr/ppp2ppp/3bp3/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn: stonewall attack *
+rnbqk1nr/ppp2ppp/3p4/2b1P3/4P3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: classical, Soldatenkov variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/1P2PP2/5N2/P1PP2PP/RNBQKB1R b KQkq -
+KGD: classical, Heath variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/2P2N2/PP1P2PP/RNBQKB1R b KQkq -
+KGD: classical, 4.c3
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation *
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP1NPPP/R1BQKB1R b KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer (Nimzovich) variation
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, fingerslip variation
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/ppp2ppp/4p3/8/3Pp3/P1b5/1PP1NPPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit
+rnbqk1nr/ppp2ppp/8/2bp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Balogh variation *
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis counter-gambit
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis gambit *
+rnbqk1nr/ppp2ppp/8/2bpp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Ponziani gambit *
+rnbqk1nr/ppp2ppp/8/4P3/1bP5/4p3/PP1B1PPP/RN1QKBNR w KQkq -
+QGD: Albin counter-gambit, Lasker trap
+rnbqk1nr/ppp3pp/3p4/2b1pp2/4PP2/2P2N2/PP1P2PP/RNBQKB1R w KQkq -
+KGD: classical counter-gambit
+rnbqk1nr/ppp3pp/4P3/2bp2N1/4p3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Berger variation
+rnbqk1nr/ppp3pp/8/2b2p2/2BpP3/2P2N2/PP4PP/RNBQK2R b KQkq -
+KGD: classical, R\'eti variation
+rnbqk1nr/pppp1pbp/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Paulsen defense
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp1P/5N2/PPPP2P1/RNBQK2R b KQkq -
+KGA: Philidor gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Hanstein gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+King's knight's gambit
+rnbqk1nr/pppp1ppp/4p3/8/1bPP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Franco-Indian (Keres) defense
+rnbqk1nr/pppp1ppp/8/2b1p3/1PB1P3/8/P1PP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Wing gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/2P5/PP1P1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Philidor variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Classical variation *
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Bishop's opening: Philidor counter-attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Bishop's opening: Berlin defense *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Bishop's opening *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bishop's opening: Calabrese counter-gambit *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: Hillbilly attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Krejcik variation *
+rnbqk1nr/pppp1ppp/8/4p3/1bB1PP2/8/P1PP2PP/RNBQK1NR b KQkq -
+Bishop's opening: MacDonnell double gambit
+rnbqk1nr/pppp1ppp/8/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English, Kramnik-Shirov counterattack
+rnbqk1nr/pppp1ppp/8/8/2B1P2b/5N2/PPPP3p/RNBQ1R1K b kq -
+KGA: Cunningham, three pawns gambit
+rnbqk1nr/pppp1ppp/8/8/2B1Pp1b/5NP1/PPPP3P/RNBQK2R b KQkq -
+KGA: Cunningham, Bertin gambit
+rnbqk1nr/pppp1ppp/8/8/2BPP2b/5N2/P1P4p/RNBQ1R1K b kq -
+Bishop's opening: Four pawns' gambit
+rnbqk1nr/pppp2pp/3b4/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Schurig gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/1P6/8/P1PP1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bledow variation *
+rnbqk1nr/pppp2pp/8/2b1pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+KGA: bishop's gambit, Maurian defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: bishop's gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Steinitz defense *
+rnbqk1nr/pppp2pp/8/2b1pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Greco gambit *
+rnbqk1nr/pppp2pp/8/4Pp2/1b1p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Nimzovich variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Anderssen variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Morphy variation *
+rnbqk1nr/ppppb1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit *
+rnbqk1nr/ppppbp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Polerio defense
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Cunningham defense
+rnbqk1nr/ppppp1bp/6p1/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, Karlsbad variation
+rnbqk1nr/ppppppbp/6p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Robatsch defense
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppppppbp/6p1/8/3PPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Robatsch defense: three pawns attack
+rnbqk1nr/ppppppbp/8/8/3P2p1/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Grob: spike attack *
+rnbqk1r1/ppp2pP1/4p3/3p4/1b1P2Qp/2N5/PPP2PP1/R3KBNR b KQq -
+French: MacCutcheon, Grigoriev variation
+rnbqk2r/1p2bp2/p2ppn1p/6p1/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Be7
+rnbqk2r/1pp2ppp/1b3n2/p2p4/4p3/1N1P2P1/PPP1PPBP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Keres variation *
+rnbqk2r/1ppnbppp/p3p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation
+rnbqk2r/2pp1ppp/5n2/ppb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, 5.a4 *
+rnbqk2r/p1p2ppp/1p1bpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation *
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: Fischer variation
+rnbqk2r/p1pp1ppp/5n2/1Bb1p3/4P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Evans counter-gambit *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n1Q1/1B6/PPPP1PPP/R1B1K1NR b KQkq -
+Evans gambit declined, Hirschbach variation *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n3/1B5N/PPPP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Lange variation *
+rnbqk2r/p2p1pp1/4pn1p/1ppP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit
+rnbqk2r/p2p1ppp/1p2pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation
+rnbqk2r/p2p1ppp/2p2n2/1pb1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Bird's attack *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Evans gambit: Mayet defense *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: 5...Be7 *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2NB4/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Stone-Ware variation *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/1Bb1p3/8/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/p4ppp/2p2n2/2b5/B3p3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit: Cochrane variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/2bpp3/BP2P3/2N5/P1PP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Leonhardt variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/N3P3/8/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: Cordel variation *
+rnbqk2r/pp1n1ppp/4p3/2bpP3/5PQ1/2N5/PPP3PP/R1B1KBNR b KQkq -
+French: Steinitz, Bradford attack
+rnbqk2r/pp1nbppp/4p3/2ppP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: close variation *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/4P3/3P4/PPP1BPPP/RNBQK1NR w KQkq -
+Philidor: Steinitz variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1b2P3/1BN5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical defense, Charousek variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Ruy Lopez: classical defense, 4.c3 *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Ruy Lopez: classical defense, Boden variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1PP2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Ruy Lopez: Cordel gambit *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4PP2/P1NP4/1PP3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation *
+rnbqk2r/pp1p1ppp/4p3/2pP4/1bP1n3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: three knights, Euwe variation
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system)
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3 c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp1p1ppp/4pn2/2pP4/1bP5/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights, Korchnoi variation
+rnbqk2r/pp1p1ppp/4pn2/4P3/1b1N4/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Pin, Koch variation
+rnbqk2r/pp1p1ppp/4pn2/8/1b1NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pin variation (Sicilian counter-attack)
+rnbqk2r/pp1p1ppp/5n2/2p1p3/2P5/3P4/PP1QPPPP/RN2KBNR w KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation *
+rnbqk2r/pp1p1ppp/5n2/4p3/1b1NP3/2NB4/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Pin, Jaffe variation
+rnbqk2r/pp1p1ppp/5n2/b1p1p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation *
+rnbqk2r/pp1pp1bp/2p3pn/5p2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Dutch: Leningrad, Basman system
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan accepted *
+rnbqk2r/pp1pppbp/5np1/2p5/1P6/P3PN2/2PP1PPP/RNBQKB1R b KQkq -
+English: Romanishin gambit *
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.cd, main line *
+rnbqk2r/pp2nppp/4p3/2ppP3/3P2Q1/P1P5/2P2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, poisoned pawn variation
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, positional main line
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance, 6...Ne7
+rnbqk2r/pp2nppp/4p3/2ppP3/P2P4/2P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, Smyslov variation
+rnbqk2r/pp2ppbp/3p1np1/2p5/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Pirc: Austrian attack, dragon formation
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical attack
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+Sicilian: dragon, Yugoslav attack
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Capablanca variation *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+Catalan: open, classical line *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+Catalan: closed, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+Dutch defense *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+Dutch: Leningrad, main variation *
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: 5.Bg2 Be7 *
+rnbqk2r/pp2ppbp/6p1/2p4n/2PP4/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: Rubinstein variation *
+rnbqk2r/pp2ppbp/6p1/2p5/2PP2n1/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: B\"urger variation *
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+Benoni: Taimanov variation
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+Benoni: classical, 8.Bg5
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+Benoni: classical without 9.O-O
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: Mikenas variation
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, main line
+rnbqk2r/pp3ppp/2p2n2/1BbP4/3p4/5N2/PPP1QPPP/RNB1K2R b KQkq -
+Bishop's opening: Urusov gambit, Panov variation *
+rnbqk2r/pp3ppp/2p2n2/2b1p3/4P3/1B1p4/PPPPQPPP/RNB1K1NR w KQkq -
+Giuoco Piano: Eisinger variation *
+rnbqk2r/pp3ppp/2p2n2/2bP4/2BPp3/2N2N2/PPP2PPP/R1BQK2R b KQkq d3
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bPN3/4p3/2N5/PPPPBPPP/R1BQK2R b KQkq -
+Hungarian defense: Tartakower variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/1BN5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: center-holding variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Delmar variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP4/1PPBNPPP/R2QKB1R b KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation *
+rnbqk2r/pp3ppp/2pb1n2/3p4/2PPp3/1QN1P3/PP3PPP/R1B1KBNR w KQkq -
+French: advance, Milner-Barry gambit *
+rnbqk2r/pp3ppp/2pb4/4n3/3pP3/3P1N2/PPP1B1PP/RNBQK2R b KQkq -
+Ponziani counter-gambit, Cordel variation *
+rnbqk2r/pp3ppp/2pbpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Colle system *
+rnbqk2r/pp3ppp/3p1n2/2p1p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Duras variation *
+rnbqk2r/pp3ppp/3p1n2/b1p1p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Morphy defense, Duras variation *
+rnbqk2r/pp3ppp/4p3/2Pn4/8/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch, Keres variation
+rnbqk2r/pp3ppp/4pn2/2b3B1/3p4/P3P3/1PP2PPP/RN1QKBNR w KQkq -
+QGA: Alekhine defense, Alatortsev variation *
+rnbqk2r/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA: classical variation *
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp3ppp/5n2/1B1pN3/1b1Pp3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Piano: Anderssen variation *
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQkq -
+Giuoco Piano: LaBourdonnais variation *
+rnbqk2r/pp3ppp/5n2/2ppp3/1b2P3/2NP4/PPPB1PPP/R2QKBNR w KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation *
+rnbqk2r/pp4pp/2p2n2/2bPp3/2B2P2/8/PPP3PP/RNBQK1NR w KQkq -
+KGD: classical, R\'eti variation *
+rnbqk2r/pp4pp/4p3/2Pn1p2/8/P1P2P2/4P1PP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation
+rnbqk2r/ppn1bppp/8/2p1p3/8/2NP2PN/PP2PPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Simagin variation *
+rnbqk2r/ppp1b1pp/3p1n2/3Pp3/4N3/2PB4/PP3PPP/RNBQK2R w KQkq -
+Ponziani counter-gambit, Cordel variation
+rnbqk2r/ppp1bppp/4p3/3p2B1/2PPn3/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Lasker variation
+rnbqk2r/ppp1bppp/4p3/3pP1B1/3Pn3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Tartakower variation
+rnbqk2r/ppp1bppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Anderssen-Richter variation
+rnbqk2r/ppp1bppp/4pB2/3p4/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Anderssen variation
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Be7
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+English: Neo-Catalan declined
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: classical variation (5.Bf4)
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: closed, 5.Nf3
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Catalan: open, classical line
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/2PP4/PP2PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern, Flohr variation *
+rnbqk2r/ppp1bppp/5n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Tayler opening *
+rnbqk2r/ppp1bppp/8/3pP3/4n3/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+Vienna gambit: Breyer variation
+rnbqk2r/ppp1npbp/6p1/3pp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Pachman system
+rnbqk2r/ppp1nppp/8/8/3PN3/8/PP3PPP/R2QKBNR w KQkq -
+Bishop's opening: Lisitsyn variation *
+rnbqk2r/ppp1ppbp/1n1p2p1/4P3/P2P4/1B3N2/1PP2PPP/RNBQK2R b KQkq -
+Alekhine's defense: modern, Keres variation
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd, main line
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+King's Indian: Smyslov system
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP3PPP/R2QKBNR b KQkq -
+King's Indian: accelerated Averbakh system
+rnbqk2r/ppp1ppbp/3p1np1/8/2BPPP2/2N5/PPP3PP/R1BQK1NR b KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+King's Indian: fianchetto variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+King's Indian: 5.Nf3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+King's Indian: S\"amisch variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+King's Indian with e4 & g3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+King's Indian: Makagonov system (5.h3)
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+King's Indian: 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2NPPP/R1BQKB1R b KQkq -
+King's Indian: Kramer system
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+King's Indian: Four pawns attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP1P1/2N5/PPP1BP1P/R1BQK1NR b KQkq -
+Pirc: Chinese variation
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP2P/2N5/PPP1BPP1/R1BQK1NR b KQkq -
+Pirc: bayonet (Mariotti) attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Pirc: classical, h3 system
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+Pirc: classical system, 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Pirc: classical (two knights) system
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bg5
+rnbqk2r/ppp1ppbp/5np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+Queen's Indian: Marienbad system *
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bf4
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Russian variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: 5.e3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Gr\"unfeld: Three knights variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.Nf3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+King's Indian: 3.g3, counterthrust variation
+rnbqk2r/ppp1ppbp/5np1/3p4/Q1PP4/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Flohr variation
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Neo-Gr\"unfeld, 5.cd
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+Gr\"unfeld: exchange, classical variation
+rnbqk2r/ppp1ppbp/6p1/8/3PP3/2P2N2/P4PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: modern exchange variation
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense, Blackburne variation *
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/6P1/PPPPP1BP/RNBQK1NR w KQkq -
+Dutch: Leningrad, Karlsbad variation *
+rnbqk2r/ppp2p1p/3b1n2/3PN3/2B2ppP/8/PPPP2P1/RNBQ1RK1 b kq -
+KGA: Kieseritsky, Rice gambit
+rnbqk2r/ppp2p2/4p1pp/3pP3/3Pn1Q1/2P5/P1PB1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Lasker variation, 8...g6
+rnbqk2r/ppp2pbp/6p1/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation
+rnbqk2r/ppp2pp1/4pP1p/3p2B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Chigorin variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P3B/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Bernstein variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Janowski variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/3P4/2b5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Lasker variation
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/3B4/PPP2PPP/RNBQK2R b KQkq -
+Petrov: classical attack, Marshall variation *
+rnbqk2r/ppp2ppp/3b3n/8/3P4/5N2/PPP1P1PP/RNBQKB1R b KQkq -
+Bird: From gambit, Lipke variation
+rnbqk2r/ppp2ppp/3b4/3np3/2B5/P3P3/1P1P1PPP/RNBQK1NR b KQkq -
+Sicilian: Kan, Polugaievsky variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P1P1/1P1P1P1P/RNBQKBNR b KQkq -
+Sicilian: Kan, Swiss cheese variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Bd3 *
+rnbqk2r/ppp2ppp/3b4/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+Petrov: classical attack, Marshall variation
+rnbqk2r/ppp2ppp/3bpn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense (Modern bishop's opening) *
+rnbqk2r/ppp2ppp/3p1n2/4p3/1b2P3/5N2/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation *
+rnbqk2r/ppp2ppp/3p1n2/4p3/4P3/2bP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation *
+rnbqk2r/ppp2ppp/3p1n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Anderssen variation *
+rnbqk2r/ppp2ppp/3p4/2b1pP2/2B1P1n1/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Giuoco Pianissimo: Dubois variation *
+rnbqk2r/ppp2ppp/3p4/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Kieseritsky variation *
+rnbqk2r/ppp2ppp/3p4/4p3/1b2n3/2P2N2/PP1PNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap *
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, main line
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: MacCutcheon variation
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1bPP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Vienna variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Ragozin variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3
+rnbqk2r/ppp2ppp/4pn2/3pP1B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, advance variation
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD: Ragozin, Vienna variation
+rnbqk2r/ppp2ppp/5n2/1BbPp3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/1PP5/8/P2P1PPP/RNBQKBNR b KQkq -
+Center game, Kieseritsky variation *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch gambit: Dubois-R\'eti defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Scotch gambit: Benima defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening/Petrov: Urusov gambit *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Klein variation *
+rnbqk2r/ppp2ppp/5n2/3P4/1b3P2/2NPp3/PPPB2PP/R2QKBNR w KQkq -
+KGD: Falkbeer, Morphy gambit
+rnbqk2r/ppp2ppp/5n2/3Pp3/1b6/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: Relfsson gambit (`MacLopez') *
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP1P2/2P3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation *
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation *
+rnbqk2r/ppp2ppp/8/1Bbp4/3NP1n1/2N5/PPP2PPP/R1BQK2R b KQkq -
+two knights defense: Pincus variation *
+rnbqk2r/ppp2ppp/8/2bPp3/2B3n1/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/8/2bPp3/5P2/3P3N/PPP3Pn/RNBQKB1R w KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation *
+rnbqk2r/ppp2ppp/8/2bPp3/6n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense, Perreux variation *
+rnbqk2r/ppp2ppp/8/2bp4/3NP1n1/2N5/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Lolli attack *
+rnbqk2r/ppp2ppp/8/2bpp3/4P1n1/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Kmoch variation *
+rnbqk2r/ppp3p1/8/2bppPPp/4nP2/8/PPPPQ2P/RNB1KBNR w KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation *
+rnbqk2r/ppp3p1/8/3ppPPp/3b4/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Urusov attack *
+rnbqk2r/ppp3pp/5n2/2bppPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Ghulam Kassim gambit *
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Prins variation, Venice attack *
+rnbqk2r/pppn1pp1/4p2p/3pP3/1b1P4/2N5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Tartakower variation
+rnbqk2r/pppnb1pp/4pp2/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation
+rnbqk2r/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR b KQkq -
+French: Albin-Alekhine-Ch\^atard attack
+rnbqk2r/pppp1ppp/1b3n2/4p3/1PB1P3/P1N5/2PP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Graz variation *
+rnbqk2r/pppp1ppp/1b3n2/4p3/NP2P3/P7/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation *
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Nimzo-Indian: Leningrad variation
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Nimzo-English opening
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Spielmann variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: 4.e3
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2P2/PP2P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: Kmoch variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Nimzo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2NQ4/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Mikenas attack
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+Bogo-Indian defense, Gr\"unfeld variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Bogo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pppp1ppp/5n2/1B2p3/1b2P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Giuoco Piano *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+King's pawn game *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Hungarian defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Italian variation *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Rousseau gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: L\'opez counter-gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Latvian gambit, 3.Bc4 *
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense *
+rnbqk2r/pppp1ppp/5n2/4P3/1bB2p2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Paulsen attack
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: Brentano defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1Q1/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Vienna: Zhuravlev countergambit
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2P2/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Nuremberg variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez (Spanish opening) *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ruy Lopez: Lucena defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPQPPP/R1B1KBNR b KQkq -
+Ruy Lopez: Vinogradov variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: old Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical (Cordel) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, Smyslov system
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7 *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack *
+rnbqk2r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1bPP/R1BQK1NR w KQkq -
+Giuoco Piano: Jerome gambit *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1PP4/2P2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred) *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/Nb2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Pollock defense *
+rnbqk2r/pppp1ppp/5n2/b2Np3/4P3/P7/1PPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/1P2P3/P1N5/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Caro variation *
+rnbqk2r/pppp1ppp/5n2/b3p3/2B1P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Classical defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Morphy defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N3P1/1PPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4PP2/P1N5/1PPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense deferred *
+rnbqk2r/pppp1ppp/5n2/bB2p3/4P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense deferred *
+rnbqk2r/pppp1ppp/8/2b1P3/3Pn3/8/PPP3PP/RNBQKBNR b KQkq -
+Latvian: Polerio variation *
+rnbqk2r/pppp1ppp/8/2b1P3/4n3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+Latvian: corkscrew counter-gambit *
+rnbqk2r/pppp1ppp/8/2b1p3/2B1P1n1/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+two knights defense: Wilkes Barre (Traxler) variation *
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/8/2b5/1P1pP1n1/2N2N2/P1P2PPP/R1BQKB1R b KQkq -
+two knights defense: Ulvestad variation *
+rnbqk2r/pppp1ppp/8/2b5/3NP3/2N5/PPP2nPP/R1BQKB1R w KQkq -
+two knights defense: Fegatello attack *
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense *
+rnbqk2r/pppp1ppp/8/2bN4/3pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense: Fritz variation *
+rnbqk2r/pppp1ppp/8/8/Nb1pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp2p1/5n2/2b1pP1p/6P1/8/PPPP1PBP/RNBQK1NR w KQkq -
+KGA: Philidor gambit *
+rnbqk2r/pppp2p1/8/2b1pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4 *
+rnbqk2r/pppp2p1/8/2b1pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Walker attack *
+rnbqk2r/pppp2pp/4pn2/5p2/1bPP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Blachly gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/8/5N2/PPPPBPPP/RNBQK2R b KQkq -
+KGA: Cunningham, Euwe defense *
+rnbqk2r/pppp2pp/5n2/2b2P2/3N4/2P5/P4PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, Botvinnik variation *
+rnbqk2r/pppp2pp/5n2/4pPP1/8/8/PPPP1b1P/RNBQKBNR w KQkq -
+KGA: Lolli gambit (wild Muzio gambit) *
+rnbqk2r/pppp2pp/8/2b1pPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Salvio gambit *
+rnbqk2r/pppp3p/5np1/2b1pP1B/8/8/PPPP1PPP/RNBQK1NR w KQkq -
+KGA: Cunningham, Bertin gambit *
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP1BPPBP/RN1QK1NR w KQkq -
+Dutch-Indian, Alekhine variation
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqk2r/ppppbppp/3n4/4p2Q/8/1BN5/PPPP1PPP/R1B1K1NR w KQkq -
+Vienna game
+rnbqk2r/ppppbppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Inverted Hungarian *
+rnbqk2r/ppppbppp/5n2/8/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Cunningham, Euwe defense
+rnbqk2r/ppppbppp/7n/8/N3P3/2P2N1P/P4PP1/R1BQKB1R w KQkq -
+two knights defense: Steinitz variation *
+rnbqk2r/ppppbppp/8/4P3/N3n3/2P2N1P/P1Q2PP1/R1B1KB1R b KQkq -
+two knights defense: G\"oring variation *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, main variation
+rnbqk2r/ppppp2p/6pb/5P2/3P4/8/PPP2PPP/RN1QKBNR b KQkq -
+Amar gambit *
+rnbqk2r/ppppppbp/5np1/6B1/3P4/8/PPPNPPPP/R2QKBNR b KQkq -
+R\'eti: King's Indian attack, Keres variation *
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack *
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+King's Indian: 4.e4
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 6.Bg5
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Lipnitzky attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, Byrne (English) attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N4P/PPP2PP1/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Adams attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Opo\v censky variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Najdorf
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Najdorf, 6.f4
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Petrosian system *
+rnbqkb1r/1p3p1p/p2ppnp1/8/2PNP3/3B4/PP3PPP/RNBQ1RK1 w kq -
+Sicilian: Kan, Gipslis variation
+rnbqkb1r/1p3ppp/p1p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation)
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 6...e6
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 7.f4
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N1B3/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Scheveningen, English variation
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, 7.Qe2
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, 6...a6
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BPP3/5N2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical, Geller variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/P1BP4/4PN2/1P3PPP/RNBQ1RK1 b kq -
+QGA: classical, Rubinstein variation
+rnbqkb1r/1p3ppp/p4n2/1N1pp1B1/Q1P5/2N5/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Krause variation
+rnbqkb1r/1pp1pppp/p4n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGA, Bogolyubov variation
+rnbqkb1r/1ppp1ppp/p3pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Dzindzikhashvili defense
+rnbqkb1r/2pp1ppp/p3pn2/1p6/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Romanishin gambit
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+Benk\"o gambit accepted
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Benk\"o gambit: Zaitsev system
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit half accepted
+rnbqkb1r/4pppp/3p1n2/1NpP4/1pB1P3/8/PP3PPP/R1BQK1NR b KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky variation
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin with ...a6 and ...b5
+rnbqkb1r/5ppp/p3pn2/1pp5/2BP4/4PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 7...b5
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Queens Indian formation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Queen's Indian: Miles variation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Queen's Indian: 4.Nc3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Queen's Indian: 4.e3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Queen's Indian: 4.g3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+Queen's Indian: Petrosian system
+rnbqkb1r/p1pp1ppp/5n2/1p2p3/2P5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit deferred *
+rnbqkb1r/p1pp1ppp/5n2/1p4N1/2P1p3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+English: Bellon gambit
+rnbqkb1r/p1pp1ppp/5n2/1p6/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: Wing gambit *
+rnbqkb1r/p1pp2pp/5n2/1p2pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Heath variation *
+rnbqkb1r/p1ppp1pp/1p3n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Nimzovich variation
+rnbqkb1r/p1pppp1p/5np1/1p1P4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian: Danube gambit
+rnbqkb1r/p1pppp1p/5np1/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation *
+rnbqkb1r/p1pppppp/1p3n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's Indian accelerated
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: Nimzovich-Larsen attack *
+rnbqkb1r/p1pppppp/5n2/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Santasiere's folly *
+rnbqkb1r/p1pppppp/5n2/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, Spassky's variation
+rnbqkb1r/p1pppppp/8/1p1nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense: O'Sullivan gambit
+rnbqkb1r/p2n1ppp/1p2p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, Botvinnik variation
+rnbqkb1r/p2p1pp1/5n1p/1ppP2B1/8/5N2/PP2PPPP/RN1QKB1R w KQkq -
+Blumenfeld counter-gambit, Spielmann variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP2B1/2P5/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP4/2P5/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit
+rnbqkb1r/p2ppp1p/1p3np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Torre defensive system *
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: London defensive system *
+rnbqkb1r/p2ppppp/1p3n2/2p3B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation *
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system *
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit
+rnbqkb1r/p3pppp/2p2n2/1p2P3/2pP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Tolush-Geller gambit
+rnbqkb1r/p3pppp/5n2/1ppP4/2p1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGA: Linares variation
+rnbqkb1r/p4p2/2p1p2p/1p1nP1N1/2pP3B/2N5/PP3PPP/R2QKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system
+rnbqkb1r/p4p2/2p1pP1p/1p2N3/2pP3p/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Ekstrom variation
+rnbqkb1r/p4p2/2p1pn1p/1p2P1N1/2pP3B/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran gambit
+rnbqkb1r/p4ppp/2p5/3n4/2B2p2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Abbazia defense, Botvinnik variation
+rnbqkb1r/p5pp/4pn2/1Ppp4/8/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit accepted
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+French: Steinitz variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system, Keres variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ponziani: Jaenisch counter-attack *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ponziani opening *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ponziani: Romanishin variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ponziani: R\'eti variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ponziani counter-gambit *
+rnbqkb1r/pp1p1ppp/2p2n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR w KQkq -
+KGA: bishop's gambit, Jaenisch variation
+rnbqkb1r/pp1p1ppp/2p5/3Nn3/1P1NP3/8/P1P2PPP/R1BQKB1R w KQkq -
+two knights defense: Fritz, Gruber variation *
+rnbqkb1r/pp1p1ppp/4pn2/2P5/8/4B3/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti accepted: Keres variation *
+rnbqkb1r/pp1p1ppp/4pn2/2p3B1/3PP3/5N2/PPP2PPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack, Wagner gambit
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Sicilian variation
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1p1ppp/4pn2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Anderssen variation
+rnbqkb1r/pp1p1ppp/5n2/2p1N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Kaufmann attack *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/2P5/6PB/PP1PPP1P/RNBQK1NR b KQkq -
+Sicilian: Acton extension *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Dresden opening *
+rnbqkb1r/pp1p1ppp/5n2/2pPp3/2P5/8/PP2PPPP/RNBQKBNR w KQkq e6
+Czech Benoni defense
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, 4.c3 *
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1PP2/3P4/PPP3PP/RNBQK1NR b KQkq -
+KGD: classical counter-gambit *
+rnbqkb1r/pp1pp1pp/2p2n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Chigorin variation
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+English: Kurajica defense *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan *
+rnbqkb1r/pp1ppppp/1n6/2p1P3/8/1B1P4/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Kmoch variation
+rnbqkb1r/pp1ppppp/2p2n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Masi defense
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti accepted *
+rnbqkb1r/pp1ppppp/5n2/2p1P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+English, Nimzovich, Flohr variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Benoni formation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein variation
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English, Nimzovich variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti: advance variation *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/3P4/2p5/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Hawk (Habichd) defense
+rnbqkb1r/pp1ppppp/8/2pP4/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Vulture defense
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Bled variation
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Bronstein-Larsen variation
+rnbqkb1r/pp2pp1p/2pp1np1/8/3PP3/2N1B3/PPPQ1PPP/R3KBNR b KQkq -
+Pirc: 150 attack
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: dragon, 6.Be3
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: dragon variation
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish variation
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, 5.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: 4.g3 Bb7 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto) *
+rnbqkb1r/pp2pp1p/5np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6
+rnbqkb1r/pp2pp1p/6p1/2p3B1/2PPp3/8/PP1QPPPP/R3KBNR w KQkq -
+Gr\"unfeld: Lundin variation
+rnbqkb1r/pp2pppp/2p2n2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian gambit
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD Slav: 4.Nc3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: 4.e3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD Slav: Breyer variation
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: 5.e3 (Alekhine variation)
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav accepted
+rnbqkb1r/pp2pppp/2p2n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Slav gambit
+rnbqkb1r/pp2pppp/2p2n2/8/3PN3/3B4/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Alekhine gambit
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav accepted: Alapin variation
+rnbqkb1r/pp2pppp/2pp1n2/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc: Ufimtsev-Pytel variation
+rnbqkb1r/pp2pppp/3p1n2/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Cortlever (Alatortsev) variation
+rnbqkb1r/pp2pppp/3p1n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense, Hromodka system
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/5P2/PPP3PP/RNBQKB1R b KQkq -
+Sicilian: Prins (Moscow) variation
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Bogo-Indian defense *
+rnbqkb1r/pp2pppp/5n2/2Pp4/1P6/8/P1P1PPPP/RNBQKBNR b KQkq -
+QGA: Ericson variation *
+rnbqkb1r/pp2pppp/5n2/2Pp4/3P4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's gambit accepted *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR b KQkq -
+QGA: Alekhine defense *
+rnbqkb1r/pp2pppp/5n2/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Adler variation *
+rnbqkb1r/pp2pppp/5n2/2p5/1PPp4/4PN2/P2P1PPP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pP4/4p3/8/PPP2PPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical, Benoni formation *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Bird's opening: Lasker variation
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian, 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/P3PN2/1PPP1PPP/RNBQKB1R b KQkq -
+Dzindzikhashvili defense *
+rnbqkb1r/pp2pppp/5n2/2ppN3/8/4P3/PPPP1PPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: exchange variation *
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: exchange variation
+rnbqkb1r/pp2pppp/5n2/8/1pPP4/4PN2/P5PP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit accepted *
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, three knights system
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: symmetrical variation *
+rnbqkb1r/pp3p1p/2p1pnp1/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Spielmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Benoni: Uhlmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Benoni: classical with e4 and Nf3
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: pawn storm variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Benoni defense
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benoni: fianchetto variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benoni: Nimzovich (knight's tour) variation
+rnbqkb1r/pp3p1p/3p1np1/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Czech Benoni: King's Indian system
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5.e3
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD semi-Slav
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD semi-Slav: 5.Bg5 dc
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran)
+rnbqkb1r/pp3ppp/2p1pn2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Soultanb\'eieff variation
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/4P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Andreaschek gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: G\"oring gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Tartakower variation *
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: exchange, positional line, 5...c6
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+QGD: exchange, positional line, 6.Qc2
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/1Q2P3/PP1B1PPP/RN2KBNR b KQkq -
+French: advance, Wade variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP1B1PPP/R2QKBNR b KQkq -
+French: advance, Euwe variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+French: advance, Paulsen attack *
+rnbqkb1r/pp3ppp/2p2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Geller's system *
+rnbqkb1r/pp3ppp/2p2n2/4N3/2BpP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Ponziani: Fraser defense *
+rnbqkb1r/pp3ppp/2p2n2/4p3/3pPP2/2NP4/PPP3PP/R1BQKBNR w KQkq -
+Ponziani counter-gambit, Schmidt attack *
+rnbqkb1r/pp3ppp/2p2p2/8/2BP4/8/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Forg\'acs variation
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Venice attack
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+Sicilian: Prins variation, Venice attack
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benoni: 6.e4
+rnbqkb1r/pp3ppp/3ppn2/1B6/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, Keres attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, fianchetto variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, 6.Be2
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Scheveningen variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, 6.f4
+rnbqkb1r/pp3ppp/4p3/2pn4/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch with e3
+rnbqkb1r/pp3ppp/4pn2/2Pp2B1/8/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Janowsky-Larsen variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/1P6/P7/2P1PPPP/RNBQKBNR b KQkq -
+QGA: Haberditz variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4BN2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Flohr variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGA: 4...e6 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+QGA, Smyslov variation *
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical variation, 6.O-O
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQK2R w KQkq -
+QGA: classical variation
+rnbqkb1r/pp3ppp/4pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Semi-Tarrasch
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch, 5.cd
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Been-Koomen variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/2P5/1P2PN2/PB1P1PPP/RN1QKB1R b KQkq -
+English: Wimpey system
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch defense
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: 4.e3 Bf5 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P1BPN2/P1P2PPP/RNBQK2R b KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P2PN2/P1PN1PPP/R1BQKB1R b KQkq -
+Queen's pawn game, Zukertort variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2PBPN2/PP3PPP/RNBQK2R b KQkq -
+Colle system
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/3p2B1/2PQ4/2N2N2/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6
+rnbqkb1r/pp3ppp/4pn2/8/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, Steinitz variation
+rnbqkb1r/pp3ppp/5n2/2Ppp3/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation *
+rnbqkb1r/pp3ppp/5n2/2p3B1/3pp3/1N1P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Vitolins attack *
+rnbqkb1r/pp3ppp/5n2/2pp2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Alekhine variation *
+rnbqkb1r/pp3ppp/5n2/2ppp1B1/8/3P2P1/PPP1PPBP/RN1QK1NR b KQkq -
+Robatsch defense: Rossolimo variation *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7 *
+rnbqkb1r/pp3ppp/8/2pnp3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation) *
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: stonewall defense
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD: Stonewall variation
+rnbqkb1r/pp4pp/5n2/3p2B1/2p5/1NN1P3/PPP1P1PP/R2QKB1R w KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation *
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Rubinstein system
+rnbqkb1r/ppp1p1pp/5n2/3p4/8/3B3N/PPP2PPP/RNBQK2R w KQkq -
+Bird: From gambit, Lipke variation *
+rnbqkb1r/ppp1pp1p/1n1p2p1/4P3/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation
+rnbqkb1r/ppp1pp1p/1n1p4/4P1p1/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Planinc variation
+rnbqkb1r/ppp1pp1p/1n4p1/8/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Czech defense
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Pirc: Byrne variation
+rnbqkb1r/ppp1pp1p/3p1np1/8/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Pirc: Holmov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Pirc: classical (two knights) system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N3P1/PPP2P1P/R1BQKBNR b KQkq -
+Pirc: Sveshnikov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP1BPPP/R1BQK1NR b KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Pirc: Austrian attack
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, fianchetto variation
+rnbqkb1r/ppp1pp1p/5np1/3P4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Richter variation
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: Stockholm variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: 4.Bf4
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP2P1/2N5/PP2PP1P/R1BQKBNR b KQkq -
+Gr\"unfeld: Spike gambit
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Gr\"unfeld: Russian variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Gr\"unfeld: Three knights variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld (Kemeri) defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: fianchetto without c4 *
+rnbqkb1r/ppp1pp1p/5np1/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Smyslov variation
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld: exchange variation
+rnbqkb1r/ppp1pp1p/6p1/8/8/2n3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense: exchange variation
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+Alekhine's defense: four pawns attack
+rnbqkb1r/ppp1pppp/1n1p4/4P3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Schmid variation
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Old Indian defense
+rnbqkb1r/ppp1pppp/3p1n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: old Indian attack *
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/2BP4/8/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Balogh variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/5n2/2P5/3p4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Hawk (Habichd) defense *
+rnbqkb1r/ppp1pppp/5n2/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Torre attack (Tartakower variation)
+rnbqkb1r/ppp1pppp/5n2/3p2B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+Old Indian: Tartakower (Wade) variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game, Krause variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Marshall defense
+rnbqkb1r/ppp1pppp/5n2/3p4/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's bishop game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P2P1/5P2/PPP1P2P/RNBQKBNR b KQkq -
+Gedult attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn game, Chigorin variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/3BP3/PPP2PPP/RNBQK1NR b KQkq -
+Queen's pawn: stonewall attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Alekhine's defense: Scandinavian variation
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian: East Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3pN3/8/8/PPPPPPPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/ppp1pppp/5n2/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+Old Benoni defense *
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGA, 4.Nc3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA, 4.e3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's gambit accepted
+rnbqkb1r/ppp1pppp/5n2/8/Q1pP4/5N2/PP2PPPP/RNB1KB1R b KQkq -
+QGA: Mannheim variation
+rnbqkb1r/ppp1pppp/8/3n4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Marshall variation
+rnbqkb1r/ppp1pppp/8/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/8/3np3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Larsen variation
+rnbqkb1r/ppp1pppp/8/8/1nPP4/8/PP3PPP/RNBQKBNR w KQkq -
+Scandinavian: Kiel variation
+rnbqkb1r/ppp2Npp/3p1n2/8/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Cochrane gambit
+rnbqkb1r/ppp2p1p/5n2/3p4/4PpNP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation
+rnbqkb1r/ppp2p1p/5n2/3pN3/3PPBpP/8/PPP3P1/RN1QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense
+rnbqkb1r/ppp2p1p/8/3pN3/3PnBpP/8/PPPN2P1/R2QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation
+rnbqkb1r/ppp2pp1/4pn1p/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Capablanca-Duras variation
+rnbqkb1r/ppp2pp1/5n1p/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Panov variation *
+rnbqkb1r/ppp2ppp/1n6/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: Romanishin variation *
+rnbqkb1r/ppp2ppp/1n6/4p3/2B5/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch: Potter variation *
+rnbqkb1r/ppp2ppp/3p1n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: French attack *
+rnbqkb1r/ppp2ppp/3p1n2/4P3/4P3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich variation
+rnbqkb1r/ppp2ppp/3p1n2/4p1N1/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich, Locock variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Nimzovich, Klein variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Old Indian: Ukrainian variation, 4.Nf3
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Ukrainian variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich (Jaenisch) variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+R\'eti: Lisitsin gambit deferred *
+rnbqkb1r/ppp2ppp/3p1n2/8/2N1P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Paulsen attack
+rnbqkb1r/ppp2ppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkb1r/ppp2ppp/3p1n2/8/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack, close variation
+rnbqkb1r/ppp2ppp/3p4/3QP3/4n3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Philidor: Nimzovich, Rellstab variation
+rnbqkb1r/ppp2ppp/3p4/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR w KQkq -
+Budapest: Alekhine variation, Balogh gambit
+rnbqkb1r/ppp2ppp/3p4/4P3/4n3/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Nimzovich, Sokolsky variation
+rnbqkb1r/ppp2ppp/3p4/8/2P1n3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Petrov: Kaufmann attack
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: Nimzovich attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: French attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/5N2/PPPPQPPP/RNB1KB1R b KQkq -
+Petrov: Cozio (Lasker) attack
+rnbqkb1r/ppp2ppp/3pp3/2PnP3/2B5/2N5/PP1P1PPP/R1BQK1NR w KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation
+rnbqkb1r/ppp2ppp/4n3/3pP3/8/3P1Q2/PPP3PP/RNB1KBNR w KQkq -
+Latvian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/4pn2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian: Icelandic gambit
+rnbqkb1r/ppp2ppp/4pn2/3P4/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: exchange variation
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: 4.Bg5
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Neo-Catalan
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Harrwitz attack
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: 4.Nf3
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: 3...Nf6
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Catalan: closed
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/3BPN2/PPP2PPP/RNBQK2R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: Henneberger variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French defense
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2NB4/PPP2PPP/R1BQK1NR b KQkq -
+French: Swiss variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, closed variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Yusupov-Rubinstein system *
+rnbqkb1r/ppp2ppp/4pn2/3pP3/2P5/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls, Flohr variation
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Steinitz variation
+rnbqkb1r/ppp2ppp/4pn2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: Burn variation
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Neo-Catalan accepted
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: 4...e6
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: open, 5.Nf3
+rnbqkb1r/ppp2ppp/4pn2/8/3P4/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Blackmar-Diemer: Euwe defense
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4
+rnbqkb1r/ppp2ppp/5n2/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Morphy variation
+rnbqkb1r/ppp2ppp/5n2/3Np3/4P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Scotch: Lolli variation *
+rnbqkb1r/ppp2ppp/5n2/3P4/4PP2/8/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 5.de
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/2N5/PPPPQ1PP/R1B1KBNR b KQkq -
+KGD: Falkbeer, Rubinstein variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, R\'eti variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPPN2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Keres variation
+rnbqkb1r/ppp2ppp/5n2/3P4/5p2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense, modern variation
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern variation, 4...Bg4 *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: exchange, positional line
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: exchange, Svenonius variation
+rnbqkb1r/ppp2ppp/5n2/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich system *
+rnbqkb1r/ppp2ppp/5n2/3p4/3NP3/8/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Larsen variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: modern, fianchetto variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/4p3/1N1P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Schmid variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack, close variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: modern attack, Symmetrical variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, reverse dragon
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Sicilian: Cortlever (Alatortsev) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Marshall variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Blackmar-Diemer: Lemberg counter-gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch opening *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich (Jaenisch) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor's defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPPN1PPP/R1BQKBNR b KQkq -
+Philidor: Hanham variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern (Steinitz) attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit, Steinitz variation
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: Philidor counter-gambit *
+rnbqkb1r/ppp2ppp/5n2/4p2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Fraser attack *
+rnbqkb1r/ppp2ppp/5n2/4p3/4p3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3P4/4nP2/8/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, Charousek gambit
+rnbqkb1r/ppp2ppp/8/3n4/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: Paulsen attack *
+rnbqkb1r/ppp2ppp/8/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR b KQkq -
+Scotch: Pulling counter-attack *
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Sicilian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3np3/4P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch: Schmidt variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPQPPPPP/R1B1KBNR b KQkq -
+Sicilian: Flohr variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P2P1/PPP2P1P/RNBQKBNR b KQkq -
+Philidor: Larsen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Sicilian: Anderssen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Kan variation *
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2N2Q2/PPPP2PP/R1B1KBNR b KQkq -
+Vienna gambit: Paulsen attack
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/8/3pp3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense
+rnbqkb1r/ppp2ppp/8/3pp3/4N3/8/PPPP1PPP/R1BQKBNR w KQkq -
+Irish (Chicago) gambit *
+rnbqkb1r/ppp2ppp/8/3pp3/4P1n1/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Locock variation *
+rnbqkb1r/ppp2ppp/8/4P3/3P2n1/4p3/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, del Rio attack *
+rnbqkb1r/ppp2ppp/8/4p2Q/1n6/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Horwitz attack *
+rnbqkb1r/ppp2ppp/8/4p3/1n2P3/2NP4/PP3PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation *
+rnbqkb1r/ppp2ppp/8/4p3/1n6/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation *
+rnbqkb1r/ppp2ppp/8/4p3/8/2n3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, exchange variation *
+rnbqkb1r/ppp2ppp/8/8/4p3/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Mieses variation *
+rnbqkb1r/ppp3p1/8/3ppPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Thorold variation *
+rnbqkb1r/ppp3pN/3p3n/5p2/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation
+rnbqkb1r/ppp3pp/5n2/3ppP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Rosentreter gambit *
+rnbqkb1r/ppp3pp/5p2/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian: Prins (Moscow) variation *
+rnbqkb1r/ppp3pp/8/3pPp2/3Pn3/2N2Q2/PPP3PP/R1B1KBNR b KQkq -
+Vienna gambit: Heyde variation
+rnbqkb1r/ppp3pp/8/3pPp2/4n3/2N2Q2/PPPP2PP/R1B1KBNR w KQkq f6
+Vienna gambit: Bardeleben variation
+rnbqkb1r/ppp3pp/8/3ppPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: S\o rensen gambit *
+rnbqkb1r/pppn1ppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Steinitz, Gledhill attack
+rnbqkb1r/pppnpppp/4P3/3p4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: Spielmann variation
+rnbqkb1r/pppp1p1p/5n2/4N3/2B1PppP/8/PPPP2P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4
+rnbqkb1r/pppp1p1p/5n2/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense
+rnbqkb1r/pppp1p1p/5n2/6N1/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Allgaier, Schlechter defense
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system with ...g6
+rnbqkb1r/pppp1p1p/5np1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Konstantinopolsky opening *
+rnbqkb1r/pppp1ppp/2n5/8/2P1PP2/8/PP4PP/RNBQKBNR w KQkq -
+Budapest: Alekhine, Abonyi variation
+rnbqkb1r/pppp1ppp/4p3/8/2PPn3/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkb1r/pppp1ppp/4pn2/6B1/2PP4/8/PP2PPPP/RN1QKBNR b KQkq -
+Neo-Indian (Seirawan) attack
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls variation
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Catalan opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn: Yusupov-Rubinstein system
+rnbqkb1r/pppp1ppp/5n2/4p1B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti: Wade defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Petrov: Italian variation
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Berlin defense
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1PP2/8/PPPP2PP/RNBQK1NR b KQkq -
+Bishop's opening: Greco gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Ponziani gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/1P6/P2PPPPP/RNBQKBNR b KQkq -
+Sicilian: Katalimov variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: Carls' Bremen system
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+Sicilian: Hungarian variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PPQPPPPP/RNB1KBNR b KQkq -
+Sicilian: Quinteros variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+Sicilian: O'Kelly variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense declined
+rnbqkb1r/pppp1ppp/5n2/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Tennison (Lemberg, Zukertort) gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: modern (Steinitz) attack
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QP counter-gambit (elephant gambit) *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov three knights game
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen-Mieses variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+King's pawn game *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Falkbeer variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov's defense
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+Damiano's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+Greco defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight opening *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+Gunderam defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/P1N5/1PPP1PPP/R1BQKBNR b KQkq -
+Vienna: Mengarini variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Latvian counter-gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: 2...Nf6
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/2N5/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Colorado counter *
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+R\'eti: Pirc-Lisitsin gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/Q1P5/8/PP1PPPPP/RNB1KBNR b KQkq -
+Sicilian: Stiletto (Althouse) variation *
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Bogolyubov variation
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense
+rnbqkb1r/pppp1ppp/5n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Bishop's opening/Petrov: Urusov gambit
+rnbqkb1r/pppp1ppp/5n2/8/3pP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+QP counter-gambit: Maroczy gambit *
+rnbqkb1r/pppp1ppp/5n2/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Schallop defense
+rnbqkb1r/pppp1ppp/8/2n1p3/8/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Paulsen attack *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Damiano variation *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Damiano variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR b KQkq -
+Budapest: Alekhine variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest: Fajarowicz variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Budapest: Fajarowicz, Steiner variation
+rnbqkb1r/pppp1ppp/8/4P3/2P2Bn1/8/PP2PPPP/RN1QKBNR b KQkq -
+Budapest: Rubinstein variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Budapest: Adler variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense
+rnbqkb1r/pppp1ppp/8/4P3/3Qn3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Petrov: modern attack, main line
+rnbqkb1r/pppp1ppp/8/4P3/3pn3/5N2/PPP1QPPP/RNB1KB1R b KQkq -
+Petrov: modern attack, Steinitz variation
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Boden-Kieseritsky gambit
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Symmetrical variation
+rnbqkb1r/pppp1ppp/8/4p3/4nP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Latvian: Fraser defense *
+rnbqkb1r/pppp1ppp/8/4p3/8/3P1N2/PPP2nPP/RNBQKB1R w KQkq -
+Petrov: Cochrane gambit *
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2p1/8/4pPPp/3Pn3/8/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n2P/8/PPPP1P2/RNBQKBNR b KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Kieseritsky, Neumann defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/3P4/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Kolisch defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPP1PBP/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Paulsen defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPBP1P/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Polerio defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPQP1P/RNB1KBNR b KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Allgaier, Schlechter defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Allgaier gambit *
+rnbqkb1r/pppp2p1/8/4pPnp/3P4/5N2/PPP2P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Bird's opening: Lasker variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Dutch defense
+rnbqkb1r/pppp2pp/4pn2/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch defense, Blackburne variation
+rnbqkb1r/pppp2pp/5n2/4N3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: corkscrew counter-gambit
+rnbqkb1r/pppp2pp/5n2/4p3/2B1p3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Soldatenkov variation *
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!]) *
+rnbqkb1r/pppp2pp/5n2/4pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: Gianutio counter-gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Fischer defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: Schallop defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/7P/PPPP1PP1/RNBQKBNR b KQkq -
+KGA: Becker defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+KGA: Cunningham defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: Bonsch-Osmolovsky variation *
+rnbqkb1r/pppp2pp/5n2/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Tartakower variation *
+rnbqkb1r/pppp2pp/5n2/5P2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, modern variation *
+rnbqkb1r/ppppnppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Keres variation (2.Ne2) *
+rnbqkb1r/ppppnppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alapin's opening *
+rnbqkb1r/ppppnppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Steinitz defense
+rnbqkb1r/ppppnppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Bonsch-Osmolovsky variation
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch with c4 & Nc3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Dutch with c4 & g3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp1pp/5n2/5p2/3P2P1/2N5/PPP1PP1P/R1BQKBNR b KQkq -
+Dutch, Spielmann gambit
+rnbqkb1r/ppppp1pp/5n2/5p2/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+R\'eti: Lisitsin gambit deferred
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Staunton's line
+rnbqkb1r/ppppp1pp/5n2/8/3Pp1P1/2N5/PPP2P1P/R1BQKBNR b KQkq -
+Dutch: Staunton gambit, Tartakower variation
+rnbqkb1r/ppppp1pp/5n2/8/4pPP1/2N5/PPPP3P/R1BQKBNR b KQkq -
+Bird's opening, Swiss gambit
+rnbqkb1r/ppppp1pp/5n2/8/6P1/3B4/PPP2P1P/RNBQK1NR b KQkq -
+Bird: From gambit, Lasker variation *
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Dutch: Leningrad variation
+rnbqkb1r/ppppp2p/5np1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp2P/2N5/PPP2PP1/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Alekhine variation
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp3/2N2P2/PPP3PP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Lasker variation
+rnbqkb1r/ppppp2p/5ppn/8/2PPP3/8/PP3PPP/RNBQKBNR w KQkq -
+Hippopotamus defense
+rnbqkb1r/ppppp2p/6pn/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Dutch defense: Bladel variation
+rnbqkb1r/pppppp1p/5np1/3P4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+King's Indian: Anti-Gr\"unfeld
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: Torre attack
+rnbqkb1r/pppppp1p/5np1/8/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, Spassky's variation *
+rnbqkb1r/pppppp1p/5np1/8/1P6/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+King's Indian defense, 3.Nc3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+King's Indian, 3.Nf3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+King's Indian: 3.g3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack (with ...c5) *
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian defense
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Queen's pawn: Mengarini attack
+rnbqkb1r/pppppp1p/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: London system
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+King's Indian: East Indian defense
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+King's Indian: fianchetto without c4
+rnbqkb1r/pppppp1p/5np1/8/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack (Barcza system) *
+rnbqkb1r/pppppp1p/5np1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Benko's opening: reversed Alekhine *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkb1r/ppppppnp/6p1/4P3/3P2P1/8/PPP2P1P/RNBQKBNR w KQkq -
+Norwegian defense
+rnbqkb1r/pppppppp/1n6/2P1P3/8/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack
+rnbqkb1r/pppppppp/1n6/4P3/2P5/1P6/P2P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Steiner variation
+rnbqkb1r/pppppppp/5n2/6B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening)
+rnbqkb1r/pppppppp/5n2/8/1PP5/8/P2PPPPP/RNBQKBNR b KQkq -
+English orang-utan
+rnbqkb1r/pppppppp/5n2/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Krejcik variation
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English, 1...Nf6 (Anglo-Indian defense)
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: London system
+rnbqkb1r/pppppppp/5n2/8/3P1P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+Canard opening
+rnbqkb1r/pppppppp/5n2/8/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Queen's pawn: Bronstein gambit
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P4/5P2/PPP1P1PP/RNBQKBNR b KQkq -
+Paleface attack
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Mar\'oczy variation
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/5n2/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+R\'eti v Dutch *
+rnbqkb1r/pppppppp/5n2/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+R\'eti: Herrstr\"om gambit *
+rnbqkb1r/pppppppp/5n2/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Indian variation
+rnbqkb1r/pppppppp/5n2/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/7n/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: T\"ubingen variation
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Amar (Paris) opening *
+rnbqkb1r/pppppppp/8/3nP3/2P5/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/8/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Welling variation
+rnbqkb1r/pppppppp/8/3nP3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: S\"amisch attack
+rnbqkb1r/pppppppp/8/3nP3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/4P3/4n3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation
+rnbqkb1r/pppppppp/8/8/3Pn3/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkbnr/1p1p1p1p/p3p1p1/8/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Swiss cheese variation
+rnbqkbnr/1p1p1ppp/p3p3/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation)
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Kan, 5.Nc3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+Sicilian: Kan, 5.Bd3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Kan variation
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: O'Kelly variation
+rnbqkbnr/1pp1pppp/p7/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Alekhine defense
+rnbqkbnr/1pp1pppp/p7/8/2pPP3/5N2/PP3PPP/RNBQKB1R b KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation
+rnbqkbnr/1pp2ppp/p3p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Janowski variation
+rnbqkbnr/1ppp1ppp/p3p3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+St. George defense
+rnbqkbnr/1ppp1ppp/p7/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Mengarini's opening *
+rnbqkbnr/1pppppp1/8/p6p/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Crab opening *
+rnbqkbnr/1pppppp1/p6p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Global opening *
+rnbqkbnr/1ppppppp/8/p7/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Corn stalk defense
+rnbqkbnr/1ppppppp/8/p7/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Ware (Meadow Hay) opening *
+rnbqkbnr/1ppppppp/p7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+St. George (Baker) defense
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anderssen's opening *
+rnbqkbnr/2p1pppp/p7/1p6/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: Haberditz variation
+rnbqkbnr/2pp1ppp/P7/4p3/8/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Carlsbad variation *
+rnbqkbnr/2pp1ppp/p7/1P2p3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Marshall variation *
+rnbqkbnr/p1p1pppp/8/1p6/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Ericson variation
+rnbqkbnr/p1p2ppp/1p2p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Alapin variation
+rnbqkbnr/p1pp1ppp/1p2p3/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Keres defense
+rnbqkbnr/p1pp1ppp/1p6/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: R\'eti (Spielmann) variation *
+rnbqkbnr/p1pp1ppp/1p6/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Welling variation *
+rnbqkbnr/p1pp1ppp/8/1p2p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit *
+rnbqkbnr/p1pp1ppp/8/1p6/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnbqkbnr/p1pp2pp/1p6/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Orsini gambit *
+rnbqkbnr/p1pppppp/1p6/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Polish variation *
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: English variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: classical variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: English defense
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: modern variation *
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Owen defense
+rnbqkbnr/p1pppppp/1p6/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Dutch variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: symmetrical variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: symmetrical variation
+rnbqkbnr/p1pppppp/1p6/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Nimzovich-Larsen attack: Indian variation *
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack *
+rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Jaenisch gambit
+rnbqkbnr/p1pppppp/8/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Polish defense
+rnbqkbnr/p1pppppp/8/1p6/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Polish variation
+rnbqkbnr/p1pppppp/8/1p6/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Polish: Outflank variation *
+rnbqkbnr/p1pppppp/8/1p6/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Polish: T\"ubingen variation *
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Polish (Sokolsky) opening *
+rnbqkbnr/p2p1ppp/1p6/2p5/4p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Steiner variation *
+rnbqkbnr/p2p1ppp/8/1Pp1p3/8/8/PP1PPPPP/RNBQKBNR w KQkq c6
+Sicilian: wing gambit, Santasiere variation *
+rnbqkbnr/p2p1ppp/8/1pp5/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Center game, Kieseritsky variation
+rnbqkbnr/p2ppppp/1p6/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Katalimov variation
+rnbqkbnr/p2ppppp/8/1pp5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English orang-utan *
+rnbqkbnr/p3pppp/2p5/1p1p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze counter-attack
+rnbqkbnr/p4ppp/2p5/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Wheeler gambit *
+rnbqkbnr/p4ppp/8/1pP5/N2p4/8/PP2PPPP/R1BQKBNR w KQkq b6
+QGD: Tarrasch defense, Tarrasch gambit
+rnbqkbnr/pp1p1ppp/2p5/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor counter-attack
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Alapin's variation (2.c3) *
+rnbqkbnr/pp1p1ppp/2p5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Lopez opening *
+rnbqkbnr/pp1p1ppp/2p5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/4p3/2pP4/4P3/8/PPP2PPP/RNBQKBNR b KQkq -
+Old Benoni: Franco-Benoni defense
+rnbqkbnr/pp1p1ppp/4p3/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+English: Adorjan defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Mafia defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense, Steiner variation *
+rnbqkbnr/pp1p1ppp/8/2p5/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+Scandinavian gambit *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Scandinavian: Icelandic gambit *
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+Old Benoni defense
+rnbqkbnr/pp1p1ppp/8/4p3/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Andreaschek gambit
+rnbqkbnr/pp1p1ppp/8/8/2p1p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack *
+rnbqkbnr/pp1pp1pp/8/2p2p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Mujannah opening *
+rnbqkbnr/pp1pp1pp/8/2pP1p2/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni: Mujannah formation
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Hungarian variation
+rnbqkbnr/pp1ppppp/2p5/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: Outflank variation
+rnbqkbnr/pp1ppppp/2p5/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Caro-Kann: Hillbilly attack
+rnbqkbnr/pp1ppppp/2p5/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: closed (Breyer) variation
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Saragossa opening *
+rnbqkbnr/pp1ppppp/8/2p5/1P2P3/8/P1PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit
+rnbqkbnr/pp1ppppp/8/2p5/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+English: Jaenisch gambit *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English: symmetrical variation *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Sicilian: closed
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Alapin's variation (2.c3)
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+Sicilian: Steinitz variation
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Sicilian: Keres variation (2.Ne2)
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Sicilian: Grand Prix attack
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+English: Anglo-Dutch defense *
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: English variation
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+English: Caro-Kann defensive system *
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+English, 1...Nf6 (Anglo-Indian defense) *
+rnbqkbnr/pp1ppppp/8/2p5/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/8/1p2P3/P7/2PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Marshall variation
+rnbqkbnr/pp1ppppp/8/8/1pP1P3/8/P2P1PPP/RNBQKBNR b KQkq c3
+Sicilian: wing gambit, Santasiere variation
+rnbqkbnr/pp1ppppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/8/4P3/p7/2PP1PPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Carlsbad variation
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkbnr/pp2pp1p/2p3p1/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze system
+rnbqkbnr/pp2pp1p/3p2p1/2pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Old Benoni: Schmid's system
+rnbqkbnr/pp2pp1p/6p1/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld (Kemeri) defense *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & g3 *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch: Leningrad variation *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Catalan opening *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: 3.g3 *
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense: exchange variation
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: exchange variation
+rnbqkbnr/pp2pppp/2p5/3p2P1/8/8/PPPPPPBP/RNBQK1NR b KQkq -
+Grob: spike attack
+rnbqkbnr/pp2pppp/2p5/3p4/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: 3.Nf3
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Caro-Kann: Tartakower (fantasy) variation
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+Caro-Kann: 3.Nd2
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Caro-Kann: two knights variation
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2Q2/PPPP1PPP/R1B1KBNR b KQkq -
+Caro-Kann: Goldman (Spielmann) variation
+rnbqkbnr/pp2pppp/2p5/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: advance variation
+rnbqkbnr/pp2pppp/2p5/8/2pPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD Slav defense, Alekhine variation
+rnbqkbnr/pp2pppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/8/3Pp3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: Rasa-Studier gambit
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack
+rnbqkbnr/pp2pppp/3p4/2p5/1P2P3/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+Sicilian: wing gambit deferred
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Sicilian, Chekhover variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Tartakower variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/8/1Bpp4/8/4P3/PPPP1PPP/RNBQK1NR b KQkq -
+Queen's pawn: Franco-Indian (Keres) defense *
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's gambit accepted *
+rnbqkbnr/pp2pppp/8/2p1N3/2Pp4/8/PP1PPPPP/RNBQKB1R b KQkq -
+Vulture defense *
+rnbqkbnr/pp2pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Fajarowicz variation *
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense *
+rnbqkbnr/pp2pppp/8/2p5/1P1p4/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+King's Indian: Danube gambit *
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Benoni defense, Hromodka system *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/2PpP3/5N2/PP1P1PPP/RNBQKB1R b KQkq e3
+Czech Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/3p4/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Anti-Gr\"unfeld *
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD: symmetrical (Austrian) defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: symmetrical (Austrian) defense
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+QGD: Grau (Sahovic) defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR w KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+QGD: Chigorin defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QGD: Marshall defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Krause variation
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QGD: Albin counter-gambit *
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense declined *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P2P3/P1PP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Keres defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian accelerated *
+rnbqkbnr/pp2pppp/8/2pp4/8/2N2N2/PPPPPPPP/R1BQKB1R b KQkq -
+Kevitz-Trajkovich defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack (with ...c5)
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/pp2pppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkbnr/pp2pppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense: exchange variation *
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit half accepted *
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit accepted *
+rnbqkbnr/pp3ppp/2p1p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Kurajica defense
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: semi-Slav
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: semi-Slav, Marshall gambit
+rnbqkbnr/pp3ppp/2p1p3/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: semi-Slav, Noteboom variation
+rnbqkbnr/pp3ppp/2p5/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Anderssen variation
+rnbqkbnr/pp3ppp/2p5/3Pp3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: S\o rensen defense *
+rnbqkbnr/pp3ppp/2p5/3Pp3/5P2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Nimzovich counter-gambit
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Danish gambit *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3pp3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD Slav: Winawer counter-gambit
+rnbqkbnr/pp3ppp/2pp4/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English, Keres variation
+rnbqkbnr/pp3ppp/3p4/2pPp3/4P3/8/PPP2PPP/RNBQKBNR w KQkq -
+Semi-Benoni (`blockade variation')
+rnbqkbnr/pp3ppp/4p3/2PpP3/8/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance, Steinitz variation
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open variation
+rnbqkbnr/pp3ppp/4p3/2pp4/4P3/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Sicilian: closed, Korchnoi variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/1P6/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+French: Wing gambit
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P2Q1/8/PPP2PPP/RNB1KBNR b KQkq -
+French: advance, Nimzovich variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+French: advance, Nimzovich system
+rnbqkbnr/pp3ppp/4p3/3P4/3p4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit
+rnbqkbnr/pp3ppp/4p3/8/2Bp4/5N2/PPPN1PPP/R1BQK2R w KQkq -
+French: Tarrasch, Eliskases variation
+rnbqkbnr/pp3ppp/8/1Npp4/8/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Kiel variation *
+rnbqkbnr/pp3ppp/8/2Ppp3/5P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+QGA: Schwartz defense *
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.e4 *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/3P4/PPP2PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine variation, Balogh gambit *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Alekhine variation *
+rnbqkbnr/pp3ppp/8/2pp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense, 4.cd ed
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open, 4.ed ed
+rnbqkbnr/pp3ppp/8/2pp4/3PP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch defense, Marshall gambit
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: exchange variation *
+rnbqkbnr/pp3ppp/8/2ppp3/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit deferred *
+rnbqkbnr/pp3ppp/8/2ppp3/8/5PPN/PPPPP2P/RNBQKB1R b KQkq -
+Hippopotamus defense *
+rnbqkbnr/pp3ppp/8/3p4/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack *
+rnbqkbnr/pp4pp/8/2p1pp2/8/2N5/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine, Abonyi variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p1P1/1N1P4/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Planinc variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: four pawns attack *
+rnbqkbnr/pp4pp/8/2pp1p2/4pB2/1N1P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation *
+rnbqkbnr/pp4pp/8/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R b KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6 *
+rnbqkbnr/ppp1p1pp/3p4/5p2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+(Dutch:) Balogh defense
+rnbqkbnr/ppp1p1pp/5p2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Paleface attack *
+rnbqkbnr/ppp1p1pp/8/3p1p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Canard opening *
+rnbqkbnr/ppp1p1pp/8/5p2/2pPP3/8/PP3PPP/RNBQKBNR w KQkq -
+QGA: Schwartz defense
+rnbqkbnr/ppp1p2p/5p2/3p2p1/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Gedult attack *
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/ppp1pp1p/6p1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/ppp1pp1p/8/3p2p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Krejcik gambit *
+rnbqkbnr/ppp1pp1p/8/3p2p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: Bronstein gambit *
+rnbqkbnr/ppp1ppp1/7p/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Korchnoi attack *
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Old Indian defense
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's Pawn
+rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/3p4/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/8/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Levitsky attack (Queen's bishop attack)
+rnbqkbnr/ppp1pppp/8/3p4/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+Santasiere's folly
+rnbqkbnr/ppp1pppp/8/3p4/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish defense *
+rnbqkbnr/ppp1pppp/8/3p4/2P2P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Mujannah opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp1pppp/8/3p4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn, Mason variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn: Chigorin variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Blackmar gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Tennison (Lemberg, Zukertort) gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Charlick (Englund) gambit *
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian (center counter) defense
+rnbqkbnr/ppp1pppp/8/3p4/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bird's opening: Williams gambit
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch *
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird's opening
+rnbqkbnr/ppp1pppp/8/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: Nimzovich-Larsen attack
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Queen's pawn: English defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: classical variation
+rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+R\'eti: old Indian attack
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's Pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack (Barcza system)
+rnbqkbnr/ppp1pppp/8/3p4/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Modern defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/8/2Pp1P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Old Benoni: Mujannah formation *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti: advance variation
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti accepted
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGA: 3.Nf3
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit accepted
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QGA: 3.e4
+rnbqkbnr/ppp2p1p/3p2p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Larsen variation
+rnbqkbnr/ppp2p1p/3p4/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Kolisch defense
+rnbqkbnr/ppp2p1p/8/3p2p1/4p3/6P1/PPPPPPNP/RNBQKB1R b KQkq -
+Norwegian defense *
+rnbqkbnr/ppp2p1p/8/3p4/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Brentano defense
+rnbqkbnr/ppp2p1p/8/3pN3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English opening
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Indian opening *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: closed (Breyer) variation *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: King's Indian attack *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Mar\'oczy variation *
+rnbqkbnr/ppp2ppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Fischer defense
+rnbqkbnr/ppp2ppp/3pp3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Lengfellner system
+rnbqkbnr/ppp2ppp/4p3/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: exchange variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: 3.Nc3
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Paulsen variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+French: Schlechter variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/4B3/PPP2PPP/RN1QKBNR b KQkq -
+French: Alapin variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+French: Tarrasch
+rnbqkbnr/ppp2ppp/4p3/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+French: Two knights variation
+rnbqkbnr/ppp2ppp/4p3/3p4/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+French: Pelikan variation
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/ppp2ppp/4p3/8/3Pp3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+rnbqkbnr/ppp2ppp/8/1B1P4/4pP2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGD: Falkbeer, Nimzovich variation
+rnbqkbnr/ppp2ppp/8/3P4/3N4/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Paulsen attack
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 4.d3
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 3...e4
+rnbqkbnr/ppp2ppp/8/3Pp3/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+Center game *
+rnbqkbnr/ppp2ppp/8/3p4/1P1Np3/8/P1PPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: O'Sullivan gambit *
+rnbqkbnr/ppp2ppp/8/3p4/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Schlechter defense
+rnbqkbnr/ppp2ppp/8/3p4/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bledow variation
+rnbqkbnr/ppp2ppp/8/3p4/3N4/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Marshall variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Scandinavian defense *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Scandinavian: Richter variation *
+rnbqkbnr/ppp2ppp/8/3p4/3pP3/2P5/PP3PPP/RNBQKBNR w KQkq -
+Danish gambit: S\o rensen defense
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!])
+rnbqkbnr/ppp2ppp/8/3pP3/8/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Blackmar gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit (elephant gambit)
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Milner-Barry variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: Falkbeer, Tartakower variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/3P4/PPP1P1PP/RNBQKBNR b KQkq -
+(Dutch:) Balogh defense *
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N2P2/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Neo-Mongoloid defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P2N2/PP1PPPPP/RNBQKB1R b KQkq -
+Caro-Masi defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Pirc defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3PP3/PPP2PPP/RNBQKBNR b KQkq -
+Lengfellner system *
+rnbqkbnr/ppp2ppp/8/3pp3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Fried fox defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/BP6/P1PPPPPP/RN1QKBNR b KQkq -
+Guatemala defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/P3P3/1PPP1PPP/RNBQKBNR b KQkq -
+St. George defense *
+rnbqkbnr/ppp2ppp/8/4P3/2Pp4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/4p3/2Pp4/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+Old Benoni: Franco-Benoni defense *
+rnbqkbnr/ppp2ppp/8/4p3/2PpP3/3P4/PP3PPP/RNBQKBNR b KQkq -
+Semi-Benoni (`blockade variation') *
+rnbqkbnr/ppp2ppp/8/8/2pPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Steinitz variation *
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 4.d3 *
+rnbqkbnr/ppp3pp/3p4/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Philidor: L\'opez counter-gambit
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Philidor counter-gambit
+rnbqkbnr/ppp3pp/4P3/3p2N1/4p3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Philidor counter-gambit, del Rio attack
+rnbqkbnr/ppp3pp/4p3/3p1p2/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Haberditz variation
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Tartakower (fantasy) variation *
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+rnbqkbnr/ppp3pp/8/3Ppp2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Halasz gambit *
+rnbqkbnr/ppp3pp/8/3pN3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: Polerio variation
+rnbqkbnr/ppp3pp/8/3ppP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Villemson (Steinitz) gambit *
+rnbqkbnr/ppp3pp/8/3ppp2/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense: three pawns attack *
+rnbqkbnr/ppp3pp/8/4pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, 5.de *
+rnbqkbnr/pppp1B1p/8/8/4Ppp1/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: Lolli gambit (wild Muzio gambit)
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+English: Adorjan defense
+rnbqkbnr/pppp1p1p/6p1/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Steinitz variation *
+rnbqkbnr/pppp1p1p/8/4N3/2B1Ppp1/8/PPPP2PP/RNBQK2R b KQkq -
+KGA: Salvio gambit
+rnbqkbnr/pppp1p1p/8/4N3/3PPpp1/8/PPP3PP/RNBQKB1R b KQkq -
+KGA: S\o rensen gambit
+rnbqkbnr/pppp1p1p/8/6N1/4PppP/8/PPPP2P1/RNBQKB1R b KQkq -
+KGA: Allgaier gambit
+rnbqkbnr/pppp1p1p/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/3PPp2/5N2/PPP3PP/RNBQKB1R b KQkq -
+KGA: Rosentreter gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+KGA: Quaade gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGA: MacDonnell gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Muzio gambit
+rnbqkbnr/pppp1p1p/8/8/2BPPpp1/5N2/PPP3PP/RNBQK2R b KQkq -
+KGA: Ghulam Kassim gambit
+rnbqkbnr/pppp1p2/8/4N2p/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense
+rnbqkbnr/pppp1pp1/7p/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Becker defense
+rnbqkbnr/pppp1ppp/4p3/4P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+French: Steinitz attack
+rnbqkbnr/pppp1ppp/4p3/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+French defense, Steiner variation
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/4p3/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn
+rnbqkbnr/pppp1ppp/4p3/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+French: R\'eti (Spielmann) variation
+rnbqkbnr/pppp1ppp/4p3/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+French: King's Indian attack
+rnbqkbnr/pppp1ppp/4p3/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+French: Chigorin variation
+rnbqkbnr/pppp1ppp/4p3/8/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+French: Labourdonnais variation
+rnbqkbnr/pppp1ppp/4p3/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Van't Kruijs opening *
+rnbqkbnr/pppp1ppp/8/4N3/4p3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation *
+rnbqkbnr/pppp1ppp/8/4p2Q/4P3/8/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Patzer opening
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English, Nimzovich variation
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Scandinavian (center counter) defense *
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Charlick (Englund) gambit
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KP: Lopez opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KP: Indian opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+King's knight opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+KP: King's head opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Napoleon's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn game *
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's pawn game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Alapin's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/P7/1PPP1PPP/RNBQKBNR b KQkq -
+KP: Mengarini's opening
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+King's gambit
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Fred *
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: From gambit
+rnbqkbnr/pppp1ppp/8/4p3/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob) *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Owen defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: modern variation
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+Dunst (Sleipner,Heinrichsen) opening
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Mieses opening
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPPNPPPP/R1BQKBNR b KQkq -
+Valencia opening
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+Benko's opening: reversed Alekhine
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Barnes defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Hammerschlag (Fried fox/Pork chop opening)
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Carr's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+King's pawn opening *
+rnbqkbnr/pppp1ppp/8/4p3/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Lemming defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/P1N5/1PPPPPPP/R1BQKBNR b KQkq -
+Battambang opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P6P/1PPPPPP1/RNBQKBNR b KQkq -
+Global opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+St. George (Baker) defense *
+rnbqkbnr/pppp1ppp/8/4p3/P6P/8/1PPPPPP1/RNBQKBNR b KQkq -
+Crab opening
+rnbqkbnr/pppp1ppp/8/4p3/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Corn stalk defense *
+rnbqkbnr/pppp1ppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGA: bishop's gambit
+rnbqkbnr/pppp1ppp/8/8/2P1p3/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English, Nimzovich, Flohr variation
+rnbqkbnr/pppp1ppp/8/8/3Np3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/8/3PPp2/8/PPP3PP/RNBQKBNR b KQkq -
+KGA: Villemson (Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/3QP3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian defense *
+rnbqkbnr/pppp1ppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Danish gambit
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3pPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Halasz gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp1P/8/PPPP2P1/RNBQKBNR b KQkq -
+KGA: Pawn's gambit (Stamma gambit)
+rnbqkbnr/pppp1ppp/8/8/4Pp2/1P6/P1PP2PP/RNBQKBNR b KQkq -
+KGA: Orsini gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGA: Keres (Mason-Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/3B4/PPPP2PP/RNBQK1NR b KQkq -
+KGA: Schurig gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5Q2/PPPP2PP/RNB1KBNR b KQkq -
+KGA: Breyer gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP1KPP/RNBQ1BNR b kq -
+KGA: Tumbleweed gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+King's gambit accepted
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPB1PP/RNBQK1NR b KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPQ1PP/RNB1KBNR b KQkq -
+KGA: Carrera (Basman) gambit
+rnbqkbnr/pppp1ppp/8/8/4p3/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Steinitz attack *
+rnbqkbnr/pppp1ppp/8/8/4p3/8/PPPPPPPP/RNBQKBNR b KQkq -
+Alekhine's defense: Brooklyn defense *
+rnbqkbnr/pppp2p1/8/4pP1p/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Pawn's gambit (Stamma gambit) *
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch defense, Rubinstein variation
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkbnr/pppp2pp/4p3/5p2/2PPP3/8/PP3PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit deferred
+rnbqkbnr/pppp2pp/4p3/5p2/3P2P1/3Q4/PPP1PP1P/RNB1KBNR b KQkq -
+Dutch, Von Pretzel gambit
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Damiano's defense
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: King's head opening *
+rnbqkbnr/pppp2pp/8/4Pp2/3p4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 3...e4 *
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's gambit accepted *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Latvian gambit, 3.Bc4
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+KGD: classical variation *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Calabrese counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+KGD: Mafia defense *
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+rnbqkbnr/pppp2pp/8/4pp2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Bird's opening: Williams gambit *
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGD: 2...Nf6 *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KGD: Norwalde variation *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's gambit *
+rnbqkbnr/pppp2pp/8/4pp2/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Labourdonnais variation *
+rnbqkbnr/pppp2pp/8/5p2/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit
+rnbqkbnr/pppp2pp/8/5p2/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGD: Nimzovich counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Gianutio counter-gambit
+rnbqkbnr/pppp3p/6p1/4pp2/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+KGD: Keene's defense *
+rnbqkbnr/ppppp1pp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Barnes defense
+rnbqkbnr/ppppp1pp/5p2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Gedult's opening *
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Anglo-Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch, Krejcik gambit
+rnbqkbnr/ppppp1pp/8/5p2/3P4/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P4/7P/PPP1PPP1/RNBQKBNR b KQkq -
+Dutch, Korchnoi attack
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Dutch
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+R\'eti: Pirc-Lisitsin gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Bird: From gambit *
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Fred
+rnbqkbnr/ppppp1pp/8/5p2/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Bird: Hobbs gambit *
+rnbqkbnr/ppppp1pp/8/5p2/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Dutch variation
+rnbqkbnr/ppppp1pp/8/5p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti v Dutch
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5pB1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Dutch, 2.Bg5 variation
+rnbqkbnr/ppppp1pp/8/8/3Pp3/8/PPP2PPP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/pppppp1p/6p1/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppppp1p/6p1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Modern defense
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqkbnr/pppppp1p/6p1/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Lasker simul special *
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Benko's opening *
+rnbqkbnr/pppppp1p/8/6p1/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob)
+rnbqkbnr/pppppp1p/8/6p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: Hobbs gambit
+rnbqkbnr/pppppp1p/8/6p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti: Herrstr\"om gambit
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Grob's attack *
+rnbqkbnr/ppppppp1/7p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Carr's defense
+rnbqkbnr/ppppppp1/7p/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening *
+rnbqkbnr/ppppppp1/8/7p/8/6P1/PPPPPP1P/RNBQKBNR w KQkq -
+Lasker simul special
+rnbqkbnr/ppppppp1/8/7p/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anti-Borg (Desprez) opening *
+rnbqkbnr/pppppppp/8/4P3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Brooklyn defense
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish (Sokolsky) opening
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English opening
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn opening
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Bird's opening
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Grob's attack
+rnbqkbnr/pppppppp/8/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Anti-Borg (Desprez) opening
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Dunst (Sleipner, Heinrichsen) opening
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Saragossa opening
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Mieses opening
+rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Van't Kruijs opening
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/pppppppp/8/8/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Gedult's opening
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Benko's opening
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Amar (Paris) opening
+rnbqkbnr/pppppppp/8/8/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening
+rnbqkbnr/pppppppp/8/8/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Durkin's attack
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+Anderssen's opening
+rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Ware (Meadow Hay) opening
+rnbqkr2/pppp1pQp/8/2b1P3/3P4/5N2/PPP3PP/RNB1KB1n b KQq -
+Latvian: Behting variation *
+rnbqkr2/ppppbp1p/5N2/4Q3/8/8/PPPP1nPP/R1B1KBNR b KQq -
+Blackburne shilling gambit *
+rnbqr1k1/1p1p1ppp/pbp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Suetin variation *
+rnbqr1k1/1p3pp1/2p2n1p/p1bpp3/4P3/PBNP1N2/1PP1QPPP/R1B1K2R w KQ -
+Giuoco Piano: Tarrasch variation *
+rnbqr1k1/1pb2ppp/2p2n2/p2pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B1K2R w KQ -
+Ruy Lopez: closed, Balla variation *
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, anti-Marshall 8.a4 *
+rnbqr1k1/p1pp1ppp/5n2/1p2p3/1bP1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQ -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+Ruy Lopez: closed, Smyslov defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation) *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.h3 *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP4/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NPBN2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Kholmov variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+Ruy Lopez: closed, Breyer defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/PP2P3/2NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (9...a5) variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4P3/1P1p4/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall, Herman Steiner variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 8.c3 *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (with ...d6) *
+rnbqr1k1/pp3p1p/1bp3pQ/3p4/1P1N4/P1PB4/5PPP/R1B2RK1 b - -
+Ruy Lopez: Marshall, main line, 14...Qh3 *
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+Benoni: classical, 9...Re8
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...Re8, 10.Nd2
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+Benoni: four pawns attack, main line
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+Ruy Lopez: closed, Breyer, 10.d4 *
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Breyer, Borisenko variation *
+rnbqr1k1/pp3pp1/1bp4p/3pp2n/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Breyer, Simagin variation *
+rnbqr1k1/pp3ppB/3b1n2/3pN1B1/3p1P2/8/PPP3PP/RN1Q1RK1 b - -
+Petrov: classical attack, Marshall trap *
+rnbqr1k1/pp3ppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Bogolyubov variation *
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.d4 *
+rnbqr1k1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, 9...Be7, 10.Re1 *
+rnbqr1k1/pp3ppp/1bp5/3nN3/1P1PN3/P3B3/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: open, Breslau variation *
+rnbqr1k1/pp3ppp/1bpp1n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Pilnik variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Krause variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1BB/3P1P2/2N5/PPP3PP/R2QK2R b KQ -
+Petrov: classical attack, Mar\'oczy variation *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Borisenko defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NP2P3/P1PP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Rossolimo defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P4/3NBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (...Nd7) defense *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed (9...Na5) *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NPP1P3/P2P1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (10...c5) *
+rnbqr1k1/ppbp1ppp/2p2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Lutikov variation *
+rnbqr1k1/ppp2ppp/1b3n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, 7...d6, 8.d4 *
+rnbqr1k1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Chigorin variation *
+rnbqr1k1/ppp2ppp/5n2/2PP4/2B5/2N1B3/PPP2PpP/R2QK2R w KQ -
+two knights: Max Lange attack, Schlechter variation *
+rnbqr1k1/ppp2ppp/8/2PP4/2B3n1/2N1BpP1/PPP2P1P/R2QK2R b KQ -
+two knights: Max Lange attack, Loman defense *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPPBPPP/R2QK2R b KQ -
+Ruy Lopez: Trajkovi\'c counter-attack *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, 7...O-O *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed *
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: closed, Averbach variation *
+rnbr2k1/1pq1ppbp/5np1/p1pp4/3P4/1PP1PN2/P2NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Zagoryansky variation *
+rnbr2k1/pp2qppp/5n2/2b1N3/3Pp3/P1N1B3/2PQBPPP/R4RK1 b - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation *
+rnq1kb1r/pp3ppp/4pn2/3p1b2/3P4/NQ2PN2/PP1B1PPP/R3KB1R b KQkq -
+QGD Slav: Landau variation
blob - /dev/null
blob + a370e2eaab8b30a2ee439e6ddc00db3fa2805782 (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/long999.idx
+1q3rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy) *
+1r2kb1r/p1pq2pp/Q1n5/3npp2/6b1/P2PPN2/1P3PPP/RNB1KB1R b KQk -
+Sicilian: Najdorf, Poisoned pawn variation *
+1rb2rk1/pp3ppp/5q2/3P4/1n6/2P1Q3/PP3PPP/RN2KB1R w KQ -
+Scotch: Gottschall variation
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+King's Indian: S\"amisch, Panno main line
+1rbq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Ruban variation
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+English: closed, 5.Rb1 *
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3PN/PPPP1PBP/R1BQK2R b KQk -
+English: closed, 5.Rb1 Taimanov variation *
+1rbqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQk -
+two knights defense: Colman variation
+2bqkbnr/r4ppp/p1npp3/1p6/4P3/1BN2N2/PP2QPPP/R1B2RK1 w k -
+Sicilian: Smith-Morra gambit, Chicago defense
+2kr1b1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQNBPPP/R1B1K2R b KQ -
+Sicilian: Najdorf, 7...Be7 main line *
+2kr1b1r/ppp3pp/2n5/3qpp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7 *
+2kr1b1r/pppq2pp/2n1bp2/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, Yugoslav attack, Rauser variation *
+2kr1b1r/pppq2pp/2n2n2/2Pp1p2/3Pp3/2N1P3/PP1NQPPP/R1B2RK1 b - -
+French: classical, St\a hlberg variation *
+2kr1b1r/pppq2pp/2n2n2/4pp2/1P6/P1NPPb2/3BBPPP/R2QK2R w KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6 *
+2kr1b1r/pppq2pp/2n5/3Npp2/6b1/3PPN2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4 *
+2kr1b1r/pppq2pp/2n5/3npp2/4P1b1/2NP1N2/PP2BPPP/R1BQ1RK1 b - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4 *
+2kr1b1r/pppq2pp/2n5/3npp2/6b1/P1NPPN2/1P1BBPPP/R2QK2R b KQ -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7 *
+2kr3r/pp2bppp/2nqbn2/3pp1B1/8/1NN3P1/PPP1PPBP/R2Q1RK1 w - -
+Gr\"unfeld: Russian, Keres variation *
+2kr3r/ppp2ppp/1bn1bPq1/6N1/2ppNPP1/8/PPP4P/R1BQR1K1 w - -
+two knights: Max Lange attack, Berger variation
+2kr3r/pppb1ppp/2n1q2n/1Bb1p3/8/2NP1N2/PPP2PPP/R1BQR1K1 w - -
+Center game: Kupreichik variation *
+2kr3r/pppq2p1/1bn1bp2/3np2p/Q7/2NP1NP1/PP1BPPBP/R1R3K1 w - -
+Sicilian: dragon, Yugoslav attack, 12.h4 *
+2kr3r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 w - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O *
+2kr3r/pppqbppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP2B1PP/R2Q1RK1 w - -
+Alekhine's defense: four pawns attack, Tartakower variation
+2kr3r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Grigoriev variation *
+2kr3r/ppq1nppp/2nbp3/3p4/3P2b1/5N2/PPP1BPPP/R1BQRNK1 w - -
+QGD: exchange, chameleon variation *
+2krr3/pppq1ppp/1bn5/3n4/QPN1p1b1/P2PPN2/1B3PPP/R3KB1R w KQ -
+Sicilian: Najdorf, Ivkov variation *
+2r1kb1r/1pq2ppp/p1n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack (with Rc1) *
+2r1kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation *
+2r1kb1r/ppq2ppp/2n1pn2/2ppN3/3P2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation *
+2r1kb1r/ppq2ppp/2n1pn2/3p4/3p2b1/P1P1PN2/1P1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Rubinstein attack, main line *
+2rq1rk1/pp2ppbp/2n2np1/2Pp4/3P2b1/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Bogolyubov variation *
+2rq1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/1PN1BN2/P3BPPP/R2Q1RK1 b - -
+QGD: Tarrasch, Stoltz variation *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, Bd3 line, 11.O-O *
+2rq1rk1/pp3ppp/2n1pn2/2bp4/8/2P1PB1P/PP1N1PP1/R1BQ1RK1 w - -
+QGD: Petrosian variation *
+2rqk2r/pp3pp1/2n1pn2/2bp3p/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line, Janowski variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/1P4b1/2P1PN2/P2NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, fianchetto variation *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N2b1/2P1P3/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver *
+2rqk2r/pp3ppp/2n1pn2/2bp4/3N4/2P1P3/PP1NQPPP/R1B2RK1 b k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2n1pn2/3p4/1b1P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Capablanca variation *
+2rqk2r/pp3ppp/2nbpn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Bd3 line *
+2rqk2r/pp3ppp/2nbpn2/3p4/3P2b1/1P3N2/P1PNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Pillsbury attack *
+2rqk2r/pp3ppp/4pn2/2bpn3/3N4/2P1P3/PP1NQPPP/R1B2RK1 w k -
+QGD: Orthodox defense, Bd3 line, Alekhine variation *
+2rqkb1r/pp1bpppp/2n2n2/2pp4/Q2P4/2P1PN2/PP1N1PPP/R1B1KB1R w KQk -
+QGD: Rochlin variation *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1NBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, 7.Rc1 *
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/P3PN2/1PPNBPPP/R1BQ1RK1 b k -
+QGD: Orthodox defense, Swiss (Henneberger) variation *
+2rqkb1r/pp3ppp/2n1pn2/3p4/3p2b1/P3PN2/1PPNBPPP/R1BQ1RK1 w k -
+QGD: Orthodox defense, Swiss, Karlsbad variation *
+2rqkb1r/pp3ppp/4pn2/3p4/3P4/1P2B2P/P1P1QPP1/RN3RK1 b k -
+QGD: Tartakower variation *
+2rqkbnr/pp3ppp/2n1p3/2p2b2/2pP4/4BNP1/PP2PPBP/RN1Q1RK1 b k -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation *
+2rqkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w k -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation *
+2rqkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w k -
+QGD: Anti-neo-orthodox variation *
+3q1rk1/pp3ppp/2r1p3/2b5/4Q3/2P5/PP3PPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical, 13.de *
+3q1rk1/pp3ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 b - -
+QGD: Orthodox defense, classical variation *
+4rrk1/pppb2pp/2np1q2/2b2P2/4Q3/2N4B/PPPPNP1P/R1B1K2R w KQ -
+KGA: Muzio gambit, Paulsen variation *
+5rk1/5ppp/p1pbr3/1p1n3q/P2P2b1/1BPQB1P1/1P1N1P1P/R3R1K1 w - -
+Ruy Lopez: Marshall, main line, Spassky variation
+5rk1/ppq2ppp/2r1pn2/2bp4/4P3/2P5/PP1NQPPP/R1B2RK1 w - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar) *
+N1bk1b1r/p2pq2p/1pnn2p1/3Qpp2/8/1B6/PPPP1PPP/R1B1K1NR w KQ -
+Vienna: `Frankenstein-Dracula' variation
+N1bk3r/pp1p1ppp/2n2n2/8/1b6/P4B1q/1PPN1P1P/R1BQK2R b KQ -
+Scotch: Berger variation
+r1b1k1nr/ppp2ppp/1bn5/3p4/4P2q/2NN4/PPPP1PPP/R1BQKB1R w KQkq -
+Vienna: Adams' gambit *
+r1b1k1nr/ppp2ppp/2n5/q3P3/1b6/2N2N2/PPPB1PPP/R2QKB1R b KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack
+r1b1k1nr/pppp1ppp/1b6/8/3qPP2/1PNN2P1/P2PQ2P/n1BK1B1R b kq -
+Vienna: `Frankenstein-Dracula' variation *
+r1b1k1nr/pppp1ppp/1b6/nP2N1q1/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Hirschbach variation
+r1b1k1nr/pppp1ppp/1bn5/8/4P2q/3N4/PPPPBPPP/RNBQK2R b KQkq -
+Vienna game *
+r1b1k1nr/pppp1ppp/2n2q2/1Nb5/4P3/4B3/PPP2PPP/RN1QKB1R b KQkq -
+Scotch: Blumenfeld attack
+r1b1k1nr/pppp1ppp/2n5/1N6/1b2P2q/8/PPPB1PPP/RN1QKB1R b KQkq -
+Scotch game
+r1b1k1nr/ppppqppp/1bn5/4p1B1/2BPP3/2P2N2/PP3PPP/RN1QK2R b KQkq -
+Giuoco Piano: Mestel variation
+r1b1k1nr/ppppqppp/1bn5/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: center-holding variation
+r1b1k1nr/ppppqppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Boden variation
+r1b1k1nr/ppppqppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano: close variation
+r1b1k1nr/pppq1ppp/1b6/n3N3/2B1P3/BQP5/P4PPP/RN3RK1 b kq -
+Evans gambit: Levenfish variation
+r1b1k2r/1pp1qppp/pbnp1n2/4p3/P1BPP3/2P2N1P/1P3PP1/RNBQR1K1 b kq -
+Giuoco Piano: Tarrasch variation
+r1b1k2r/1pp2ppp/p1n5/2bpq3/3NP3/2P1K3/PPN3PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Leonhardt variation *
+r1b1k2r/1pq1bppp/p1nppn2/8/P2NPP2/2N5/1PP1B1PP/R1BQ1R1K b kq -
+Sicilian: Scheveningen, classical, Mar\'oczy system
+r1b1k2r/1pqnbppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/2KR1B1R w kq -
+Sicilian: Najdorf, 7...Be7 main line
+r1b1k2r/2q1bppp/p2p1n2/npp1p3/P2PP3/2P2N2/1PB2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, Balla variation
+r1b1k2r/p1q2pp1/2pb1n1p/n3N3/3Pp3/8/PPPBBPPP/RN1QK2R b KQkq -
+two knights defense: Knorre variation
+r1b1k2r/pp1n1ppp/2p1pn2/q2p2B1/1bPP4/2N1P3/PPQN1PPP/R3KB1R b KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation
+r1b1k2r/pp3ppp/1qn1p3/2bp4/6n1/5NP1/PPPNPPBP/R1BQ1RK1 w kq -
+Gr\"unfeld: Pachman variation *
+r1b1k2r/pp3ppp/3b1q2/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Stahlberg variation *
+r1b1k2r/ppp1qppp/5n2/4p1B1/2BnP3/2N5/PPP3PP/R2Q1RK1 b kq -
+Giuoco piano: Holzhausen attack
+r1b1k2r/ppp2ppp/2N5/1B1pP3/4n2q/8/PPP2bPP/RNBQ1K1R w kq -
+Two knights defense, Keidanz variation
+r1b1k2r/ppp3p1/2np1q1p/2b1pP2/2B5/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+KGD: classical, Svenonius variation *
+r1b1k2r/pppp1ppp/1bn5/8/4n2q/2NN4/PPPPBPPP/R1BQK2R w KQkq -
+Vienna: Alekhine variation *
+r1b1k2r/pppp1ppp/2n2q2/2b5/3NP3/4K3/PPP1N1PP/R1BQ1B1R b kq -
+two knights defense: Fegatello attack, Polerio defense *
+r1b1k2r/ppppnp1p/2n4b/4q3/2B2p2/2NP1Q2/PPPB2PP/4RRK1 b kq -
+KGA: Muzio gambit, Paulsen variation
+r1b1k2r/ppppnppp/2n2q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R b KQkq -
+Scotch: Paulsen attack
+r1b1k2r/ppppnppp/2n2q2/2b5/3NP3/2P1B3/PP1Q1PPP/RN2KB1R b KQkq -
+Scotch: Blackburne attack
+r1b1k2r/ppppnppp/2n2q2/2b5/4P3/2P1B3/PPN2PPP/RN1QKB1R b KQkq -
+Scotch: Meitner variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/1QN2N2/P4PPP/R1BR2K1 b kq -
+Evans gambit: compromised defense, Potter variation
+r1b1k2r/ppppnppp/2n3q1/b3P3/2B5/BQN2N2/P4PPP/R4RK1 b kq -
+Evans gambit: compromised defense, Paulsen variation
+r1b1kb1r/1pp3pp/p1n2n2/5pq1/2BPp3/2N1PP2/PP1N2PP/R1BQ1RK1 b kq -
+French: Steinitz, Brodsky-Jones variation *
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b kq -
+Sicilian: Scheveningen, classical
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6
+r1b1kb1r/2p1nppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Qkq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation *
+r1b1kb1r/p1q2pp1/2p2n1p/n3N3/4p3/8/PPPPBPPP/RNBQK2R w KQkq -
+two knights defense: G\"oring variation
+r1b1kb1r/p1q2ppp/2p2n2/n3p1N1/8/3B1Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Paoli variation
+r1b1kb1r/pp1n1ppp/2p1p3/q2n2B1/3P4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation
+r1b1kb1r/pp1n1ppp/2p1pB2/q2p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, Capablanca variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q2P2B1/3P4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD: Cambridge Springs defense, 7.cd
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p4/2PP4/2N2N2/PP1BPPPP/2RQKB1R b Kkq -
+QGD: Rochlin variation
+r1b1kb1r/pp1n1ppp/2p1pn2/q5B1/2pP4/2N1P3/PP1N1PPP/R2QKB1R w KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation
+r1b1kb1r/pp1p1ppp/1qn1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R w KQkq -
+English: symmetrical, Geller variation
+r1b1kb1r/pp1p1ppp/4pn2/1Bp5/3nPq2/2N2N2/PPPP1PPP/R1BQR1K1 w kq -
+English: four knights, Stean variation *
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kb1r/pp2pppp/1qn2n2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation
+r1b1kb1r/pp2pppp/1qnp1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Benk\"o variation
+r1b1kb1r/pp2pppp/2n2n2/q1pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: Flohr variation *
+r1b1kb1r/pp2pppp/2n2n2/q2p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/4PNP1/PPP2PBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Botvinnik variation *
+r1b1kb1r/pp3ppp/1qn1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Qb3 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp1B1/8/5NP1/PPP1PPBP/RN1Q1RK1 b kq -
+Gr\"unfeld: Russian, Smyslov variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/1P3NP1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Levenfish variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2N2NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Byrne (Simagin) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/2P2NP1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Russian variation with e4 *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/N4NP1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: Russian, Prins variation *
+r1b1kb1r/pp3ppp/2n2n2/2qpp3/8/P4NP1/1PP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation *
+r1b1kb1r/pp3ppp/2n5/2pqp3/8/3P1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation *
+r1b1kb1r/ppppq1pp/2n2n2/3Q4/8/5N2/PPP1PPPP/RNB1KB1R w KQkq -
+Queen's pawn: Englund gambit
+r1b1kb1r/ppppq1pp/2n2n2/4N1B1/3Pp3/8/PPP2PPP/RN1QKB1R w KQkq -
+Vienna gambit: Kaufmann variation *
+r1b1kb1r/ppppqppp/5n2/1B2N3/3nPP2/2N5/PPPP2PP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation
+r1b1kb1r/ppq1pppp/2n2n2/1Bpp4/8/2NPPN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation *
+r1b1kb1r/ppq2ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Stoltz variation *
+r1b1kb1r/ppqp1ppp/2B1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+English: four knights, Romanishin variation *
+r1b1kbnr/1p2pppp/p1q5/2pp4/1P6/4PN2/P1PP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Adorjan gambit *
+r1b1kbnr/1p2pppp/p1q5/2pp4/3P4/2N1PN2/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, Botvinnik variation *
+r1b1kbnr/1p2pppp/p1q5/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, main line *
+r1b1kbnr/1pp2ppp/p1pq4/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Bronstein variation
+r1b1kbnr/1pq1pppp/p1n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3 *
+r1b1kbnr/1pq1pppp/p7/2ppN3/3P4/4P3/PPP2PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2 *
+r1b1kbnr/1pq2ppp/p3p3/2ppN3/3PP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, San Remo variation *
+r1b1kbnr/1pqp1ppp/p1n1p3/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/2p2ppp/p1p5/3p2q1/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, poisoned pawn variation *
+r1b1kbnr/p1p2ppp/2p5/3pN1q1/3Pp3/4P2P/PPP2PP1/RNBQ1K1R w kq -
+French: MacCutcheon, Duras variation *
+r1b1kbnr/p1pp1ppp/1pn5/8/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation
+r1b1kbnr/pp1qpppp/2np4/1B6/3QP3/5N2/PPP2PPP/RNB1K2R w KQkq -
+Sicilian: Chekhover, Zaitsev variation
+r1b1kbnr/pp2pppp/1qn5/1Bp5/2p5/2N1PN2/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6 *
+r1b1kbnr/pp2pppp/1qn5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Spielmann variation *
+r1b1kbnr/pp2pppp/1qn5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Russian variation *
+r1b1kbnr/pp2pppp/2nq4/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Mikenas attack *
+r1b1kbnr/pp3ppp/1qn1p3/2ppP3/3P4/2PB1N2/PP3PPP/RNBQK2R b KQkq -
+French: advance, Milner-Barry gambit
+r1b1kbnr/ppp1pppp/2n5/3q4/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Marshall gambit
+r1b1kbnr/ppp1pppp/2n5/7q/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Novosibirsk opening *
+r1b1kbnr/ppp1qppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Balogh variation
+r1b1kbnr/ppp2ppp/2n5/1B1p2q1/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Russian variation *
+r1b1kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPN1PPP/RNBQKB1R w KQkq -
+French: Steinitz, Gledhill attack *
+r1b1kbnr/ppp2ppp/2n5/3p4/3PPp1q/2N5/PPP1K1PP/R1BQ1BNR w kq -
+Vienna: Steinitz gambit, Zukertort defense
+r1b1kbnr/ppp3pp/2n2q2/3pN3/3PpP2/8/PPP3PP/RNBQKB1R w KQkq -
+Vienna gambit: Heyde variation *
+r1b1kbnr/ppp3pp/2n5/5pq1/2BPp3/4P3/PP1N1PPP/RNBQK2R w KQkq -
+French: Steinitz, Bradford attack *
+r1b1kbnr/pppnq2p/8/4Npp1/3Q1P2/8/PPP3PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, Charousek variation *
+r1b1kbnr/pppp1Npp/8/8/4q3/5n2/PPPPBP1P/RNBQKR2 w Qkq -
+Blackburne shilling gambit
+r1b1kbnr/pppp1p1p/2n5/4N3/2B1Pppq/8/PPPP2PP/RNBQ1K1R w kq -
+KGA: Herzfeld gambit
+r1b1kbnr/pppp1p1p/5q2/4n3/2B1PQ2/2N5/PPPP2PP/R1B2RK1 w kq -
+Vienna: Hamppe-Muzio, Dubois variation
+r1b1kbnr/pppp1ppp/2n2q2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Goldman (Spielmann) variation *
+r1b1kbnr/pppp1ppp/2n5/1B2p1q1/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Vienna: Zhuravlev countergambit *
+r1b1kbnr/pppp1ppp/2n5/1N6/4P2q/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Horwitz attack
+r1b1kbnr/pppp1ppp/2n5/8/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Boden defense
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Scotch: Steinitz variation
+r1b1kbnr/pppp1ppp/2n5/8/3NP2q/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Pulling counter-attack
+r1b1kbnr/pppp1ppp/2n5/8/4P2q/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Fraser attack
+r1b1kbnr/pppp2pp/2n2q2/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit: Paulsen attack *
+r1b1kbnr/pppp2pp/2n2q2/4N3/3PpP2/8/PPP3PP/RNBQKB1R b KQkq f3
+Vienna gambit: Bardeleben variation *
+r1b1kbnr/ppppq1pp/2n5/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Rubinstein variation *
+r1b1kbnr/ppppqppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Vinogradov variation
+r1b1kbnr/ppq1pppp/2n5/1B1p4/3P4/5N2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed *
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: classical, Pir\'c variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, 4...c5 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+Nimzo-Indian: classical, Noa variation *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: classical, 4...Nc6 *
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: classical variation *
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Taimanov variation
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov (Bastrikov) variation
+r1b1kbnr/ppqppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Flohr variation
+r1b2knr/pppp3p/2n2qP1/2b1p2Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Fraser variation *
+r1b2rk1/1p2qp1p/2n1pn2/pBbpN1p1/5B2/2P1P3/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch, S\"amisch variation *
+r1b2rk1/1p2qppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1Q1RK1 w - -
+QGD Slav: Dutch variation, main line *
+r1b2rk1/1pp1qppp/2n2n2/p1bPp3/8/2PP1N2/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Nimzovich, Sozin variation *
+r1b2rk1/1pq1bppp/p1nppn2/8/3NPP2/2N1B3/PPP1B1PP/R3QRK1 w - -
+Sicilian: Scheveningen, classical main line
+r1b2rk1/2q1bppp/p1np1n2/1pP1p3/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, Rauzer attack
+r1b2rk1/2q1bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, 12...Nc6
+r1b2rk1/2q1bppp/p1pp1n2/np2p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Rossolimo defense
+r1b2rk1/2q1bppp/p2p1n2/np2p3/3PP3/5N1P/PPBN1PP1/R1BQR1K1 b - -
+Ruy Lopez: closed, Chigorin, 12...c5d4
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Chigorin defense
+r1b2rk1/5ppp/p1pb4/1p1n4/3P4/1BP3Pq/PP3P1P/RNBQR1K1 w - -
+Ruy Lopez: Marshall, main line, 14...Qh3
+r1b2rk1/p1q2ppp/2n2n2/3pp3/N7/1B1P4/PPPB1bPP/R2Q1KNR w - -
+Evans gambit: Fraser-Mortimer attack *
+r1b2rk1/p4ppp/1qB2n2/2bp4/3P4/2N5/PPP2PPP/R1BQK2R b KQ -
+Giuoco Piano: Bernstein variation *
+r1b2rk1/p4ppp/2n2n2/q1bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR w KQ -
+Evans gambit: Fraser attack *
+r1b2rk1/pp1n1ppp/2p1pn2/q2p4/1bPP3B/2N1P3/PPQN1PPP/R3KB1R b KQ -
+QGD: Cambridge Springs defense, Argentine variation
+r1b2rk1/pp1nqppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2Q1RK1 w - -
+Ruy Lopez: open, Malkin variation *
+r1b2rk1/pp1nqppp/2n1p3/3pP3/2pP1P2/2N2N2/PPPQ2PP/2KR1B1R w - -
+French: classical, St\a hlberg variation
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Orthodox defense, Bd3 line, 11.O-O
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line
+r1b2rk1/pp1nqppp/2p1p3/3n4/2BPN3/4PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Alekhine variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/1Q3RK1 b - -
+QGD: Orthodox defense, classical, 13.d1b1 (Mar\'oczy)
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical variation
+r1b2rk1/pp1nqppp/2p5/4p3/2BP4/2R1PN2/PPQ2PPP/5RK1 b - -
+QGD: Orthodox defense, classical, 13.d1c2 (Vidmar)
+r1b2rk1/pp2nppp/2pq1n2/3pp1B1/1b2P2N/1BNP4/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Blake variation
+r1b2rk1/pp2ppbp/1qnp1np1/4P3/3N1P2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Zollner gambit
+r1b2rk1/pp2ppbp/2nq1np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Botvinnik variation *
+r1b2rk1/pp2ppbp/2q2np1/2pp4/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 9.Qxc3 *
+r1b2rk1/pp2qppp/1bn2n2/4p3/1P6/P1NPP3/R4PPP/2BQKBNR b K -
+Sicilian: Smith-Morra gambit, Chicago defense *
+r1b2rk1/pp2qppp/2n1pn2/2bp4/2P1P3/2NB1N2/PP2QPPP/R1B2RK1 b - -
+QGD: Semi-Tarrasch, Levenfish variation
+r1b2rk1/pp2qppp/2nb1n2/2p1p3/2BP4/2N1PN2/PP2QPPP/R1B2RK1 w - -
+QGD: Semi-Tarrasch, Levenfish variation *
+r1b2rk1/pp3ppp/2p5/4q3/2B5/2R1P3/PP3PPP/3Q1RK1 w - -
+QGD: Orthodox defense, classical, 13.de
+r1b2rk1/ppp1qppp/2n2n2/1B1pp3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 w - -
+Four knights: Alatortsev variation
+r1b2rk1/ppp1qppp/2np1n2/1B2p1B1/4P3/2PP1N2/P1P2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Metger unpin
+r1b2rk1/pppp2pp/2n5/2b1pq2/4N3/5Q2/PPPP1P1P/R1B1KBNR b KQ -
+Vienna: Hamppe-Muzio, Dubois variation *
+r1b2rk1/ppq1ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with Qc2 *
+r1b2rk1/ppqnppbp/5np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, main line *
+r1b3nr/ppppkBpp/1b6/nP2N1qQ/4P3/8/P1PP1PPP/RNB1K2R b KQ -
+Evans gambit declined, V\'asquez variation
+r1b3r1/ppp2k1p/1b6/nP2B1q1/3PP3/8/P1PN1PPP/R2QK2R b KQ -
+Evans gambit declined, Pavlov variation
+r1bB1rk1/pp3ppp/8/4p3/3nn3/3P4/PPP1KbPP/R2Q1BNR w - -
+Scotch: Sea-cadet mate *
+r1bk1bnr/2p2ppp/p1p5/3P4/3Pp3/4P3/PPQ1NP1q/RNB1K1R1 w Q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation *
+r1bk2nr/pppp1Qpp/1b6/nP2q3/2B1P3/8/PBPP1PPP/RN2K2R b KQ -
+Evans gambit declined, Hicken variation
+r1bk2nr/pppp1ppp/2n3q1/1N6/8/8/PPPNBPPP/R2Q1RK1 w - -
+Scotch: Rosenthal variation
+r1bk2nr/ppppq1pp/2n5/2b1PP1Q/8/8/PPPP2PP/RNBK1BNR b - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation *
+r1bnk2r/ppppnppp/5q2/1Bb5/3NP3/2P1B3/PP3PPP/RN1QK2R w KQkq -
+Scotch: Paulsen, Gunsberg defense
+r1bq1b1r/ppn3pp/2p1k3/3np3/2BPQ3/P1N5/1PP2PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Leonhardt variation
+r1bq1b1r/ppp1n1pp/4k3/3np3/2B5/2N2Q2/PPPP1PPP/R1B1K2R w KQ -
+two knights defense: Fegatello attack, Polerio defense
+r1bq1b1r/ppp2kp1/2n5/1B1p1PPp/3Qn3/5N2/PPP2P1P/RNB1K2R w KQ -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/3P4/2N5/PPP2PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Zukertort defense *
+r1bq1bnr/ppp1k1pp/2n5/3ppP1Q/8/1PN5/P1PP1PPP/R1B1KBNR b KQ -
+Vienna: Steinitz gambit, Fraser-Minckwitz variation *
+r1bq1k1r/2p2ppp/p4n2/1pbPR1N1/3n4/1B6/PPPP1PPP/RNBQ2K1 w - -
+Ruy Lopez: Rabinovich variation
+r1bq1k1r/pp2nppp/2n5/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit: Ne2 variation *
+r1bq1knr/pp3p1p/2n3p1/4p3/2Pp4/3P1NP1/4PP1P/RN1QKB1R w KQ -
+Benk\"o gambit *
+r1bq1knr/ppp3pp/2n5/2bp1P1Q/4p1P1/3P4/PPP2PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, Grimm attack *
+r1bq1knr/ppp3pp/2n5/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R b KQ -
+KGA: bishop's gambit, classical defense *
+r1bq1knr/ppp4p/2n3p1/2bppP1Q/6P1/8/PPPPNPBP/RNB1K2R w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1knr/pppp3p/2n3p1/2b1pP1Q/6P1/8/PPPP1PBP/RNB1K1NR w KQ -
+KGA: bishop's gambit, McDonnell attack *
+r1bq1r1k/1pp1b1pp/2n5/p2npp2/8/P1NPPN2/1PQ1BPPP/R1B1K2R w KQ -
+Sicilian: Scheveningen, classical, Mar\'oczy system *
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+King's Indian: orthodox, 7...Nbd7, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3P2B1/3P4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, main line
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Karlsbad variation
+r1bq1rk1/1p1nbppp/p1p1pn2/3p2B1/2PP4/P1N1PN2/1PQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack, Gr\"unfeld variation
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+Benoni: fianchetto, 11...Re8 *
+r1bq1rk1/1p2bppp/2n2n2/p3p1B1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 b - -
+Benoni: classical with ...a6 and 10...Bg4 *
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9...a6, 10.a4 *
+r1bq1rk1/1p2ppbp/2np1np1/p7/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, Byrne variation
+r1bq1rk1/1p2ppbp/2np1np1/p7/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Alekhine variation
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+QGD Slav: Dutch variation *
+r1bq1rk1/1p3ppp/p1n1pn2/1BbP4/8/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd *
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Panno variation
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, Panno formation
+r1bq1rk1/1pp2ppp/1bn5/p2PN3/1P1P4/P7/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Berger variation *
+r1bq1rk1/1ppnbppp/p3pn2/3P2B1/3P4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, Swiss, Karlsbad variation
+r1bq1rk1/1ppnbppp/p3pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense, Swiss (Henneberger) variation
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Smyslov defense
+r1bq1rk1/2p1bppp/2np1n2/pp2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (9...a5) variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1P4/4p3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall, Herman Steiner variation
+r1bq1rk1/2p1bppp/p1n2n2/1p1pp3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: Marshall counter-attack
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.d4
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, 9.h3
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed (with ...d6)
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BPP1N2/PP3PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Pilnik variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/2P2N2/PPBP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Lutikov variation
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/PBP2N2/1P1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, Suetin variation
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+Ruy Lopez: closed (9...Na5)
+r1bq1rk1/2pnbppp/p1np4/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP2N/1BP4P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, Simagin variation
+r1bq1rk1/2pnbppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer, Borisenko variation
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, 7...O-O
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w - -
+Ruy Lopez: Worrall attack, sharp line
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/4P3/1BP2N2/PP1P1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, 8.c3
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+Ruy Lopez: closed, anti-Marshall 8.a4
+r1bq1rk1/3nbppp/p2p4/npp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Keres (...Nd7) defense
+r1bq1rk1/4bppp/p1np1n2/1pp1p3/3PP3/2P2N1P/PPB2PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Borisenko defense
+r1bq1rk1/4bppp/p1p5/1p1nR3/3P4/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, main line, 12.d2d4
+r1bq1rk1/4bppp/p1p5/1p1nR3/8/1BP5/PP1P1PPP/RNBQ2K1 w - -
+Ruy Lopez: Marshall counter-attack, 11...c6
+r1bq1rk1/4bppp/p2p1n2/npp1p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed (10...c5)
+r1bq1rk1/4bppp/ppnppn2/8/2P1P3/N1N5/PP2BPPP/R1BQ1RK1 w - -
+Sicilian, Sz\'en, hedgehog variation
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line *
+r1bq1rk1/5ppp/p1pbpn2/2pp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3 *
+r1bq1rk1/5ppp/p2b4/1p1p4/3P4/2P1R3/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: Marshall, Kevitz variation
+r1bq1rk1/p1p2ppp/2pp1n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Svenonius variation *
+r1bq1rk1/p1pnbppp/1p3n2/1B1p2B1/3P4/2N1PN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Capablanca variation
+r1bq1rk1/p1pnbppp/1p3n2/3p2B1/3P4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Pillsbury attack
+r1bq1rk1/p1ppbppp/8/2p1P3/3B4/2N5/PPP1QPPP/R3R1K1 w - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation
+r1bq1rk1/p2nbppp/1pp1pn2/3p4/P1PP4/5NP1/1PQ1PPBP/RNBR2K1 b - -
+Catalan: closed, Zagoryansky variation
+r1bq1rk1/p2nbppp/2p1pn2/1p4B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, fianchetto variation
+r1bq1rk1/p2pppbp/1pn2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with b3 *
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack *
+r1bq1rk1/p3nppp/2p5/2bpp3/8/1P4P1/P1PQPPBP/RNB2RK1 b - -
+Gr\"unfeld: exchange, Larsen variation *
+r1bq1rk1/p3ppbp/1pn2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky variation with b3 *
+r1bq1rk1/p4ppp/2n2n2/2bpp1B1/8/1BNP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit *
+r1bq1rk1/p4ppp/2n2n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Morphy attack *
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical main line
+r1bq1rk1/pp1n1pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 9...Nbd7
+r1bq1rk1/pp1n1pp1/2p1pb1p/8/2BP4/2N1PN2/PP3PPP/2RQ1RK1 b - -
+QGD: Petrosian variation
+r1bq1rk1/pp1n1ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, St. Petersburg variation *
+r1bq1rk1/pp1n1ppp/1bp5/3P4/1PN1p1n1/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation, Karpov gambit *
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation
+r1bq1rk1/pp1n1ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7
+r1bq1rk1/pp1n2pp/2n1pp2/2bpP3/5PQ1/P1N2N2/1PP3PP/R1B1KB1R w KQ -
+French: Steinitz, Brodsky-Jones variation
+r1bq1rk1/pp1nb1pp/2n2p2/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 w - -
+Benoni: classical, 11.f3 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 w - -
+Benoni: classical, 9...Re8, 10.Nd2 *
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+Benoni: classical with ...Re8 and ...Na6 *
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP3P/2N1PN2/PP3PP1/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line, Janowski variation
+r1bq1rk1/pp1nbppp/2p1p3/3n2B1/2BP4/2N1PN2/PP3PPP/2RQK2R w K -
+QGD: Orthodox defense, Bd3 line, Capablanca freeing maneuver
+r1bq1rk1/pp1nbppp/2p1p3/3p2B1/2PPn3/2N1PN2/PPQ2PPP/2R1KB1R w K -
+QGD: Orthodox defense, Rubinstein attack, Wolf variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R w K -
+QGD: Orthodox defense
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/2R1KB1R b K -
+QGD: Orthodox defense, Rubinstein attack (with Rc1)
+r1bq1rk1/pp1nbppp/2p1pn2/3p2B1/2PP4/2NBPN2/PP3PPP/2RQK2R b K -
+QGD: Orthodox defense, Bd3 line
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/1P3NP1/P1Q1PPBP/RNB2RK1 b - -
+Catalan: closed, Qc2 & b3
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/2NQ1NP1/PP2PPBP/R1B2RK1 b - -
+Catalan: closed, Botvinnik variation
+r1bq1rk1/pp1nbppp/2p1pn2/3p4/2PP4/5NP1/PPQNPPBP/R1B2RK1 b - -
+Catalan: closed, main line
+r1bq1rk1/pp1nbppp/2p4n/3pp1N1/2BPPP2/2P5/PP4PP/RNBQ1RK1 w - -
+Philidor: Hanham, Berger variation
+r1bq1rk1/pp1nbppp/2pp1n2/8/P1BpP3/2N2N2/1PP1QPPP/R1B2RK1 w - -
+Philidor: Nimzovich, Sozin variation
+r1bq1rk1/pp1nbppp/4pn2/2pP2B1/3P4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein)
+r1bq1rk1/pp1p1ppp/2n1pn2/2p5/2PP4/P1PBP3/5PPP/R1BQK1NR w KQ -
+Nimzo-Indian: S\"amisch, main line
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+English: symmetrical, hedgehog system *
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1PN2NP1/P2PPPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with b3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2NP1NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d3
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+English: symmetrical, main line with d4
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+English: Symmetrical, Keres defense *
+r1bq1rk1/pp2b1pp/2n2n2/2pp4/4pB2/1N2PP2/PPP1B1PP/RN1Q1RK1 b - -
+Alekhine's defense: four pawns attack, Korchnoi variation *
+r1bq1rk1/pp2bppp/2n1pn2/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQR1K1 b - -
+R\'eti: King's Indian attack, French variation
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+QGD: Tarrasch, Prague variation, 9.Bg5
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, Normal position
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation) *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b - -
+King's Indian: orthodox, Donner variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+King's Indian: orthodox variation *
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7 *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+Benoni: classical, 9.O-O *
+r1bq1rk1/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+Benoni: classical, 9...Re8 *
+r1bq1rk1/pp2bppp/2np1n2/4p1B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, Geller variation
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9.f4
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/1BN1B3/PPP3PP/R2QK2R b KQ -
+Sicilian: Sozin, Fischer variation
+r1bq1rk1/pp2bppp/2nppn2/8/3NPP2/2N1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line
+r1bq1rk1/pp2bppp/3ppn2/6B1/3QPP2/2N5/PPP3PP/2KR1B1R b - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/3ppn2/6B1/3nPP2/2N5/PPPQ2PP/2KR1B1R w - -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 defense, 9...Nxd4
+r1bq1rk1/pp2bppp/n1n5/2p1p3/8/PPNPPN2/4BPPP/R1BQ1RK1 b - -
+Sicilian, Sz\'en, hedgehog variation *
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2Pp4/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav Panno *
+r1bq1rk1/pp2ppbp/2n2np1/2pp2B1/8/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, Simagin variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d4 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+King's Indian: fianchetto, Yugoslav, 7.O-O *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 b - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2NP1NP1/PPP1PPBP/R2Q1RK1 b - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5B2/2PP1NP1/PP2PPBP/RN1Q1RK1 b - -
+King's Indian: fianchetto, Larsen system *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2NP1NP1/PPP1P1BP/R1BQ1RK1 b - -
+Dutch: Leningrad, main variation with Nc6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/2PP1NP1/PP2P1BP/RNBQ1RK1 b - -
+Dutch: Leningrad, main variation with c6 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 b - -
+Dutch: Ilyin-Genevsky variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: old main line, 7.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Panno variation *
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3 *
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+QGD: Tarrasch, Prague variation, Normal position *
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP1N1PBP/R1BQ1RK1 b - -
+Benoni: fianchetto, 9...Nbd7 *
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd
+r1bq1rk1/pp2ppbp/2np1np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+English: symmetrical, main line with d3 *
+r1bq1rk1/pp2ppbp/2np1np1/2pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav Panno
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+Sicilian: dragon, Yugoslav attack, 9.Bc4
+r1bq1rk1/pp2ppbp/2np1np1/8/2PNPP2/2N1B3/PP2B1PP/R2QK2R b KQ -
+King's Indian: Four pawns attack, main line
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/2KR3R b - -
+Sicilian: dragon, classical, Grigoriev variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R4RK1 b - -
+Sicilian: dragon, classical, Richter variation
+r1bq1rk1/pp2ppbp/2np1np1/8/3NP3/2N1BP2/PPPQ2PP/2KR1B1R b - -
+Sicilian: dragon, Yugoslav attack, Rauser variation
+r1bq1rk1/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2Q1RK1 b - -
+Sicilian: dragon, classical, 9.Nb3
+r1bq1rk1/pp2ppbp/5np1/n7/2BP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+QGD: Tarrasch, R\'eti variation *
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical main line *
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation, 8.e4 *
+r1bq1rk1/pp3ppp/2B2n2/2b1N3/3p4/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller (Therkatz) attack *
+r1bq1rk1/pp3ppp/2B2n2/2bpN3/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano *
+r1bq1rk1/pp3ppp/2N2n2/1Bbp4/8/2N5/PPPP1PPP/R1BQK2R b KQ -
+Giuoco Piano: Greco variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Bronstein variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP2QPPP/RNB2RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation *
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP3PPP/RNBQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc *
+r1bq1rk1/pp3ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/2PP4/P1PBPN2/5PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 8...Bxc3
+r1bq1rk1/pp3ppp/2n1pn2/8/1bBp4/P1N1PN2/1P3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, main line with 8...dc and 9...cd
+r1bq1rk1/pp3ppp/2n2n2/2bp4/N7/5NP1/PP2PPBP/R1BQ1RK1 b - -
+QGD: Tarrasch, R\'eti variation
+r1bq1rk1/pp3ppp/2nbpn2/1BPp4/8/2N1PN2/PPP2PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Ragozin variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/1P2PN2/P4PPP/RNBQ1RK1 b - -
+Nimzo-Indian: 4.e3, Keres variation *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, main line with 7...Nc6 *
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...Nbd7 *
+r1bq1rk1/pp3ppp/2nbpn2/2pp2B1/3P4/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Smyslov defense *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+QGD: Semi-Tarrasch, symmetrical variation *
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+QGD: Semi-Tarrasch, symmetrical variation
+r1bq1rk1/pp3ppp/2nbpn2/2pp4/3P1B2/2P2NP1/PP2PPBP/RN1Q1RK1 b - -
+Gr\"unfeld: Flohr defense *
+r1bq1rk1/pp3ppp/3b4/3P4/1P2n3/4PN2/5PPP/R1BQKB1R w KQ -
+QGD semi-Slav: Meran, Sozin variation *
+r1bq1rk1/pp4bp/2nppnp1/2p5/2P1PPPP/2N5/PP2B3/R1BQK1NR b KQ -
+King's Indian: Six pawns attack
+r1bq1rk1/ppbn1Npp/2p2n2/8/1PBPp3/P1N1B3/2P2PPP/R2Q1RK1 b - -
+Ruy Lopez: open, Dilworth variation *
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+Sicilian: Scheveningen, classical variation with ...Qc7 and ...Nc6 *
+r1bq1rk1/ppp1bppp/2n1pn2/8/3PN3/P5N1/1PP1BPPP/R1BQK2R w KQ -
+French: Winawer, Alekhine gambit, Alatortsev variation
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1P1N1PPP/R1BQKB1R b KQ -
+Sicilian: Scheveningen, classical, Nd7 system *
+r1bq1rk1/ppp1bppp/2n5/3np3/8/P2PPN2/1PQ2PPP/RNB1KB1R b KQ -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, bayonet attack
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1
+r1bq1rk1/ppp1nppN/3p4/3P4/2B1R3/8/PP3PPP/R2Q2K1 b - -
+Giuoco Piano: Therkatz-Herzog variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Pillsbury variation
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b1PP3/2N2N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: Alatortsev variation *
+r1bq1rk1/ppp1nppp/3p1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical, Mar\'oczy system *
+r1bq1rk1/ppp1p1bp/2np1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with Nc6
+r1bq1rk1/ppp1ppbp/2n2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Byrne (Simagin) variation
+r1bq1rk1/ppp1ppbp/2n3p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's improved variation
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nc6
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, 6...Nc6
+r1bq1rk1/ppp1ppbp/n2p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Kazakh variation
+r1bq1rk1/ppp1ppbp/n4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Prins variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Uhlmann (Szabo) variation
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov variation (Yugoslav attack / Mar del Plata variation)
+r1bq1rk1/ppp2ppp/1b1p1n2/4p3/N3P3/3P1B2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation
+r1bq1rk1/ppp2ppp/2Bp1n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights *
+r1bq1rk1/ppp2ppp/2n1pn2/8/1bpP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Ragozin variation
+r1bq1rk1/ppp2ppp/2n2n2/1B1pp3/4P3/2PP1N2/P1P2PPP/R1BQ1RK1 w - -
+Four knights: Svenonius variation
+r1bq1rk1/ppp2ppp/2n2n2/3Pp3/1b6/2NP1N2/PPPB1PPP/R2QKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Wolf variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2QK2R b KQ -
+Ruy Lopez: Berlin defense, hedgehog variation *
+r1bq1rk1/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Showalter variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: double Ruy Lopez *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: symmetrical variation *
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: symmetrical variation
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/1b2P3/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Mar\'oczy system
+r1bq1rk1/ppp2ppp/2np1n2/1B2p3/4P3/2PP1N2/P1P2PPP/R1BQR1K1 b - -
+Four knights: Janowski variation
+r1bq1rk1/ppp2ppp/3p1b2/n3p3/4P3/1B1P1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: Rubinstein counter-gambit Mar\'oczy variation *
+r1bq1rk1/ppp3pp/2n2P2/2bp1PB1/8/2p5/PPP2P1P/R2QKBNR w KQ -
+Vienna: Pierce gambit, Rushmere attack *
+r1bq1rk1/ppp3pp/2n5/1B1p1p2/1b2p3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Bardeleben variation *
+r1bq1rk1/pppn1pb1/3p3p/3Pp1pn/2P1P2P/2N2NB1/PP2BPP1/R2QK2R b KQ -
+King's Indian: Petrosian system, Keres variation
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, main line
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, classical variation
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, classical variation, 8.e4
+r1bq1rk1/pppn1ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Bernstein variation *
+r1bq1rk1/pppnbBpp/3p1n2/4p1N1/3PP3/2N5/PPP2PPP/R1BQK2R b KQ -
+Philidor: Nimzovich, L\"arobok variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/1QN1PN2/PP3PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rauzer variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QGD: Orthodox defense, 7.Rc1
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Orthodox defense
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Orthodox defense, Rubinstein variation
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2NBPN2/PP3PPP/R2QK2R b KQ -
+QGD: Orthodox defense, Botvinnik variation
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Catalan: closed, 6...Nbd7
+r1bq1rk1/pppnbppp/4pn2/3p4/2PP4/5NP1/PPQ1PPBP/RNB2RK1 b - -
+Catalan: closed, 7.Qc2
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P1P1/2N2P2/PP2B2P/R1BQNRK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, main line
+r1bq1rk1/pppnppbp/3p1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto with ...Nd7
+r1bq1rk1/pppnppbp/5np1/6N1/2BP4/1QN1P3/PP3PPP/R1B1K2R b KQ -
+Gr\"unfeld: Pachman variation
+r1bq1rk1/pppp1ppp/1bn2n2/1B2p3/3PP3/2P2N2/PP3PPP/RNBQ1RK1 w - -
+Ruy Lopez: classical defense, Benelux variation
+r1bq1rk1/pppp1ppp/2B2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Nimzovich (Paulsen) variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2P3/1b1P1P2/2N5/PPP3PP/R1BQ1RK1 w - -
+Four knights: Bardeleben variation
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 b - -
+Four knights: double Ruy Lopez
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2b2N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Nimzovich (Paulsen) variation *
+r1bq1rk1/pppp1ppp/2n2n2/1B2p3/4P3/2bP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights
+r1bq1rk1/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQ -
+Four knights: Rubinstein counter-gambit, Henneberger variation *
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/2BPP3/2P5/P4PPP/RNBQ1RK1 b - -
+Evans gambit: Richardson attack
+r1bq1rk1/pppp1ppp/2n2n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Knorre variation *
+r1bq1rk1/pppp1ppp/2n5/1B1P4/1b2p3/5N2/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Gunsberg counter-attack
+r1bq1rk1/pppp1ppp/2n5/3Np3/1bB1n3/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Marshall variation *
+r1bq1rk1/pppp1ppp/5n2/1B2P3/1b1p4/2N5/PPPP1PPP/R1BQ1RK1 b - -
+Four knights: Gunsberg counter-attack *
+r1bq1rk1/pppp1ppp/5n2/1Bb1N3/3nP3/2N5/PPPP1PPP/R1BQ1RK1 w - -
+Four knights: Marshall variation
+r1bq1rk1/pppp1ppp/5n2/4n1N1/1bB5/8/PB3PPP/RN1Q1RK1 w - -
+Scotch gambit: Hanneken variation
+r1bq1rk1/pppp2pp/2n2n2/2b1pPP1/8/2N5/PPPP1P1P/R1BQKBNR w KQ -
+Vienna: Hamppe-Muzio gambit *
+r1bq2k1/pp3p1p/5n2/2b1r1p1/3p4/3P1B2/PPP1NPPP/R1BQK2R w KQ -
+Giuoco Piano: M\"oller, bayonet attack *
+r1bq3r/pp3pkp/2n2np1/4p3/2Pp4/3P1NP1/4PPBP/RN1Q1RK1 w - -
+Benk\"o gambit: main line *
+r1bq3r/ppp2k1p/2n3p1/2Qp4/3pP3/8/PPP2PPP/RNB1K2R w KQ -
+Scotch gambit: Cochrane-Shumov defense
+r1bq3r/ppp3pp/5k2/3pN3/1n1Pn3/1Q3P2/PP4PP/RN2K2R b KQ -
+Giuoco Piano: Krause variation
+r1bqk1nr/1ppp1ppp/p1n5/2b1p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Classical defense deferred
+r1bqk1nr/1ppp1ppp/p1n5/4p3/Bb2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense deferred
+r1bqk1nr/1ppp1ppp/pbn5/4p3/PPB1P3/2N2N2/2PP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Showalter variation
+r1bqk1nr/2pp1ppp/p1n5/1pb1p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Graz variation
+r1bqk1nr/5ppp/p1pbp3/2pp4/2P5/2N1PN2/PP1P1PPP/R1BQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, main line *
+r1bqk1nr/5ppp/p1pbp3/2pp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3, Botvinnik system *
+r1bqk1nr/p1pp1ppp/2n5/bp2p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Leonhardt variation
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: exchange, classical variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/1P2P3/P2N1PPP/RNBQKB1R b KQkq -
+French: Tarrasch, Botvinnik variation *
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqk1nr/pp1nbppp/2pp4/4P3/2B1P3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Steiner variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p2P2/2B1P3/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+Sicilian: Grand Prix attack, Schofman variation
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk1nr/pp1p1pbp/2n3p1/1Bp1p3/1P2P3/5N2/P1PP1PPP/RNBQR1K1 b kq -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical, Botvinnik system reversed
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Botvinnik system *
+r1bqk1nr/pp1p1pbp/4p1p1/2p5/3nP3/3PB1P1/PPP1NPBP/R2QK1NR b KQkq -
+Sicilian: closed, Smyslov variation
+r1bqk1nr/pp1p1ppp/2n5/2b5/2pNp3/3PP3/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation *
+r1bqk1nr/pp1pppbp/2N3p1/8/8/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+English: ultra-symmetrical variation *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: ultra-symmetrical variation
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/2NPB3/PPP2PPP/R2QKBNR b KQkq -
+English, Tr\"oger defense *
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Rubinstein system *
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/4B3/PP3PPP/RN1QKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3
+r1bqk1nr/pp1pppbp/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7
+r1bqk1nr/pp1pppbp/2n3p1/8/8/1N4P1/PPP1PP1P/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld, Czech defense *
+r1bqk1nr/pp2b1pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, 6.Be2 *
+r1bqk1nr/pp2b3/2n5/2p1pppp/2P5/2NPPNP1/PP4BP/R1BQ1RK1 w kq -
+King's Indian: Six pawns attack *
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Be2 *
+r1bqk1nr/pp2ppbp/2n3p1/2pp4/5P2/2PP1N2/PPQ1P1PP/RNB1KB1R b KQkq -
+Dutch: Hort-Antoshin system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+English: closed system (without ...d6) *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+English: closed system *
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+Sicilian: closed
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+Sicilian: closed, 6.Be3
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4PP2/2NP2P1/PPP3BP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP1NPBP/R1BQK2R w KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik)
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+English: Botvinnik system *
+r1bqk1nr/pp3pbp/2np2p1/2p1p3/4PP2/2NP2P1/PPP3BP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik)
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5 *
+r1bqk1nr/pp3ppp/2nbp3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 *
+r1bqk1nr/pp3ppp/2nbp3/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: Dus-Khotimirsky variation *
+r1bqk1nr/pp3ppp/8/1Pb1p3/1nPp4/3P1N2/4PPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack *
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Taimanov variation *
+r1bqk1nr/ppp1bp1p/2n5/3pp1p1/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Chinese variation *
+r1bqk1nr/ppp1bpp1/2n5/3pp2p/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: bayonet (Mariotti) attack *
+r1bqk1nr/ppp1bppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc defense *
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Kotov variation
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+English: Botvinnik system
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+Sicilian: closed *
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/ppp2ppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 b kq -
+Evans gambit: Ulvestad variation
+r1bqk1nr/ppp2ppp/1b1p4/n5B1/2BPP3/2N2N2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: G\"oring attack
+r1bqk1nr/ppp2ppp/1bnp4/4p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Lasker defense
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/2N2N2/P4PPP/R1BQ1RK1 b kq -
+Evans gambit: Morphy attack
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: normal variation
+r1bqk1nr/ppp2ppp/1bnp4/8/2BPP3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: LaBourdonnais variation
+r1bqk1nr/ppp2ppp/2n1p3/8/3Pp3/P1N5/1PP2PPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit, Kan variation
+r1bqk1nr/ppp2ppp/2n5/2bpp3/1PB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans counter-gambit
+r1bqk1nr/ppp2ppp/2n5/2bpp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Holmov system *
+r1bqk1nr/ppp2ppp/2nb4/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Swiss variation *
+r1bqk1nr/ppp2ppp/2np4/b3p1B1/2BPP3/2P2N2/P4PPP/RN1QK2R b KQkq -
+Evans gambit: Sokolsky variation
+r1bqk1nr/ppp2ppp/2np4/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 w kq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/1QP2N2/P4PPP/RNB1K2R b KQkq -
+Evans gambit: Tartakower attack
+r1bqk1nr/ppp2ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/ppp2ppp/2np4/b7/2BpP3/1QP2N2/P4PPP/RNB2RK1 b kq -
+Evans gambit: Waller attack
+r1bqk1nr/ppp2ppp/3b4/3pn3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Alekhine gambit *
+r1bqk1nr/ppp2ppp/8/2bp4/8/2P2P2/PP3PPP/RNBQKB1R w KQkq -
+Caro-Kann: Forg\'acs variation *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.f4 e5 (Botvinnik) *
+r1bqk1nr/ppp3bp/2np2p1/4pp2/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.f4 *
+r1bqk1nr/ppp3pp/1b1p1p2/n7/2BPP3/2N1BN2/P4PPP/R2Q1RK1 b kq -
+Evans gambit: Steinitz variation
+r1bqk1nr/ppp3pp/2n5/2bppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation *
+r1bqk1nr/pppn1ppp/3p4/2b1p3/4PP2/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+KGD: classical, Hanham variation
+r1bqk1nr/pppp1Bpp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Jerome gambit
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+English: closed, 5.Rb1
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: closed system
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+English: closed system (without ...d6)
+r1bqk1nr/pppp1ppp/1bn5/1B2p3/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical defense, Charousek variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/1PB1P3/5N2/PBPP1PPP/RN1QK2R b KQkq -
+Evans gambit declined, Cordel variation
+r1bqk1nr/pppp1ppp/1bn5/4p3/PPB1P3/5N2/2PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined, 5.a4
+r1bqk1nr/pppp1ppp/2n5/1B2p3/1b2P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Alapin's defense
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: classical defense, 4.c3
+r1bqk1nr/pppp1ppp/2n5/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: classical (Cordel) defense
+r1bqk1nr/pppp1ppp/2n5/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+Evans gambit declined
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Giuoco Pianissimo
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna game *
+r1bqk1nr/pppp1ppp/2n5/2b3N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch game
+r1bqk1nr/pppp1ppp/2n5/2b5/4P3/1N6/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Potter variation
+r1bqk1nr/pppp1ppp/2n5/4p3/1bB1P3/5N2/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/1N6/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Romanishin variation
+r1bqk1nr/pppp1ppp/2n5/8/1b2P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Scotch: G\"oring gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bB1P3/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/8/1bBpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit
+r1bqk1nr/pppp1ppp/2n5/b3P3/2B5/2P2N2/P4PPP/RNBQK2R b KQkq -
+Scotch gambit: Cochrane variation
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQ1RK1 b kq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b3p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit
+r1bqk1nr/pppp1ppp/2n5/b7/2B1P3/2p2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: compromised defense
+r1bqk1nr/pppp1ppp/2nb4/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Stone-Ware variation
+r1bqk1nr/pppp1ppp/8/1Bb1p3/1P1nP3/5N2/P1PP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: classical defense, Zaitsev variation
+r1bqk1nr/pppp2pp/2n5/1Bb1pp2/4P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cordel gambit
+r1bqk1nr/pppp2pp/2n5/1Bb2P2/4p3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+KGA: bishop's gambit, Paulsen attack *
+r1bqk1nr/pppp2pp/2n5/2b1p1N1/2B1Pp2/3P4/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo: Dubois variation
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Jaenisch variation *
+r1bqk1nr/pppp2pp/2n5/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KGA: bishop's gambit, Bogolyubov variation *
+r1bqk1nr/ppppbppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Lucena defense
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: 5...Be7
+r1bqk1nr/ppppbppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Hungarian defense
+r1bqk1nr/ppppbppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Romanishin variation
+r1bqk1nr/ppppbppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Benima defense
+r1bqk1nr/ppppbppp/2n5/8/4P3/2P1Q3/PP3PPP/RNB1KBNR w KQkq -
+Center game: Charousek variation
+r1bqk1nr/ppppbppp/8/n3p3/2BPP3/2P2N2/P4PPP/RNBQK2R w KQkq -
+Evans gambit: Cordel variation
+r1bqk2r/1p1p1ppp/p1n1pn2/8/1bPNP3/2N5/PPB2PPP/R1BQK2R b KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: closed, Averbach variation
+r1bqk2r/1pp1bppp/p5n1/3pn3/8/2N1PN2/PPP1BPPP/R1BQ1RK1 b kq -
+French: Winawer, Alekhine gambit, Alatortsev variation *
+r1bqk2r/1ppn1p1p/p4b1Q/1B6/8/2N2N2/PP1P1PPP/n1BK3R w kq -
+Scotch: Berger variation *
+r1bqk2r/1ppp1ppp/p1n2n2/2b1p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: M\"oller defense
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Exchange variation doubly deferred (DERLD)
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, center attack
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed defense
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: Worrall attack
+r1bqk2r/1pppbppp/p1n5/4P3/B2pn3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: closed, Basque gambit (North Spanish variation)
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/3PP3/1B3N2/PPP2PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed, 7...d6, 8.d4
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPPQPPP/RNB2RK1 w kq -
+Ruy Lopez: Worrall attack, solid line
+r1bqk2r/2pp1ppp/2n2n2/ppb1p3/4P3/PBN5/1PPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Showalter variation *
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+Ruy Lopez: closed
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Wing attack
+r1bqk2r/4bppp/p2p1n2/1pp5/3QP3/1B6/PPP2PPP/RNB1R1K1 w kq -
+Ruy Lopez: Noah's ark trap
+r1bqk2r/4nppp/p1pb4/2ppp3/2P5/1PN1P3/P2P1PPP/R1BQNRK1 b kq -
+Nimzo-Indian: S\"amisch, Capablanca variation *
+r1bqk2r/5ppp/p1n1pn2/1pb1P3/2B5/5N2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, Furman variation
+r1bqk2r/p1ppbppp/2p5/4Pn2/8/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Cordel variation
+r1bqk2r/p3nppp/2p5/2bpp3/2P5/6P1/PP2PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Spassky variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/1P4P1/P1P1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's lesser variation *
+r1bqk2r/p3nppp/2p5/2bpp3/8/2N3P1/PPP1PPBP/R1BQ1RK1 b kq -
+Gr\"unfeld: exchange, Simagin's improved variation *
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+Nimzo-Indian: e3, H\"ubner variation *
+r1bqk2r/pnppbppp/2p5/4P3/2P5/5N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Zukertort variation
+r1bqk2r/pnppbppp/2p5/4P3/3N4/8/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Winawer attack
+r1bqk2r/pnppbppp/2p5/4P3/8/1P3N2/P1P1QPPP/RNB2RK1 b kq -
+Ruy Lopez: Berlin defense, Pillsbury variation
+r1bqk2r/pp1n1ppp/2p1pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Romih variation
+r1bqk2r/pp1n1ppp/2pbpn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Chigorin defense
+r1bqk2r/pp1n1ppp/3bpn2/2pp4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav: Semmering variation *
+r1bqk2r/pp1n1ppp/3bpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD: Stonewall variation *
+r1bqk2r/pp1nbppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Bogolyubov variation
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/1NN1P3/PP3PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Leningrad variation *
+r1bqk2r/pp1nnppp/3b4/3p4/3Pp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, closed variation, main line *
+r1bqk2r/pp1p1ppp/2n1p3/2P5/1bP5/1QN2N2/PP1nPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation
+r1bqk2r/pp1p1ppp/2n1p3/2n5/1bP5/1QN2N2/PP1BPPPP/R3KB1R w KQkq -
+Nimzo-Indian: Spielmann, San Remo variation
+r1bqk2r/pp1p1ppp/2n1pn2/2P5/1bP5/1QN5/PP2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: Spielmann, 4...c5, 5.dc Nc6
+r1bqk2r/pp1p1ppp/2nNpn2/8/1b2P3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov, American attack
+r1bqk2r/pp1p1ppp/2nb1n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+English: Queens Indian, Romanishin variation *
+r1bqk2r/pp1p2pp/2n1p3/2n2p2/1bP5/2N2NP1/PPQBPP1P/R3KB1R b KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2PN/PPP2PBP/R1BQK2R b KQkq -
+English: closed, Taimanov variation *
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NPB1P1/PPP2PBP/R2QK1NR b KQkq -
+English: closed, Hort variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+English: symmetrical, Botvinnik system reversed *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: symmetrical variation
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical variation *
+r1bqk2r/pp1pppbp/2n2np1/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/6P1/PPP2PBP/RNBQK2R b KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation *
+r1bqk2r/pp1pppbp/2n3p1/8/2PNP1n1/2N1B3/PP3PPP/R2QKB1R w KQkq -
+Sicilian: accelerated fianchetto, Breyer variation
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack *
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, Florentine gambit *
+r1bqk2r/pp2b1pp/2n2n2/2pppp2/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, with Be2 and Nf3 *
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+Benoni: four pawns attack, main line *
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: Symmetrical, Keres defense
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Petrosian system *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+King's Indian: Petrosian system, main line *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/4p3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Andersson variation *
+r1bqk2r/pp2bppp/2n2n2/2p1p3/P2pP3/3P1NP1/1PP2PBP/RNBQ1RK1 b kq -
+King's Indian: Petrosian system, Stein variation *
+r1bqk2r/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: classical variation *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: 6.Be2 *
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/N2P1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: Kazakh variation *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical without 9.O-O *
+r1bqk2r/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7
+r1bqk2r/pp2bppp/2nppn2/8/2BNP3/2N1B3/PPP1QPPP/R3K2R b KQkq -
+Sicilian: Velimirovi\'c attack
+r1bqk2r/pp2bppp/2nppn2/8/3NPP2/2N1BQ2/PPP3PP/R3KB1R b KQkq -
+Sicilian: Scheveningen, Tal variation
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Pomar system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: fianchetto, Yugoslav system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: anti-Queen's Indian system *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nc6 *
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+King's Indian: fianchetto with ...Nd7 *
+r1bqk2r/pp2ppbp/2n2np1/3p2B1/2PP4/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Tarrasch, Wagner variation *
+r1bqk2r/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+QGD: Tarrasch, Prague variation, 7...Be7 *
+r1bqk2r/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: fianchetto variation *
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPP1BPPP/R2Q1RK1 b kq -
+Sicilian: dragon, classical, 8.O-O
+r1bqk2r/pp2ppbp/2np1np1/8/3NP3/2N1B3/PPPQBPPP/R3K2R b KQkq -
+Sicilian: dragon, classical, Amsterdam variation
+r1bqk2r/pp2ppbp/2np1np1/8/4P3/1NN1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical, Nottingham variation
+r1bqk2r/pp2ppbp/2np2pn/8/2P1P3/8/PPN1BPPP/RNBQK2R w KQkq -
+Sicilian: accelerated fianchetto, Simagin variation
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran variation *
+r1bqk2r/pp3ppp/2n1pn2/2bp4/8/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 7.Bc4 *
+r1bqk2r/pp3ppp/2n2n2/1Bb1p3/8/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Scotch: G\"oring gambit, Bardeleben variation *
+r1bqk2r/pp3ppp/2n2n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Greco's attack *
+r1bqk2r/pp3ppp/2nb1n2/1P1pp3/8/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Pir\'c variation *
+r1bqk2r/pp3ppp/2nb1n2/3p4/1PP1p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, old main line *
+r1bqk2r/pp3ppp/2nb1n2/3pp3/1PP5/P3PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran *
+r1bqk2r/pp3ppp/2nb1n2/4p3/1PPp4/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Reynolds' variation *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...c5 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/1P2PN2/P1P2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3, main line with ...b6 *
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/2P1PN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Romih variation *
+r1bqk2r/pp3ppp/2nbpn2/1P1p4/8/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation) *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 6.Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQK2R b KQkq -
+QGD semi-Slav: Bogolyubov variation *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/2PBPN2/PP1N1PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Chigorin defense *
+r1bqk2r/pp3ppp/2nbpn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with e3 & Bd3 *
+r1bqk2r/pp3ppp/2nbpn2/2ppN3/3P1P2/2P1P3/PP4PP/RNBQKB1R b KQkq -
+QGD semi-Slav: stonewall defense *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/2P1PN2/PB1N1PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Meran, Wade variation *
+r1bqk2r/pp3ppp/2nbpn2/3p4/1P6/P1P1PN2/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, 8...a6 *
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch, 7.Bd3 *
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+Nimzo-Indian: e3, H\"ubner variation
+r1bqk2r/pp3ppp/3b1n2/3P2N1/1n2p3/P3P3/3N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Rabinovich variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2N3/P3PN2/5PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Meran, Sozin variation *
+r1bqk2r/pp3ppp/3b1n2/3P4/1n2p3/P3PN2/3N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation *
+r1bqk2r/ppb2ppp/2n5/1Bpnp3/8/P1N1PN2/1P1P1PPP/R1BQK2R w KQkq -
+Sicilian: Kan, Mar\'oczy bind - Bronstein variation *
+r1bqk2r/ppp1bpp1/5n1p/3P4/2P1p3/5N2/PPP1QPPP/RNB1K2R w KQkq -
+two knights defense: Mar\'oczy variation
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/2NP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3 *
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical system, 5.Be2 *
+r1bqk2r/ppp1bppp/2n5/1B1pp3/3Pn3/5N2/PPP1QPPP/RNB2RK1 w kq -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation
+r1bqk2r/ppp1bppp/2n5/3np3/4P3/2NP1N2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Boleslavsky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: classical *
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: modern Scheveningen *
+r1bqk2r/ppp1bppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.Be2 *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Opo\v censky variation *
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation *
+r1bqk2r/ppp1bppp/2n5/3p4/2PPn3/3B1N2/PP3PPP/RNBQ1RK1 b kq -
+Petrov: classical attack, Jaenisch variation
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Chigorin variation
+r1bqk2r/ppp1bppp/2n5/4p3/4P3/2nP1N2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Boleslavsky, Louma variation *
+r1bqk2r/ppp1npbp/2np2p1/4p3/2P1P3/2NP2P1/PP3PBP/R1BQK1NR b KQkq -
+Sicilian: closed, 6.Ne2 e5 (Botvinnik) *
+r1bqk2r/ppp1nppp/1b1p4/n2P4/2B1P3/5N2/PB3PPP/RN1Q1RK1 w kq -
+Evans gambit: Paulsen variation
+r1bqk2r/ppp1nppp/3p1b2/3P4/2B1R1P1/5N2/PP3P1P/R1BQ2K1 b kq -
+Giuoco Piano: M\"oller, bayonet attack
+r1bqk2r/ppp2pbp/2np2pn/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Taimanov variation
+r1bqk2r/ppp2pp1/5n1p/2bP4/2P1p3/8/PPPNQPPP/RNB1K2R b KQkq -
+two knights defense: Yankovich variation
+r1bqk2r/ppp2ppp/1bn5/3np3/1P6/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Sozin with ...a6 and ...b5 *
+r1bqk2r/ppp2ppp/2n1pn2/3p4/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Botvinnik variation
+r1bqk2r/ppp2ppp/2n2n2/2bpP3/2Bp4/2P2N2/PP3PPP/RNBQK2R w KQkq d6
+Giuoco Piano
+r1bqk2r/ppp2ppp/2n2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Schlechter variation *
+r1bqk2r/ppp2ppp/2n2n2/3pp3/4P3/2bP1N2/PPPB1PPP/R2QKB1R w KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack *
+r1bqk2r/ppp2ppp/2n5/1B1pP3/1b1Pn3/5N2/PP3PPP/RNBQK2R w KQkq -
+Giuoco Piano: Anderssen variation
+r1bqk2r/ppp2ppp/2n5/2b5/4p3/2PP1NP1/P3PP1P/R1BQKB1R w KQkq -
+Sicilian: Magnus Smith trap *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/1QNP1N2/PP2PPPP/R1B1KB1R b KQkq -
+Sicilian: Sozin, Benk\"o variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, not Scheveningen *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Sozin, Leonhardt variation *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Sozin attack *
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Lipnitzky attack *
+r1bqk2r/ppp2ppp/2n5/3np1N1/1bBP4/8/PPP2PPP/RNBQK2R w KQkq -
+two knights defense: Pincus variation
+r1bqk2r/ppp2ppp/2n5/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Venice attack *
+r1bqk2r/ppp2ppp/2n5/3np3/1b6/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation *
+r1bqk2r/ppp2ppp/2n5/3p4/2BP4/1Qb2N2/P4PPP/R1B2RK1 w kq -
+Giuoco Piano: Bernstein variation
+r1bqk2r/ppp2ppp/2n5/3p4/2BPn3/B1P2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Steinitz variation
+r1bqk2r/ppp2ppp/2n5/3pp3/2PPn3/P3P3/1PQ2PPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, San Remo variation
+r1bqk2r/ppp2ppp/2n5/3pp3/4P1n1/3P1N2/PPPNBbPP/R1BQ1RK1 w kq -
+Philidor: Nimzovich, L\"arobok variation *
+r1bqk2r/ppp2ppp/2nb4/1B1np3/4P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin, Jaffe variation *
+r1bqk2r/ppp2ppp/2np1n2/2b1p1B1/2B1P3/2NP1N2/PPP2PPP/R2QK2R b KQkq -
+Giuoco Pianissimo: Canal variation
+r1bqk2r/ppp2ppp/2np1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Italian four knights variation *
+r1bqk2r/ppp2ppp/2np1n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Romanovsky variation *
+r1bqk2r/ppp2ppp/2nppn2/8/1bPP4/2N2N2/PPQ1PPPP/R1B1KB1R w KQkq -
+Nimzo-Indian: classical, Milner-Barry (Zurich) variation
+r1bqk2r/ppp2ppp/3p1n2/4p1B1/2BnP3/8/PPP2PPP/RN1Q1RK1 w kq -
+Giuoco piano
+r1bqk2r/ppp3p1/2n5/2bppPPp/4n2P/7B/PPPP1P1R/RNBQK1N1 w Qkq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation *
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Bd3 *
+r1bqk2r/pppn1ppp/4pn2/3p2B1/1bPP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Manhattan variation
+r1bqk2r/pppn1ppp/5n2/2bP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, Eliskases variation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3P4/2N1PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Reversed Philidor formation *
+r1bqk2r/pppnbppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Inverted Hanham *
+r1bqk2r/pppp1p2/5n1p/4p1p1/2BnPP1B/8/PPP3PP/RN1Q1RK1 b kq -
+Giuoco piano: Rosentreter variation
+r1bqk2r/pppp1pbp/2n3pn/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR w Kkq -
+English: closed, 5.Rb1 Taimanov variation
+r1bqk2r/pppp1pp1/5n1p/4n3/2PN3B/2P5/P3PPPP/R2QKB1R w KQkq -
+English: Nenarokov variation
+r1bqk2r/pppp1ppp/1b5n/nP2N3/2B1P3/8/P1PP1PPP/RNBQK2R w KQkq -
+Evans gambit declined, Lange variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation
+r1bqk2r/pppp1ppp/2n1pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...Nc6
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: double Ruy Lopez *
+r1bqk2r/pppp1ppp/2n2n2/1B2p3/1b2P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: double Ruy Lopez
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Spanish, classical defense
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/3PBN2/PPP2PPP/RN1QK2R b KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation
+r1bqk2r/pppp1ppp/2n2n2/1Bb1p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Beverwijk variation
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense *
+r1bqk2r/pppp1ppp/2n2n2/2b1N3/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Boden-Kieseritsky gambit *
+r1bqk2r/pppp1ppp/2n2n2/2b1P3/2Bp4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p1N1/2B1P3/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Wilkes Barre (Traxler) variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/1PB1P3/2P2N2/P2P1PPP/RNBQK2R b KQkq -
+Giuoco Piano: Bird's attack
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano: four knights variation *
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo: Italian four knights variation
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Giuoco Pianissimo
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2B1PP2/2P5/PP1PQ1PP/RNB1K1NR b KQkq -
+Bishop's opening: Lopez gambit
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Italian variation *
+r1bqk2r/pppp1ppp/2n2n2/2b5/2BPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Rubinstein counter-gambit *
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Schlechter variation
+r1bqk2r/pppp1ppp/2n2n2/4N3/1b1PP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, Krause variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Spanish variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N3P1/PPPPNP1P/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Ruy Lopez: Schliemann defense, Berger variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish, classical defense *
+r1bqk2r/pppp1ppp/2n2n2/4p3/2P5/2b1PN2/PPQP1PPP/R1B1KB1R w KQkq -
+English: four knights, Romanishin variation
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange, Keres variation *
+r1bqk2r/pppp1ppp/2n2n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Four knights: Ranken variation *
+r1bqk2r/pppp1ppp/2n2n2/8/1bB1P3/2N2N2/PP3PPP/R1BQK2R w KQkq -
+Scotch: G\"oring gambit, Bardeleben variation
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/2N2N2/PP3PPP/R1BQK2R b KQkq -
+Giuoco Piano: Greco's attack
+r1bqk2r/pppp1ppp/2n2n2/8/1bBPP3/5N2/PP3PPP/RNBQ1K1R b kq -
+Giuoco Piano: Cracow variation
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: four knights (Tarrasch) variation *
+r1bqk2r/pppp1ppp/2n2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation *
+r1bqk2r/pppp1ppp/2n4n/2b3NQ/2BpP3/8/PPP2PPP/RNB1K2R b KQkq -
+Scotch gambit: Vitzhum attack
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+two knights: Max Lange attack, Krause variation
+r1bqk2r/pppp1ppp/2n5/2b1P3/2Bp2n1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+two knights: Max Lange attack, Steinitz variation
+r1bqk2r/pppp1ppp/2n5/2bBP3/8/2p2NK1/PP4PP/RNBQ3R b kq -
+Giuoco Piano: Ghulam Kassim variation
+r1bqk2r/pppp1ppp/2n5/2bPp3/4n3/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+Ponziani: Fraser defense
+r1bqk2r/pppp1ppp/2n5/3P4/2B1n3/2b2N2/PP3PPP/R1BQ1RK1 b kq -
+Giuoco Piano: M\"oller (Therkatz) attack
+r1bqk2r/pppp1ppp/2n5/3np3/1b2P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation *
+r1bqk2r/pppp1ppp/2n5/8/1bBP4/2n2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano: Greco variation
+r1bqk2r/pppp1ppp/2n5/8/2BP4/B1b2N2/P4PPP/R2Q1RK1 b kq -
+Giuoco Piano: Aitken variation
+r1bqk2r/pppp1ppp/2n5/8/2BPn3/2b2N2/PP3PPP/R1BQ1RK1 w kq -
+Giuoco Piano
+r1bqk2r/pppp2pp/2n2n2/1Bb1pQ2/4P3/8/PPPP1PPP/RNB1K1NR w KQkq -
+KGD: Norwalde variation, B\"ucker gambit *
+r1bqk2r/pppp2pp/2n2n2/2b1p3/2P2p2/2N1P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: Grand Prix attack, Schofman variation *
+r1bqk2r/pppp2pp/2n2n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: MacDonnell gambit *
+r1bqk2r/pppp2pp/2n5/3Npp2/1b2n3/5N2/PPPPQPPP/R1B1KB1R w KQkq -
+Four knights: Rubinstein counter-gambit, Bogolyubov variation *
+r1bqk2r/ppppbppp/2n2n2/3Np3/4P3/5N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2 *
+r1bqk2r/ppppbppp/2n5/1B2P3/4n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Minckwitz variation
+r1bqk2r/ppppbppp/2n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open Berlin defense, 5...Be7
+r1bqk2r/ppppbppp/2n5/4P3/2Bpn3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Hungarian defense: Tartakower variation
+r1bqk2r/ppppbppp/2nn4/4N2Q/8/1BN5/PPPP1PPP/R1B1K2R b KQkq -
+Vienna: Alekhine variation
+r1bqk3/ppp3p1/2n5/2bppP2/4n1P1/2PP4/PP3P2/RNBQK1NB w KQq -
+KGA: Greco gambit *
+r1bqkb1r/1p1n1ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen, classical, Nd7 system
+r1bqkb1r/1p1ppppp/p1n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Marini variation *
+r1bqkb1r/1p2nppp/p1n1p3/2pp4/3P4/3BPN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: Simagin variation *
+r1bqkb1r/1p2pp1p/2n3p1/p1np4/4PB2/2P2N2/PPQN1PPP/R3KB1R b KQkq -
+QGD Slav: Carlsbad variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp2B1/8/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Steiner variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: Czech defense *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: Soultanb\'eieff variation *
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav accepted: Alapin variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P1PN2/PP3PPP/RN1QKB1R b KQkq -
+QGD Slav: Wiesbaden variation *
+r1bqkb1r/1p2pppp/2n5/p1Pp4/4nB2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Krause attack *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: Dutch variation *
+r1bqkb1r/1p3ppp/2n1pn2/p1Pp4/5B2/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Dutch, Lasker variation *
+r1bqkb1r/1p3ppp/2n2n2/p1Ppp1B1/8/N1P2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: Smyslov variation *
+r1bqkb1r/1p3ppp/p1n1pn2/3p4/2P1P3/N1N5/PP3PPP/R1BQKB1R w KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6
+r1bqkb1r/1pp1nppp/p1B5/3pP3/8/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer, Alekhine gambit *
+r1bqkb1r/1pp2ppp/2P2n2/1p6/3Pp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Rauzer variation *
+r1bqkb1r/1pp2ppp/p1n5/3pP3/8/2N1P3/PPP2PPP/R1BQK1NR b KQkq -
+French: Winawer, Alekhine gambit, Kan variation *
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B1P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Morphy defense, Duras variation
+r1bqkb1r/1pp2ppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred (Russian defense)
+r1bqkb1r/1ppn1ppp/p3pn2/8/3P4/6P1/PPQ1PPBP/RNB1K1NR b KQkq -
+Catalan: open, Alekhine variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Ranken variation
+r1bqkb1r/1ppp1ppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred)
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Gunsberg variation *
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: four knights (Tarrasch) variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Anderssen variation
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: 5.O-O
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Morphy defense
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPPQPPP/RNB1K2R b KQkq -
+Ruy Lopez: Wormald (Alapin) attack
+r1bqkb1r/1ppp1ppp/p1n5/1B2p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, Rosenthal variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 6.d4
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Knorre variation
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open (Tarrasch) defense
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPPQPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Tartakower variation
+r1bqkb1r/1ppp1ppp/p1n5/8/B2pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Riga variation
+r1bqkb1r/1pppnppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense deferred
+r1bqkb1r/2p1nppp/p7/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Zukertort variation
+r1bqkb1r/2p2ppp/p1n5/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 8.de
+r1bqkb1r/2p2ppp/p1n5/1p1pp3/2PPn3/1B3N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Harksen gambit
+r1bqkb1r/2p2ppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: ...b5 & ...d6
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, positional main line *
+r1bqkb1r/2p2ppp/p1pp4/4p3/3Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation
+r1bqkb1r/2p2ppp/p7/1p1p4/P2pn3/1BN5/1PP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Berger variation
+r1bqkb1r/2p2ppp/p7/1p1pp3/P2nn3/1B3N2/1PP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Schlechter defense
+r1bqkb1r/2p3pp/p1p5/3pPp2/4n3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation
+r1bqkb1r/2pp1ppp/p1n5/1p1Pp3/B3n3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Richter variation
+r1bqkb1r/2pp1ppp/p1n5/1p2N3/B2Pn3/8/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, Friess attack
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/3Pn3/1B3N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 7.Bb3
+r1bqkb1r/2pp1ppp/p1n5/1p2p3/B2Pn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 6.d4 b5
+r1bqkb1r/3n1ppp/p1p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, 8...a6
+r1bqkb1r/3n1ppp/p1p1pn2/8/1p1PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Pir\'c variation
+r1bqkb1r/3n1ppp/p3p3/1N2P3/3p2n1/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Rabinovich variation
+r1bqkb1r/3n1ppp/p3pn2/1N2P3/3p4/3B1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Blumenfeld variation
+r1bqkb1r/3n1ppp/p3pn2/1pp1P3/3P4/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, old main line
+r1bqkb1r/3n1ppp/p3pn2/1pp5/3PP3/2NB1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran
+r1bqkb1r/3n1ppp/p3pn2/1ppP4/4P3/2NB1N2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: Meran, Reynolds' variation
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Sveshnikov variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B1Q2/PP3PPP/R1B1K2R b KQkq -
+QGD semi-Slav: Meran, Stahlberg variation
+r1bqkb1r/5ppp/4pn2/1p2N3/3p4/3B4/PP3PPP/R1BQ1RK1 b kq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Chelyabinsk variation
+r1bqkb1r/5ppp/p3pn2/1N2n3/3p4/3B1N2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Sozin variation
+r1bqkb1r/p1p2ppp/2n2n2/1p1Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Ulvestad variation
+r1bqkb1r/p1p2ppp/8/1p1np3/3nN3/2P5/PP1P1PPP/RNBQKB1R b KQkq -
+two knights defense: Fritz, Gruber variation
+r1bqkb1r/p1pn1ppp/1p2pn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Zukertort variation *
+r1bqkb1r/p1pp1ppp/2p2n2/4P3/8/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch: Mieses variation
+r1bqkb1r/p1pp1ppp/2p2n2/8/4P3/8/PPPN1PPP/R1BQKB1R b KQkq -
+Scotch: Tartakower variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N2Q2/PP3PPP/R3KB1R b KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation
+r1bqkb1r/p2n1p2/2p1pn2/1p2P1B1/2pP4/2N3P1/PP3P1P/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran variation
+r1bqkb1r/p2n1ppp/2p1pn2/8/1p1P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: neo-Meran (Lundin variation)
+r1bqkb1r/p3pp1p/2pp1np1/4P3/2B5/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Magnus Smith trap
+r1bqkb1r/p4pp1/2p2n1p/n3p1N1/8/8/PPPPBPPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/p4pp1/2p2n1p/n3p3/8/7N/PPPPBPPP/RNBQK2R b KQkq -
+two knights defense: Steinitz variation
+r1bqkb1r/p4ppp/2n1pn2/1ppp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Makogonov variation *
+r1bqkb1r/p4ppp/2p2n2/3pp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: modern exchange variation *
+r1bqkb1r/p4ppp/2p2n2/n3p1N1/8/8/PPPPBPPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/p4ppp/2p2n2/nB2p1N1/8/5Q2/PPPP1PPP/RNB1K2R b KQkq -
+two knights defense: Bogolyubov variation
+r1bqkb1r/p4ppp/5n2/np2p1N1/8/5Q2/PPPP1PPP/RNB1K2R w KQkq -
+two knights defense: Blackburne variation
+r1bqkb1r/pp1n1ppp/2n1p3/2PpP3/5P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+French: Steinitz variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P1P2/2N1BN2/PPP3PP/R2QKB1R b KQkq -
+French: Steinitz, Boleslavsky variation
+r1bqkb1r/pp1n1ppp/2n1p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, closed variation
+r1bqkb1r/pp1n1ppp/2n1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R b KQkq -
+French: Tarrasch, closed variation, main line
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: 5...c6
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQkq -
+QGD
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/4PN2/PP1N1PPP/R2QKB1R b KQkq -
+QGD: Capablanca variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PP4/P1N1P3/1P3PPP/R2QKBNR b KQkq -
+QGD: Capablanca anti-Cambridge Springs variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p2B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD: Alekhine variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: 5...Nd7
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2N1PN2/PPQ2PPP/R1B1KB1R b KQkq -
+QGD semi-Slav: Stoltz variation
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 6.Bd3
+r1bqkb1r/pp1n1ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD Slav
+r1bqkb1r/pp1n1ppp/2p1pn2/3pN3/2PP4/2N1P3/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system
+r1bqkb1r/pp1n1ppp/2p1pn2/8/2BP4/2N1PN2/PP3PPP/R1BQK2R b KQkq -
+QGD semi-Slav: 7.Bc4
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/2PP4/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD Slav: Semmering variation
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav *
+r1bqkb1r/pp1n1ppp/4pn2/2pp4/3P4/2P1PNP1/PP3P1P/RNBQKB1R b KQkq -
+QGD: Spielmann variation *
+r1bqkb1r/pp1npp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R w KQkq -
+Sicilian: dragon, Levenfish; Flohr variation
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Nimzovich (knight's tour) variation *
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: Nd2 variation *
+r1bqkb1r/pp1npppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Bogo-Indian defense, Gr\"unfeld variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+QGD: Albin counter-gambit, Janowski variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP1QPPP/R1B1KBNR b KQkq -
+QGD: Albin counter-gambit, Balogh variation *
+r1bqkb1r/pp1npppp/5n2/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, Alapin variation *
+r1bqkb1r/pp1npppp/5n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Breyer variation *
+r1bqkb1r/pp1p1Npp/2p1nn2/8/2B1P3/8/PPP2PPP/RNBQ1RK1 b kq -
+Scotch: Cochrane variation
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, 4.e3 *
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+English: symmetrical variation
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Nimzovich variation *
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation
+r1bqkb1r/pp1p1ppp/2n5/2ppP3/3P4/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit
+r1bqkb1r/pp1p1ppp/n1p2n2/8/2PNp3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+Sicilian: 2.c3, Heidenfeld variation *
+r1bqkb1r/pp1pnppp/2p2n2/1B2N3/4P3/3P4/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, kingside fianchetto *
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+English: Nimzo-English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p3B1/4P3/3P4/PPP2PPP/RN1QKBNR b KQkq -
+English, Smyslov defense *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: symmetrical, four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, four knights system
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: four knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+English: three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkb1r/pp1ppppp/2n2n2/2p5/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Queens Indian formation *
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, three knights system *
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/8/PPP1PPPP/RNBQKB1R w KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkb1r/pp1ppppp/2n5/2p1P3/1P4n1/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+English: Bellon gambit *
+r1bqkb1r/pp1ppppp/2n5/2pnP3/8/N1P2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: 2.c3, Heidenfeld variation
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system) *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2 *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: Reshevsky variation *
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/BP2PN2/P1PP1PPP/RN1QK2R b KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation *
+r1bqkb1r/pp2nppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Kramer system *
+r1bqkb1r/pp2pp1p/2n2np1/2Pp4/3P4/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation *
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Tarrasch, Prague variation *
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+Benk\"o gambit: fianchetto variation *
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/1QN1PN2/PP1P1PPP/R1B1KB1R b KQkq -
+English: symmetrical, Geller variation *
+r1bqkb1r/pp2pp1p/2np1np1/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation
+r1bqkb1r/pp2pp1p/3p1np1/8/2PQP3/2N5/PP3PPP/R1B1KB1R w KQkq -
+Sicilian: accelerated fianchetto, Gurgenidze variation
+r1bqkb1r/pp2pppp/2n2n2/1Bp1N3/2Pp4/4P3/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: three knights, Euwe variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bp5/2Pp4/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights, Korchnoi variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin variation *
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+QGD: Chigorin defense, Janowski variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav, Noteboom variation *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav accepted *
+r1bqkb1r/pp2pppp/2n2n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Semi-Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/1QP2N2/PP2PPPP/RNB1KB1R b KQkq -
+QGD Slav: S\"uchting variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+Gr\"unfeld: Three knights variation *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Old Indian: Ukrainian variation, 4.Nf3 *
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.Nc3 *
+r1bqkb1r/pp2pppp/2n2n2/2ppP3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Bradley Beach variation *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense *
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, 5.cd *
+r1bqkb1r/pp2pppp/2n2n2/3p4/3P1B2/2PB4/PP3PPP/RN1QK1NR b KQkq -
+Caro-Kann: exchange, Rubinstein variation
+r1bqkb1r/pp2pppp/2n2n2/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Benoni defense *
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: symmetrical variation *
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+English: four knights, Capablanca variation *
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer
+r1bqkb1r/pp2pppp/2np1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin, not Scheveningen
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: classical
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian
+r1bqkb1r/pp2pppp/5n2/n2P2B1/2p5/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense
+r1bqkb1r/pp3p1p/2n2np1/2Ppp3/3P4/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation *
+r1bqkb1r/pp3ppp/1nn1p3/3pP3/3P4/3B4/PP1NNPPP/R1BQK2R w KQkq -
+French: Tarrasch, Leningrad variation
+r1bqkb1r/pp3ppp/2Np1n2/4p3/4P3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky, Louma variation
+r1bqkb1r/pp3ppp/2Nppn2/6B1/4P3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Richter attack
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+QGD: Semi-Tarrasch, 7.Bd3
+r1bqkb1r/pp3ppp/2n1p3/2pp4/3Pn3/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: Rubinstein (anti-Meran) system *
+r1bqkb1r/pp3ppp/2n1p3/3p4/3PnB2/4P3/PP1N1PPP/RN1QKB1R b KQkq -
+QGD Slav: Amsterdam variation *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5 *
+r1bqkb1r/pp3ppp/2n1pn2/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5 *
+r1bqkb1r/pp3ppp/2n1pn2/2Pp4/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 5.e3 (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5...Nd7 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.e3 *
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/P1P1PN2/1P3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation) *
+r1bqkb1r/pp3ppp/2n1pn2/3p2B1/2PP4/2N5/PP3PPP/R2QKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PN4/4P3/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch with e3 *
+r1bqkb1r/pp3ppp/2n1pn2/3p4/3P1B2/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD Slav: exchange variation *
+r1bqkb1r/pp3ppp/2n2n2/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: G\"oring gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Pp4/1P2p3/2P2N2/P3PPPP/RNBQKB1R w KQkq -
+QGD Slav: Tolush-Geller gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: Slav gambit *
+r1bqkb1r/pp3ppp/2n2n2/2Ppp3/8/P4N2/1PP1PPPP/RNBQKB1R w KQkq -
+QGA, Bogolyubov variation *
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Prague variation
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+Old Indian: main line *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: 5.Nf3 *
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/Q1P5/3P2P1/PP2PPBP/RNB1K1NR b KQkq -
+Pterodactyl defense *
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: classical with e4 and Nf3 *
+r1bqkb1r/pp3ppp/2np1n2/4p3/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Boleslavsky variation
+r1bqkb1r/pp3ppp/2np1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Boleslavsky variation, 7.Nb3
+r1bqkb1r/pp3ppp/2nppn2/1B4B1/3NP3/2N5/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, 6...e6
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack
+r1bqkb1r/pp3ppp/2nppn2/6B1/3NP3/2NQ4/PPP2PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Keres variation
+r1bqkb1r/pp3ppp/2nppn2/6B1/4P3/1NN5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N1B3/PPP2PPP/R2QK2R b KQkq -
+Sicilian: Sozin, 7.Be3
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin, Leonhardt variation
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: modern Scheveningen
+r1bqkb1r/pp3ppp/n1n5/2p1p3/3P4/P1N1PN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian, Sz\'en variation, Dely-Kasparov gambit *
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+King's Indian: Four pawns attack, dynamic line *
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+Benoni: four pawns attack *
+r1bqkb1r/ppp1nppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit *
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/4B3/PP4PP/RN1QKBNR b KQkq -
+Alekhine's defense: four pawns attack, 7.Be3
+r1bqkb1r/ppp1pppp/1nn5/4P3/2PP4/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6
+r1bqkb1r/ppp2Npp/2n5/3np3/2B5/8/PPPP1PPP/RNBQK2R b KQkq -
+two knights defense: Fegatello attack
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, fianchetto variation *
+r1bqkb1r/ppp2p1p/2n3p1/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation *
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, Keres attack *
+r1bqkb1r/ppp2p1p/2n5/3p2p1/Q3nB2/2P2N2/PP2PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Gr\"unfeld variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3p2B1/Q7/5N2/PPP1PPPP/RN2KB1R w KQkq -
+Scandinavian defense, Lasker variation *
+r1bqkb1r/ppp2pp1/2n2n1p/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+Pirc: classical, h3 system *
+r1bqkb1r/ppp2pp1/2n4p/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Adams attack *
+r1bqkb1r/ppp2pp1/5nn1/3p3p/8/2P3BP/PP1NPPP1/R2QKBNR b KQkq -
+Caro-Kann: classical, 7...Nd7 *
+r1bqkb1r/ppp2pp1/5nn1/3p4/7p/2P3BP/PP1NPPP1/R2QKBNR w KQkq -
+Caro-Kann: classical, Spassky variation *
+r1bqkb1r/ppp2ppp/2Bp1n2/4p3/4P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/3PP3/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, Guimard main line
+r1bqkb1r/ppp2ppp/2n1pn2/3p4/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+French: Reversed Philidor formation
+r1bqkb1r/ppp2ppp/2n2n2/3Pp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Scotch, 4...exd4 *
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: exchange, Bogolyubov variation
+r1bqkb1r/ppp2ppp/2n2n2/3p2B1/Q3P3/8/PPP2PPP/RN2KBNR b KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q3P3/8/PPP2PPP/RNB1KBNR w KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system *
+r1bqkb1r/ppp2ppp/2n2n2/3p4/Q4B2/5N2/PPP1PPPP/RN2KB1R b KQkq -
+Scandinavian defense *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Scotch variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Improved Hanham variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4P3/3P1N2/PPPNBPPP/R1BQK2R b KQkq -
+Inverted Hanham
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/2PP2P1/PP2PPBP/RNBQK1NR b KQkq -
+Robatsch defense: two knights, Suttles variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+Pirc: classical (two knights) system *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: two knights variation *
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Leonhardt variation
+r1bqkb1r/ppp2ppp/2n5/1B1n4/4p3/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Sicilian: Pin, Koch variation *
+r1bqkb1r/ppp2ppp/2n5/1B1np3/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Pin variation (Sicilian counter-attack) *
+r1bqkb1r/ppp2ppp/2n5/1B1pp3/4n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Scotch, Krause variation *
+r1bqkb1r/ppp2ppp/2n5/1B2p3/8/2NnPN2/PP1P1PPP/R1BQK2R w KQkq -
+Sicilian: Taimanov, American attack *
+r1bqkb1r/ppp2ppp/2n5/3np1N1/2BP4/8/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Lolli attack
+r1bqkb1r/ppp2ppp/2n5/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Steinitz variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan (Lasker/Sveshnikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+Sicilian: Taimanov (Bastrikov) variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, modern variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+Sicilian: dragon variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Scheveningen variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P1N1P3/1P1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Taimanov variation *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf *
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Nc3 *
+r1bqkb1r/ppp2ppp/2n5/3p4/2Bpn3/2N2N2/PPP2PPP/R1BQR1K1 b kq -
+two knights defense: Canal variation
+r1bqkb1r/ppp2ppp/2n5/4P3/2BP2n1/4p3/PPP3PP/RNBQK1NR w KQkq -
+Philidor: Philidor counter-gambit, Berger variation *
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/2P1P3/3P1N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: Berlin defense, Duras variation
+r1bqkb1r/ppp2ppp/2np1n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, 4.O-O, d6
+r1bqkb1r/ppp2ppp/2np1n2/4p3/2P5/1PN1P3/P2P1PPP/R1BQKBNR w KQkq -
+Amsterdam attack
+r1bqkb1r/ppp2ppp/4pn2/4N3/3P4/8/PPP2PPP/R1BQKB1R b KQkq -
+French: Rubinstein, Capablanca line
+r1bqkb1r/ppp2ppp/5n2/3Pp1N1/2Bn4/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense: Fritz variation
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Belgrade gambit *
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Three knights: Steinitz, Rosenthal variation *
+r1bqkb1r/ppp2ppp/5n2/3p4/2PPp3/2N5/PP1P1PPP/R1BQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein; Rubinstein counter-gambit *
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2B1P3/PPP2PPP/RN1QKBNR b KQkq -
+French: Fort Knox variation *
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/3P4/PPP2PPP/RNBQK2R b KQkq -
+two knights defense: Kieseritsky variation
+r1bqkb1r/ppp2ppp/5n2/n2Pp1N1/2B5/8/PPPP1PPP/RNBQK2R w KQkq -
+two knights defense
+r1bqkb1r/ppp2ppp/5n2/nB1Pp1N1/8/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/ppp2ppp/6nn/3p4/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Flohr variation *
+r1bqkb1r/ppp2ppp/8/3p4/4n3/4PN2/PPP2PPP/R1BQKB1R w KQkq -
+French: Rubinstein, Capablanca line *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkb1r/ppp3pp/2n2n2/3p1p2/4p3/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.e5 *
+r1bqkb1r/ppp3pp/2n2n2/3p4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Euwe defense *
+r1bqkb1r/ppp3pp/2n2n2/3ppP2/6P1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Pierce gambit *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/2P5/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+Pirc: Austrian attack, dragon formation *
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Pirc: Austrian attack *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP1NPP1P/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish; Flohr variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, Levenfish variation *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, 6.f4 *
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.f4 *
+r1bqkb1r/ppp4p/3p1nN1/8/3np2Q/8/PPP2PPP/RNB1KB1R w KQkq -
+Vienna gambit, Wurzburger trap *
+r1bqkb1r/pppn1ppp/2np4/1B2p3/3PP3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Chigorin variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2NBP3/PP3PPP/R1BQK1NR b KQkq -
+Old Indian: Dus-Khotimirsky variation
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Old Indian: main line
+r1bqkb1r/pppn1ppp/3p1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Philidor: Improved Hanham variation
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR b KQkq -
+QGD
+r1bqkb1r/pppn1ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Nbd7
+r1bqkb1r/pppn1ppp/4pn2/8/2QP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+French: Tarrasch, open variation, main line *
+r1bqkb1r/pppn1ppp/5n2/3p4/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: exchange, S\"amisch variation
+r1bqkb1r/pppn1ppp/5n2/3pp3/3P4/2N1PN2/PPP2PPP/R1BQKB1R b KQkq -
+French: Tarrasch, Guimard main line *
+r1bqkb1r/pppn1ppp/5n2/4N3/4p3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Sokolsky variation *
+r1bqkb1r/pppn1ppp/8/4p3/8/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Tartakower variation *
+r1bqkb1r/pppp1ppp/2n1pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Kevitz variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Spanish variation
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, 4.O-O
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense
+r1bqkb1r/pppp1ppp/2n2n2/1B6/3pP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Berlin defense, Nyholm attack
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Belgrade gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/4P3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights: Schultze-M\"uller gambit
+r1bqkb1r/pppp1ppp/2n2n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Nimzovich attack *
+r1bqkb1r/pppp1ppp/2n2n2/4p1B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: two knights, 3...Bg4 *
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Italian variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/3P1N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense (Modern bishop's opening)
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, Nimzovich variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+English: four knights, 4.e3
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: four knights system
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+English: four knights, kingside fianchetto
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+English: four knights, Capablanca variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/P1N2N2/1P1PPPPP/R1BQKB1R b KQkq -
+English: four knights, Marini variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Two knights variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Four knights: Scotch variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/3PP3/5N2/PPP1BPPP/RNBQK2R b KQkq -
+Tayler opening
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Four knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights game
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Three knights: Steinitz variation *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: Jaenisch counter-attack
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov three knights game *
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Four knights: Gunsberg variation
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Three knights: Winawer defense (Gothic defense) *
+r1bqkb1r/pppp1ppp/2n2n2/6N1/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Two knights defense, Perreux variation
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Scotch gambit: Dubois-R\'eti defense
+r1bqkb1r/pppp1ppp/2n2n2/8/2PPp3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+English: Bradley Beach variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Schmidt variation
+r1bqkb1r/pppp1ppp/2n2n2/8/3pP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Four knights: Scotch, 4...exd4
+r1bqkb1r/pppp1ppp/2n2n2/8/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: Berger variation
+r1bqkb1r/pppp1ppp/2n5/1B2p3/4n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Berlin defense, open variation
+r1bqkb1r/pppp1ppp/2n5/2n1P3/3N4/8/PPP1QPPP/RNB1KB1R w KQkq -
+Petrov: modern attack, Bardeleben variation
+r1bqkb1r/pppp1ppp/2n5/4p3/4n3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Four knights: Schultze-M\"uller gambit *
+r1bqkb1r/pppp1ppp/2n5/8/2Bpn3/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Two knights defense
+r1bqkb1r/pppp1ppp/2nn4/1B2P3/8/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, l'Hermet variation
+r1bqkb1r/pppp1ppp/2nn4/4p2Q/3P4/1BN5/PPP2PPP/R1B1K1NR b KQkq -
+Vienna: Adams' gambit
+r1bqkb1r/pppp1ppp/2nn4/4p3/B2P4/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open Berlin defense, Showalter variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3NP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, exchange variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQ1RK1 b kq -
+Four knights: Rubinstein counter-gambit, Henneberger variation
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Three knights: Schlechter variation *
+r1bqkb1r/pppp1ppp/5n2/1B2p3/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Four knights: Rubinstein counter-gambit
+r1bqkb1r/pppp1ppp/5n2/4p3/3nP3/2N2N2/PPPPBPPP/R1BQK2R b KQkq -
+Four knights: Rubinstein counter-gambit, 5.Be2
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2N5/PPPP1P1P/R1BQKBNR w KQkq -
+Vienna: Hamppe-Allgaier gambit *
+r1bqkb1r/pppp2p1/2n5/4pPPp/6n1/2NP4/PPP2P1P/R1BQKBNR b KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation *
+r1bqkb1r/pppp2p1/2n5/4pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Blackburne gambit *
+r1bqkb1r/pppp2pp/2n2n2/4N3/3Pp3/8/PPP1BPPP/RNBQK2R b KQkq -
+Vienna gambit: Breyer variation *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Quaade gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkb1r/pppp2pp/2n2n2/4pp2/2B1P3/3P4/PPPN1PPP/R1BQK1NR b KQkq -
+KGD: classical, Hanham variation *
+r1bqkb1r/ppppnp1p/2n3p1/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Cozio defense, Paulsen variation
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Cozio defense
+r1bqkb1r/ppppnppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: chameleon variation *
+r1bqkb1r/ppppnppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani: R\'eti variation
+r1bqkb1r/ppppnppp/5n2/1B2p3/4P3/3P1N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation
+r1bqkb1r/ppppnppp/8/1B6/3pP3/8/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Bird's defense, Paulsen variation
+r1bqkb1r/pppppppp/2n2n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Kevitz-Trajkovich defense
+r1bqkbnr/1p1p1ppp/p1n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/1pp2ppp/p1n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, 5.a3 *
+r1bqkbnr/1pp2ppp/p1np4/4p3/B1P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Three knights variation
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: modern Steinitz defense, 5.O-O
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Keres variation
+r1bqkbnr/1pp2ppp/p1p5/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: exchange variation, 5.O-O
+r1bqkbnr/1pp3pp/p1np4/4pp2/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/2NP1N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: exchange, Romanovsky variation
+r1bqkbnr/1pp3pp/p1p2p2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: exchange, Gligori\'c variation
+r1bqkbnr/1ppp1p1p/p1n3p1/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto defense deferred
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez: exchange variation
+r1bqkbnr/1ppp1ppp/p1n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Mengarini variation *
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez
+r1bqkbnr/1ppp1ppp/p7/4p3/B2nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense deferred
+r1bqkbnr/1ppp2pp/p1n5/4pp2/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense deferred
+r1bqkbnr/1ppppppp/p1n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Battambang opening *
+r1bqkbnr/2p2ppp/2p5/p2p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+French: Winawer, advance, Smyslov variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R b KQkq -
+French: Winawer, advance, 6...Ne7 *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PPQ2PPP/RNB1K1NR b KQkq -
+French: Winawer, classical variation *
+r1bqkbnr/2p2ppp/p1pp4/4p3/3PP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation
+r1bqkbnr/2p2ppp/p1pp4/4p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation
+r1bqkbnr/2p3pp/p1pp1p2/4p3/3PP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation
+r1bqkbnr/2pp1ppp/p1n5/1p2p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Caro variation
+r1bqkbnr/2pp1ppp/p7/np2p3/4P3/1B3N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation
+r1bqkbnr/4p1pp/p1p2p2/3p4/2Pp4/4PN2/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN1P2/4P3/PP4PP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation *
+r1bqkbnr/4p1pp/p1p2p2/8/2pN4/4P3/PP3PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch, Keres variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/1P2PN2/P2P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p1p1p3/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+Nimzo-Indian: S\"amisch variation *
+r1bqkbnr/5ppp/p2p4/1pp5/3QP3/1B6/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: Noah's ark trap
+r1bqkbnr/6pp/p1p1pp2/3p4/2PN4/4P3/PP3PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: S\"amisch, Botvinnik variation *
+r1bqkbnr/p1pp1ppp/2n5/1p6/Q7/8/PPP1PPPP/RNB1KBNR w KQkq -
+Scandinavian, Mieses-Kotr\v c gambit *
+r1bqkbnr/p2p1ppp/1pn1p3/2p5/4P3/2NP1N2/PPP2PPP/R1BQKB1R b KQkq -
+Amsterdam attack *
+r1bqkbnr/p3pppp/2p5/2p5/2Pp1P2/6P1/PP1PP2P/RNBQK1NR b KQkq -
+Beefeater defense *
+r1bqkbnr/pp1n1ppp/2pp4/4p1N1/2BPP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Kmoch variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Philidor: Hanham, Schlechter variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Philidor: Hanham, Delmar variation
+r1bqkbnr/pp1n1ppp/2pp4/4p3/2BPP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+Philidor: Hanham, Krause variation
+r1bqkbnr/pp1npppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Steinitz variation
+r1bqkbnr/pp1p1p1p/2n3p1/2p1p3/2P4P/2NP4/PP2PPP1/R1BQKBNR b KQkq -
+Sicilian: Gloria variation *
+r1bqkbnr/pp1p1ppp/2n1p3/1N6/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Taimanov variation
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/2P5/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Mikenas-Carls, Sicilian variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2N1PN2/PPPP1PPP/R1BQKB1R b KQkq -
+English: Mikenas-Carls, Kevitz variation *
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls variation *
+r1bqkbnr/pp1p1ppp/2n5/2p5/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+English: Mikenas-Carls, Flohr variation *
+r1bqkbnr/pp1p1ppp/2n5/4p3/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation
+r1bqkbnr/pp1ppp1p/2N3p1/8/4P3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, exchange variation
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+English: Bremen, Smyslov system *
+r1bqkbnr/pp1ppp1p/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6)
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+English: Bremen, reverse dragon *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+English: Bremen system, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2PP4/PP3PPP/RNBQKBNR b KQkq -
+English, Keres variation *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+English: Carls' Bremen system *
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+English: Bremen system with ...g6 *
+r1bqkbnr/pp1ppp1p/2n3p1/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: accelerated fianchetto, modern variation
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6)
+r1bqkbnr/pp1ppppp/2n5/1Bp5/4P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+English, Kramnik-Shirov counterattack *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: symmetrical variation
+r1bqkbnr/pp1ppppp/2n5/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation *
+r1bqkbnr/pp1ppppp/2n5/2p5/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense *
+r1bqkbnr/pp1ppppp/2n5/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Sicilian: closed
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+English: Sicilian reversed *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Sicilian: closed, 2...Nc6
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Sicilian: chameleon variation
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Sicilian: Grand Prix attack
+r1bqkbnr/pp1ppppp/2n5/2p5/8/2NP2P1/PPP1PP1P/R1BQKBNR b KQkq -
+Venezolana opening
+r1bqkbnr/pp1ppppp/2n5/2p5/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+r1bqkbnr/pp1ppppp/2n5/8/7Q/2N5/PPP1PPPP/R1B1KBNR b KQkq -
+Novosibirsk opening
+r1bqkbnr/pp2p1pp/2n2p2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Kmoch variation *
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system *
+r1bqkbnr/pp2pp1p/2n5/2pp2p1/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Spike gambit *
+r1bqkbnr/pp2ppp1/2np4/2p4p/2P1P3/2N3P1/PP1P1P1P/R1BQKBNR w KQkq -
+Sicilian: Gloria variation
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/1P2P3/P1P2PPP/RNBQKBNR b KQkq -
+QGD: Alapin variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: semi-Slav *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+QGD: Charousek (Petrosian) variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+QGD: 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGD: 3...Nf6 *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/P3P3/1PP2PPP/RNBQKBNR b KQkq -
+QGD: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/3PP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+QGD Slav: Winawer counter-gambit *
+r1bqkbnr/pp2pppp/2n5/2pp4/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Old Indian: Ukrainian variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5B2/3P1N2/PPP1PPPP/RN1QKB1R b KQkq -
+Old Indian: Janowski variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch defense, Rubinstein variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & Nc3 *
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/6PN/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense: Bladel variation *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Modern defense *
+r1bqkbnr/pp2pppp/2n5/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian defense, 3.Nc3 *
+r1bqkbnr/pp2pppp/2n5/3P4/3p4/4P3/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit *
+r1bqkbnr/pp2pppp/2n5/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+QGD: Tarrasch defense, 4.cd ed *
+r1bqkbnr/pp2pppp/2n5/3p4/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: exchange variation *
+r1bqkbnr/pp2pppp/2n5/3p4/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich variation
+r1bqkbnr/pp2pppp/2n5/3p4/3p4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange variation *
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit: Zaitsev system *
+r1bqkbnr/pp2pppp/8/n2P4/1Pp5/8/P4PPP/RNBQKBNR b KQkq b3
+QGD: Tarrasch defense, Tarrasch gambit *
+r1bqkbnr/pp3p1p/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian with e4 & g3 *
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Makagonov system (5.h3) *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: 4.e3 c5 *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+Nimzo-Indian: Fischer variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/2N1PN2/PPPP1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: 4.e3, Taimanov variation *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+Nimzo-Indian: 4.e3 O-O *
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: 4.e3 *
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+French: advance, Paulsen attack
+r1bqkbnr/pp3ppp/2n1p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation
+r1bqkbnr/pp3ppp/2n5/2P1p3/1PPp4/5N2/P3PPPP/RNBQKB1R b KQkq -
+QGA: Linares variation *
+r1bqkbnr/pp3ppp/2n5/2Ppp3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense, Alekhine variation *
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1NP1/PP3P1P/RNBQKB1R b KQkq -
+Czech Benoni: King's Indian system *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6 *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+French: Tarrasch, open variation, main line
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6 *
+r1bqkbnr/pp3ppp/2n5/2ppp3/3P4/2P1P3/PP3PPP/RNBQKBNR w KQkq -
+QGD: semi-Slav, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/2ppp3/5P2/3P2P1/PPP1P1BP/RNBQK1NR b KQkq -
+Modern defense: Averbakh system, Randspringer variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+Modern defense: Averbakh system, Kotov variation *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Modern defense: Averbakh system *
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+King's Indian: 4.e4 *
+r1bqkbnr/pp3ppp/2n5/3p4/2pP4/2N2NP1/PP2PP1P/R1BQKB1R w KQkq -
+QGD: Tarrasch, Folkestone (Swedish) variation
+r1bqkbnr/pp3ppp/2n5/3p4/2pPP3/2N2NP1/PP3P1P/R1BQKB1R b KQkq -
+QGD: Tarrasch, Schlechter-Rubinstein system, Rey Ardid variation
+r1bqkbnr/pp3ppp/2n5/3pp3/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+QGD: Tarrasch defense, Marshall gambit *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Benoni: 6.e4 *
+r1bqkbnr/pp3ppp/2n5/4p3/2Pp4/B2P1N2/4PPPP/RN1QKB1R w KQkq -
+Benk\"o gambit: 7.e4 *
+r1bqkbnr/pp3ppp/2np4/1N2p3/4P3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, 5...O-O *
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: S\"amisch variation *
+r1bqkbnr/pp4pp/2n5/2pppp2/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Four pawns attack *
+r1bqkbnr/pp4pp/2n5/4pp2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: pawn storm variation *
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: Mikenas variation *
+r1bqkbnr/ppnppppp/2p5/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+de Bruycker defense
+r1bqkbnr/ppp1pp1p/2n5/3p2p1/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch, Spielmann gambit *
+r1bqkbnr/ppp1pp1p/2np2p1/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Venezolana opening *
+r1bqkbnr/ppp1pppp/2n5/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: Anti-Veresov *
+r1bqkbnr/ppp1pppp/2n5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Chigorin defense
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Chigorin variation
+r1bqkbnr/ppp1pppp/2n5/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Chigorin variation *
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense, Bogolyubov variation
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/3P2P1/PP2PP1P/RNBQKBNR b KQkq -
+Old Benoni: Schmid's system *
+r1bqkbnr/ppp1pppp/2n5/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Chigorin defense, Janowski variation
+r1bqkbnr/ppp1pppp/2n5/8/Q1Pp4/5N2/PP1PPPPP/RNB1KB1R b KQkq -
+Woozle defense *
+r1bqkbnr/ppp2p1p/2n3p1/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Sveshnikov system *
+r1bqkbnr/ppp2p1p/2n5/3pP1p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Tartakower variation *
+r1bqkbnr/ppp2p1p/2np4/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R w KQkq -
+Vienna: Hamppe-Allgaier gambit, Alapin variation
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, 6.h4 *
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Guimard variation
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, advance variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPPQ1PPP/RNB1K1NR b KQkq -
+French: Winawer, Petrosian variation *
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation *
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+French: Winawer (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp2ppp/2n5/3p4/3Q4/2N5/PPP1PPPP/R1B1KBNR w KQkq -
+KP: Nimzovich defense, Marshall gambit *
+r1bqkbnr/ppp2ppp/2n5/3p4/Q3P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Scandinavian: Anderssen counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pP3/8/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/1P1P4/2P5/P3PPPP/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze counter-attack *
+r1bqkbnr/ppp2ppp/2n5/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Marshall variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Bogolyubov variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P3P1/PP2PP1P/RNBQKBNR b KQkq -
+Caro-Kann: Gurgenidze system *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Paulsen variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Blackmar-Diemer: Lemberg counter-gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Fyfe gambit *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2P5/PPNPPPPP/R1BQKBNR b KQkq -
+de Bruycker defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/2PP1N2/PP2PPPP/RNBQKB1R b KQkq -
+Pirc: Ufimtsev-Pytel variation *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Pirc defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense *
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD: Albin counter-gambit, Alapin variation
+r1bqkbnr/ppp2ppp/2n5/4P3/2Pp4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit, 5.g3
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: old Steinitz defense
+r1bqkbnr/ppp2ppp/3p4/8/3QP3/3B4/PPP2PPP/RNB1K2R b KQkq -
+Scotch: Ghulam Kassim variation
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+Caro-Kann: Bronstein-Larsen variation *
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/3Q4/4P3/PPP2PPP/RNB1KBNR b KQkq -
+French: Frere (Becker) variation *
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+Caro-Kann: classical variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP1NPPPP/R1BQKBNR b KQkq -
+Caro-Kann: Steinitz variation *
+r1bqkbnr/ppp2ppp/8/3pn3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPPN1PPP/R1BQKBNR b KQkq -
+French: Rubinstein variation *
+r1bqkbnr/ppp3pp/2n2p2/3pP3/8/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Rasa-Studier gambit *
+r1bqkbnr/ppp3pp/2n2p2/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Steinitz variation
+r1bqkbnr/ppp3pp/2n2p2/4P3/2Pp4/5N2/PP1NPPPP/R1BQKB1R w KQkq -
+QGD: Albin counter-gambit, Janowski variation
+r1bqkbnr/ppp3pp/2n5/3p1p2/3Pp2P/2P3P1/PP2PPB1/RNBQK1NR b KQkq -
+Robatsch defense: Gurgenidze variation *
+r1bqkbnr/ppp3pp/2n5/3ppP2/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Steinitz gambit *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Austrian attack *
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Pseudo-Austrian attack *
+r1bqkbnr/ppp3pp/2n5/5p2/2pPp3/2N1P3/PP1N1PPP/R1BQKB1R b KQkq -
+French: Steinitz variation *
+r1bqkbnr/ppp3pp/2np4/3Ppp2/4P3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Ponziani counter-gambit, Schmidt attack
+r1bqkbnr/ppp3pp/2np4/4N3/3Pp3/8/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/ppp3pp/2np4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Vienna gambit, Steinitz variation *
+r1bqkbnr/ppp3pp/6n1/3p1p2/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+Caro-Kann: classical, Mar\'oczy attack *
+r1bqkbnr/pppn1ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Hanham variation
+r1bqkbnr/pppn1ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open, 4.ed ed *
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+French: Tarrasch, open variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P1P2/4P3/PPP3PP/RNBQKBNR b KQkq -
+French: Tarrasch, Haberditz variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/1QP5/PP2PPPP/RNB1KBNR b KQkq -
+Caro-Kann: Edinburgh variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+French: Tarrasch, Guimard variation *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: 3.Nd2 *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Tarrasch *
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Tarrasch, closed variation *
+r1bqkbnr/pppn2pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Keres variation *
+r1bqkbnr/pppnpppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Valencia opening *
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense
+r1bqkbnr/pppp1p1p/2n3p1/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+Three knights: Steinitz, Rosenthal variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: closed, Korchnoi variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Steinitz variation
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Paulsen variation *
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna: Paulsen-Mieses variation *
+r1bqkbnr/pppp1p1p/2n5/1B2p1p1/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Brentano defense
+r1bqkbnr/pppp1p1p/2n5/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Neumann defense
+r1bqkbnr/pppp1p1p/2n5/6N1/4PppP/2N5/PPPP2P1/R1BQKB1R b KQkq -
+Vienna: Hamppe-Allgaier gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Blachly gambit
+r1bqkbnr/pppp1p1p/2n5/6p1/3PPp2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+Vienna: Pierce gambit
+r1bqkbnr/pppp1p1p/2n5/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, Holloway defense
+r1bqkbnr/pppp1p1p/2n5/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQ1RK1 b kq -
+Vienna: Hamppe-Muzio gambit
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Ruy Lopez (Spanish opening)
+r1bqkbnr/pppp1ppp/2n5/1B6/3pP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch: Relfsson gambit (`MacLopez')
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/2P2N2/P2P1PPP/RNBQK2R w KQkq -
+Evans gambit: Mayet defense
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/2P1P3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Dresden opening
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: three knights system
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian: closed, 2...Nc6 *
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Sicilian reversed
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: closed *
+r1bqkbnr/pppp1ppp/2n5/4p3/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Scandinavian variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Vienna: Fyfe gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Scotch opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Three knights game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen variation
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game, Max Lange defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna game, Max Lange defense
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+Ponziani opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Vienna: Falkbeer variation *
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+King's pawn game
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5N2/PPPPBPPP/RNBQK2R b KQkq -
+Inverted Hungarian
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/5NP1/PPPP1P1P/RNBQKB1R b KQkq -
+Konstantinopolsky opening
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Vienna game *
+r1bqkbnr/pppp1ppp/2n5/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+r1bqkbnr/pppp1ppp/2n5/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+r1bqkbnr/pppp1ppp/2n5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Maurian defense
+r1bqkbnr/pppp1ppp/2n5/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Scotch gambit
+r1bqkbnr/pppp1ppp/2n5/8/2Q1P3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Hall variation
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Scotch game
+r1bqkbnr/pppp1ppp/2n5/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: S\"amisch attack *
+r1bqkbnr/pppp1ppp/2n5/8/3P4/4p3/PPPNPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Spielmann variation *
+r1bqkbnr/pppp1ppp/2n5/8/3PPp2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Vienna: Steinitz gambit
+r1bqkbnr/pppp1ppp/2n5/8/3QP3/8/PPP2PPP/RNB1KBNR w KQkq -
+Center game
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Scotch: G\"oring gambit
+r1bqkbnr/pppp1ppp/2n5/8/4P3/4Q3/PPP2PPP/RNB1KBNR b KQkq -
+Center game: Paulsen attack
+r1bqkbnr/pppp1ppp/2n5/8/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+Vienna gambit
+r1bqkbnr/pppp1ppp/2n5/8/8/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Scandinavian: Pytel-Wade variation *
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Bird's defense
+r1bqkbnr/pppp1ppp/8/4n3/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Irish (Chicago) gambit
+r1bqkbnr/pppp1ppp/8/4p3/3nP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Scotch: Lolli variation
+r1bqkbnr/pppp1ppp/8/nB2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Pollock defense
+r1bqkbnr/pppp2pp/2n2p2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Nuremberg variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Ruy Lopez: Schliemann defense, Berger variation
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Ruy Lopez: Schliemann defense
+r1bqkbnr/pppp2pp/2n5/4Np2/4P3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian: Fraser defense
+r1bqkbnr/pppp2pp/2n5/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Keres (Mason-Steinitz) gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Rousseau gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+r1bqkbnr/pppp2pp/2n5/4pp2/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Pelikan variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Milner-Barry variation *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Three knights: Winawer defense (Gothic defense)
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/2P2N2/PP1P1PPP/RNBQKB1R w KQkq -
+Ponziani counter-gambit
+r1bqkbnr/pppp2pp/2n5/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Vienna gambit *
+r1bqkbnr/pppp2pp/2n5/5p2/4P3/4Q3/PPP2PPP/RNB1KBNR w KQkq -
+Center game: l'Hermet variation
+r1bqkbnr/pppp3p/2n5/4Ppp1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird's opening, Swiss gambit *
+r1bqkbnr/ppppp1pp/2n2p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP: Neo-Mongoloid defense
+r1bqkbnr/ppppp1pp/2n5/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP: Colorado counter
+r1bqkbnr/pppppppp/2n5/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense
+r1bqkbnr/pppppppp/2n5/8/3PP3/2P5/P4PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense, Wheeler gambit
+r1bqkbnr/pppppppp/2n5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Dunst (Sleipner,Heinrichsen) opening *
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Nimzovich defense
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Dunst (Sleipner, Heinrichsen) opening *
+r1bqkbnr/pppppppp/n7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Lemming defense
+r1bqkbnr/pppppppp/n7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Durkin's attack *
+r1bqnrk1/p2p1ppp/1pn1p3/2p5/2PPP3/P1PB4/4NPPP/R1BQK2R w KQ -
+Nimzo-Indian: S\"amisch, Capablanca variation
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+King's Indian: orthodox, Aronin-Taimanov, main line *
+r1bqnrk1/pp2b2p/2n2p2/2p1p1p1/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, Benk\"o attack *
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+King's Indian: orthodox, Aronin-Taimanov, 9.Ne1 *
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+Benoni: fianchetto, 11...Re8
+r1bqr1k1/p1p2ppp/2pp1n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQ1RK1 w - -
+Four knights: Janowski variation *
+r1bqr1k1/pp1n1ppp/2p2n2/b2pp3/4P3/P1NP1N2/1PP1BPPP/R2QBRK1 b - -
+Ruy Lopez: Kecskem\'et variation *
+r1bqr1k1/pp1n1ppp/2pb1n2/3pN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Berger variation *
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+King's Indian: orthodox, 7...Nbd7, 8.Re1 *
+r1bqr1k1/pp2ppbp/2n2np1/2pp4/5P2/3PPN2/PPP1B1PP/RNB1QRK1 w - -
+Dutch: Ilyin-Genevsky, Winter variation *
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N2P2/PP1NB1PP/R1BQ1RK1 b - -
+Benoni: classical, 11.f3
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+Benoni: classical with ...Re8 and ...Na6
+r1bqr1k1/ppb2pp1/2p1nn1p/3pp3/NPP1P3/P2P1NP1/2QBBP1P/R3R1K1 b - -
+Ruy Lopez: closed, Chigorin, Yugoslav system *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin, 12...Nc6 *
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/1PP1P3/P2P1N2/1B1NBPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1PPpP1P1/P2P1N2/2Q1BP1P/RNB1K2R b KQ -
+Ruy Lopez: closed, Leonhardt variation *
+r1bqr1k1/ppbn1pp1/2p2n1p/4p3/1Pp1P3/P1NP1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, Rauzer attack *
+r1bqr1k1/ppbn1pp1/5n1p/3pp3/NP2P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+Ruy Lopez: closed, Chigorin, 12...c5d4 *
+r1bqr1k1/ppp2ppp/2n2n2/2bPN3/3P4/2N5/PPP2PPP/R1BQKB1R w KQ -
+two knights defense: Canal variation *
+r1bqr1k1/ppp2ppp/2n2n2/3pp3/1b2P3/2NP1N2/PPPBBPPP/R2Q1RK1 b - -
+Ruy Lopez: Berlin defense, Tarrasch trap *
+r1bqr1k1/ppp2ppp/2n2n2/4N3/3PpP2/P1P5/2P3PP/R1BQKB1R w KQ -
+Ruy Lopez: Steinitz defense deferred, Boleslavsky variation *
+r1bqr1k1/ppp2ppp/2np1n2/8/1bB1P3/2N1Q2N/PPPB1PPP/2KR3R b - -
+Center game: Kupreichik variation
+r1bqr1k1/ppp2ppp/8/2PPn3/2B2Qn1/2N1Bp2/PPP2PPP/R3K2R w KQ -
+two knights: Max Lange attack, Marshall variation *
+r1bqr1k1/ppp2ppp/8/2PPn3/5Qn1/2N1Bp2/PPP2PPP/R3KB1R b KQ -
+two knights: Max Lange attack, Rubinstein variation *
+r1bqr1k1/ppp2ppp/8/3pn3/3Q4/P1P1B3/1PP2PPP/R3KB1R b KQ -
+Four knights: Spielmann variation *
+r1bqr1k1/ppp4p/8/2PPnpp1/6n1/1BN1BpQ1/PPP2PPP/2KR3R b - -
+two knights: Max Lange attack, Berger variation *
+r1bqr1k1/pppn1pbp/3p1np1/4p3/2PP4/2N1PN2/PP2BPPP/R1BQ1RK1 w - -
+R\'eti: King's Indian attack, French variation *
+r1bqr1k1/pppp1ppp/2n2n2/3NpQ2/1bP5/4PN2/PP1P1PPP/R1B1KB1R b KQ -
+English: four knights, Stean variation
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+King's Indian: orthodox, 7...Nbd7, main line *
+r1bqrnk1/ppp1bppp/5n2/3p2B1/3P4/2NBP3/PPQ1NPPP/2KR3R b - -
+QGD: exchange, chameleon variation
+r1br2k1/p1q1ppbp/1pn2np1/2pp4/1P1P4/2P1PN2/PB1NBPPP/R2Q1RK1 b - -
+Catalan: closed, Spassky gambit *
+r1br2k1/p3ppbp/1pn2np1/2pq4/8/PP1PPN2/1B1NBPPP/R2QK2R b KQ -
+English: symmetrical, hedgehog, flexible formation *
+r1br2k1/p4ppp/1qn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Potter variation *
+r1br2k1/pp2qppp/1bn1pn2/3p4/1PP5/P2BPN2/1B1N1PPP/R2QK2R b KQ -
+QGA: classical, Smyslov variation *
+r1br2k1/ppq2ppp/2n1pn2/2P5/1P1p4/P3PN2/1BQ2PPP/R3KB1R b KQ -
+QGA: classical, Flohr variation *
+r1q2rk1/pp2ppbp/2npbnp1/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation
+r1r3k1/pp1bppbp/2np1np1/q7/3NP2P/1BN1BP2/PPPQ2P1/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 12.h4
+r2n1rk1/ppp1qppp/3p1n2/1B2p1B1/3PP1b1/2P2N2/P1P2PPP/R2QR1K1 w - -
+Four knights: symmetrical, Capablanca variation
+r2q1bnr/ppp1kBpp/3p4/3NN3/4P3/8/PP3PPP/R1Bb1RK1 b - -
+Scotch: Sea-cadet mate
+r2q1knr/pppb1Bpp/1b1p4/n7/3PP3/2N2N2/P1Q2PPP/R1B2RK1 b - -
+Evans gambit: Fraser-Mortimer attack
+r2q1rk1/1b1nbppp/p2p1n2/1pp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Breyer, Gligori\'c variation
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation)
+r2q1rk1/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP1NQPPP/R1B2RK1 b - -
+Ruy Lopez: open, Malkin variation
+r2q1rk1/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: closed, Bogolyubov variation
+r2q1rk1/2p1bppp/p1npbn2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Kholmov variation
+r2q1rk1/2p1bppp/p3b3/1p1pn3/3Nn3/1BP5/PP3PPP/RNBQR1K1 w - -
+Ruy Lopez: open, Breslau variation
+r2q1rk1/2p2ppp/p1n1b3/1pbpP3/8/2P2N2/PPBN1nPP/R1BQ1RK1 w - -
+Ruy Lopez: open, Dilworth variation
+r2q1rk1/3nbppp/bpp1pn2/p2p4/2PP4/1P3NP1/PBQNPPBP/R4RK1 w - -
+Catalan: closed, Sokolsky variation
+r2q1rk1/p1p2ppp/2pp1n2/4p3/1b2P1b1/2NP1N2/PPP1QPPP/R1B2RK1 b - -
+Four knights: symmetrical, Metger unpin *
+r2q1rk1/p3bppp/1pn1bn2/2pp2B1/3P4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Stoltz variation
+r2q1rk1/p3n1pp/2p1bp2/3pp1B1/N1P5/6P1/PP2PbBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Seville variation *
+r2q1rk1/p3n1pp/3bbp2/3pp3/N7/4B1P1/PP2PPBP/R2Q1RK1 b - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3 *
+r2q1rk1/p3n1pp/3bbp2/4p3/N2p4/4B1P1/PP2PPBP/R2Q1RK1 w - -
+Gr\"unfeld: exchange, Sokolsky variation *
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 10...cd, 11.cd *
+r2q1rk1/p4ppp/2n1bn2/2bpp3/N7/1B1P1P2/PPP3PP/R1BQK1NR w KQ -
+Evans gambit: Steinitz variation *
+r2q1rk1/p4ppp/2n2n2/2bpp3/N5b1/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: G\"oring attack *
+r2q1rk1/p4ppp/b1B2n2/2bp4/8/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Aitken variation *
+r2q1rk1/p4ppp/b1p2n2/2bpN3/3P4/2N5/PPP2PPP/R1BQK2R w KQ -
+Giuoco Piano: Steinitz variation *
+r2q1rk1/pb1nbppp/2p1pn2/1p1p4/2PP4/1PN2NP1/P1Q1PPBP/R1BR2K1 w - -
+Catalan: closed, Spassky gambit
+r2q1rk1/pp1bbppp/2nppn2/8/4PP2/1NN1B3/PPP1B1PP/R2Q1RK1 b - -
+Sicilian: modern Scheveningen, main line with Nb3
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/2KR3R b - -
+Sicilian: dragon, Yugoslav attack, 10.O-O-O
+r2q1rk1/pp1bppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R w KQ -
+Sicilian: dragon, Yugoslav attack, 9...Bd7
+r2q1rk1/pp2b1pp/2n1bn2/2pp4/4pB2/1NN1P3/PPPQBPPP/2KR3R b - -
+Alekhine's defense: four pawns attack, Tartakower variation *
+r2q1rk1/pp2bpp1/2n2n1p/2pp1b2/5B2/1NNP2P1/PP2PPBP/R2Q1RK1 w - -
+Alekhine's defense: exchange, Karpov variation *
+r2q1rk1/pp2bppp/2n1bn2/3p2B1/2pP4/2N2NP1/PP2PPBP/2RQ1RK1 w - -
+QGD: Tarrasch, Bogolyubov variation
+r2q1rk1/pp2bppp/2npbn2/2p3B1/4P3/2N2N2/PPP1BPPP/R2QR1K1 b - -
+Philidor: Berger variation
+r2q1rk1/pp2pBbp/6p1/n1p5/3PP1b1/2P1BP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Seville variation
+r2q1rk1/pp2ppbp/1nnp2p1/5b2/2PP1B2/2N2N1P/PP2BPP1/R2Q1RK1 b - -
+Alekhine's defense: exchange, Karpov variation
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+QGD: Tarrasch, Prague variation, 9.Bg5 *
+r2q1rk1/pp2ppbp/3p1np1/n4P2/2b1P3/1NNBB3/PPP3PP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Spielmann variation
+r2q1rk1/pp2ppbp/4b1p1/n2P4/4P3/3BBP2/P3N1PP/R2Q1RK1 b - -
+Gr\"unfeld: exchange, Sokolsky variation
+r2q1rk1/pp2ppbp/4b1p1/n7/3PP3/3BBP2/P3N1PP/R2Q1RK1 w - -
+Gr\"unfeld: Spassky variation, main line, 13.Bd3
+r2q1rk1/pp2ppbp/5np1/n2p1P2/4P3/1NNPB3/PP4PP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Bernard defense
+r2q1rk1/pp4pp/1nnpb3/4p3/N2P1p2/5NP1/PP2PPBP/R2Q1RK1 b - -
+Sicilian: dragon, classical, Bernard defense *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPBNP1/PP2PPBP/R1Q2RK1 b - -
+Sicilian: dragon, classical, R\'eti-Tartakower variation *
+r2q1rk1/ppp1b1pp/1nn1b3/4pp2/8/2NPPN2/PP1BBPPP/R2Q1RK1 w - -
+Sicilian: modern Scheveningen, main line with Nb3 *
+r2q1rk1/ppp1b1pp/2n1b3/3n1p2/4p3/1QNP1NP1/PP2PPBP/R1B2RK1 w - -
+Sicilian: dragon, classical, Zollner gambit *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w - -
+Sicilian: modern Scheveningen, main line *
+r2q1rk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R w KQ -
+Sicilian: Scheveningen, classical *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, 9.Nb3 *
+r2q1rk1/ppp1bppp/1nn1b3/4p3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b - -
+Sicilian: dragon, classical, Alekhine variation *
+r2q1rk1/ppp1bppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQ -
+Sicilian: dragon, classical, 8.O-O *
+r2q1rk1/ppp1ppbp/1nn3p1/8/3PP1b1/2NQBN2/PP2BPPP/2KR3R b - -
+Gr\"unfeld: Russian, Keres variation
+r2q1rk1/ppp1ppbp/2np1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, lesser Simagin (Spassky) variation
+r2q1rk1/ppp1ppbp/2np1np1/8/2PP2b1/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Simagin variation
+r2q1rk1/ppp2ppp/1bnp4/1B2p2n/3PP1b1/2PQ1N2/PP2NPPP/R1B2RK1 b - -
+Four knights: symmetrical, Blake variation *
+r2q1rk1/ppp2ppp/2n2n2/3pp3/1b2P1b1/2NP1N2/PPPBBPPP/R2QK2R w KQ -
+Ruy Lopez: closed Berlin defense, Bernstein variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/2NPBN2/PPP2PPP/R2Q1RK1 b - -
+Four knights: symmetrical, Tarrasch variation *
+r2q1rk1/ppp2ppp/2np1n2/1B2p3/1b2P1b1/3P1N2/PPP1NPPP/R1BQ1RK1 b - -
+Four knights: symmetrical, Pillsbury variation *
+r2q1rk1/ppp2ppp/2npbn2/1B2p1B1/1b2P3/2NP1N2/PPP2PPP/R2Q1RK1 w - -
+Four knights: symmetrical, Tarrasch variation
+r2q1rk1/ppp3pp/1nnbb3/2B1p3/N4p2/3P1NP1/PP2PPBP/R2Q1RK1 w - -
+Sicilian: dragon, classical, Spielmann variation *
+r2q1rk1/ppp3pp/2n5/2bNp3/4P1b1/5N2/PPP1QPPP/R1B1K2R w KQ -
+Giuoco piano: Holzhausen attack *
+r2q1rk1/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQR1K1 w - -
+Ruy Lopez: Berlin defense, Tarrasch trap
+r2q1rk1/pppnbppp/8/8/1n6/2N3Q1/PPPP1PPP/R1BK2NR b - -
+Scotch: Rosenthal variation *
+r2q2k1/pp3ppp/8/2b1r3/3p4/3P4/PPP1NPPn/R1BQ1RK1 w - -
+Giuoco Piano: Therkatz-Herzog variation *
+r2qbrk1/1pp1bppp/p1np1n2/4p3/B2PP3/2P2N2/PP1N1PPP/R1BQR1K1 w - -
+Ruy Lopez: Kecskem\'et variation
+r2qk1nr/pp2bppp/2n1b3/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Semi-Averbakh system *
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, main line *
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+King's Indian: Averbakh, 6...c5 *
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Averbakh system *
+r2qk1nr/pp4pp/2nbbp2/2ppp3/8/P1PP1NP1/1P2PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, Byrne variation *
+r2qk1nr/ppp1npbp/3pb1p1/3Np3/2P5/4P1P1/PP1P1PBP/R1BQK1NR w KQkq -
+Sicilian: closed, Smyslov variation *
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R w KQkq -
+English: closed, Hort variation
+r2qk1nr/ppp2pbp/2npb1p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR w KQkq -
+Sicilian: closed, 6.Be3 *
+r2qk1nr/ppp2ppp/1bnp4/8/2BPP1b1/2N2N2/P4PPP/R1BQ1RK1 w kq -
+Evans gambit
+r2qk1nr/ppp2ppp/1bnp4/8/Q1BPP1b1/2N2N2/P4PPP/R1B2RK1 b kq -
+Evans gambit: Fraser attack
+r2qk1nr/ppp2ppp/2nb4/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Tarrasch variation *
+r2qk1nr/ppp2ppp/2np4/2b5/2BpP1b1/2P2N2/PP3PPP/RNBQ1RK1 w kq -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack
+r2qk1nr/ppp2ppp/2np4/b3p3/2BPP1b1/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Alapin-Steinitz variation
+r2qk1nr/pppb1ppp/2nb4/1B1p4/2PQ4/4P3/PP3PPP/RNB1K1NR w KQkq -
+French: Winawer, Kondratiyev variation *
+r2qk1nr/pppb1ppp/2np4/b3p3/2BPP3/2P2N2/P4PPP/RNBQ1RK1 w kq -
+Evans gambit: Sanders-Alapin variation
+r2qk2r/1b1n1ppp/p2bpn2/1pp5/3P4/1BN1PN2/PP2QPPP/R1BR2K1 w kq -
+QGA: classical, Smyslov variation
+r2qk2r/1b1nbppp/pp1ppn2/8/2PQ4/1PN2NP1/P3PPBP/R1BR2K1 w kq -
+English: symmetrical, hedgehog, flexible formation
+r2qk2r/1bppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+Ruy Lopez: Trajkovi\'c counter-attack
+r2qk2r/1p1bbppp/p1nppn2/6B1/3NPP2/2N5/PPPQ2PP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 9...Be7
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/2P1n3/1B3N2/PP2QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack, Adam variation
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, classical defense
+r2qk2r/2p1bppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQR1K1 b kq -
+Ruy Lopez: open, 9...Be7, 10.Re1
+r2qk2r/2p1bppp/p1np1n2/1p2p3/3PP1b1/1BP2N2/PP2QPPP/RNB1K2R w KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation
+r2qk2r/2p1nppp/p3b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 w kq -
+Ruy Lopez: open, Motzko attack, Nenarokov variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, St. Petersburg variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Italian variation
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BPQ1N2/PP3PPP/RNB2RK1 b kq -
+Ruy Lopez: open, Motzko attack
+r2qk2r/3bbppp/p1nppB2/1p6/4PP2/2N2N2/PPPQ2PP/2KR1B1R b kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 11.Bxf6
+r2qk2r/p1pn1ppp/8/3pp3/Np2b1Q1/1B6/PPP2K1P/R1B3R1 w kq -
+Evans gambit declined, Pavlov variation *
+r2qk2r/pp1bppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1QK2R w KQkq -
+Queen's Indian: Opo\v censky variation *
+r2qk2r/pp2b1pp/2n1b3/2pnpp2/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+King's Indian: Four pawns attack, main line *
+r2qk2r/pp2bpp1/2n2nb1/2p1p2p/3pP1PN/3P3P/PPPN1PB1/R1BQ1RK1 w kq -
+King's Indian: Petrosian system, Keres variation *
+r2qk2r/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: Gligori\'c-Taimanov system *
+r2qk2r/pp3ppp/2n1pn2/3p1b2/1b1P1B2/1QN1PN2/PP3PPP/R3KB1R w KQkq -
+QGD Slav: exchange, Trifunovi\'c variation
+r2qk2r/pp3ppp/2nbp3/3p4/3Pn1b1/1P3N2/PBP1BPPP/RN1Q1RK1 w kq -
+QGD: Pillsbury attack *
+r2qk2r/pp3ppp/2nbpn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Botvinnik variation *
+r2qk2r/ppp1b1pp/2n5/3p1p2/2PPn1b1/3B1N2/PP3PPP/RNBQR1K1 b kq -
+Petrov: classical attack, Krause variation
+r2qk2r/ppp1b1pp/2n5/3p1p2/3Pn1b1/2PB1N2/PP1N1PPP/R1BQR1K1 b kq -
+Petrov: classical attack, Berger variation
+r2qk2r/ppp1bppp/1nn1b3/4p3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Nottingham variation *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, classical attack *
+r2qk2r/ppp1bppp/2n1b3/3np3/8/P1N1P3/1PQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qk2r/ppp2p1p/2n1bPp1/2b3N1/2pp4/8/PPP2PPP/RNBQR1K1 w kq -
+two knights: Max Lange attack, Loman defense
+r2qk2r/ppp2pPp/2n1b3/2b5/2pp4/5N2/PPP2PPP/RNBQR1K1 b kq -
+two knights: Max Lange attack, Schlechter variation
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+Sicilian: accelerated fianchetto, modern variation with Bc4 *
+r2qk2r/ppp2ppp/2n1b3/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Sozin, 7.Be3 *
+r2qk2r/ppp2ppp/2n5/3np3/1b4b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Margate (Alekhine) variation *
+r2qk2r/ppp2ppp/2np1n2/2b1p3/2B1P1b1/2NP1N2/PPP2PPP/R1BQK2R w KQkq -
+Giuoco Pianissimo: Canal variation *
+r2qk2r/ppp2ppp/2np1n2/2b5/2B1Pp2/2NP1Q1P/PPP3P1/R1B1K2R w KQkq -
+KGD: classical, Svenonius variation
+r2qk2r/ppp3pp/1bn1b3/3npp2/8/2NPPN2/PP2BPPP/R1BQ1RK1 w kq -
+Sicilian: Sozin, Fischer variation *
+r2qk2r/ppp3pp/2n5/3p1p2/2PPn1bb/3B1N2/PP3PPP/RNBQR1K1 w kq -
+Petrov: classical attack, Mar\'oczy variation
+r2qk2r/pppbbppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Showalter variation
+r2qk2r/pppbbppp/2np1n2/1B2p1B1/3PP3/2N2N2/PPP2PPP/R2Q1RK1 b kq -
+Ruy Lopez: closed Berlin defense, Bernstein variation
+r2qk2r/pppbbppp/2np1n2/1B2p3/3PP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: Berlin defense, hedgehog variation
+r2qkb1r/1bpp1ppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Archangelsk (counterthrust) variation
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/1QP1P3/P4PPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Junge variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/1P6/2P1P3/P3QPPP/RNB1K1NR b KQkq -
+QGD: semi-Slav, Koomen variation *
+r2qkb1r/1p1b1ppp/2n1pn2/pBPp4/PP6/2P1P3/5PPP/RNBQK1NR b KQkq -
+QGD: semi-Slav, Abrahams variation *
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 defense, 8...Bd7
+r2qkb1r/1p3ppp/p1npbn2/4p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Pelikan, Bird variation
+r2qkb1r/1ppbnppp/p1np4/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+Ruy Lopez: open, Howell attack
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, 8...Be6
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPPN1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+Ruy Lopez: open, 9.c3
+r2qkb1r/2p2ppp/p1n1b3/1pn1P1N1/3p4/1BP5/PP1N1PPP/R1BQ1RK1 b kq -
+Ruy Lopez: open, Bernstein variation, Karpov gambit
+r2qkb1r/2p2ppp/p1n1b3/1pnpP3/8/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+Ruy Lopez: open, Berlin variation
+r2qkb1r/2p2ppp/p1pp1n2/4p3/3PP1b1/5N2/PPP2PPP/RNBQ1RK1 w kq -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation
+r2qkb1r/p2b1ppp/5n2/1B1pp3/Q7/4P3/PP3PPP/RNB1K2R b KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation *
+r2qkb1r/p3pppp/2p5/2pn3b/4N3/5N1P/PPPP1PP1/R1BQK2R b KQkq -
+English: Nenarokov variation *
+r2qkb1r/p4ppp/2p1pn2/3p4/3p4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, main line *
+r2qkb1r/pb1n1ppp/2p1pn2/1p6/3P4/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: Meran, Wade variation
+r2qkb1r/pp1b1ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld: Opo\v censky variation *
+r2qkb1r/pp1bppp1/5n1p/1BpP4/4p3/2N5/PPP1QPPP/R3K1NR b KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation *
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation
+r2qkb1r/pp1bpppp/2np1n2/6B1/3NP3/2N5/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2
+r2qkb1r/pp1n1ppp/2n1p3/2Pp4/Q5b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Rubinstein variation *
+r2qkb1r/pp1n1ppp/4pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca variation *
+r2qkb1r/pp2n1pp/2n1bp2/2p1p3/3PP3/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox main line *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6 *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Ruban variation *
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, Panno formation *
+r2qkb1r/pp2pppp/2n2n2/1BPp4/6b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Ragozin, Vienna variation *
+r2qkb1r/pp2pppp/2n2n2/1Bpp3b/8/1P2PN1P/PBPP1PP1/RN1QK2R b KQkq -
+Queen's Indian: 4.Nc3, main line *
+r2qkb1r/pp2pppp/2n2n2/2Pp4/6b1/2P1PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD semi-Slav: 5.Bg5 dc *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+QGD: classical variation (5.Bf4) *
+r2qkb1r/pp2pppp/2n2n2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bf4 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation *
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Gr\"unfeld: 5.Bg5 *
+r2qkb1r/pp2pppp/2n2n2/2pp4/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: Smyslov system *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5 *
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P1B2/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD Slav: exchange variation, 6.Bf4 Bf5
+r2qkb1r/pp2pppp/2n2n2/3p1b2/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD: exchange, S\"amisch variation *
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+Benoni: Uhlmann variation *
+r2qkb1r/pp2pppp/2n2nb1/2pp4/6PN/1P2P2P/PBPP1P2/RN1QKB1R b KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation *
+r2qkb1r/pp2pppp/n1p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Dutch, Lasker variation
+r2qkb1r/pp2pppp/n1p2n2/8/P1pPP1b1/2N2N2/1P3PPP/R1BQKB1R w KQkq -
+QGD Slav: Smyslov variation
+r2qkb1r/pp3p1p/2n3p1/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Lilienthal variation *
+r2qkb1r/pp3ppp/2n1b3/2pnp1N1/8/2N3P1/PP1PPPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Breyer variation *
+r2qkb1r/pp3ppp/2n1bn2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Larsen variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Gr\"unfeld with Bf4 & e3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system *
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/4PN1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bh4 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN1P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Neo-orthodox variation *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QGD: 6.Nf3 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QGD: Orthodox defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4Pb1P/PPP1BPP1/RNBQ1RK1 w kq -
+QGD: Neo-orthodox variation, 7.Bxf6 *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense *
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P4/2P1Pb2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, Capablanca variation *
+r2qkb1r/pp3ppp/2n1pn2/2ppN2b/3P4/4P2P/PPP1BPP1/RNBQ1RK1 b kq -
+QGD: Lasker defense *
+r2qkb1r/pp3ppp/2n1pn2/3p3b/3N4/1P2P2P/P1P1BPP1/RNBQ1RK1 b kq -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5 *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2N2b1/2P1P3/PP1N1PPP/R1B1KB1R b KQkq -
+QGD: Cambridge Springs defense, Yugoslav variation *
+r2qkb1r/pp3ppp/2n1pn2/3p4/Q2p2b1/2P1PN2/PP1N1PPP/R1B1KB1R w KQkq -
+QGD: Cambridge Springs defense, 7.cd *
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/6b1/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran) *
+r2qkb1r/pp3ppp/2n2n2/2pp4/3P2b1/2N2NP1/PP2PPBP/R1BQK2R w KQkq -
+QGD: Tarrasch, Wagner variation
+r2qkb1r/pp3ppp/2n2n2/2ppp3/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Alekhine variation *
+r2qkb1r/pp3ppp/2n2n2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+King's Indian: Zinnowitz variation *
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+Benoni: classical, 8.Bg5 *
+r2qkb1r/pp3ppp/2n5/2Pp3P/1P2n3/2P1Pp1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: Ekstrom variation *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P1Np1n1/2P1P2P/P4P2/RNBQKB1R b KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system *
+r2qkb1r/pp3ppp/2n5/2Pp3b/1P2p1n1/2P1PN1P/P4P2/RNBQKB1R w KQkq -
+QGD semi-Slav: anti-Meran gambit *
+r2qkb1r/ppp1p1pp/1nn1p3/2P5/3P2b1/5N2/PP4PP/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation
+r2qkb1r/ppp2ppp/1nn5/4p3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Pod\v ebrady variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR w KQkq -
+Sicilian: Taimanov variation *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Sicilian: dragon, 6.Be3 *
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, Byrne (English) attack *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R b KQkq -
+Sicilian: Richter-Rauzer, Larsen variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1NP1/PP2PP1P/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Bondarevsky variation *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 6.Bg5 *
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, 6...e6 *
+r2qkb1r/ppp2ppp/2n5/4p3/6b1/2nPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Richter attack *
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+Sicilian: Pelikan, Chelyabinsk variation *
+r2qkb1r/ppp2ppp/n1n5/4p3/4P1b1/P1NPBN2/1P3PPP/R2QKB1R b KQkq -
+Sicilian: Pelikan, Bird variation *
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+Sicilian: Sveshnikov variation *
+r2qkb1r/ppp3pp/2n1bn2/3p1p2/2PPp3/2N1P3/PP1N1PPP/R1BQKB1R w KQkq -
+French: Steinitz, Boleslavsky variation *
+r2qkb1r/ppp3pp/2n1bn2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Pirc: Austrian attack, 6.Be3 *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 7...O-O *
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+Sicilian: dragon, Yugoslav attack *
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky variation *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+Sicilian: Najdorf, 7...Be7 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Najdorf, 7.f4 *
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+Sicilian: Najdorf, 7...Qb6 *
+r2qkb1r/pppb1ppp/2Bp1n2/4p3/3PP3/2N2N2/PPP2PPP/R1BQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, Nimzovich attack
+r2qkb1r/pppb1ppp/2n2n2/1B6/Q3p3/2N5/PPP2PPP/R1B1K1NR w KQkq -
+Scandinavian: Anderssen counter-attack orthodox attack *
+r2qkb1r/pppb1ppp/2np1n2/1B6/3pP3/2N2N2/PPP2PPP/R1BQ1RK1 w kq -
+Ruy Lopez: closed Berlin defense, Wolf variation
+r2qkb1r/pppn2p1/8/3pNbPp/3Pn3/8/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation *
+r2qkbnr/1p3ppp/p1n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Capablanca anti-Cambridge Springs variation *
+r2qkbnr/1pp2pp1/p1p5/4p2p/4P1b1/5N1P/PPPP1PP1/RNBQ1RK1 w kq -
+Ruy Lopez: exchange variation, Alapin gambit
+r2qkbnr/1pp3pp/p1np4/4pb2/B7/2P2N2/PP1P1PPP/RNBQ1RK1 b kq -
+Ruy Lopez: Siesta, Kopayev variation
+r2qkbnr/1ppb1p1p/p1np2p1/4p3/B2PP3/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation
+r2qkbnr/1ppb1ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R w KQkq -
+Ruy Lopez: modern Steinitz defense
+r2qkbnr/pp1b1ppp/2n1p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Euwe variation
+r2qkbnr/pp1nppp1/2p3bp/7P/3P4/5NN1/PPP2PP1/R1BQKB1R b KQkq -
+Caro-Kann: classical, Spassky variation
+r2qkbnr/pp1nppp1/2p3bp/8/3P3P/5NN1/PPP2PP1/R1BQKB1R w KQkq -
+Caro-Kann: classical, 7...Nd7
+r2qkbnr/pp2pppp/2n5/1Bp4b/1PPp4/4PN1P/P2P1PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit *
+r2qkbnr/pp2pppp/2n5/1Bp4b/2Pp4/3PPN1P/PP3PP1/RNBQK2R b KQkq -
+Nimzo-Indian: Leningrad, main line *
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+Nimzo-Indian: Leningrad variation *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: Harrwitz attack *
+r2qkbnr/pp2pppp/2n5/2pp1b2/3P4/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: 4.Bf4 *
+r2qkbnr/pp2pppp/2n5/2pp4/2PP2b1/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD: Been-Koomen variation *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QGD: 4.Bg5 Be7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: 4.Bg5 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R b KQkq -
+QGD: 4.Bg5 Nbd7 *
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/5NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Gr\"unfeld: Stockholm variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/1Q2PN2/PP3PPP/RNB1KB1R b KQkq -
+QGD: Canal (Venice) variation *
+r2qkbnr/pp2pppp/2n5/3p4/2Pp2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+QGD: exchange, positional line, 5...c6 *
+r2qkbnr/pp2pppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line *
+r2qkbnr/pp3ppp/2n1p3/1Bpp4/3P2b1/4PN2/PPPN1PPP/R1BQK2R b KQkq -
+QGD: Manhattan variation *
+r2qkbnr/pp3ppp/2n1p3/2pp1b2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+Gr\"unfeld: Gr\"unfeld gambit *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/2P1PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD: 5...c6 *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQ1RK1 b kq -
+QGD: 4.Bg5 Be7, 5.e3 O-O *
+r2qkbnr/pp3ppp/2n1p3/2pp4/3P2b1/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+QGD *
+r2qkbnr/pp3ppp/2n1p3/2ppN3/3P2b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+QGD: Lasker variation *
+r2qkbnr/pp3ppp/2n5/2P5/N2p2b1/5N2/PP2PPPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Herzog defense *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Reifir (Spielmann) variation *
+r2qkbnr/pp3ppp/2n5/2pp4/3P2b1/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, normal variation *
+r2qkbnr/pp3ppp/2n5/2pp4/Q2P2b1/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Caro-Kann: Panov-Botvinnik, Czerniak variation *
+r2qkbnr/pp3ppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+King's Indian: accelerated Averbakh system *
+r2qkbnr/pp3ppp/4p3/3p4/3Q4/6P1/PPb1PPBP/RNB2RK1 w kq -
+Gr\"unfeld: Gr\"unfeld gambit accepted *
+r2qkbnr/pp3ppp/8/3pn3/8/8/PPP1NPPP/RNBQK2R b KQkq -
+Bishop's opening: Lisitsyn variation
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/2PP1NP1/PP3PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox, 7.d5 c6 *
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+King's Indian: S\"amisch, orthodox, 7.d5 *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, orthodox variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+King's Indian: S\"amisch, double fianchetto variation *
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+King's Indian: S\"amisch, 6...Nc6 *
+r2qkbnr/ppp1p1pp/2n2p2/3p4/3P1Bb1/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Richter variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P1B2/5b2/PPP1PPPP/RN1QKB1R w KQkq -
+Richter-Veresov attack, Veresov variation *
+r2qkbnr/ppp1pppp/2n5/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Richter-Veresov attack *
+r2qkbnr/ppp2p1p/2P5/8/2BP1pb1/2N2p2/PPP3PP/R1BQ1RK1 b kq -
+Vienna: Pierce gambit, Rushmere attack
+r2qkbnr/ppp2pp1/2n5/3p3p/2PPp1b1/4P3/PP1NBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQ1RK1 b kq -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4P3/PPPNBPPP/RNBQK2R w KQkq -
+French: Albin-Alekhine-Ch\^atard attack *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/4PP2/PPPNB1PP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation *
+r2qkbnr/ppp2pp1/2n5/3p3p/3Pp1b1/P3P3/1PPNBPPP/RNBQK2R b KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation *
+r2qkbnr/ppp2pp1/2n5/3pP2p/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Alekhine variation *
+r2qkbnr/ppp2ppp/2n1b3/1B1p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Janowski variation *
+r2qkbnr/ppp2ppp/2n1b3/3p4/3Pp3/1P2P3/P1P1BPPP/RNBQK1NR b KQkq -
+French: classical, Frankfurt variation *
+r2qkbnr/ppp2ppp/2n1b3/3pp3/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+French: Henneberger variation *
+r2qkbnr/ppp2ppp/2n5/1B1p3b/3Pp3/4PN1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Bernstein variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3P2b1/4Pp1P/PPP2PP1/RNBQK2R w KQkq -
+French: MacCutcheon, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/1B1p4/3Pp1b1/4PN2/PPP2PPP/RNBQK2R w KQkq -
+French: MacCutcheon, advance variation *
+r2qkbnr/ppp2ppp/2n5/1B1pp3/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+French: MacCutcheon variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+French: exchange, Bogolyubov variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+French: exchange, Svenonius variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp1b1/4P3/PPP1BPPP/RNBQK1NR b KQkq -
+French: classical, Vistaneckis (Nimzovich) variation *
+r2qkbnr/ppp2ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R b KQkq -
+French: classical variation *
+r2qkbnr/ppp2ppp/2n5/3pN3/3Pp1b1/4P3/PPP1BPPP/RNBQK2R b KQkq -
+French: classical, Tartakower variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/1P3N2/P1PPP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Nimzovich variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/2P2N2/PP1PP1PP/RNBQKB1R b KQkq -
+Dutch: Staunton gambit, Chigorin variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+French: Burn variation *
+r2qkbnr/ppp2ppp/2n5/3pP3/6b1/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Staunton's line *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+French: classical *
+r2qkbnr/ppp2ppp/2n5/3pp3/3P4/4Pb2/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen variation *
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+Pirc: Byrne variation *
+r2qkbnr/ppp2ppp/2npb3/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English, Tr\"oger defense
+r2qkbnr/ppp2ppp/8/3p4/1n1Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Alapin variation *
+r2qkbnr/ppp3pp/2n2p2/3pP3/6b1/5NP1/PPPPP2P/RNBQKB1R w KQkq -
+Dutch: Staunton gambit, Lasker variation *
+r2qkbnr/ppp3pp/2n5/3p1p2/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Steinitz variation *
+r2qkbnr/pppb1ppp/2B5/3p4/3Pp3/4PN1P/PPP2PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+French: Winawer, advance, Bogolyubov variation *
+r2qkbnr/pppb1ppp/2n5/1B1p4/3Pp3/4P2P/PPPN1PP1/RNBQK2R b KQkq -
+French: MacCutcheon, Tartakower variation *
+r2qkbnr/pppb1ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR w KQkq -
+French: Winawer, fingerslip variation *
+r2qkbnr/pppb1ppp/2n5/3pp3/Q3P3/2P2N2/PP1P1PPP/RNB1KB1R w KQkq -
+Ponziani: Caro variation
+r2qkbnr/pppb1ppp/2np4/1B2p3/2PPP3/5N2/PP3PPP/RNBQK2R b KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation
+r2qkbnr/pppb2pp/2npP3/1B3p2/3p4/5N2/PPP2PPP/RNBQK2R b KQkq -
+KGD: Falkbeer, Morphy gambit *
+r2qkbnr/pppnpppp/8/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R w KQkq -
+R\'eti: King's Indian attack, Keres variation
+r2qr1k1/p1p2ppp/2p2n2/3pp1B1/1b2P1b1/3P1N2/PPP1QPPP/R2N1RK1 b - -
+Four knights: symmetrical, Capablanca variation *
+r2qr1k1/p1p2ppp/5n2/1p1P3b/Q5P1/2N1Bn1P/PPP1KP2/R4B1R w - -
+two knights defense: Yurdansky attack *
+r2qr1k1/ppp1bppp/2n2n2/4p3/2P3b1/2NPBN2/PP2BPPP/R2Q1RK1 w - -
+Philidor: Berger variation *
+r2r2k1/ppq2ppp/2n1pn2/2bp4/2P5/2N1PN1P/PP1BQPP1/R4RK1 b - -
+QGD: Lasker defense, Russian variation *
+r3k1nr/ppp1qppp/2n5/4P3/1bPp4/5N1P/PP1BPPP1/R2QKB1R w KQkq -
+QGD: Albin counter-gambit, Kr\'enosz variation
+r3k2r/p2q1ppp/5n2/3pp3/1b6/4P3/PP3PPP/RNBQ1RK1 w kq -
+QGD: Semi-Tarrasch, Kmoch variation *
+r3k2r/ppp1qppp/2n1b3/2bnp3/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Velimirovi\'c attack *
+r3k2r/ppp2ppp/2n1bP2/2b2qN1/2ppN3/8/PPP2PPP/R1BQR1K1 b kq -
+two knights: Max Lange attack, Marshall variation
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP1BPPBP/R2Q1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, 9...Bd7 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+Sicilian: dragon, Yugoslav attack, 9.Bc4 *
+r3k2r/pppq2pp/2n1bp2/2bnp3/P7/2NP1NP1/1P2PPBP/R1BQ1RK1 b kq -
+Sicilian: dragon, Yugoslav attack, Byrne variation *
+r3k2r/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQK2R w KQkq -
+Sicilian: dragon, classical, Amsterdam variation *
+r3k2r/ppq1ppbp/2N3p1/2pp4/6n1/1P2P3/PBPP1PPP/RN1Q1RK1 w kq -
+Bogo-Indian defense, Monticelli trap *
+r3kb1r/1b3ppp/p2ppn2/qpn1P1B1/3N4/1BN5/PPPQ1PPP/2KRR3 b kq -
+Sicilian: Najdorf, Ivkov variation
+r3kb1r/1bq2ppp/p3pn2/1p1P4/2p5/2N1PN2/PPQ2PPP/R1BR2K1 w kq -
+QGA: classical, Flohr variation
+r3kb1r/1pp2ppp/p1p1b3/3q4/3PN3/8/PPP2PPP/R1BQR1K1 w kq -
+Four knights: Spielmann variation
+r3kb1r/5ppp/b3pn2/1p1qN1B1/3p4/3B4/PP2QPPP/R4RK1 b kq -
+QGD semi-Slav: Meran, Rellstab attack
+r3kb1r/p4ppp/1qp1pn2/3p4/3P4/3Q3P/PPP2PP1/RNB2RK1 b kq -
+QGD: Lasker defense, Bernstein variation *
+r3kb1r/pp1Npppp/1qn2n2/1Bp5/2p5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, Karlsbad variation *
+r3kb1r/pp1b1ppp/nq2pn2/3p4/3P1B2/4PN2/PP3PPP/RNQ1KB1R w KQkq -
+QGD Slav: Landau variation *
+r3kb1r/pp1bpppp/1qn2n2/1Bp5/2N5/2N1P3/PP1P1PPP/R1BQK2R b KQkq -
+Nimzo-Indian: Spielmann, San Remo variation *
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+King's Indian: S\"amisch, Panno main line *
+r3kb1r/pp1qpppp/2np1n2/2p5/3PP3/2P2N2/PP3PPP/RNBQ1RK1 b kq -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit
+r3kb1r/pp2pppp/1qn2n2/2pp4/3P4/2P1PQ1P/PP3PP1/RNB1KB1R w KQkq -
+QGD/QGD semi-Slav: Hastings variation *
+r3kb1r/pp2pppp/2n2n2/2pq4/3P2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation *
+r3kb1r/pp2pppp/2n5/q1p5/1n1PP1b1/P4N2/1P3PPP/RNBQKB1R w KQkq -
+QGD: Semi-Tarrasch, Krause variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/2P5/6P1/PP1NPPBP/RN1Q1RK1 b kq -
+Gr\"unfeld defense: Smyslov, Yugoslav variation *
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+Gr\"unfeld defense: Smyslov, main line *
+r3kb1r/pp3ppp/1qn1pn2/1B1p1b2/3P1B2/2N1PN2/PP3PPP/R2QK2R b KQkq -
+QGD Slav: exchange, Trifunovi\'c variation *
+r3kb1r/pp3ppp/1qn1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rauzer variation *
+r3kb1r/pp3ppp/2n2q2/2Pp4/1P2p1b1/2P1PN2/P2N1P2/R1BQKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Szab\'o variation *
+r3kb1r/ppp1q1pp/2n5/3n4/1P2p1b1/P3PN2/2Q2PPP/RNB1KB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation *
+r3kb1r/ppp2ppp/2n1bP2/5qN1/2ppN3/8/PPP2PPP/R1BQR1K1 w kq -
+two knights: Max Lange attack, Rubinstein variation
+r3kb1r/ppp2ppp/2nq4/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Keres variation *
+r3kb1r/ppp3pp/2n1bq2/3npp2/8/2NPPN2/PP2BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen, Tal variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/6P1/P2PPN1P/1P2BP2/RNBQK2R b KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation *
+r3kb1r/ppp3pp/2n2q2/3npp1b/8/P2PPN1P/1PQ1BPP1/RNB1K2R b KQkq -
+Sicilian: Najdorf, Browne variation *
+r3kb1r/ppp3pp/2n2q2/3npp2/6b1/P2PPN2/1PQ1BPPP/RNB1K2R b KQkq -
+Sicilian: Najdorf variation *
+r3kb1r/pppq1ppp/2n1b3/3np3/8/P2PPN2/1P3PPP/RNBQKB1R w KQkq -
+Sicilian: Scheveningen, English variation *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NP1N2/PP1BPPPP/R2QKB1R w KQkq -
+Sicilian: Richter-Rauzer, Larsen variation, 7.Qd2 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQK2R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...Be7 *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP3PPP/R1BQKB1R w KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack *
+r3kb1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R b KQkq -
+Sicilian: Richter-Rauzer, Rauzer attack, 7...a6 *
+r3kb1r/ppq2ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, Rubinstein variation *
+r3kb1r/ppq2ppp/2n1pn2/2ppN3/3P4/4P2P/PPP1QPP1/RNB2RK1 w kq -
+QGD: Lasker defense, Teichmann variation *
+r3kb1r/ppq2ppp/2n1pn2/3p4/2Pp2b1/4PN2/PP1NBPPP/R1BQ1RK1 w kq -
+QGD: Orthodox defense, 7.Qc2 c5, 8.cd (Rubinstein) *
+r3kb1r/ppqbpp1p/2n2np1/1Bp5/2N2P2/2N1P3/PP1P2PP/R1BQK2R w KQkq -
+Nimzo-Indian: Spielmann, St\aa hlberg variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp3b/Q2P4/2P1PN2/PP1N1PPP/R1B2RK1 w kq -
+QGD: Cambridge Springs defense, Argentine variation *
+r3kb1r/ppqn1ppp/2n1p3/1Bpp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1K2R w KQkq -
+QGD: Cambridge Springs defense, Bogolyubov variation *
+r3kb1r/ppqn1ppp/2p2n2/4pb2/P1NP4/2N3P1/1P2PP1P/R1BQKB1R w KQkq -
+QGD Slav: Carlsbad variation
+r3kbnr/1ppb1ppp/p1p5/8/3NP3/8/PPP2PPP/RNB1K2R w KQkq -
+Ruy Lopez: exchange, Alekhine variation
+r3kbnr/p1pb1ppp/2p5/3pN1q1/3Pp3/4P1PP/PPP2P2/RNBQK2R b KQkq -
+French: MacCutcheon, Lasker variation, 8...g6 *
+r3kbnr/pp1qpppp/8/2ppP3/2P3b1/6P1/PP2PP1P/RNBQKB1R b KQkq -
+Gr\"unfeld: Lundin variation *
+r3kbnr/ppp2pp1/2n5/1B1p2qP/3P4/4P3/PPP2Pp1/RNBQK1R1 w Qkq -
+French: MacCutcheon, Grigoriev variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPP1BPPP/RNBQK2R w KQkq -
+French: classical, Anderssen-Richter variation *
+r3kbnr/ppp2ppp/2n5/3p2q1/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Pollock variation *
+r3kbnr/pppq1ppp/2n1b3/3pp3/8/2PP1NP1/PP2PP1P/RNBQKB1R w KQkq -
+Pirc: 150 attack *
+r3kbnr/pppq1ppp/2n5/1B1p4/Q7/4PP2/PPP2P1P/RNB1K2R b KQkq -
+French: MacCutcheon, Bogolyubov variation *
+r3kbnr/pppq1ppp/2n5/3p4/3Pp3/4P3/PPPNQPPP/RNB1K2R w KQkq -
+French: classical, Rubinstein variation *
+r3kbnr/ppq1pppp/2n5/3p4/3P2b1/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+QGD: exchange, positional line, 6.Qc2 *
+r3qrk1/ppp1b1pp/2n1b3/3npp2/8/P1NPPN2/1PQ1BPPP/R1B2RK1 b - -
+Sicilian: Scheveningen, classical main line *
+r3r1k1/1p1n1p1p/1bpqb1p1/p2p2B1/1P1N3Q/P1PBR3/5PPP/5RK1 b - -
+Ruy Lopez: Marshall, main line, Spassky variation *
+r3r1k1/2qbbp1p/p2p1np1/npp1p3/3PP3/2P1NN1P/PPB2PP1/R1BQR1K1 w - -
+Ruy Lopez: closed, Chigorin, Yugoslav system
+r3r1k1/ppp1qppp/2n5/3b4/2P1p3/8/P1PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Berlin defense, Rio de Janeiro variation *
+r4b1r/ppp1kp2/2n1bN1p/q5p1/1P1p3B/5N2/P1P2PPP/R2QR1K1 b - -
+two knights defense: Yurdansky attack
+r4rk1/2pqb1pp/p1n1p3/1p1pP3/4R3/1BP5/PP3PPP/RNBQ2K1 b - -
+Ruy Lopez: open, Tarrasch trap
+r4rk1/2pqbppp/p1n1b3/3pP3/2B1n3/5N2/PP2QPPP/RNBR2K1 w - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation
+r4rk1/p4ppp/bqn2n2/2b5/B3p3/2N3Q1/PPPPNPPP/R1B1K2R w KQ -
+Evans gambit: compromised defense, Paulsen variation *
+r4rk1/pbqnppbp/1p3np1/2pp4/P2P4/BPP1PN2/3NBPPP/R2Q1RK1 b - -
+Catalan: closed, Sokolsky variation *
+r4rk1/pp1bqpp1/2n1pn1p/2p5/2BP4/2N1PN2/PPQ2PPP/R2R2K1 w - -
+QGD: Lasker defense, Russian variation
+r4rk1/pp2ppbp/3p1np1/q4P2/4P1P1/2N1B3/PPP1Q2P/R4RK1 b - -
+Sicilian: dragon, classical, Stockholm attack
+r4rk1/pp2qppp/3b4/3P4/1P1Qn1b1/B3PN2/5PPP/R3KB1R w KQ -
+QGD semi-Slav: Meran, Rellstab attack *
+r4rk1/ppp1q2p/2n1b3/4p1p1/Q4p2/3P1NP1/PP2PPBP/R4RK1 w - -
+Sicilian: dragon, classical, Stockholm attack *
+r4rk1/ppp3pp/2n1bq2/4pP2/8/5Q2/PPPP1K1P/RNB2BNR w - -
+KGA: Lolli gambit, Young variation *
+r4rk1/pppqbppp/2n1b3/3np3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w - -
+Sicilian: dragon, classical, Richter variation *
+r4rk1/ppq1ppbp/2n2np1/2pp4/3P1Pb1/2P1PN2/PP2B1PP/RNB1QRK1 w - -
+Dutch: stonewall: Chekhover variation *
+r5nr/pp2k2p/2n2p2/2N1p2q/3pP3/3P2P1/PPP2PBP/RNB2RK1 b - -
+King's Indian: S\"amisch, orthodox, Bronstein variation *
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P1b1/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+Benoni: classical with ...a6 and 10...Bg4
+rn1q1rk1/4ppbp/3p1np1/2pP4/4P3/2N2NP1/PP3PKP/R1BQ3R b - -
+Benk\"o gambit: main line
+rn1q1rk1/p3ppbp/bp3np1/2pp4/3P1P2/2P1PN2/PP2B1PP/RNBQ1RK1 w - -
+Dutch: stonewall with Ba3 *
+rn1q1rk1/pb1pbppp/1p2pn2/8/2PN4/1P1BP3/PB3PPP/RN1Q1RK1 b - -
+Queen's Indian: Averbakh variation
+rn1q1rk1/pb3ppp/1p1bp3/2pn4/8/1P2PN2/PB1PBPPP/RN1Q1RK1 w - -
+Queen's Indian: Averbakh variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP1NPPP/R1BQK2R b KQ -
+Evans gambit: Paulsen variation *
+rn1q1rk1/pb3ppp/5n2/2b1p3/N2p4/1B1P4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Ulvestad variation *
+rn1q1rk1/pb3ppp/8/1Bb5/4N1n1/5N2/PPPP1PPP/R1BQ1RK1 b - -
+Scotch gambit: Hanneken variation *
+rn1q1rk1/pbp1bppp/1p3n2/3pN1B1/3P4/2NBP3/PP3PPP/R2QK2R b KQ -
+QGD: Pillsbury attack
+rn1q1rk1/pbpp1ppp/1p2p3/6N1/2PP4/2n3P1/PPQ1PPBP/R3K2R b KQ -
+Bogo-Indian defense, Monticelli trap
+rn1q1rk1/pbppbppp/1p2p3/8/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 b - -
+Queen's Indian: old main line, 9.Qxc3
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Queen's Indian: Euwe variation
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Queen's Indian: old main line, 7.Nc3
+rn1q1rk1/pp1nppbp/6p1/2p5/3PP1b1/1QN1BN2/PP3PPP/R3KB1R w KQ -
+Gr\"unfeld defense: Smyslov, Yugoslav variation
+rn1q1rk1/pp2ppbp/2p2np1/3p1b2/2PP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Flohr defense
+rn1q1rk1/pp2ppbp/2p2np1/3p4/2PP2b1/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Gr\"unfeld: Smyslov defense
+rn1q1rk1/pp2ppbp/2pp1np1/5b2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Larsen system
+rn1q1rk1/pp2ppbp/4bnp1/2Pp4/2P2B2/2N1P3/PP3PPP/2RQKBNR w K -
+Gr\"unfeld: Gr\"unfeld gambit, Botvinnik variation
+rn1q1rk1/pp3ppp/2p1p3/5b2/PbBPn1P1/2N1PN2/1P2QP1P/R1B2RK1 b - -
+QGD Slav: Dutch, S\"amisch variation
+rn1q1rk1/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P2QPPP/R1B2RK1 b - -
+QGD Slav: Dutch variation, main line
+rn1q1rk1/ppp1b1pp/1n2pp2/4Pb2/2PP4/2N2N2/PP2B1PP/R1BQ1RK1 w - -
+Alekhine's defense: four pawns attack, Korchnoi variation
+rn1q1rk1/ppp1ppbp/5np1/8/2QPP1b1/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Smyslov variation
+rn1q1rk1/ppp2ppp/3b4/3p4/2PPn1b1/3B1N2/PP3PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Tarrasch variation
+rn1q1rk1/ppp2ppp/8/2bNp3/4P1b1/3P1N2/PPP2PPP/R1BQK2R b KQ -
+Giuoco piano *
+rn1q1rk1/ppp2ppp/8/2bP1b2/4nPP1/5N2/PPP1Q2P/RNB1KB1R w KQ -
+KGD: Falkbeer, Tarrasch variation
+rn1q1rk1/ppp3pp/8/2bNpp1b/4P1P1/5N1P/PPPP1P2/R1BQK2R w KQ -
+Giuoco piano: Rosentreter variation *
+rn1q1rk1/ppp3pp/8/3P1p2/3Pn1b1/3B1N2/PP3PPb/RNBQR1K1 w - -
+Petrov: classical attack, Marshall trap
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+Gr\"unfeld defense: Smyslov, main line
+rn1qk1nr/pb3ppp/8/2b1p3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: Schlechter defense *
+rn1qk1nr/pb3ppp/8/2b1p3/8/8/PPPPQPPP/RNB1KBNR b KQkq -
+Danish gambit: Collijn defense *
+rn1qk1nr/pp1bppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch-Indian, Alekhine variation *
+rn1qk1nr/pp3ppp/2pb4/3p1b2/3P4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Caro-Kann: exchange, Rubinstein variation *
+rn1qk1nr/ppp1ppbp/3p2p1/8/2PPP1b1/5N2/PP3PPP/RNBQKB1R w KQkq -
+Robatsch defense: Rossolimo variation
+rn1qk1nr/ppp2ppp/8/2b1p3/Q3P1b1/2P2N2/PP1P2PP/RNB1KB1R b KQkq -
+KGD: classical, Marshall attack
+rn1qk2r/1bpp1ppp/1p2pn2/p7/1bPP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Yates variation
+rn1qk2r/p1pp1ppp/bp2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: 4.e3, Bronstein (Byrne) variation
+rn1qk2r/p4ppp/2p2n2/2bpp3/B3P1b1/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Sokolsky variation *
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+English: symmetrical, hedgehog system
+rn1qk2r/pbpp1pp1/1p2pn1p/8/1bPP3B/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, main line
+rn1qk2r/pbpp1ppp/1p2pn2/8/1bPP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: Capablanca variation
+rn1qk2r/pbpp1ppp/5n2/1pb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, Cordel variation *
+rn1qk2r/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP1BPPBP/R2QK2R b KQkq -
+Queen's Indian: Opo\v censky variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R b KQkq -
+Queen's Indian: anti-Queen's Indian system
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP1BPPBP/RN1QK2R w KQkq -
+Queen's Indian: Riumin variation
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b kq -
+Queen's Indian: old main line, 6.O-O
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Queen's Indian: 5.Bg2 Be7
+rn1qk2r/pp1bppbp/5np1/1Bpp4/P7/1P2PN2/1BPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Yates variation *
+rn1qk2r/pp1bppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: Riumin variation *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Paulsen attack *
+rn1qk2r/pp3ppp/2p1b3/3np3/1bB5/5Q2/PPPPNPPP/R1BNK2R b KQkq -
+Scotch: Paulsen, Gunsberg defense *
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+QGD Slav: Dutch variation
+rn1qk2r/pp3ppp/2p2n2/2bpp3/4P1b1/1BN5/PPPPQPPP/R1B1K1NR w KQkq -
+Giuoco Piano: Mestel variation *
+rn1qk2r/ppp2ppp/3pbn2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Ruy Lopez: Berlin defense, Kaufmann variation *
+rn1qk2r/ppp2ppp/8/2bP1b2/4nP2/5N2/PPP1Q1PP/RNB1KB1R w KQkq -
+KGD: Falkbeer, main line, 7...Bf5
+rn1qk2r/ppp3p1/8/2bpP1Pp/4b3/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Cook variation *
+rn1qk2r/pppbbppp/8/3pP3/N3n3/2PB1N1P/P1Q2PP1/R1B1K2R w KQkq -
+two knights defense: Knorre variation *
+rn1qkb1r/1b3ppp/p3pn2/1pp5/3P4/1B2PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 8...Bb7
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N3P1/PP3P1P/R1BQ1KNR b kq -
+Benk\"o gambit
+rn1qkb1r/4pp1p/3p1np1/2pP4/4P3/2N5/PP2NPPP/R1BQ1K1R b kq -
+Benk\"o gambit: Ne2 variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benk\"o gambit: fianchetto variation
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benk\"o gambit: Nd2 variation
+rn1qkb1r/4pppp/b2p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benk\"o gambit: 7.e4
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto)
+rn1qkb1r/pb1p1ppp/1p2pn2/2p5/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+English: Wimpey system *
+rn1qkb1r/pb1p1ppp/1p3n2/2pp2N1/2P5/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: B\"urger variation
+rn1qkb1r/pb1p1ppp/1p3n2/2pp4/2P4N/6P1/PP2PPBP/RNBQK2R b KQkq -
+Queen's Indian: Rubinstein variation
+rn1qkb1r/pb1ppppp/1p3n2/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Capablanca's variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: New York (London) defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/2P2NP1/PP2PP1P/RNBQKB1R b KQkq -
+English: Bled variation *
+rn1qkb1r/pb1ppppp/1p3n2/2p5/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Queen's Indian: Marienbad system
+rn1qkb1r/pb1ppppp/1p3n2/8/2PQ4/5NP1/PP2PPBP/RNB1K2R b KQkq -
+Queen's Indian: Marienbad system, Berg variation
+rn1qkb1r/pbpp1p2/1p2p2p/6pn/2PP4/2N2NB1/PP2PPPP/R2QKB1R w KQkq -
+Queen's Indian: 4.Nc3, Botvinnik variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2NB1N2/PP1P1PPP/R1BQK2R b KQkq -
+English: Queens Indian, Romanishin variation
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 Bb7
+rn1qkb1r/pp1bpppp/5n2/1Bpp4/8/4PN2/PPPPQPPP/RNB1K2R b KQkq -
+Bogo-Indian defense, Nimzovich variation *
+rn1qkb1r/pp1n1ppp/4p3/3pNb2/3P4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+QGD Slav: Amsterdam variation
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: New York (London) defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: London defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 Bf5
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Capablanca's variation
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/1P3NP1/P2PPP1P/RNBQKB1R w KQkq -
+English: Torre defensive system
+rn1qkb1r/pp2pppp/2p2n2/3p4/6b1/5NP1/PPPPPPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Yugoslav variation
+rn1qkb1r/pp2pppp/2p2n2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav: Krause attack
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N1PN2/1P3PPP/R1BQKB1R b KQkq -
+QGD Slav: Dutch variation
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Czech defense
+rn1qkb1r/pp2pppp/2p2n2/8/P1pP2b1/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Steiner variation
+rn1qkb1r/pp2pppp/2pp4/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Flohr variation
+rn1qkb1r/pp2pppp/5n2/1Bpp4/3P2b1/4PN2/PPP2PPP/RNBQK2R b KQkq -
+QGD: Vienna variation *
+rn1qkb1r/pp2pppp/5n2/2p5/1PPp2b1/4PN2/P2P1PPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation *
+rn1qkb1r/pp2pppp/5n2/2pp1b2/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Miles variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN1P/PPP2PP1/RNBQKB1R b KQkq -
+QGD: Capablanca-Duras variation *
+rn1qkb1r/pp2pppp/5n2/2pp4/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+QGD *
+rn1qkb1r/pp2pppp/5n2/3p1b2/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: exchange variation
+rn1qkb1r/pp2pppp/5n2/8/1PPp2b1/5N1P/P2P1PP1/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit, Spielmann variation *
+rn1qkb1r/pp3ppp/2p1pn2/4Nb2/P1pP4/2N5/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Wiesbaden variation
+rn1qkb1r/pp3ppp/4b3/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 6.Be3 *
+rn1qkb1r/ppn2ppp/2p1b3/4p3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Meitner variation *
+rn1qkb1r/ppp1pppp/1n1p4/3PP3/2P3b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Vitolins attack
+rn1qkb1r/ppp1pppp/1n1p4/4Pb2/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation
+rn1qkb1r/ppp1pppp/3p1n2/5b2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Janowski variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/2PP2b1/5N2/PP3PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Alekhine variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N1P/PPP2PP1/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Panov variation
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation, 4...Bg4
+rn1qkb1r/ppp1pppp/4bn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Flohr variation
+rn1qkb1r/ppp1pppp/5B2/3p1b2/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack, Veresov variation
+rn1qkb1r/ppp1pppp/5n2/3p1b2/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's bishop game *
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: London system *
+rn1qkb1r/ppp1pppp/5n2/3p1bB1/3P4/2N2P2/PPP1P1PP/R2QKBNR b KQkq -
+Richter-Veresov attack, Richter variation
+rn1qkb1r/ppp1pppp/5n2/3p4/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Torre attack (Tartakower variation) *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Torre attack *
+rn1qkb1r/ppp1pppp/5n2/8/2pP2b1/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Janowsky-Larsen variation
+rn1qkb1r/ppp2ppp/4b3/4p3/1nB5/2N2Q2/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch: Blumenfeld attack *
+rn1qkb1r/ppp2ppp/5n2/3pp3/2P3b1/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Torre attack, Wagner gambit *
+rn1qkb1r/ppp2ppp/8/3pP3/4n1b1/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Vienna gambit: Kaufmann variation
+rn1qkb1r/ppp3p1/8/3ppbPp/3Pn3/5N2/PPP2P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano defense *
+rn1qkb1r/pppb1ppp/8/1B2p2Q/1n6/2N5/PPPP1PPP/R1B1K1NR w KQkq -
+Scotch game *
+rn1qkbnr/1bpp1ppp/p7/1P6/3Q4/8/PP2PPPP/RNB1KBNR w KQkq -
+Sicilian: wing gambit, Marienbad variation *
+rn1qkbnr/1pp2ppp/p3p3/3P4/2B3b1/4PN2/PP3PPP/RNBQK2R b KQkq -
+QGA: Alekhine defense, Alatortsev variation
+rn1qkbnr/p1pppppp/bp6/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Guatemala defense
+rn1qkbnr/pp1b1ppp/4P3/1Bp5/4p3/8/PPP2PPP/RNBQK1NR b KQkq -
+QGD: Albin counter-gambit, Lasker trap *
+rn1qkbnr/pp1bpppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7
+rn1qkbnr/pp2pppp/2p3b1/8/3P1P2/6N1/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: classical, Mar\'oczy attack
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+Caro-Kann: classical, 6.h4
+rn1qkbnr/pp2pppp/2p3b1/8/3P4/6NN/PPP2PPP/R1BQKB1R b KQkq -
+Caro-Kann: classical, Flohr variation
+rn1qkbnr/pp2pppp/2p5/3p4/2P3b1/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation
+rn1qkbnr/pp2pppp/2p5/3p4/4P1b1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Caro-Kann: two knights, 3...Bg4
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: classical variation
+rn1qkbnr/pp2pppp/8/2p2bN1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Rubinstein variation *
+rn1qkbnr/pp2pppp/8/2pp4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Neo-Indian (Seirawan) attack *
+rn1qkbnr/pp3ppp/2p1p3/3pPb2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+Caro-Kann: advance, Short variation
+rn1qkbnr/pp4pp/4b3/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R w KQkq -
+Alekhine's defense: four pawns attack, 7.Be3 *
+rn1qkbnr/ppp1pppp/3p4/8/3P2b1/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Old Indian: Tartakower (Wade) variation
+rn1qkbnr/ppp1pppp/3p4/8/4P1b1/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+R\'eti: Wade defense
+rn1qkbnr/ppp1pppp/4b3/8/2p5/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+R\'eti accepted: Keres variation
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit *
+rn1qkbnr/ppp1pppp/8/3p1b2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Grau (Sahovic) defense
+rn1qkbnr/ppp1pppp/8/3p1b2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn, Mason variation *
+rn1qkbnr/ppp1pppp/8/3p1b2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: London system *
+rn1qkbnr/ppp1pppp/8/3p4/2P3b1/8/PP1PPPBP/RNBQK1NR b KQkq -
+Grob: Fritz gambit
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Queen's pawn: Anti-Veresov
+rn1qkbnr/ppp1pppp/8/3p4/3P2b1/8/PPP1PPPP/RNBQKBNR w KQkq -
+Levitsky attack (Queen's bishop attack) *
+rn1qkbnr/ppp1pppp/8/3p4/5Pb1/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, 2.Bg5 variation *
+rn1qkbnr/ppp1pppp/8/3p4/6b1/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening) *
+rn1qkbnr/ppp1pppp/8/8/2Pp2b1/8/PP1PPPBP/RNBQK1NR w KQkq -
+Grob: Romford counter-gambit
+rn1qkbnr/ppp2ppp/2b1p3/8/3PN3/5N2/PPP2PPP/R1BQKB1R w KQkq -
+French: Fort Knox variation
+rn1qkbnr/ppp2ppp/3p4/4p3/2P3b1/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English, Smyslov defense
+rn1qkbnr/ppp2ppp/4b3/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Alapin variation *
+rn1qkbnr/ppp2ppp/8/3p4/5p2/6PB/PPPPP2P/RNBQK2R w KQkq -
+Amar gambit
+rn1qkbnr/pppb1ppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R w KQkq -
+Philidor: Boden variation
+rn2k2r/pbpp1ppp/8/2b1p3/Np2Q3/1B6/PPPP1qPP/R1BK2NR w kq -
+Evans gambit declined, Hicken variation *
+rn2k2r/pp4pp/1q3p2/1N1pN3/3Pn3/5K2/PPP3PP/R1BQ3R w kq -
+Giuoco Piano: Krause variation *
+rn2kb1r/pp1q1ppp/2p1b3/3np3/2B5/2N2Q2/PPPPNPPP/R1B1K2R w KQkq -
+Scotch: Blackburne attack *
+rn2kb1r/pp2pppp/2p2n2/q3Nb2/3P2P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Scandinavian defense, Gr\"unfeld variation
+rn2kb1r/pp3ppp/2p1q3/1N6/3p4/5Q2/PP3PPP/1RB2RK1 b kq -
+Scotch: Gottschall variation *
+rn2kb1r/ppp1pppp/5n2/q4b2/3P4/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian defense
+rn2kb1r/ppp1pppp/5n2/q7/3P2b1/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Scandinavian defense, Lasker variation
+rn2kbnr/pp1b1ppp/1q2p3/2ppP3/3P4/2P2N2/PP3PPP/RNBQKB1R w KQkq -
+French: advance, Wade variation
+rn2kbnr/pp1qpppp/3p4/2p5/2P1P3/5N2/PP1P1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation
+rn2kbnr/ppp2ppp/8/q3p3/3P2b1/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Scandinavian: Anderssen counter-attack, Collijn variation
+rn3rk1/p1p1qpp1/1p2b2p/3p4/3P4/4PN2/PP3PPP/2RQKB1R w K -
+QGD: Tartakower variation
+rn3rk1/p4ppp/bqp5/2b1p3/N3n3/1B6/PPPQ1PPP/R1B1K1NR w KQ -
+Evans gambit: Levenfish variation *
+rnb1k1nr/p3qppp/2p1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Koomen variation
+rnb1k1nr/p4ppp/1qp1p3/1p6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Junge variation
+rnb1k1nr/pp1pq1pp/2p5/2b1pp2/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Bishop's opening: Lopez gambit *
+rnb1k1nr/pp2ppbp/3p2p1/q1p5/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+Pterodactyl defense
+rnb1k1nr/pp2ppbp/6p1/2qp4/8/4PN2/PPPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, 5.Qa4 Nbd7, 6.Qxc4 *
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Qa4 *
+rnb1k1nr/pp3ppp/2p5/2PP4/2B4q/5p2/PPP2PPP/RNBQ1RK1 b kq -
+Bishop's opening: Pratt variation *
+rnb1k1nr/pp3ppp/4p3/2pq4/1b1P4/2NB4/PPPB1PPP/R2QK1NR b KQkq -
+French: Winawer, Kondratiyev variation
+rnb1k1nr/ppp2pbp/3p4/4P1p1/2BP1p1q/2N5/PPP3PP/R1BQ1KNR b kq -
+KGA: bishop's gambit, Grimm attack
+rnb1k1nr/ppp2ppp/3b4/3B4/4Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bor\'en-Svenonius variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1P2q/2N2Qp1/PPPP3P/R1B2KNR b kq -
+KGA: bishop's gambit, Fraser variation
+rnb1k1nr/pppp1pbp/8/6p1/2B1Pp1q/2N3P1/PPPP3P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k1nr/pppp1ppp/8/2b1p1q1/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: del Rio variation
+rnb1k1nr/pppp1ppp/8/2b5/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Greco variation
+rnb1k1nr/pppp1ppp/8/4p3/1bB1Pq2/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGD: Norwalde variation, B\"ucker gambit
+rnb1k1nr/ppppqppp/1b1P4/4p3/2B1P3/2P2N2/PP3PPP/RNBQK2R b KQkq -
+Giuoco Piano: Eisinger variation
+rnb1k1nr/pppq1ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, Petrosian variation
+rnb1k1nr/ppq1ppbp/6p1/3p4/8/P3PN2/1PPN1PPP/R1BQKB1R w KQkq -
+Catalan: open, Alekhine variation *
+rnb1k1nr/ppq2ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, classical variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P1NPPP/R1B1KB1R b KQq -
+French: Winawer, advance, poisoned pawn, Konstantinopolsky variation
+rnb1k1r1/ppq1np1Q/4p3/3pP3/3p4/P1P5/2P2PPP/R1BK1BNR b q -
+French: Winawer, advance, poisoned pawn, Euwe-Gligori\'c variation
+rnb1k2r/1pq1bpp1/p2ppn1p/8/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, Browne variation
+rnb1k2r/1pq1bppp/p2ppn2/6B1/3NPP2/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf variation
+rnb1k2r/2q1bp1p/p2p1n2/1ppPp1p1/4P3/2P2N1P/PPBN1PP1/R1BQR1K1 w kq -
+Ruy Lopez: closed, Leonhardt variation
+rnb1k2r/p1pp1ppp/8/4p3/Np2n1Qq/1B6/PPPPKbPP/R1B3NR w kq -
+Evans gambit declined, V\'asquez variation *
+rnb1k2r/p4ppp/1qp2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR w KQkq -
+Evans gambit: Tartakower attack *
+rnb1k2r/pp2ppbp/5np1/2pq4/8/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+Queen's Indian: Marienbad system, Berg variation *
+rnb1k2r/pp2qppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2QK2R b KQkq -
+Ruy Lopez: Wormald attack, Gr\"unfeld variation *
+rnb1k2r/pp3ppp/4p3/q7/1b1PP3/5N2/P2B1PPP/R2QKB1R w KQkq -
+QGD: Semi-Tarrasch, San Sebastian variation
+rnb1k2r/ppp1qppp/5n2/2p1P3/3p4/5N1P/PPP1BPP1/R1BQK2R b KQkq -
+two knights defense: Mar\'oczy variation *
+rnb1k2r/ppp1qppp/5n2/3P4/1bBp4/2P2N2/PP3PPP/RNBQK2R w KQkq -
+Bishop's opening: Urusov gambit, Panov variation
+rnb1k2r/ppp2p1p/4pp2/q7/1b1P4/2N5/PPPQ1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Bogolyubov variation
+rnb1k2r/ppp2p1p/5n2/3qN3/1b1P1ppP/2N5/PPP2KP1/R1BQ1B1R b kq -
+KGA: Kieseritsky, Brentano defense, Kaplanek variation
+rnb1k2r/ppp2ppp/1b6/3qp3/1PP5/P2P4/5PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Noah's ark trap *
+rnb1k2r/ppp2ppp/3b4/3qp3/8/3P4/PPP2PPP/R1BQKBNR w KQkq -
+Scotch: Ghulam Kassim variation *
+rnb1k2r/ppp2ppp/5n2/3qp3/1b6/2NP4/PP1QPPPP/R1B1KBNR b KQkq -
+Sicilian: Chekhover, Zaitsev variation *
+rnb1k2r/ppp2ppp/8/2bPp3/2B3nq/2N4N/PPPP1PPP/R1BQK2R w KQkq -
+Scotch gambit: Vitzhum attack *
+rnb1k2r/ppp2ppp/8/3Pp3/2qP4/2N3P1/PPP2K1P/R1BQ3R b kq -
+Scotch gambit: Cochrane-Shumov defense *
+rnb1k2r/ppp2ppp/8/3np3/8/P1P5/1PPB1PPP/R3KBNR b KQkq -
+Ruy Lopez: exchange, Alekhine variation *
+rnb1k2r/ppp2ppp/8/3q4/4nP2/8/PPPNQbPP/RNBK1B1R b kq -
+KGD: Falkbeer, Alapin variation
+rnb1k2r/ppp3p1/3q1n2/2bppP1p/6P1/3P3P/PPP2PB1/RNBQK1NR w KQkq -
+KGA: Philidor gambit, Schultz variation *
+rnb1k2r/pppnqppp/4p3/1N1pP3/3P4/8/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Alapin variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P1P2/2N5/PPP3PP/R2QKBNR b KQkq -
+French: classical, Steinitz variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Pollock variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2N5/PPPQ1PPP/R3KBNR b KQkq -
+French: classical, Rubinstein variation
+rnb1k2r/pppnqppp/4p3/3pP3/3P4/2NB4/PPP2PPP/R2QK1NR b KQkq -
+French: classical, Tarrasch variation
+rnb1k2r/pppnqppp/8/2p1P3/2Bp4/5N1P/PPP2PP1/R1BQK2R w KQkq -
+two knights defense: Yankovich variation *
+rnb1k2r/pppp1ppp/3b1q2/8/N3P1n1/2P2N2/P1Q2PPP/R1B1KB1R w KQkq -
+two knights defense: Paoli variation *
+rnb1k2r/pppp1ppp/5q2/8/NP2P1n1/5N2/P4PPP/R1BQKB1R b KQkq -
+two knights defense: Blackburne variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/1RBQKB1R b Kkq -
+two knights defense: Colman variation *
+rnb1k2r/pppp1ppp/5q2/8/Nb2P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+two knights defense: Bogolyubov variation *
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N3P1/PPP4P/R1BQ1KNR b kq -
+KGA: bishop's gambit, McDonnell attack
+rnb1k2r/ppppnpbp/8/6p1/2BPPp1q/2N5/PPP3PP/R1BQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1k2r/ppppqppp/4pn2/8/1bPP4/5N2/PP1BPPPP/RN1QKB1R w KQkq -
+Bogo-Indian defense, Nimzovich variation
+rnb1k2r/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Wormald (Alapin) attack *
+rnb1kb1N/ppp3pp/5n2/3p4/2B1p3/8/PPPP1PqP/RNBQKR2 w Qkq -
+Latvian: Behting variation
+rnb1kb1r/1p3ppp/p2ppn2/6B1/3NPP2/q1N5/P1PQ2PP/1R2KB1R w Kkq -
+Sicilian: Najdorf, Poisoned pawn variation
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Qb6
+rnb1kb1r/1pq2ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQ1RK1 w kq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnb1kb1r/2q2ppp/p3pn2/1p2P1B1/3N4/2N5/PPP1Q1PP/R3KB1R b KQkq -
+Sicilian: Najdorf, Polugayevsky, Simagin variation
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Ponziani: Leonhardt variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Ponziani: Steinitz variation *
+rnb1kb1r/pp1p1ppp/2p2n2/q3p3/3PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+Ponziani: Caro variation *
+rnb1kb1r/pp1p2pp/2p2n2/q3p1B1/2B1P3/8/PPP2PPP/RN1QK1NR w KQkq -
+KGD: classical, Marshall attack *
+rnb1kb1r/pp1ppppp/5n2/q1pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Woozle defense
+rnb1kb1r/pp2pppp/1qp2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav: S\"uchting variation
+rnb1kb1r/pp2pppp/5n2/q1Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA: Mannheim variation *
+rnb1kb1r/pp3pp1/2p1pq1p/3p4/2PP4/1QN2N2/PP2PPPP/R3KB1R b KQkq -
+QGD/QGD semi-Slav: Hastings variation
+rnb1kb1r/pp3ppp/1q2pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Canal (Venice) variation
+rnb1kb1r/ppp1pppp/5n2/8/3q4/2N2N2/PPPPQ1PP/R1B1KB1R b KQkq -
+Queen's pawn: Englund gambit *
+rnb1kb1r/ppp1q1pp/5n2/4Np2/2Bp1B2/8/PPP2PPP/RN1QK2R b KQkq -
+KGD: Falkbeer, main line, 7...Bf5 *
+rnb1kb1r/ppp1q2p/5n2/4Npp1/2Bp1B2/8/PPP2PPP/RN1Q1RK1 b kq -
+KGD: Falkbeer, Tarrasch variation *
+rnb1kb1r/ppp1qppp/5n2/3PN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Steinitz variation *
+rnb1kb1r/ppp1qppp/8/3n4/2N1p3/2N5/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: modern attack, Bardeleben variation *
+rnb1kb1r/ppp2p1p/3p3n/4N3/2BPPppq/8/PPP3PP/RNBQ1K1R w kq -
+KGA: Salvio gambit, Anderssen counter-attack
+rnb1kb1r/ppp2ppp/5n2/3qN3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, main line *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian, Chekhover variation *
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PPPB1PPP/RN1QKBNR b KQkq -
+Philidor: Boden variation *
+rnb1kb1r/ppp2ppp/5n2/4N3/3qp3/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Rellstab variation *
+rnb1kb1r/ppp2ppp/8/3NP2q/8/3P1Nn1/PPP4P/R1BQKB1R b KQkq -
+Vienna gambit, Wurzburger trap
+rnb1kb1r/ppp3pp/8/3q1p2/4nPP1/8/PPPNQ2P/R1B1KBNR b KQkq -
+KGD: Falkbeer, Charousek variation
+rnb1kb1r/pppp1p1p/7n/4N3/2BPP1pq/5p2/PPP3PP/RNBQ1K1R w kq -
+KGA: Silberschmidt gambit
+rnb1kb1r/pppp2p1/8/4pq1p/8/3B1N1P/PPPP1K2/RNBQ3R b kq -
+KGA: Allgaier, Horny defense *
+rnb1kb1r/ppppqppp/5n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Cozio (Lasker) attack *
+rnb1kb1r/ppq1p1pp/2pp1n2/5p2/2PP4/2N3P1/PP2PPBP/R1BQK1NR w KQkq -
+Dutch: Hort-Antoshin system
+rnb1kbnr/p1pp1ppp/8/1p6/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnb1kbnr/pp1ppppp/8/q1p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Stiletto (Althouse) variation
+rnb1kbnr/pp2pppp/1qp5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+Caro-Kann: Edinburgh variation
+rnb1kbnr/pp2pppp/8/3q4/1p6/P7/1BPP1PPP/RN1QKBNR b KQkq -
+Sicilian: wing gambit, Marienbad variation
+rnb1kbnr/pp3ppp/2p1q3/4p3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Center game: Charousek variation *
+rnb1kbnr/ppp1pp1p/3q4/3p2p1/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch, Von Pretzel gambit *
+rnb1kbnr/ppp1pppp/3q4/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation *
+rnb1kbnr/ppp1pppp/3q4/8/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scandinavian: Pytel-Wade variation
+rnb1kbnr/ppp1pppp/8/q7/1P6/2N5/P1PP1PPP/R1BQKBNR b KQkq -
+Scandinavian, Mieses-Kotr\v c gambit
+rnb1kbnr/ppp1q1pp/3p4/4Pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, R\'eti variation *
+rnb1kbnr/ppp1q1pp/8/4Np2/3p4/8/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, Charousek gambit *
+rnb1kbnr/ppp2p1p/8/3B2p1/4Pp1q/6P1/PPPP3P/RNBQ1KNR b kq -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation)
+rnb1kbnr/ppp2ppp/4p3/3q4/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+French: Frere (Becker) variation
+rnb1kbnr/ppp2ppp/4q3/4p3/5P2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Center game: l'Hermet variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Center game: Berger variation *
+rnb1kbnr/ppp2ppp/4q3/4p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Paulsen attack *
+rnb1kbnr/ppp2ppp/8/2q1p3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Center game: Hall variation *
+rnb1kbnr/ppp2ppp/8/3p2q1/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich variation *
+rnb1kbnr/ppp2ppp/8/3qp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/3qp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Center game *
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Scandinavian: Anderssen counter-attack, Goteborg system
+rnb1kbnr/ppp2ppp/8/q3p3/3P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Scandinavian: Anderssen counter-attack
+rnb1kbnr/ppp3pp/3p1q2/8/3Pp3/4N3/PPP2PPP/RNBQKB1R b KQkq -
+Latvian: Nimzovich variation
+rnb1kbnr/pppp1B1p/8/4q3/5p2/5Q2/PPPP2PP/RNB2RK1 b kq -
+KGA: double Muzio gambit
+rnb1kbnr/pppp1p1p/8/4N3/2B1P1pq/5p2/PPPP2PP/RNBQ1K1R w kq -
+KGA: Cochrane gambit
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/5Q2/PPPP2PP/RNB2KNR b kq -
+KGA: bishop's gambit, classical defense, Cozio attack
+rnb1kbnr/pppp1p1p/8/6p1/2B1Pp1q/8/PPPP2PP/RNBQ1KNR w kq -
+KGA: bishop's gambit, classical defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Greco defense
+rnb1kbnr/pppp1ppp/5q2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Napoleon's opening *
+rnb1kbnr/pppp1ppp/5q2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Norwalde variation
+rnb1kbnr/pppp1ppp/8/4p3/4P2q/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Patzer opening *
+rnb1kbnr/pppp2pp/5q2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Breyer gambit *
+rnb1kbnr/ppppq1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Carrera (Basman) gambit *
+rnb1kbnr/ppppq2p/8/4Np2/2BPPppP/8/PPP3P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation
+rnb1kbnr/ppppqp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense
+rnb1kbnr/ppppqp1p/8/8/2B1Pp2/5Q2/PPPP2PP/RNB2RK1 w kq -
+KGA: Muzio gambit, From defense
+rnb1kbnr/ppppqp1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Kling and Horwitz counter-attack
+rnb1kbnr/ppppqppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Gunderam defense
+rnb1kbnr/ppppqppp/8/4p3/4PP2/6P1/PPPP3P/RNBQKBNR w KQkq -
+KGD: Keene's defense
+rnb1kbnr/ppppqppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Chigorin variation *
+rnb1kbnr/ppppqppp/8/8/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Collijn defense
+rnb1kbnr/ppq1pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Fajarowicz, Steiner variation *
+rnb1kbnr/ppq1pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+Queen's pawn: Mengarini attack *
+rnb1kbnr/ppqppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Quinteros variation
+rnb1qrk1/pp2b1pp/2p1pn2/3p1pB1/2PP4/2N2NP1/PPQ1PPBP/R4RK1 b - -
+Dutch: stonewall: Chekhover variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/1PN2NP1/P3PPBP/R1BQ1RK1 b - -
+Dutch: Ilyin-Genevsky variation with b3
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Ilyin-Genevsky variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PP2PPBP/R1BQR1K1 b - -
+Dutch: Ilyin-Genevsky, Winter variation
+rnb1qrk1/ppp1b1pp/3ppn2/5p2/2PP4/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+Dutch: Ilyin-Genevsky variation with Qc2
+rnb1r1k1/ppp2ppp/1b6/3qp3/1PP5/P2P1N2/4BPPP/R1BQK2R b KQ -
+Ruy Lopez: Noah's ark trap *
+rnb2bnr/pppp1k1p/5q2/8/4Pp2/2N1BQ2/PPP3PP/R4RK1 b - -
+KGA: Lolli gambit, Young variation
+rnb2knr/pppp2pp/5q2/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, classical defense, Cozio attack *
+rnb2rk1/p1p1qppp/1p3n2/8/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Pillsbury variation *
+rnb2rk1/p1pqppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQ1RK1 w - -
+Gr\"unfeld: exchange, Larsen variation
+rnb2rk1/p1q1ppbp/1p3np1/2pp4/3P4/2P1PN2/PP1NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Qc2 & b3 *
+rnb2rk1/p4ppp/1qp2n2/2bPp3/B7/2NP4/PPP2PPP/R1BQK1NR w KQ -
+Evans gambit: Waller attack *
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+King's Indian: fianchetto, Kavalek (Bronstein) variation
+rnb2rk1/pp2qppp/1b2pn2/3p4/1PP5/P3PN2/1B3PPP/RN1QKB1R b KQ -
+QGA: classical, 8...Bb7 *
+rnb2rk1/pp2qppp/1b3n2/2p1N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, Howell attack, Adam variation *
+rnb2rk1/pp2qppp/4pn2/2bp4/1PP5/P3PN2/5PPP/RNBQKB1R b KQ -
+QGA: classical, 7...b5 *
+rnb2rk1/pp2qppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, 7.Qe2 *
+rnb2rk1/pp2qppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Gligori\'c system, Smyslov variation
+rnb2rk1/pp2qppp/5n2/2b5/1PB1p3/P1N1PN2/5PPP/R1BQK2R w KQ -
+QGA: classical, Furman variation *
+rnb2rk1/pp2qppp/5n2/2p5/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Zukertort variation *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R w KQ -
+Ruy Lopez: open, Motzko attack *
+rnb2rk1/pp3ppp/1bpq1n2/4N3/1PBPp3/P3B3/2P1NPPP/R2QK2R b KQ -
+Ruy Lopez: open, Motzko attack, Nenarokov variation *
+rnb2rk1/ppB1ppbp/6p1/3q4/3P4/4P3/PP3PPP/R2QKBNR b KQ -
+Gr\"unfeld: Gr\"unfeld gambit accepted
+rnb2rk1/ppp1qpp1/4p2p/3P4/3P4/2P1PN2/P4PPP/R2QKB1R b KQ -
+QGD: Lasker defense, main line
+rnb2rk1/ppp1qpp1/4p2p/3p4/2PPn3/2N1PN2/PPQ2PPP/R3KB1R b KQ -
+QGD: Lasker defense, Teichmann variation
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, Howell attack *
+rnb2rk1/ppp1qppp/5n2/3pN3/1b1PP3/2N5/PPP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Trifunovi\'c variation *
+rnb2rk1/ppp1qppp/5n2/8/4pN2/2P5/P1PPBPPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Cordel variation *
+rnb2rk1/ppp1qppp/8/3n4/4p3/2P5/PNPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Winawer attack *
+rnb2rk1/ppp2pbp/3p2p1/3Pp3/2n1P2Q/2N2P2/PP2K2P/R5NR w - -
+King's Indian: S\"amisch, orthodox, Bronstein variation
+rnb2rk1/ppp2pp1/3q3p/3p4/3P4/1QP1PN2/P4PPP/R3KB1R w KQ -
+QGD: Lasker defense, Bernstein variation
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/2N5/PPPP1P1P/R1BQKBNR b KQ -
+KGA: Muzio gambit, Holloway defense *
+rnb2rk1/pppp2pp/5q2/2b1pP2/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, From defense *
+rnb2rk1/pppp2pp/5q2/5P2/4Q3/8/PPPP1b1P/RNB1KBNR w KQ -
+KGA: double Muzio gambit *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: Worrall attack, sharp line *
+rnb2rk1/ppppqppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+Ruy Lopez: Worrall attack, solid line *
+rnb2rk1/ppppqppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Tartakower variation *
+rnb2rk1/ppppqppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Worrall attack *
+rnb2rk1/ppq1ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 w - -
+Catalan: closed, 7.Qc2 *
+rnbk1b1r/pppnqBpp/8/4Np2/3Q4/8/PPP2PPP/RNB1K2R w KQ -
+KGD: Falkbeer, Alapin variation *
+rnbk1bnr/pppp2pp/8/8/2B1pp1q/2N5/PPPPQ1PP/R1BK2NR w - -
+KGA: L\'opez-Gianutio counter-gambit, Hein variation
+rnbq1bnr/ppp3k1/7p/3B4/3PPppP/8/PPP3P1/RNBQK2R b KQ -
+KGA: Allgaier, Urusov attack
+rnbq1bnr/ppp3k1/7p/4B3/2BPp1pP/8/PPP3P1/RN1QK2R b KQ -
+KGA: Allgaier, Cook variation
+rnbq1bnr/pppp1k2/7p/8/2B1PppP/8/PPPP2P1/RNBQK2R b KQ -
+KGA: Allgaier, Walker attack
+rnbq1bnr/pppp1k2/7p/8/3PPppP/8/PPP3P1/RNBQKB1R b KQ -
+KGA: Allgaier, Thorold variation
+rnbq1bnr/pppp1k2/7p/8/4PppP/2N5/PPPP2P1/R1BQKB1R b KQ -
+KGA: Allgaier, Blackburne gambit
+rnbq1bnr/pppp1kpp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQ -
+KGA: Tumbleweed gambit *
+rnbq1bnr/pppppkpp/5p2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQ -
+Fried fox defense
+rnbq1bnr/pppppkpp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQ -
+Hammerschlag (Fried fox/Pork chop opening) *
+rnbq1k1r/pp3ppp/5n2/1Bbpp3/8/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Cracow variation *
+rnbq1k1r/ppp2Bpp/8/4N2Q/1b1Pp3/2n5/PPP2PPP/R1B1K2R b KQ -
+Two knights defense, Keidanz variation *
+rnbq1k1r/ppp2pp1/4p2p/3pP3/3Pn1Q1/2P5/P1P2PPP/R1B1KBNR b KQ -
+French: MacCutcheon, Duras variation
+rnbq1k1r/ppp3pp/5P2/2bpp1PQ/4n3/7N/PPPP1P1P/RNB1KB1R b KQ -
+KGA: Silberschmidt gambit *
+rnbq1k1r/ppp3pp/8/2bppPPQ/4n3/3P3N/PPP2P1P/RNB1KB1R b KQ -
+KGA: Salvio gambit, Anderssen counter-attack *
+rnbq1k1r/pppp2pp/5P2/2b1p1PQ/4n3/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: Cochrane gambit *
+rnbq1k1r/pppp2pp/8/2b1pPPQ/4n3/2N5/PPPP1P1P/R1B1KBNR b KQ -
+KGA: Herzfeld gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/1P6/8/P1PP1PPP/RNB1KBNR b KQ -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbq1knr/pppp2pp/8/2b1pP1Q/2B5/8/PPPP1PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Greco variation *
+rnbq1knr/pppp2pp/8/2b1pP1Q/6P1/8/PPPP1P1P/RNB1KBNR b KQ -
+KGA: bishop's gambit, classical defense *
+rnbq1knr/pppp2pp/8/2b1pP1Q/8/2N5/PPPP1PPP/R1B1KBNR b KQ -
+KGA: bishop's gambit, Boden defense *
+rnbq1knr/pppp2pp/8/4pP1Q/3b4/3B4/PPP2PPP/RNB1K1NR b KQ -
+KGA: bishop's gambit, Bor\'en-Svenonius variation *
+rnbq1knr/pppp3p/6p1/4pP1Q/3b2P1/8/PPP2P1P/RNB1KBNR w KQ -
+KGA: bishop's gambit, Chigorin's attack (Gifford variation) *
+rnbq1r1k/p1p4P/5n2/2bpp2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+Bishop's opening: Four pawns' gambit *
+rnbq1r1k/pppp3P/5n2/2b1p2B/8/8/PPPP1PPP/RNBQK1NR w KQ -
+KGA: Cunningham, three pawns gambit *
+rnbq1rk1/1p2ppbp/p1pp1np1/8/2PPP3/2NBBP2/PP4PP/R2QK1NR w KQ -
+King's Indian: S\"amisch, Byrne variation
+rnbq1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...a6, 10.a4
+rnbq1rk1/1p3ppp/4pn2/p1bp4/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Rubinstein variation *
+rnbq1rk1/1pp1ppbp/p4np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Alekhine (Hungarian) variation
+rnbq1rk1/1pp2pbp/3p1np1/p2Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: Petrosian system, Stein variation
+rnbq1rk1/1pp2ppp/1b3n2/p2NN3/1P1PP3/P7/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Schlechter defense *
+rnbq1rk1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Wing attack *
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/3PP3/1BP2N1P/PP3PP1/RNBQR1K1 b - -
+Ruy Lopez: closed, Breyer, 10.d4
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+Ruy Lopez: closed, Breyer defense
+rnbq1rk1/p1p1bpp1/1p2p2p/3n4/3P3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system, 8.cd Nxd5
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Tartakower (Makagonov-Bondarevsky) system
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, double fianchetto variation
+rnbq1rk1/p1p1ppbp/1p3np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Levenfish variation
+rnbq1rk1/p1p1ppbp/1p4p1/8/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Simagin's lesser variation
+rnbq1rk1/p1p2ppp/1p2pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...b6
+rnbq1rk1/p1pp1ppp/4pn2/1p6/2PP4/P1Q5/1P2PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Adorjan gambit
+rnbq1rk1/p1pp1ppp/5n2/1p1Np3/1bB1P3/8/PPPP1PPP/R1BQK1NR w KQ -
+Ruy Lopez: classical defense, Zaitsev variation *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR w KQ -
+Evans gambit *
+rnbq1rk1/p2p1ppp/2p2n2/2b1p3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 w - -
+Dutch: stonewall, Botwinnik variation *
+rnbq1rk1/p3ppbp/1p3np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+Queen's Indian: Euwe variation *
+rnbq1rk1/p4ppp/1p2pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 w - -
+Nimzo-Indian: 4.e3, Keres variation
+rnbq1rk1/p4ppp/2P2n2/2b1p3/B7/2N5/PPPP1PPP/R1BQK1NR b KQ -
+Evans gambit: compromised defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp1B1/B3P3/2NP4/PPP2PPP/R2QK1NR b KQ -
+Evans gambit: Alapin-Steinitz variation *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/4P3/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: Lasker defense *
+rnbq1rk1/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPPB1PPP/R2QK1NR b KQ -
+Evans gambit: Sanders-Alapin variation *
+rnbq1rk1/p4ppp/2p5/2bpp3/B3n3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+Evans gambit: Richardson attack *
+rnbq1rk1/p4ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQ -
+Evans gambit: normal variation *
+rnbq1rk1/pp1p1ppp/2p2n2/b7/4PB2/P1NP4/1PP3PP/R2QKBNR w KQ -
+Ruy Lopez: Siesta, Kopayev variation *
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+Nimzo-Indian: classical, Pir\'c variation
+rnbq1rk1/pp1pppbp/5np1/2p5/3P4/4PN2/PPP1BPPP/RNBQK2R w KQ -
+English: Neo-Catalan declined *
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: stonewall with Nc3
+rnbq1rk1/pp2b1pp/2p1pn2/3p1p2/2PP4/BP3NP1/P3PPBP/RN1Q1RK1 b - -
+Dutch: stonewall with Ba3
+rnbq1rk1/pp2p1bp/2pp1np1/5p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+Dutch: Leningrad, main variation with c6
+rnbq1rk1/pp2ppbp/2p2np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O c6
+rnbq1rk1/pp2ppbp/2p2np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Russian, Szabo (Boleslavsky) variation
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, 6...c5
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+King's Indian: fianchetto, Yugoslav, 7.O-O
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+King's Indian: fianchetto, Yugoslav system
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PPPP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, with Be2 and Nf3
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R b KQ -
+King's Indian: Four pawns attack, dynamic line
+rnbq1rk1/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R w KQ -
+Sicilian: dragon, Yugoslav attack, 7...O-O
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P1P2/4PN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: stonewall variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/2P2NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O c6 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/4PN2/PPPNBPPP/R1BQ1RK1 b - -
+Catalan: closed, 6...Nbd7 *
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+Dutch: classical variation *
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R w KQ -
+Queen's Indian: old main line, 6.O-O *
+rnbq1rk1/pp2ppbp/5np1/2ppN3/5P2/4P3/PPPPB1PP/RNBQ1RK1 b - -
+Dutch defense, Alekhine variation *
+rnbq1rk1/pp2ppbp/5np1/3p4/3N4/6P1/PPP1PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O, main line *
+rnbq1rk1/pp2ppbp/5np1/3p4/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.O-O, main line
+rnbq1rk1/pp2ppbp/5np1/3p4/8/1N4P1/PPP1PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6 *
+rnbq1rk1/pp2ppbp/5np1/8/2pN4/6P1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc *
+rnbq1rk1/pp2ppbp/6p1/2Pn4/8/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.dc
+rnbq1rk1/pp2ppbp/6p1/2p5/2BPP3/2P5/P3NPPP/R1BQK2R w KQ -
+Gr\"unfeld: exchange, Spassky variation
+rnbq1rk1/pp2ppbp/6p1/2pn4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O c5, 8.Nc3
+rnbq1rk1/pp3pbp/2pp1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox, 7.d5 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox, 7.Nge2 c6
+rnbq1rk1/pp3pbp/2pp1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+King's Indian: orthodox, Donner variation
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+Benoni: classical, 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+Benoni: classical without 9.O-O
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+Benoni: four pawns attack
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+Benoni: fianchetto variation
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack, Florentine gambit
+rnbq1rk1/pp3pbp/3p1np1/3pp3/2P1P3/2N1BP2/PP2N1PP/R2QKB1R w KQ -
+King's Indian: S\"amisch, orthodox main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+King's Indian: Averbakh, main line
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+King's Indian: Four pawns attack
+rnbq1rk1/pp3ppp/1b3n2/2ppN3/1P1PP3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Harksen gambit *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R b KQ -
+Ruy Lopez: open, classical defense *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+Ruy Lopez: open, 9.c3 *
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+Ruy Lopez: open, Italian variation *
+rnbq1rk1/pp3ppp/1bp2n2/8/1PNPp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, Berlin variation *
+rnbq1rk1/pp3ppp/2p2n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack, Krause variation *
+rnbq1rk1/pp3ppp/2p2n2/2bPp1B1/2B5/2NP4/PPP2PPP/R2QK1NR b KQ -
+Scotch gambit: Anderssen (Paulsen, Suhle) counter-attack *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/1b2P3/1BN2N2/PPPP1PPP/R1BQ1RK1 b - -
+Ruy Lopez: classical defense, Benelux variation *
+rnbq1rk1/pp3ppp/2p2n2/3pp3/2P5/2NP1N2/PP1QPPPP/R3KB1R w KQ -
+Sicilian: Canal-Sokolsky attack, Bronstein gambit *
+rnbq1rk1/pp3ppp/2p2n2/b2PN3/4p3/P1N5/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, Basque gambit (North Spanish variation) *
+rnbq1rk1/pp3ppp/3b1n2/2ppN1B1/3P4/3B4/PPP2PPP/RN1Q1RK1 b - -
+Petrov: classical attack, Tarrasch variation *
+rnbq1rk1/pp3ppp/3b1n2/2ppN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Jaenisch variation *
+rnbq1rk1/pp3ppp/3b4/2pnp3/8/P2PPNP1/1P3P1P/RNBQKB1R b KQ -
+Sicilian: Kan, Gipslis variation *
+rnbq1rk1/pp3ppp/3b4/2ppN3/3PB3/8/PPP2PPP/RNBQ1RK1 b - -
+Petrov: modern attack, Trifunovi\'c variation *
+rnbq1rk1/pp3ppp/4p3/1B6/3PP3/5N2/P2Q1PPP/R3K2R b KQ -
+QGD: Semi-Tarrasch, Kmoch variation
+rnbq1rk1/pp3ppp/4p3/2pn4/3P4/P1P1PP2/6PP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch, Botvinnik variation
+rnbq1rk1/pp3ppp/4pn2/2bP4/8/4PN2/PP3PPP/RNBQKB1R b KQ -
+QGA: classical, Steinitz variation *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R w KQ -
+QGA: classical variation, 6.O-O *
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QGA: classical, 6...a6 *
+rnbq1rk1/pp3ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 b - -
+Nimzo-Indian: 4.e3, Gligori\'c system with 7...dc
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQK2R w KQ -
+Nimzo-Indian: 4.e3, main line with ...c5
+rnbq1rk1/pp3ppp/5n2/2bpp3/2P5/P3PN2/1P3PPP/RNBQKB1R w KQ -
+QGA: classical, Geller variation *
+rnbq1rk1/pp4pp/2p5/2bppp2/3PP1n1/2P4N/PP1NBPPP/R1BQ1RK1 b - -
+Philidor: Hanham, Berger variation *
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: classical variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/1P3NP1/P3PPBP/RNBQ1RK1 b - -
+Dutch: stonewall, Botwinnik variation
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+Dutch: stonewall with Nc3
+rnbq1rk1/ppp1b1pp/4pn2/3p1p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch: stonewall variation
+rnbq1rk1/ppp1bpp1/4p2p/3p4/2PPn2B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Lasker defense
+rnbq1rk1/ppp1bpp1/4pB1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bxf6
+rnbq1rk1/ppp1bpp1/4pn1p/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QGD: Neo-orthodox variation
+rnbq1rk1/ppp1bpp1/4pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: Neo-orthodox variation, 7.Bh4
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/2RQKBNR b K -
+QGD: Anti-neo-orthodox variation
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1P3/PP3PPP/R2QKBNR w KQ -
+QGD: 4.Bg5 Be7, 5.e3 O-O
+rnbq1rk1/ppp1bppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QGD: 6.Nf3
+rnbq1rk1/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w - -
+Petrov: classical attack, Mason variation
+rnbq1rk1/ppp1ppbp/1n4p1/8/3P4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O Nb6
+rnbq1rk1/ppp1ppbp/3p1np1/4P3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQ -
+Pirc: Austrian attack, 6.e5
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2N2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Zinnowitz variation
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1B3/PP2BPPP/R2QK1NR b KQ -
+King's Indian: Semi-Averbakh system
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N1BN2/PP3PPP/R2QKB1R b KQ -
+King's Indian: Larsen variation
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQ -
+King's Indian: S\"amisch, 5...O-O
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP2B1PP/R1BQK1NR b KQ -
+King's Indian: Four pawns attack, 6.Be2
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PP3/6P1/PPP1NPBP/RNBQK2R b KQ -
+R\'eti: King's Indian attack, Pachman system *
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N1BN2/PPP3PP/R2QKB1R b KQ -
+Pirc: Austrian attack, 6.Be3
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+Pirc: Austrian attack
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+Pirc: Austrian attack, 6.Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/1PPP4/2N1PN2/P4PPP/R1BQKB1R b KQ -
+Gr\"unfeld: Makogonov variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/2RQKBNR b K -
+Gr\"unfeld: Gr\"unfeld gambit, Capablanca variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1P3/PP3PPP/R2QKBNR w KQ -
+Gr\"unfeld: Gr\"unfeld gambit
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+Gr\"unfeld with Bf4 & e3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld with e3 & Qb3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP1B1PPP/R2QKB1R b KQ -
+Gr\"unfeld: Opo\v censky variation
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+Gr\"unfeld with e3 & Bd3
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.O-O
+rnbq1rk1/ppp1ppbp/5np1/3p4/5P2/2P3PN/PP1PP1BP/RNBQK2R b KQ -
+Dutch: Leningrad, Basman system *
+rnbq1rk1/ppp1ppbp/5np1/8/2QPP3/2N2N2/PP3PPP/R1B1KB1R b KQ -
+Gr\"unfeld: Russian variation with e4
+rnbq1rk1/ppp1ppbp/6p1/3n4/3P4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+Neo-Gr\"unfeld, 6.cd Nxd5, 7.O-O
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+King's Indian: S\"amisch, orthodox, 7.d5
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Petrosian system
+rnbq1rk1/ppp2pbp/3p1np1/4P3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+King's Indian: Andersson variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2QK2R b KQ -
+King's Indian: Gligori\'c-Taimanov system
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+King's Indian: S\"amisch, orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+King's Indian: orthodox variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+King's Indian: classical variation
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+King's Indian: Pomar system
+rnbq1rk1/ppp2pbp/4pnp1/3p4/2PP4/1QN1PN2/PP3PPP/R1B1KB1R w KQ -
+Gr\"unfeld: Botvinnik variation
+rnbq1rk1/ppp2ppp/1b3n2/3pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 7.Bb3 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: open, 8...Be6 *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P1N5/2P2PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 8.de *
+rnbq1rk1/ppp2ppp/1b3n2/4N3/1P1Pp3/P7/2P1NPPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Zukertort variation *
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQ1RK1 b - -
+Petrov: classical attack, Mason variation *
+rnbq1rk1/ppp2ppp/3bpn2/3p4/2PP4/P1N1P3/1P2NPPP/R1BQKB1R w KQ -
+Nimzo-Indian: Simagin variation
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3 d7d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBP3/PP3PPP/R1BQK1NR w KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3 d5
+rnbq1rk1/ppp2ppp/4pn2/3p4/2PP4/P1PBP3/5PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3, Botvinnik system
+rnbq1rk1/ppp2ppp/5P2/2b4Q/2pp4/2P5/PP3PPP/RNB1K1NR w KQ -
+Bishop's opening: Pratt variation
+rnbq1rk1/ppp2ppp/5n2/2b1p3/4p3/2PP4/PP1NBPPP/R1BQK1NR w KQ -
+Philidor: Hanham, Steiner variation *
+rnbq1rk1/ppp2ppp/5n2/2bP2N1/2B1p3/2N5/PPPP1PPP/R1BQK2R b KQ -
+two knights: Max Lange attack, Steinitz variation *
+rnbq1rk1/ppp2ppp/5n2/2bP4/2B1p3/2N2N2/PPPP1PPP/R1BQK2R w KQ -
+two knights: Max Lange attack *
+rnbq1rk1/ppp2ppp/5n2/2bPN3/8/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Two knights defense *
+rnbq1rk1/ppp2ppp/5n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQ -
+Philidor: Hanham, Krause variation *
+rnbq1rk1/ppp2ppp/5n2/3Pp3/1b6/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, Nyholm attack *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/2N5/PPPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: open Berlin defense, 5...Be7 *
+rnbq1rk1/ppp2ppp/5n2/3pN3/1b2P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, Rosenthal variation *
+rnbq1rk1/ppp2ppp/5n2/3pN3/4P3/P1PP4/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Rubinstein variation *
+rnbq1rk1/ppp2ppp/5n2/3pp1B1/4P3/P1PP1N2/2P2PPP/R2QKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred, Lipnitsky variation *
+rnbq1rk1/ppp2ppp/5n2/3pp3/1b2P3/2NP4/PPPN1PPP/R1BQKB1R b KQ -
+Ruy Lopez: closed Berlin defense, Chigorin variation *
+rnbq1rk1/ppp2ppp/5n2/4N3/1b2p3/2N5/PPPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Berlin defense, Minckwitz variation *
+rnbq1rk1/ppp2ppp/5n2/8/1b2p3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, l'Hermet variation *
+rnbq1rk1/ppp2ppp/5n2/b2PN3/8/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, Riga variation *
+rnbq1rk1/ppp2ppp/5n2/b2p4/4P3/2NN4/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open Berlin defense, Showalter variation *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/1P2P3/P1N5/2PP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open, 6.d4 b5 *
+rnbq1rk1/ppp2ppp/5n2/b2pN3/4P3/P1N5/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, 6.d4 *
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, center attack *
+rnbq1rk1/ppp2ppp/5n2/b3N3/1P1pP3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Richter variation *
+rnbq1rk1/ppp2ppp/8/2b1p3/8/2P1NN2/PP1P1nPP/R1BQKB1R w KQ -
+Scotch: Cochrane variation *
+rnbq1rk1/ppp2ppp/8/3pb3/2PPn3/3B4/PP3PPP/RNBQ1RK1 w - -
+Petrov: modern attack, Trifunovi\'c variation
+rnbq1rk1/ppp2ppp/8/b2pN3/1P2n3/P1N5/2PP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: open, Friess attack *
+rnbq1rk1/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQ -
+French: Albin-Alekhine-Ch\^atard attack, Spielmann variation
+rnbq1rk1/pppp1pp1/5n1p/4p1B1/4P2P/P1P5/1PP2PP1/R2QKBNR b KQ -
+Ruy Lopez: exchange variation, Alapin gambit *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPP1PPP/R2QKB1R b KQ -
+Ruy Lopez: Archangelsk (counterthrust) variation *
+rnbq1rk1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P2PPP/R1BQKB1R b KQ -
+Ruy Lopez: ...b5 & ...d6 *
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+Nimzo-Indian: Reshevsky variation
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+Nimzo-Indian: 4.e3 O-O
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1PN2/PP3PPP/R1BQKB1R b KQ -
+Nimzo-Indian: 4.e3 e8g8, 5.Nf3, without ...d5
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2NBP3/PP3PPP/R1BQK1NR b KQ -
+Nimzo-Indian: 4.e3 O-O, 5.Bd3
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P1P3/5PPP/R1BQKBNR b KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR w KQ -
+Nimzo-Indian: S\"amisch variation
+rnbq1rk1/pppp1ppp/5n2/4N3/1b2P3/2N5/PPPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, open variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: Berlin defense, 4.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Berlin defense, 4.O-O, d6 *
+rnbq1rk1/pppp1ppp/5n2/4p3/1bB1P3/2N2N2/PPPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: Berlin defense, Beverwijk variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P2P2/1PP3PP/R1BQKBNR b KQ -
+Ruy Lopez: exchange, Gligori\'c variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1P5/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: exchange variation, 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1PQ4/1PP2PPP/R1B1KBNR b KQ -
+Ruy Lopez: exchange, Bronstein variation *
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+Ruy Lopez: Exchange variation doubly deferred (DERLD) *
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+Ruy Lopez: open (Tarrasch) defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/2B1P3/P1N2N2/1PPP1PPP/R1BQK2R b KQ -
+Ruy Lopez: M\"oller defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQ -
+Ruy Lopez: 5.O-O *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+Ruy Lopez: closed defense *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R b KQ -
+Ruy Lopez: Steinitz defense deferred (Russian defense) *
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQ -
+Ruy Lopez: modern Steinitz defense, 5.O-O *
+rnbq1rk1/pppp1ppp/8/3Pp3/1b6/8/PPPPNPPP/R1BQKB1R b KQ -
+Ruy Lopez: Bird's defense, Paulsen variation *
+rnbq1rk1/pppp2p1/8/2b2PPp/3pn3/3B1N2/PPP2P1P/RNBQK2R w KQ -
+KGA: Kieseritsky, Rice gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR w KQ -
+KGA: Hanstein gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/3P4/8/PPP2P1P/RNBQKBNR b KQ -
+KGA: Muzio gambit, Brentano defense *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPP1P1P/RNBQKBNR w KQ -
+KGA: Muzio gambit *
+rnbq1rk1/pppp2pp/5n2/2b1pPP1/8/8/PPPPQP1P/RNB1KBNR b KQ -
+KGA: Muzio gambit, Kling and Horwitz counter-attack *
+rnbq1rk1/ppppb1pp/4p3/5p2/2PPn3/5NP1/PP2PPBP/RNBQ1RK1 w - -
+Dutch defense, Alekhine variation
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R w KQ -
+Dutch defense
+rnbq1rk1/ppppppbp/5np1/6B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQ -
+R\'eti: King's Indian attack, Yugoslav variation *
+rnbq2k1/pp1p1ppp/1bp5/8/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack, 11...c6 *
+rnbq2k1/pp3ppp/1bp5/3p4/1P1Nr3/P1P5/4BPPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, main line, 12.d2d4 *
+rnbq2k1/pp3ppp/1bp5/4r3/1P1Pp3/P1N1P3/2PQB1PP/R4RK1 w - -
+Ruy Lopez: open, Tarrasch trap *
+rnbq2k1/pp3ppp/2p1r3/3p4/1P1P4/P2B4/5PPP/R1BQ1RK1 w - -
+Ruy Lopez: Marshall, Kevitz variation *
+rnbq2k1/pppp1ppp/1b6/3N4/1PBpr1n1/P4N2/2P2PPP/R1BQ1K1R b - -
+Ruy Lopez: Rabinovich variation *
+rnbq3r/pp4pp/2P2nk1/8/2Bbp3/2N5/PPPP1PPP/R1BQK2R w KQ -
+Giuoco Piano: Ghulam Kassim variation *
+rnbq3r/pppp1k2/3b1n1p/8/4PQ1P/8/PPPP2P1/RNB1KB1R w KQ -
+KGA: Allgaier, Horny defense
+rnbqk1n1/pppp1p1r/7b/4N2p/2BPPppP/2N5/PPP3P1/R1BQK2R b KQq -
+KGA: Kieseritsky, long whip defense, Jaenisch variation
+rnbqk1nb/pp3p2/2pp4/4N1p1/2BPPp2/2N5/PPP3P1/R1BQK3 b Qkq -
+KGA: Greco gambit
+rnbqk1nr/1p1p1ppp/p3p3/2b5/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Polugaievsky variation
+rnbqk1nr/5ppp/2p1p3/pp6/PbpP4/2N1PN2/1P1B1PPP/R2QKB1R w KQkq -
+QGD: semi-Slav, Abrahams variation
+rnbqk1nr/p1p1bppp/1p2p3/3pP3/3P4/2N1B3/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Frankfurt variation
+rnbqk1nr/p1pp1ppp/8/1pb1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Wing gambit *
+rnbqk1nr/p1pp2pp/8/1Bb1pp2/4P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: MacDonnell double gambit *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P1Q1/8/PPPP1PPP/RNB1K1NR b KQkq -
+Bishop's opening: del Rio variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor variation *
+rnbqk1nr/pp1p1ppp/2p5/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis counter-gambit *
+rnbqk1nr/pp1pp2p/6p1/2pP1p2/2P5/2P5/P3PPPP/R1BQKBNR w KQkq -
+Beefeater defense
+rnbqk1nr/pp1ppp1p/6pb/2p5/2P1P3/5N2/PP1P1PPP/RNBQKB1R w KQkq -
+Sicilian: Acton extension
+rnbqk1nr/pp1pppbp/8/2p3B1/3P4/8/PPP1PPPP/RN1QKBNR w KQkq -
+Grob: Fritz gambit *
+rnbqk1nr/pp1pppbp/8/2pP2B1/8/8/PPP1PPPP/RN1QKBNR b KQkq -
+Grob: Romford counter-gambit *
+rnbqk1nr/pp2bppp/2p5/3p4/3PpB2/2P1P3/PP3PPP/RN1QKBNR w KQkq -
+Caro-Kann: advance, Short variation *
+rnbqk1nr/pp2ppb1/2p3p1/3pP2p/3P1P2/2N5/PPP3PP/R1BQKBNR w KQkq -
+Robatsch defense: Gurgenidze variation
+rnbqk1nr/pp2ppbp/2pp2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Robatsch defense: two knights, Suttles variation
+rnbqk1nr/pp2ppbp/6p1/1Bpp4/5P2/4PN2/PPPP2PP/RNBQK2R b KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: closed *
+rnbqk1nr/pp2ppbp/6p1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+King's Indian: 3.g3, counterthrust variation *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPPB1PP/RNBQK2R b KQkq -
+Dutch defense *
+rnbqk1nr/pp2ppbp/6p1/3p4/3N4/6P1/PPP1PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd *
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, Russian variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, advance, Bogolyubov variation
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/P1N5/1PP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, 5.a3
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/pp3ppp/4p3/3pP3/1P6/2p2N2/1PP2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, Rauzer variation
+rnbqk1nr/ppp1bppp/3p4/4p3/2B1P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+Philidor: Steinitz variation
+rnbqk1nr/ppp1bppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Charousek (Petrosian) variation
+rnbqk1nr/ppp1bppp/4p3/3pP1B1/3P4/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Vistaneckis (Nimzovich) variation
+rnbqk1nr/ppp1p1bp/3p2p1/5p2/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Modern defense: Averbakh system, Randspringer variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Modern defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Modern defense: Averbakh system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Robatsch defense: two knights variation
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Robatsch defense: Geller's system
+rnbqk1nr/ppp1ppbp/3p2p1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Robatsch defense: Pseudo-Austrian attack
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqk1nr/ppp2p1p/3b4/6p1/8/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Bird: From gambit, Lasker variation
+rnbqk1nr/ppp2pb1/3p3p/6p1/2BPPp1P/3Q1N2/PPP3P1/RNB1K2R b KQkq -
+KGA: Philidor gambit, Schultz variation
+rnbqk1nr/ppp2ppp/1b1p4/8/2P1p3/1N6/PP1PPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Kmoch variation *
+rnbqk1nr/ppp2ppp/3b4/3Pp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit: Maroczy gambit
+rnbqk1nr/ppp2ppp/3b4/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: Schlechter variation *
+rnbqk1nr/ppp2ppp/3bp3/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn: stonewall attack *
+rnbqk1nr/ppp2ppp/3p4/2b1P3/4P3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: classical, Soldatenkov variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/1P2PP2/5N2/P1PP2PP/RNBQKB1R b KQkq -
+KGD: classical, Heath variation
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/2P2N2/PP1P2PP/RNBQKB1R b KQkq -
+KGD: classical, 4.c3
+rnbqk1nr/ppp2ppp/3p4/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation *
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP1NPPP/R1BQKB1R b KQkq -
+French: Winawer, Alekhine (Mar\'oczy) gambit
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Winawer (Nimzovich) variation
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPPB1PPP/R2QKBNR b KQkq -
+French: Winawer, fingerslip variation
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance variation
+rnbqk1nr/ppp2ppp/4p3/8/3Pp3/P1b5/1PP1NPPP/R1BQKB1R w KQkq -
+French: Winawer, Alekhine gambit
+rnbqk1nr/ppp2ppp/8/2bp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Balogh variation *
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/2P5/PP1P1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis counter-gambit
+rnbqk1nr/ppp2ppp/8/2bpp3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Lewis gambit *
+rnbqk1nr/ppp2ppp/8/2bpp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Ponziani gambit *
+rnbqk1nr/ppp2ppp/8/4P3/1bP5/4p3/PP1B1PPP/RN1QKBNR w KQkq -
+QGD: Albin counter-gambit, Lasker trap
+rnbqk1nr/ppp3pp/3p4/2b1pp2/4PP2/2P2N2/PP1P2PP/RNBQKB1R w KQkq -
+KGD: classical counter-gambit
+rnbqk1nr/ppp3pp/4P3/2bp2N1/4p3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Berger variation
+rnbqk1nr/ppp3pp/8/2b2p2/2BpP3/2P2N2/PP4PP/RNBQK2R b KQkq -
+KGD: classical, R\'eti variation
+rnbqk1nr/pppp1pbp/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Paulsen defense
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp1P/5N2/PPPP2P1/RNBQK2R b KQkq -
+KGA: Philidor gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Hanstein gambit
+rnbqk1nr/pppp1pbp/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+King's knight's gambit
+rnbqk1nr/pppp1ppp/4p3/8/1bPP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Franco-Indian (Keres) defense
+rnbqk1nr/pppp1ppp/8/2b1p3/1PB1P3/8/P1PP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Wing gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/2P5/PP1P1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Philidor variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening: Classical variation *
+rnbqk1nr/pppp1ppp/8/2b1p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Lewis gambit
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Bishop's opening: Philidor counter-attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Bishop's opening: Berlin defense *
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Bishop's opening *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bishop's opening: Calabrese counter-gambit *
+rnbqk1nr/pppp1ppp/8/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: classical variation
+rnbqk1nr/pppp1ppp/8/2b1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: Hillbilly attack *
+rnbqk1nr/pppp1ppp/8/2b1p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Krejcik variation *
+rnbqk1nr/pppp1ppp/8/4p3/1bB1PP2/8/P1PP2PP/RNBQK1NR b KQkq -
+Bishop's opening: MacDonnell double gambit
+rnbqk1nr/pppp1ppp/8/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English, Kramnik-Shirov counterattack
+rnbqk1nr/pppp1ppp/8/8/2B1P2b/5N2/PPPP3p/RNBQ1R1K b kq -
+KGA: Cunningham, three pawns gambit
+rnbqk1nr/pppp1ppp/8/8/2B1Pp1b/5NP1/PPPP3P/RNBQK2R b KQkq -
+KGA: Cunningham, Bertin gambit
+rnbqk1nr/pppp1ppp/8/8/2BPP2b/5N2/P1P4p/RNBQ1R1K b kq -
+Bishop's opening: Four pawns' gambit
+rnbqk1nr/pppp2pp/3b4/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Schurig gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/1P6/8/P1PP1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bryan counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Bledow variation *
+rnbqk1nr/pppp2pp/8/2b1pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+KGA: bishop's gambit, Maurian defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: bishop's gambit *
+rnbqk1nr/pppp2pp/8/2b1pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Steinitz defense *
+rnbqk1nr/pppp2pp/8/2b1pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening: Greco gambit *
+rnbqk1nr/pppp2pp/8/4Pp2/1b1p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Nimzovich variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGA: bishop's gambit, Anderssen variation *
+rnbqk1nr/pppp2pp/8/4pP2/3b4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: bishop's gambit, Morphy variation *
+rnbqk1nr/ppppb1pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit *
+rnbqk1nr/ppppbp1p/8/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Polerio defense
+rnbqk1nr/ppppbppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Cunningham defense
+rnbqk1nr/ppppp1bp/6p1/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, Karlsbad variation
+rnbqk1nr/ppppppbp/6p1/8/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Robatsch defense
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqk1nr/ppppppbp/6p1/8/3PPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Robatsch defense: three pawns attack
+rnbqk1nr/ppppppbp/8/8/3P2p1/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Grob: spike attack *
+rnbqk1r1/ppp2pP1/4p3/3p4/1b1P2Qp/2N5/PPP2PP1/R3KBNR b KQq -
+French: MacCutcheon, Grigoriev variation
+rnbqk2r/1p2bp2/p2ppn1p/6p1/3NPP1B/2N2Q2/PPP3PP/R3KB1R w KQkq -
+Sicilian: Najdorf, G\"oteborg (Argentine) variation
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 7...Be7
+rnbqk2r/1pp2ppp/1b3n2/p2p4/4p3/1N1P2P1/PPP1PPBP/RNBQK2R w KQkq -
+Alekhine's defense: modern, Keres variation *
+rnbqk2r/1ppnbppp/p3p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Mar\'oczy variation
+rnbqk2r/2pp1ppp/5n2/ppb1p3/4P3/1BN5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined, 5.a4 *
+rnbqk2r/p1p2ppp/1p1bpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation *
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: Fischer variation, 5.Ne2
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: Fischer variation
+rnbqk2r/p1pp1ppp/5n2/1Bb1p3/4P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Evans gambit declined *
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Evans counter-gambit *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n1Q1/1B6/PPPP1PPP/R1B1K1NR b KQkq -
+Evans gambit declined, Hirschbach variation *
+rnbqk2r/p1pp1ppp/8/2b1p3/Np2n3/1B5N/PPPP1PPP/R1BQK2R b KQkq -
+Evans gambit declined, Lange variation *
+rnbqk2r/p2p1pp1/4pn1p/1ppP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, ...b5 gambit
+rnbqk2r/p2p1ppp/1p2pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, O'Kelly variation
+rnbqk2r/p2p1ppp/2p2n2/1pb1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano: Bird's attack *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Evans gambit: Mayet defense *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: 5...Be7 *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/4P3/2NB4/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Stone-Ware variation *
+rnbqk2r/p2p1ppp/2p2n2/2b1p3/B3P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/1Bb1p3/8/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/p4ppp/2p2n2/2b5/B3p3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit: Cochrane variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/B3P3/2NP4/PPP2PPP/R1BQK1NR b KQkq -
+Evans gambit *
+rnbqk2r/p4ppp/2p2n2/2bpp3/BP2P3/2N5/P1PP1PPP/R1BQK1NR b KQkq -
+Evans gambit: Leonhardt variation *
+rnbqk2r/p4ppp/2p2n2/2bpp3/N3P3/8/PPPPBPPP/R1BQK1NR b KQkq -
+Evans gambit: Cordel variation *
+rnbqk2r/pp1n1ppp/4p3/2bpP3/5PQ1/2N5/PPP3PP/R1B1KBNR b KQkq -
+French: Steinitz, Bradford attack
+rnbqk2r/pp1nbppp/4p3/2ppP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Breyer variation
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Piano *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/2B1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: close variation *
+rnbqk2r/pp1p1ppp/2p2n2/2b1p3/4P3/3P4/PPP1BPPP/RNBQK1NR w KQkq -
+Philidor: Steinitz variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1b2P3/1BN5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical defense, Charousek variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Ruy Lopez: classical defense, 4.c3 *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1P3/2N5/PPPPQPPP/R1B1K1NR b KQkq -
+Ruy Lopez: classical defense, Boden variation *
+rnbqk2r/pp1p1ppp/2p2n2/4p3/1bB1PP2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Ruy Lopez: Cordel gambit *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PPB1PPP/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4PP2/P1NP4/1PP3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, siesta variation *
+rnbqk2r/pp1p1ppp/4p3/2pP4/1bP1n3/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Nimzo-Indian: three knights, Euwe variation
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: 4.e3 c5, 5.Ne2 (Rubinstein, anti-H\"ubner system)
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+Nimzo-Indian: 4.e3 c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, 4...c5
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P1P3/5PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp1p1ppp/4pn2/2pP4/1bP5/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights, Korchnoi variation
+rnbqk2r/pp1p1ppp/4pn2/4P3/1b1N4/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Pin, Koch variation
+rnbqk2r/pp1p1ppp/4pn2/8/1b1NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Pin variation (Sicilian counter-attack)
+rnbqk2r/pp1p1ppp/5n2/2p1p3/2P5/3P4/PP1QPPPP/RN2KBNR w KQkq -
+Sicilian: Canal-Sokolsky attack, Sokolsky variation *
+rnbqk2r/pp1p1ppp/5n2/4p3/1b1NP3/2NB4/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Pin, Jaffe variation
+rnbqk2r/pp1p1ppp/5n2/b1p1p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Duras (Keres) variation *
+rnbqk2r/pp1pp1bp/2p3pn/5p2/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w kq -
+Dutch: Leningrad, Basman system
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan accepted *
+rnbqk2r/pp1pppbp/5np1/2p5/1P6/P3PN2/2PP1PPP/RNBQKB1R b KQkq -
+English: Romanishin gambit *
+rnbqk2r/pp2npbp/6p1/3pp3/8/1N4P1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.cd, main line *
+rnbqk2r/pp2nppp/4p3/2ppP3/3P2Q1/P1P5/2P2PPP/R1B1KBNR b KQkq -
+French: Winawer, advance, poisoned pawn variation
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+French: Winawer, advance, positional main line
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR w KQkq -
+French: Winawer, advance, 6...Ne7
+rnbqk2r/pp2nppp/4p3/2ppP3/P2P4/2P5/2P2PPP/R1BQKBNR b KQkq -
+French: Winawer, advance, Smyslov variation
+rnbqk2r/pp2ppbp/3p1np1/2p5/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Pirc: Austrian attack, dragon formation
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP1BPPP/R2QK2R b KQkq -
+Sicilian: dragon, classical attack
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+Sicilian: dragon, Yugoslav attack
+rnbqk2r/pp2ppbp/5np1/1Bpp4/8/1P2PN2/PBPP1PPP/RN1QK2R b KQkq -
+Queen's Indian: Capablanca variation *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+Catalan: open, classical line *
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Catalan: open, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+Catalan: closed, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+Neo-Gr\"unfeld, 5.Nf3 *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 b kq -
+Dutch defense *
+rnbqk2r/pp2ppbp/5np1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R w KQkq -
+Dutch: Leningrad, main variation *
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+Queen's Indian: 5.Bg2 Be7 *
+rnbqk2r/pp2ppbp/6p1/2p4n/2PP4/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: Rubinstein variation *
+rnbqk2r/pp2ppbp/6p1/2p5/2PP2n1/1P3N2/PB1P1PPP/RN1QKB1R w KQkq -
+Queen's Indian: B\"urger variation *
+rnbqk2r/pp3pbp/3p1np1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR b KQkq -
+Benoni: Taimanov variation
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+Benoni: classical, 8.Bg5
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+Benoni: classical without 9.O-O
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: Mikenas variation
+rnbqk2r/pp3pp1/3ppn1p/2pP4/1bP4B/2N5/PP2PPPP/R2QKBNR w KQkq -
+Nimzo-Indian: Leningrad, main line
+rnbqk2r/pp3ppp/2p2n2/1BbP4/3p4/5N2/PPP1QPPP/RNB1K2R b KQkq -
+Bishop's opening: Urusov gambit, Panov variation *
+rnbqk2r/pp3ppp/2p2n2/2b1p3/4P3/1B1p4/PPPPQPPP/RNB1K1NR w KQkq -
+Giuoco Piano: Eisinger variation *
+rnbqk2r/pp3ppp/2p2n2/2bP4/2BPp3/2N2N2/PPP2PPP/R1BQK2R b KQkq d3
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bPN3/4p3/2N5/PPPPBPPP/R1BQK2R b KQkq -
+Hungarian defense: Tartakower variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/1BN5/PPPPQPPP/R1B1K1NR b KQkq -
+Giuoco Piano: center-holding variation *
+rnbqk2r/pp3ppp/2p2n2/2bpp3/4P3/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Delmar variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP2P1/1PPB1P1P/R2QKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, fianchetto (Bronstein) variation *
+rnbqk2r/pp3ppp/2p2n2/b2pp3/4P3/P1NP4/1PPBNPPP/R2QKB1R b KQkq -
+Ruy Lopez: modern Steinitz defense, Rubinstein variation *
+rnbqk2r/pp3ppp/2pb1n2/3p4/2PPp3/1QN1P3/PP3PPP/R1B1KBNR w KQkq -
+French: advance, Milner-Barry gambit *
+rnbqk2r/pp3ppp/2pb4/4n3/3pP3/3P1N2/PPP1B1PP/RNBQK2R b KQkq -
+Ponziani counter-gambit, Cordel variation *
+rnbqk2r/pp3ppp/2pbpn2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+Colle system *
+rnbqk2r/pp3ppp/3p1n2/2p1p3/1b2P3/2NP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Duras variation *
+rnbqk2r/pp3ppp/3p1n2/b1p1p3/4P3/P1NP1N2/1PP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Morphy defense, Duras variation *
+rnbqk2r/pp3ppp/4p3/2Pn4/8/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch, Keres variation
+rnbqk2r/pp3ppp/4pn2/2b3B1/3p4/P3P3/1PP2PPP/RN1QKBNR w KQkq -
+QGA: Alekhine defense, Alatortsev variation *
+rnbqk2r/pp3ppp/4pn2/2bp4/2P5/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA: classical variation *
+rnbqk2r/pp3ppp/4pn2/2pP4/3P4/P1P2P2/4P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pp3ppp/5n2/1B1pN3/1b1Pp3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Giuoco Piano: Anderssen variation *
+rnbqk2r/pp3ppp/5n2/2bpp3/2B5/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Giuoco Piano *
+rnbqk2r/pp3ppp/5n2/2bpp3/8/1BNP4/PPP2PPP/R1BQK1NR b KQkq -
+Giuoco Piano: LaBourdonnais variation *
+rnbqk2r/pp3ppp/5n2/2ppp3/1b2P3/2NP4/PPPB1PPP/R2QKBNR w KQkq -
+Ruy Lopez: old Steinitz defense, semi-Duras variation *
+rnbqk2r/pp4pp/2p2n2/2bPp3/2B2P2/8/PPP3PP/RNBQK1NR w KQkq -
+KGD: classical, R\'eti variation *
+rnbqk2r/pp4pp/4p3/2Pn1p2/8/P1P2P2/4P1PP/R1BQKBNR w KQkq -
+Nimzo-Indian: S\"amisch, Romanovsky variation
+rnbqk2r/ppn1bppp/8/2p1p3/8/2NP2PN/PP2PPBP/R1BQK2R b KQkq -
+Sicilian: accelerated fianchetto, Simagin variation *
+rnbqk2r/ppp1b1pp/3p1n2/3Pp3/4N3/2PB4/PP3PPP/RNBQK2R w KQkq -
+Ponziani counter-gambit, Cordel variation
+rnbqk2r/ppp1bppp/4p3/3p2B1/2PPn3/2N1P3/PP3PPP/R2QKBNR w KQkq -
+QGD: Lasker variation
+rnbqk2r/ppp1bppp/4p3/3pP1B1/3Pn3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical, Tartakower variation
+rnbqk2r/ppp1bppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R3KBNR b KQkq -
+French: classical, Anderssen-Richter variation
+rnbqk2r/ppp1bppp/4pB2/3p4/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: classical, Anderssen variation
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: 4.Bg5 Be7
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: classical
+rnbqk2r/ppp1bppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+English: Neo-Catalan declined
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: classical variation (5.Bf4)
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: closed, 5.Nf3
+rnbqk2r/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+Catalan: open, classical line
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/2PP4/PP2PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern, Flohr variation *
+rnbqk2r/ppp1bppp/5n2/3pp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Tayler opening *
+rnbqk2r/ppp1bppp/8/3pP3/4n3/2N2N2/PPPP2PP/R1BQKB1R w KQkq -
+Vienna gambit: Breyer variation
+rnbqk2r/ppp1npbp/6p1/3pp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+R\'eti: King's Indian attack, Pachman system
+rnbqk2r/ppp1nppp/8/8/3PN3/8/PP3PPP/R2QKBNR w KQkq -
+Bishop's opening: Lisitsyn variation *
+rnbqk2r/ppp1ppbp/1n1p2p1/4P3/P2P4/1B3N2/1PP2PPP/RNBQK2R b KQkq -
+Alekhine's defense: modern, Keres variation
+rnbqk2r/ppp1ppbp/1n4p1/8/3PP3/6P1/PP2NPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.cd, main line
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+King's Indian: Smyslov system
+rnbqk2r/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP3PPP/R2QKBNR b KQkq -
+King's Indian: accelerated Averbakh system
+rnbqk2r/ppp1ppbp/3p1np1/8/2BPPP2/2N5/PPP3PP/R1BQK1NR b KQkq -
+Pirc: Austrian attack, Ljubojevi\'c variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+King's Indian: fianchetto variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+King's Indian: 5.Nf3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+King's Indian: S\"amisch variation
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3P1P/R1BQKBNR b KQkq -
+King's Indian with e4 & g3
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR b KQkq -
+King's Indian: Makagonov system (5.h3)
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+King's Indian: 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2NPPP/R1BQKB1R b KQkq -
+King's Indian: Kramer system
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPPP2/2N5/PP4PP/R1BQKBNR b KQkq -
+King's Indian: Four pawns attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP1P1/2N5/PPP1BP1P/R1BQK1NR b KQkq -
+Pirc: Chinese variation
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP2P/2N5/PPP1BPP1/R1BQK1NR b KQkq -
+Pirc: bayonet (Mariotti) attack
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N1P/PPP2PP1/R1BQKB1R b KQkq -
+Pirc: classical, h3 system
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+Pirc: classical system, 5.Be2
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+Pirc: classical (two knights) system
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bg5
+rnbqk2r/ppp1ppbp/5np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+Queen's Indian: Marienbad system *
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP1B2/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Gr\"unfeld: 5.Bf4
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Russian variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: 5.e3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Gr\"unfeld: Three knights variation
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Neo-Gr\"unfeld, 5.Nf3
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+King's Indian: 3.g3, counterthrust variation
+rnbqk2r/ppp1ppbp/5np1/3p4/Q1PP4/2N2N2/PP2PPPP/R1B1KB1R b KQkq -
+Gr\"unfeld: Flohr variation
+rnbqk2r/ppp1ppbp/6p1/3n4/3P4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Neo-Gr\"unfeld, 5.cd
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+Gr\"unfeld: exchange, classical variation
+rnbqk2r/ppp1ppbp/6p1/8/3PP3/2P2N2/P4PPP/R1BQKB1R b KQkq -
+Gr\"unfeld: modern exchange variation
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Dutch defense, Blackburne variation *
+rnbqk2r/ppp1ppbp/6pn/3p4/5P2/6P1/PPPPP1BP/RNBQK1NR w KQkq -
+Dutch: Leningrad, Karlsbad variation *
+rnbqk2r/ppp2p1p/3b1n2/3PN3/2B2ppP/8/PPPP2P1/RNBQ1RK1 b kq -
+KGA: Kieseritsky, Rice gambit
+rnbqk2r/ppp2p2/4p1pp/3pP3/3Pn1Q1/2P5/P1PB1PPP/R3KBNR w KQkq -
+French: MacCutcheon, Lasker variation, 8...g6
+rnbqk2r/ppp2pbp/6p1/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+English: Anglo-Gr\"unfeld defense, Korchnoi variation
+rnbqk2r/ppp2pp1/4pP1p/3p2B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Chigorin variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P3B/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Bernstein variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, Janowski variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: MacCutcheon, Dr. Olland (Dutch) variation
+rnbqk2r/ppp2pp1/4pn1p/3pP3/3P4/2b5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Lasker variation
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/3B4/PPP2PPP/RNBQK2R b KQkq -
+Petrov: classical attack, Marshall variation *
+rnbqk2r/ppp2ppp/3b3n/8/3P4/5N2/PPP1P1PP/RNBQKB1R b KQkq -
+Bird: From gambit, Lipke variation
+rnbqk2r/ppp2ppp/3b4/3np3/2B5/P3P3/1P1P1PPP/RNBQK1NR b KQkq -
+Sicilian: Kan, Polugaievsky variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P1P1/1P1P1P1P/RNBQKBNR b KQkq -
+Sicilian: Kan, Swiss cheese variation *
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, 5.Bd3 *
+rnbqk2r/ppp2ppp/3b4/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+Petrov: classical attack, Marshall variation
+rnbqk2r/ppp2ppp/3bpn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Giuoco Pianissimo *
+rnbqk2r/ppp2ppp/3p1n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense (Modern bishop's opening) *
+rnbqk2r/ppp2ppp/3p1n2/4p3/1b2P3/5N2/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer variation *
+rnbqk2r/ppp2ppp/3p1n2/4p3/4P3/2bP1N2/PPP2PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Berlin defense, Anderssen variation *
+rnbqk2r/ppp2ppp/3p1n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Anderssen variation *
+rnbqk2r/ppp2ppp/3p4/2b1pP2/2B1P1n1/2N5/PPPP2PP/R1BQK1NR b KQkq -
+Giuoco Pianissimo: Dubois variation *
+rnbqk2r/ppp2ppp/3p4/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Kieseritsky variation *
+rnbqk2r/ppp2ppp/3p4/4p3/1b2n3/2P2N2/PP1PNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense, Mortimer trap *
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P1Q5/1P2PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, main line
+rnbqk2r/ppp2ppp/4p3/3p4/2PPn3/P7/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, main line, 7.Qc2
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1b1PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: MacCutcheon variation
+rnbqk2r/ppp2ppp/4pn2/3p2B1/1bPP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Vienna variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Ragozin variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/P1N5/1PQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical, Noa variation, 5.a3
+rnbqk2r/ppp2ppp/4pn2/3pP1B1/1b1P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: MacCutcheon, advance variation
+rnbqk2r/ppp2ppp/4pn2/6B1/1bpP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD: Ragozin, Vienna variation
+rnbqk2r/ppp2ppp/5n2/1BbPp3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/1PP5/8/P2P1PPP/RNBQKBNR b KQkq -
+Center game, Kieseritsky variation *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch gambit: Dubois-R\'eti defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Scotch gambit: Benima defense *
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Bishop's opening/Petrov: Urusov gambit *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppp2ppp/5n2/2bpp3/4P3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Klein variation *
+rnbqk2r/ppp2ppp/5n2/3P4/1b3P2/2NPp3/PPPB2PP/R2QKBNR w KQkq -
+KGD: Falkbeer, Morphy gambit
+rnbqk2r/ppp2ppp/5n2/3Pp3/1b6/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: Relfsson gambit (`MacLopez') *
+rnbqk2r/ppp2ppp/5n2/3p4/1b1P4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+Nimzo-Indian: classical, Noa variation, 5.cd ed
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP1P2/2P3PP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, Alapin variation *
+rnbqk2r/ppp2ppp/5n2/3pp3/4P3/P1PP4/2P2PPP/R1BQKBNR w KQkq -
+Ruy Lopez: modern Steinitz defense, Richter variation *
+rnbqk2r/ppp2ppp/8/1Bbp4/3NP1n1/2N5/PPP2PPP/R1BQK2R b KQkq -
+two knights defense: Pincus variation *
+rnbqk2r/ppp2ppp/8/2bPp3/2B3n1/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch gambit *
+rnbqk2r/ppp2ppp/8/2bPp3/5P2/3P3N/PPP3Pn/RNBQKB1R w KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation *
+rnbqk2r/ppp2ppp/8/2bPp3/6n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense, Perreux variation *
+rnbqk2r/ppp2ppp/8/2bp4/3NP1n1/2N5/PPP2PPP/R1BQKB1R w KQkq -
+two knights defense: Lolli attack *
+rnbqk2r/ppp2ppp/8/2bpp3/4P1n1/2PP4/PP1N1PPP/R1BQKBNR w KQkq -
+Philidor: Hanham, Kmoch variation *
+rnbqk2r/ppp3p1/8/2bppPPp/4nP2/8/PPPPQ2P/RNB1KBNR w KQkq -
+KGA: Kieseritsky, Salvio defense, Cozio variation *
+rnbqk2r/ppp3p1/8/3ppPPp/3b4/7P/PPP3K1/RNBQ1BNR w kq -
+KGA: Allgaier, Urusov attack *
+rnbqk2r/ppp3pp/5n2/2bppPP1/8/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Ghulam Kassim gambit *
+rnbqk2r/ppp3pp/5p2/3np3/1b2P3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+Sicilian: Prins variation, Venice attack *
+rnbqk2r/pppn1pp1/4p2p/3pP3/1b1P4/2N5/PPPB1PPP/R2QKBNR w KQkq -
+French: MacCutcheon, Tartakower variation
+rnbqk2r/pppnb1pp/4pp2/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR w KQkq -
+French: Albin-Alekhine-Ch\^atard attack, Teichmann variation
+rnbqk2r/pppnbppp/4p3/3pP1B1/3P3P/2N5/PPP2PP1/R2QKBNR b KQkq -
+French: Albin-Alekhine-Ch\^atard attack
+rnbqk2r/pppp1ppp/1b3n2/4p3/1PB1P3/P1N5/2PP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Graz variation *
+rnbqk2r/pppp1ppp/1b3n2/4p3/NP2P3/P7/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Taimanov (chase/wing/accelerated counterthrust) variation *
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Nimzo-Indian: Leningrad variation
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Nimzo-English opening
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Spielmann variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+Nimzo-Indian: 4.e3
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Nimzo-Indian: three knights variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2P2/PP2P1PP/R1BQKBNR b KQkq -
+Nimzo-Indian: Kmoch variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+Nimzo-Indian: Romanishin-Kasparov (Steiner) system
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Nimzo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: classical variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2NQ4/PP2PPPP/R1B1KBNR b KQkq -
+Nimzo-Indian: Mikenas attack
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+Bogo-Indian defense, Gr\"unfeld variation
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Bogo-Indian defense
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+Nimzo-Indian: S\"amisch variation
+rnbqk2r/pppp1ppp/5n2/1B2p3/1b2P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Giuoco Piano *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+King's pawn game *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Hungarian defense *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Italian variation *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Rousseau gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: L\'opez counter-gambit *
+rnbqk2r/pppp1ppp/5n2/2b1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+Latvian gambit, 3.Bc4 *
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense *
+rnbqk2r/pppp1ppp/5n2/4P3/1bB2p2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Paulsen attack
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: Brentano defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P1Q1/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Vienna: Zhuravlev countergambit
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Berlin defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2P2/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Nuremberg variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto (Smyslov/Barnes) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez (Spanish opening) *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ruy Lopez: Lucena defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPQPPP/R1B1KBNR b KQkq -
+Ruy Lopez: Vinogradov variation *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: old Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bB1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: classical (Cordel) defense *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+Sicilian: Nimzovich-Rossolimo attack (with ...g6, without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, Smyslov system
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian: Nimzovich-Rossolimo attack (without ...d6) *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP1BPPPP/RN1QKBNR b KQkq -
+Sicilian: Canal-Sokolsky attack, 3...Bd7 *
+rnbqk2r/pppp1ppp/5n2/4p3/1bP5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack *
+rnbqk2r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1bPP/R1BQK1NR w KQkq -
+Giuoco Piano: Jerome gambit *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1PP4/2P2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense, exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPP1PPP/R1BQKB1R w KQkq -
+Ruy Lopez: Treybal (Bayreuth) variation (exchange var. deferred) *
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez: exchange variation *
+rnbqk2r/pppp1ppp/5n2/4p3/Nb2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Pollock defense *
+rnbqk2r/pppp1ppp/5n2/b2Np3/4P3/P7/1PPP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Bird's defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/1P2P3/P1N5/2PP1PPP/R1BQKBNR b KQkq -
+Ruy Lopez: Caro variation *
+rnbqk2r/pppp1ppp/5n2/b3p3/2B1P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Classical defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+Ruy Lopez: Morphy defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N3P1/1PPP1P1P/R1BQKBNR b KQkq -
+Ruy Lopez: fianchetto defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+Ruy Lopez *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPPNPPP/R1BQKB1R b KQkq -
+Ruy Lopez: Cozio defense deferred *
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+Ruy Lopez: modern Steinitz defense *
+rnbqk2r/pppp1ppp/5n2/b3p3/4PP2/P1N5/1PPP2PP/R1BQKBNR b KQkq -
+Ruy Lopez: Schliemann defense deferred *
+rnbqk2r/pppp1ppp/5n2/bB2p3/4P3/P1N5/1PPP1PPP/R1BQK1NR b KQkq -
+Ruy Lopez: Alapin's defense deferred *
+rnbqk2r/pppp1ppp/8/2b1P3/3Pn3/8/PPP3PP/RNBQKBNR b KQkq -
+Latvian: Polerio variation *
+rnbqk2r/pppp1ppp/8/2b1P3/4n3/5N2/PPPP2PP/RNBQKB1R b KQkq -
+Latvian: corkscrew counter-gambit *
+rnbqk2r/pppp1ppp/8/2b1p3/2B1P1n1/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+two knights defense: Wilkes Barre (Traxler) variation *
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp1ppp/8/2b5/1P1pP1n1/2N2N2/P1P2PPP/R1BQKB1R b KQkq -
+two knights defense: Ulvestad variation *
+rnbqk2r/pppp1ppp/8/2b5/3NP3/2N5/PPP2nPP/R1BQKB1R w KQkq -
+two knights defense: Fegatello attack *
+rnbqk2r/pppp1ppp/8/2b5/N2pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense *
+rnbqk2r/pppp1ppp/8/2bN4/3pP1n1/5N2/PPP2PPP/R1BQKB1R b KQkq -
+two knights defense: Fritz variation *
+rnbqk2r/pppp1ppp/8/8/Nb1pP1n1/5N2/PPP2PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/pppp2p1/5n2/2b1pP1p/6P1/8/PPPP1PBP/RNBQK1NR w KQkq -
+KGA: Philidor gambit *
+rnbqk2r/pppp2p1/8/2b1pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4 *
+rnbqk2r/pppp2p1/8/2b1pPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Walker attack *
+rnbqk2r/pppp2pp/4pn2/5p2/1bPP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense: Dutch-Indian (Nimzo-Dutch) variation
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Blachly gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/6P1/8/PPPP1PBP/RNBQK1NR b KQkq -
+King's knight's gambit *
+rnbqk2r/pppp2pp/5n2/2b1pP2/8/5N2/PPPPBPPP/RNBQK2R b KQkq -
+KGA: Cunningham, Euwe defense *
+rnbqk2r/pppp2pp/5n2/2b2P2/3N4/2P5/P4PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, Botvinnik variation *
+rnbqk2r/pppp2pp/5n2/4pPP1/8/8/PPPP1b1P/RNBQKBNR w KQkq -
+KGA: Lolli gambit (wild Muzio gambit) *
+rnbqk2r/pppp2pp/8/2b1pPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Salvio gambit *
+rnbqk2r/pppp3p/5np1/2b1pP1B/8/8/PPPP1PPP/RNBQK1NR w KQkq -
+KGA: Cunningham, Bertin gambit *
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP1BPPBP/RN1QK1NR w KQkq -
+Dutch-Indian, Alekhine variation
+rnbqk2r/ppppb1pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqk2r/ppppbppp/3n4/4p2Q/8/1BN5/PPPP1PPP/R1B1K1NR w KQkq -
+Vienna game
+rnbqk2r/ppppbppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Inverted Hungarian *
+rnbqk2r/ppppbppp/5n2/8/2B1Pp2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Cunningham, Euwe defense
+rnbqk2r/ppppbppp/7n/8/N3P3/2P2N1P/P4PP1/R1BQKB1R w KQkq -
+two knights defense: Steinitz variation *
+rnbqk2r/ppppbppp/8/4P3/N3n3/2P2N1P/P1Q2PP1/R1B1KB1R b KQkq -
+two knights defense: G\"oring variation *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N1P/P4PP1/R1BQKB1R b KQkq -
+Two knights defense *
+rnbqk2r/ppppbppp/8/8/N3P1n1/2P2N2/P4PPP/R1BQKB1R w KQkq -
+Two knights defense *
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Dutch: Leningrad, main variation
+rnbqk2r/ppppp2p/6pb/5P2/3P4/8/PPP2PPP/RN1QKBNR b KQkq -
+Amar gambit *
+rnbqk2r/ppppppbp/5np1/6B1/3P4/8/PPPNPPPP/R2QKBNR b KQkq -
+R\'eti: King's Indian attack, Keres variation *
+rnbqk2r/ppppppbp/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack *
+rnbqk2r/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+King's Indian: 4.e4
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 6.Bg5
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Lipnitzky attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: Najdorf, Byrne (English) attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Zagreb (fianchetto) variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N4P/PPP2PP1/R1BQKB1R b KQkq -
+Sicilian: Najdorf, Adams attack
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Najdorf, Opo\v censky variation
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Najdorf
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Najdorf, 6.f4
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: Petrosian system *
+rnbqkb1r/1p3p1p/p2ppnp1/8/2PNP3/3B4/PP3PPP/RNBQ1RK1 w kq -
+Sicilian: Kan, Gipslis variation
+rnbqkb1r/1p3ppp/p1p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+QGD semi-Slav: accelerated Meran (Alekhine variation)
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R w KQkq -
+Sicilian: Najdorf, 6...e6
+rnbqkb1r/1p3ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R b KQkq -
+Sicilian: Najdorf, 7.f4
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N1B3/PPPQ1PPP/R3KB1R b KQkq -
+Sicilian: Scheveningen, English variation
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+Sicilian: Scheveningen (Paulsen), classical variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP2QPPP/RNB2RK1 b kq -
+QGA: classical, 7.Qe2
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, 6...a6
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BPP3/5N2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical, Geller variation
+rnbqkb1r/1p3ppp/p3pn2/2p5/P1BP4/4PN2/1P3PPP/RNBQ1RK1 b kq -
+QGA: classical, Rubinstein variation
+rnbqkb1r/1p3ppp/p4n2/1N1pp1B1/Q1P5/2N5/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Krause variation
+rnbqkb1r/1pp1pppp/p4n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGA, Bogolyubov variation
+rnbqkb1r/1ppp1ppp/p3pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Dzindzikhashvili defense
+rnbqkb1r/2pp1ppp/p3pn2/1p6/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Romanishin gambit
+rnbqkb1r/3ppppp/P4n2/2pP4/8/8/PP2PPPP/RNBQKBNR b KQkq -
+Benk\"o gambit accepted
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Benk\"o gambit: Zaitsev system
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit half accepted
+rnbqkb1r/4pppp/3p1n2/1NpP4/1pB1P3/8/PP3PPP/R1BQK1NR b KQkq -
+Benk\"o gambit: Nescaf\'e Frapp\'e attack
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+Sicilian: Najdorf, Polugayevsky variation
+rnbqkb1r/5ppp/p2ppn2/1p6/3NP3/1BN5/PPP2PPP/R1BQK2R w KQkq -
+Sicilian: Sozin with ...a6 and ...b5
+rnbqkb1r/5ppp/p3pn2/1pp5/2BP4/4PN2/PP2QPPP/RNB2RK1 w kq -
+QGA: classical, 7...b5
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2P5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: Queens Indian formation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP1B2/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Queen's Indian: Miles variation
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Queen's Indian: 4.Nc3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+Queen's Indian: 4.e3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R b KQkq -
+Queen's Indian: 4.g3
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+Queen's Indian: Petrosian system
+rnbqkb1r/p1pp1ppp/5n2/1p2p3/2P5/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit deferred *
+rnbqkb1r/p1pp1ppp/5n2/1p4N1/2P1p3/2N5/PP1PPPPP/R1BQKB1R w KQkq -
+English: Bellon gambit
+rnbqkb1r/p1pp1ppp/5n2/1p6/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: Wing gambit *
+rnbqkb1r/p1pp2pp/5n2/1p2pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Heath variation *
+rnbqkb1r/p1ppp1pp/1p3n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Nimzovich variation
+rnbqkb1r/p1pppp1p/5np1/1p1P4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian: Danube gambit
+rnbqkb1r/p1pppp1p/5np1/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation *
+rnbqkb1r/p1pppppp/1p3n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's Indian accelerated
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's Indian defense
+rnbqkb1r/p1pppppp/1p3n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: Nimzovich-Larsen attack *
+rnbqkb1r/p1pppppp/5n2/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Santasiere's folly *
+rnbqkb1r/p1pppppp/5n2/1p6/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack, Spassky's variation
+rnbqkb1r/p1pppppp/8/1p1nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense: O'Sullivan gambit
+rnbqkb1r/p2n1ppp/1p2p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR w KQkq -
+French: Tarrasch, Botvinnik variation
+rnbqkb1r/p2p1pp1/5n1p/1ppP2B1/8/5N2/PP2PPPP/RN1QKB1R w KQkq -
+Blumenfeld counter-gambit, Spielmann variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP2B1/2P5/5N2/PP2PPPP/RN1QKB1R b KQkq -
+Blumenfeld counter-gambit, Dus-Chotimursky variation
+rnbqkb1r/p2p1ppp/4pn2/1ppP4/2P5/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit
+rnbqkb1r/p2ppp1p/1p3np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: Torre defensive system *
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+English: London defensive system *
+rnbqkb1r/p2ppppp/1p3n2/2p3B1/3P4/2P5/PP2PPPP/RN1QKBNR b KQkq -
+English: Caro-Kann defensive system, Bogolyubov variation *
+rnbqkb1r/p2ppppp/1p3n2/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system *
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benk\"o gambit
+rnbqkb1r/p3pppp/2p2n2/1p2P3/2pP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Tolush-Geller gambit
+rnbqkb1r/p3pppp/5n2/1ppP4/2p1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+QGA: Linares variation
+rnbqkb1r/p4p2/2p1p2p/1p1nP1N1/2pP3B/2N5/PP3PPP/R2QKB1R w KQkq -
+QGD semi-Slav: anti-Meran, Alatortsev system
+rnbqkb1r/p4p2/2p1pP1p/1p2N3/2pP3p/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Ekstrom variation
+rnbqkb1r/p4p2/2p1pn1p/1p2P1N1/2pP3B/2N5/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: anti-Meran gambit
+rnbqkb1r/p4ppp/2p5/3n4/2B2p2/5N2/PPPP2PP/RNBQK2R w KQkq -
+KGA: Abbazia defense, Botvinnik variation
+rnbqkb1r/p5pp/4pn2/1Ppp4/8/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Blumenfeld counter-gambit accepted
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P1P2/2N2N2/PPP3PP/R1BQKB1R b KQkq -
+French: Steinitz variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system, Keres variation
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Ponziani: Jaenisch counter-attack *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Ponziani opening *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPBPPP/R1BQK1NR b KQkq -
+Ponziani: Romanishin variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+Ponziani: R\'eti variation *
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Ponziani counter-gambit *
+rnbqkb1r/pp1p1ppp/2p2n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR w KQkq -
+KGA: bishop's gambit, Jaenisch variation
+rnbqkb1r/pp1p1ppp/2p5/3Nn3/1P1NP3/8/P1P2PPP/R1BQKB1R w KQkq -
+two knights defense: Fritz, Gruber variation *
+rnbqkb1r/pp1p1ppp/4pn2/2P5/8/4B3/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti accepted: Keres variation *
+rnbqkb1r/pp1p1ppp/4pn2/2p3B1/3PP3/5N2/PPP2PPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack, Wagner gambit
+rnbqkb1r/pp1p1ppp/4pn2/2p5/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+English: Mikenas-Carls, Sicilian variation
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1p1ppp/4pn2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Anderssen variation
+rnbqkb1r/pp1p1ppp/5n2/2p1N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Kaufmann attack *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/2P5/6PB/PP1PPP1P/RNBQK1NR b KQkq -
+Sicilian: Acton extension *
+rnbqkb1r/pp1p1ppp/5n2/2p1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Dresden opening *
+rnbqkb1r/pp1p1ppp/5n2/2pPp3/2P5/8/PP2PPPP/RNBQKBNR w KQkq e6
+Czech Benoni defense
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, 4.c3 *
+rnbqkb1r/pp1p2pp/2p2n2/4pp2/2B1PP2/3P4/PPP3PP/RNBQK1NR b KQkq -
+KGD: classical counter-gambit *
+rnbqkb1r/pp1pp1pp/2p2n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+Dutch: Staunton gambit, Chigorin variation
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+English: Kurajica defense *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+English: Neo-Catalan *
+rnbqkb1r/pp1ppppp/1n6/2p1P3/8/1B1P4/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Kmoch variation
+rnbqkb1r/pp1ppppp/2p2n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Masi defense
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti accepted *
+rnbqkb1r/pp1ppppp/5n2/2p1P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+English, Nimzovich, Flohr variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+English: symmetrical, Benoni formation
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+English opening: Agincourt variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Nimzovich-Rubinstein variation
+rnbqkb1r/pp1ppppp/5n2/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+English, Nimzovich variation *
+rnbqkb1r/pp1ppppp/5n2/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English opening *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti: advance variation *
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkb1r/pp1ppppp/5n2/3P4/2p5/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Hawk (Habichd) defense
+rnbqkb1r/pp1ppppp/8/2pP4/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Vulture defense
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R w KQkq -
+English: Bled variation
+rnbqkb1r/pp2pp1p/2p2np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav\Gr\"unfeld: Schlechter variation
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Bronstein-Larsen variation
+rnbqkb1r/pp2pp1p/2pp1np1/8/3PP3/2N1B3/PPPQ1PPP/R3KBNR b KQkq -
+Pirc: 150 attack
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R b KQkq -
+Sicilian: dragon, 6.Be3
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: dragon variation
+rnbqkb1r/pp2pp1p/3p1np1/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: dragon, Levenfish variation
+rnbqkb1r/pp2pp1p/5np1/2pP4/4p3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+QGD: Albin counter-gambit, 5.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.g3 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: 4.g3 Bb7 *
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+Queen's Indian: Nimzovich variation (exaggerated fianchetto) *
+rnbqkb1r/pp2pp1p/5np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...g6
+rnbqkb1r/pp2pp1p/6p1/2p3B1/2PPp3/8/PP1QPPPP/R3KBNR w KQkq -
+Gr\"unfeld: Lundin variation
+rnbqkb1r/pp2pppp/2p2n2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian gambit
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3N2/PB1PPPPP/RN1QKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD Slav: 4.Nc3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGD Slav: 4.e3
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/5N2/PP1NPPPP/R1BQKB1R b KQkq -
+QGD Slav: Breyer variation
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: 5.e3 (Alekhine variation)
+rnbqkb1r/pp2pppp/2p2n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD Slav accepted
+rnbqkb1r/pp2pppp/2p2n2/8/2pPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+QGD Slav: Slav gambit
+rnbqkb1r/pp2pppp/2p2n2/8/3PN3/3B4/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Alekhine gambit
+rnbqkb1r/pp2pppp/2p2n2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R b KQkq -
+QGD Slav accepted: Alapin variation
+rnbqkb1r/pp2pppp/2pp1n2/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc: Ufimtsev-Pytel variation
+rnbqkb1r/pp2pppp/3p1n2/2p5/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Cortlever (Alatortsev) variation
+rnbqkb1r/pp2pppp/3p1n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+Benoni defense, Hromodka system
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian
+rnbqkb1r/pp2pppp/3p1n2/8/3NP3/5P2/PPP3PP/RNBQKB1R b KQkq -
+Sicilian: Prins (Moscow) variation
+rnbqkb1r/pp2pppp/5n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+Bogo-Indian defense *
+rnbqkb1r/pp2pppp/5n2/2Pp4/1P6/8/P1P1PPPP/RNBQKBNR b KQkq -
+QGA: Ericson variation *
+rnbqkb1r/pp2pppp/5n2/2Pp4/3P4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's gambit accepted *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/P7/1PP1PPPP/RNBQKBNR b KQkq -
+QGA: Alekhine defense *
+rnbqkb1r/pp2pppp/5n2/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Adler variation *
+rnbqkb1r/pp2pppp/5n2/2p5/1PPp4/4PN2/P2P1PPP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pP4/4p3/8/PPP2PPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit *
+rnbqkb1r/pp2pppp/5n2/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English: symmetrical, Benoni formation *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav: 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+Bird's opening: Lasker variation
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian, 3.Nf3 *
+rnbqkb1r/pp2pppp/5n2/2pp4/8/P3PN2/1PPP1PPP/RNBQKB1R b KQkq -
+Dzindzikhashvili defense *
+rnbqkb1r/pp2pppp/5n2/2ppN3/8/4P3/PPPP1PPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: exchange variation *
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: exchange variation
+rnbqkb1r/pp2pppp/5n2/8/1pPP4/4PN2/P5PP/RNBQKB1R b KQkq -
+Blumenfeld counter-gambit accepted *
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+English: symmetrical, three knights system
+rnbqkb1r/pp2pppp/8/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+English: symmetrical variation *
+rnbqkb1r/pp3p1p/2p1pnp1/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R w KQkq -
+QGD: Spielmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+Benoni: Uhlmann variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+Benoni: classical with e4 and Nf3
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PP2/2N5/PP4PP/R1BQKBNR b KQkq -
+Benoni: pawn storm variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+Benoni defense
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+Benoni: fianchetto variation
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+Benoni: Nimzovich (knight's tour) variation
+rnbqkb1r/pp3p1p/3p1np1/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR w KQkq -
+Czech Benoni: King's Indian system
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD semi-Slav: 5.e3
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD semi-Slav
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/4PN2/PP1N1PPP/R1BQKB1R b KQkq -
+QGD Slav
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pP4/2N2N2/PP2PPPP/R2QKB1R w KQkq -
+QGD semi-Slav: 5.Bg5 dc
+rnbqkb1r/pp3ppp/2p1pn2/6B1/2pPP3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+QGD semi-Slav: Botvinnik system (anti-Meran)
+rnbqkb1r/pp3ppp/2p1pn2/8/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+QGD Slav: Soultanb\'eieff variation
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/4P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Andreaschek gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch: G\"oring gambit *
+rnbqkb1r/pp3ppp/2p2n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian: Tartakower variation *
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: exchange, positional line, 5...c6
+rnbqkb1r/pp3ppp/2p2n2/3p2B1/3P4/2N5/PPQ1PPPP/R3KBNR b KQkq -
+QGD: exchange, positional line, 6.Qc2
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/1Q2P3/PP1B1PPP/RN2KBNR b KQkq -
+French: advance, Wade variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP1B1PPP/R2QKBNR b KQkq -
+French: advance, Euwe variation *
+rnbqkb1r/pp3ppp/2p2n2/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+French: advance, Paulsen attack *
+rnbqkb1r/pp3ppp/2p2n2/3pp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+Robatsch defense: Geller's system *
+rnbqkb1r/pp3ppp/2p2n2/4N3/2BpP3/2N5/PPPP1PPP/R1BQK2R b KQkq -
+Ponziani: Fraser defense *
+rnbqkb1r/pp3ppp/2p2n2/4p3/3pPP2/2NP4/PPP3PP/R1BQKBNR w KQkq -
+Ponziani counter-gambit, Schmidt attack *
+rnbqkb1r/pp3ppp/2p2p2/8/2BP4/8/PPP2PPP/R1BQK1NR b KQkq -
+Caro-Kann: Forg\'acs variation
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Tartakower (Nimzovich) variation
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Venice attack
+rnbqkb1r/pp3ppp/3p1n2/1B2p3/3NP3/5P2/PPP3PP/RNBQK2R b KQkq -
+Sicilian: Prins variation, Venice attack
+rnbqkb1r/pp3ppp/3p1n2/2pP4/4P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+Benoni: 6.e4
+rnbqkb1r/pp3ppp/3ppn2/1B6/3NP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, Vitoli\'n\'s variation
+rnbqkb1r/pp3ppp/3ppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+Sicilian: Sozin attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, Keres attack
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N3P1/PPP2P1P/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, fianchetto variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+Sicilian: Scheveningen, 6.Be2
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+Sicilian: Scheveningen variation
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+Sicilian: Scheveningen, 6.f4
+rnbqkb1r/pp3ppp/4p3/2pn4/3P4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch with e3
+rnbqkb1r/pp3ppp/4pn2/2Pp2B1/8/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Janowsky-Larsen variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/1P6/P7/2P1PPPP/RNBQKBNR b KQkq -
+QGA: Haberditz variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4BN2/PPP1PPPP/RN1QKB1R b KQkq -
+QGA, Flohr variation *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QGA: 4...e6 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QGA, 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+QGA, Smyslov variation *
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+QGA: classical variation, 6.O-O
+rnbqkb1r/pp3ppp/4pn2/2p5/2BP4/4PN2/PP3PPP/RNBQK2R w KQkq -
+QGA: classical variation
+rnbqkb1r/pp3ppp/4pn2/2pP2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Semi-Tarrasch
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Semi-Tarrasch, 5.cd
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+QGD: Semi-Tarrasch defense, Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/2pp2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QGD: Been-Koomen variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/2P5/1P2PN2/PB1P1PPP/RN1QKB1R b KQkq -
+English: Wimpey system
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: Semi-Tarrasch defense
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD Slav: 4.e3 Bf5 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P1BPN2/P1P2PPP/RNBQK2R b KQkq -
+Queen's pawn game, Rubinstein (Colle-Zukertort) variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/1P2PN2/P1PN1PPP/R1BQKB1R b KQkq -
+Queen's pawn game, Zukertort variation
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+QGD Slav: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/2pp4/3P4/2PBPN2/PP3PPP/RNBQK2R b KQkq -
+Colle system
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+Queen's Indian: 4.e3 *
+rnbqkb1r/pp3ppp/4pn2/3p2B1/2PQ4/2N2N2/PP2PPPP/R3KB1R b KQkq -
+QGD: Semi-Tarrasch, Primitive Pillsbury variation
+rnbqkb1r/pp3ppp/4pn2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack, 5...e6
+rnbqkb1r/pp3ppp/4pn2/8/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QGA: classical, Steinitz variation
+rnbqkb1r/pp3ppp/5n2/2Ppp3/8/P7/1PP1PPPP/RNBQKBNR w KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation *
+rnbqkb1r/pp3ppp/5n2/2p3B1/3pp3/1N1P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Vitolins attack *
+rnbqkb1r/pp3ppp/5n2/2pp2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Alekhine variation *
+rnbqkb1r/pp3ppp/5n2/2ppp1B1/8/3P2P1/PPP1PPBP/RN1QK1NR b KQkq -
+Robatsch defense: Rossolimo variation *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind *
+rnbqkb1r/pp3ppp/8/2pnp3/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+Sicilian: accelerated fianchetto, Mar\'oczy bind, 5...Bg7 *
+rnbqkb1r/pp3ppp/8/2pnp3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation) *
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/2NBPN2/PP3PPP/R1BQK2R w KQkq -
+QGD semi-Slav: stonewall defense
+rnbqkb1r/pp4pp/2p1p3/3p1p2/2PPn3/3BPN2/PP1N1PPP/R1BQK2R w KQkq -
+QGD: Stonewall variation
+rnbqkb1r/pp4pp/5n2/3p2B1/2p5/1NN1P3/PPP1P1PP/R2QKB1R w KQkq -
+Alekhine's defense: four pawns attack, Ilyin-Genevsky variation *
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: symmetrical, Rubinstein system
+rnbqkb1r/ppp1p1pp/5n2/3p4/8/3B3N/PPP2PPP/RNBQK2R w KQkq -
+Bird: From gambit, Lipke variation *
+rnbqkb1r/ppp1pp1p/1n1p2p1/4P3/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation
+rnbqkb1r/ppp1pp1p/1n1p4/4P1p1/2PP1P2/8/PP4PP/RNBQKBNR w KQkq -
+Alekhine's defense: four pawns attack, Planinc variation
+rnbqkb1r/ppp1pp1p/1n4p1/8/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Czech defense
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Pirc: Byrne variation
+rnbqkb1r/ppp1pp1p/3p1np1/8/2BPP3/2N5/PPP2PPP/R1BQK1NR b KQkq -
+Pirc: Holmov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Pirc: classical (two knights) system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N3P1/PPP2P1P/R1BQKBNR b KQkq -
+Pirc: Sveshnikov system
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP1BPPP/R1BQK1NR b KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR b KQkq -
+Pirc: Austrian attack
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, fianchetto variation
+rnbqkb1r/ppp1pp1p/5np1/3P4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Richter variation
+rnbqkb1r/ppp1pp1p/5np1/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: Stockholm variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+Gr\"unfeld: 4.Bf4
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP2P1/2N5/PP2PP1P/R1BQKBNR b KQkq -
+Gr\"unfeld: Spike gambit
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/1QN5/PP2PPPP/R1B1KBNR b KQkq -
+Gr\"unfeld: Russian variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Gr\"unfeld: Three knights variation
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/5P2/PP2P1PP/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Neo-Gr\"unfeld (Kemeri) defense
+rnbqkb1r/ppp1pp1p/5np1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: fianchetto without c4 *
+rnbqkb1r/ppp1pp1p/5np1/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA, Smyslov variation
+rnbqkb1r/ppp1pp1p/6p1/3n4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Gr\"unfeld: exchange variation
+rnbqkb1r/ppp1pp1p/6p1/8/8/2n3P1/PP1PPPBP/R1BQK1NR w KQkq -
+English: Anglo-Gr\"unfeld, Smyslov defense
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense: exchange variation
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+Alekhine's defense: four pawns attack
+rnbqkb1r/ppp1pppp/1n1p4/4P3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Schmid variation
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Old Indian defense
+rnbqkb1r/ppp1pppp/3p1n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: old Indian attack *
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Pirc defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/2BP4/8/PPP2PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Balogh variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern variation
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/ppp1pppp/5n2/2P5/3p4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Hawk (Habichd) defense *
+rnbqkb1r/ppp1pppp/5n2/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian defense
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/2N5/PPP1PPPP/R2QKBNR b KQkq -
+Richter-Veresov attack
+rnbqkb1r/ppp1pppp/5n2/3p2B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Torre attack (Tartakower variation)
+rnbqkb1r/ppp1pppp/5n2/3p2B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+Old Indian: Tartakower (Wade) variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game, Krause variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Marshall defense
+rnbqkb1r/ppp1pppp/5n2/3p4/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's bishop game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P2P1/5P2/PPP1P2P/RNBQKBNR b KQkq -
+Gedult attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn game, Chigorin variation *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/3BP3/PPP2PPP/RNBQK1NR b KQkq -
+Queen's pawn: stonewall attack
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp1pppp/5n2/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Blackmar-Diemer gambit
+rnbqkb1r/ppp1pppp/5n2/3p4/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Alekhine's defense: Scandinavian variation
+rnbqkb1r/ppp1pppp/5n2/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian: East Indian defense *
+rnbqkb1r/ppp1pppp/5n2/3pN3/8/8/PPPPPPPP/RNBQKB1R b KQkq -
+D\"ory defense *
+rnbqkb1r/ppp1pppp/5n2/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+Old Benoni defense *
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGA, 4.Nc3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QGA, 4.e3
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Queen's gambit accepted
+rnbqkb1r/ppp1pppp/5n2/8/Q1pP4/5N2/PP2PPPP/RNB1KB1R b KQkq -
+QGA: Mannheim variation
+rnbqkb1r/ppp1pppp/8/3n4/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+Scandinavian: Marshall variation
+rnbqkb1r/ppp1pppp/8/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English: Anglo-Gr\"unfeld defense
+rnbqkb1r/ppp1pppp/8/3np3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern, Larsen variation
+rnbqkb1r/ppp1pppp/8/8/1nPP4/8/PP3PPP/RNBQKBNR w KQkq -
+Scandinavian: Kiel variation
+rnbqkb1r/ppp2Npp/3p1n2/8/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Cochrane gambit
+rnbqkb1r/ppp2p1p/5n2/3p4/4PpNP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation
+rnbqkb1r/ppp2p1p/5n2/3pN3/3PPBpP/8/PPP3P1/RN1QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense
+rnbqkb1r/ppp2p1p/8/3pN3/3PnBpP/8/PPPN2P1/R2QKB1R b KQkq -
+KGA: Kieseritsky, Brentano defense, Caro variation
+rnbqkb1r/ppp2pp1/4pn1p/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R w KQkq -
+QGD: Capablanca-Duras variation
+rnbqkb1r/ppp2pp1/5n1p/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R w KQkq -
+Alekhine's defense: modern, Panov variation *
+rnbqkb1r/ppp2ppp/1n6/1B2p3/8/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch: Romanishin variation *
+rnbqkb1r/ppp2ppp/1n6/4p3/2B5/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Scotch: Potter variation *
+rnbqkb1r/ppp2ppp/3p1n2/4N3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: French attack *
+rnbqkb1r/ppp2ppp/3p1n2/4P3/4P3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich variation
+rnbqkb1r/ppp2ppp/3p1n2/4p1N1/3PP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich, Locock variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2BPP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Philidor: Nimzovich, Klein variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+Old Indian: Ukrainian variation, 4.Nf3
+rnbqkb1r/ppp2ppp/3p1n2/4p3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Old Indian: Ukrainian variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich (Jaenisch) variation
+rnbqkb1r/ppp2ppp/3p1n2/4p3/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+R\'eti: Lisitsin gambit deferred *
+rnbqkb1r/ppp2ppp/3p1n2/8/2N1P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Paulsen attack
+rnbqkb1r/ppp2ppp/3p1n2/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkb1r/ppp2ppp/3p1n2/8/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack, close variation
+rnbqkb1r/ppp2ppp/3p4/3QP3/4n3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Philidor: Nimzovich, Rellstab variation
+rnbqkb1r/ppp2ppp/3p4/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR w KQkq -
+Budapest: Alekhine variation, Balogh gambit
+rnbqkb1r/ppp2ppp/3p4/4P3/4n3/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+Philidor: Nimzovich, Sokolsky variation
+rnbqkb1r/ppp2ppp/3p4/8/2P1n3/5N2/PP1P1PPP/RNBQKB1R b KQkq -
+Petrov: Kaufmann attack
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov: Nimzovich attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: French attack
+rnbqkb1r/ppp2ppp/3p4/8/4n3/5N2/PPPPQPPP/RNB1KB1R b KQkq -
+Petrov: Cozio (Lasker) attack
+rnbqkb1r/ppp2ppp/3pp3/2PnP3/2B5/2N5/PP1P1PPP/R1BQK1NR w KQkq -
+Alekhine's defense: two pawns' attack, Mikenas variation
+rnbqkb1r/ppp2ppp/4n3/3pP3/8/3P1Q2/PPP3PP/RNB1KBNR w KQkq -
+Latvian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/4pn2/3P4/2P5/8/PP1P1PPP/RNBQKBNR w KQkq -
+Scandinavian: Icelandic gambit
+rnbqkb1r/ppp2ppp/4pn2/3P4/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: exchange variation
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: 4.Bg5
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/2PP4/5N2/PP2PPPP/RN1QKB1R b KQkq -
+QGD
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Neo-Catalan
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP1B2/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: Harrwitz attack
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: 4.Nf3
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: 3...Nf6
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Catalan: closed
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/3BPN2/PPP2PPP/RNBQK2R b KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+Queen's pawn game
+rnbqkb1r/ppp2ppp/4pn2/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N1B3/PPP2PPP/R2QKBNR b KQkq -
+French: Henneberger variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French defense
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/2NB4/PPP2PPP/R1BQK1NR b KQkq -
+French: Swiss variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, closed variation
+rnbqkb1r/ppp2ppp/4pn2/3p4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Queen's pawn: Yusupov-Rubinstein system *
+rnbqkb1r/ppp2ppp/4pn2/3pP3/2P5/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls, Flohr variation
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Steinitz variation
+rnbqkb1r/ppp2ppp/4pn2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR w KQkq -
+French: Burn variation
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+English: Neo-Catalan accepted
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: 4...e6
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+Catalan: open, 5.Nf3
+rnbqkb1r/ppp2ppp/4pn2/8/3P4/2N2N2/PPP3PP/R1BQKB1R w KQkq -
+Blackmar-Diemer: Euwe defense
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+Catalan: open, 5.Qa4
+rnbqkb1r/ppp2ppp/5n2/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Morphy variation
+rnbqkb1r/ppp2ppp/5n2/3Np3/4P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+Scotch: Lolli variation *
+rnbqkb1r/ppp2ppp/5n2/3P4/4PP2/8/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 5.de
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/2N5/PPPPQ1PP/R1B1KBNR b KQkq -
+KGD: Falkbeer, Rubinstein variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, R\'eti variation
+rnbqkb1r/ppp2ppp/5n2/3P4/4pP2/3P4/PPPN2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Keres variation
+rnbqkb1r/ppp2ppp/5n2/3P4/5p2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense, modern variation
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: modern variation, 4...Bg4 *
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PP2PPPP/R2QKBNR b KQkq -
+QGD: exchange, positional line
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3P4/2N5/PPP2PPP/R2QKBNR b KQkq -
+French: exchange, Svenonius variation
+rnbqkb1r/ppp2ppp/5n2/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Nimzovich system *
+rnbqkb1r/ppp2ppp/5n2/3p4/3NP3/8/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Larsen variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: modern, fianchetto variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: modern variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/4p3/1N1P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense: modern, Schmid variation *
+rnbqkb1r/ppp2ppp/5n2/3p4/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: classical attack, close variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: modern attack, Symmetrical variation *
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: classical attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen, reverse dragon
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2P5/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Sicilian: Cortlever (Alatortsev) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Marshall variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Blackmar-Diemer: Lemberg counter-gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch opening *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Nimzovich (Jaenisch) variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor's defense *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPPN1PPP/R1BQKBNR b KQkq -
+Philidor: Hanham variation *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: modern (Steinitz) attack *
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit, Steinitz variation
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+Philidor: Philidor counter-gambit *
+rnbqkb1r/ppp2ppp/5n2/4p2Q/8/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Fraser attack *
+rnbqkb1r/ppp2ppp/5n2/4p3/4p3/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3P4/4nP2/8/PPP1Q1PP/RNB1KBNR b KQkq -
+KGD: Falkbeer, Charousek gambit
+rnbqkb1r/ppp2ppp/8/3n4/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: Paulsen attack *
+rnbqkb1r/ppp2ppp/8/3np2Q/8/2N5/PPPP1PPP/R1B1KBNR b KQkq -
+Scotch: Pulling counter-attack *
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/3P4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Sicilian: Nimzovich variation *
+rnbqkb1r/ppp2ppp/8/3np3/4P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+Sicilian defense *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Scotch: Schmidt variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Scotch game *
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPQPPPPP/R1B1KBNR b KQkq -
+Sicilian: Flohr variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P2P1/PPP2P1P/RNBQKBNR b KQkq -
+Philidor: Larsen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+Sicilian *
+rnbqkb1r/ppp2ppp/8/3np3/8/3P4/PPP2PPP/RNBQKBNR w KQkq -
+Philidor: exchange variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Sicilian: Anderssen variation *
+rnbqkb1r/ppp2ppp/8/3np3/8/P3P3/1P1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Kan variation *
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2N2Q2/PPPP2PP/R1B1KBNR b KQkq -
+Vienna gambit: Paulsen attack
+rnbqkb1r/ppp2ppp/8/3pP3/4n3/2NP4/PPP3PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/ppp2ppp/8/3pp3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+Boden-Kieseritsky gambit: Lichtenhein defense
+rnbqkb1r/ppp2ppp/8/3pp3/4N3/8/PPPP1PPP/R1BQKBNR w KQkq -
+Irish (Chicago) gambit *
+rnbqkb1r/ppp2ppp/8/3pp3/4P1n1/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Nimzovich, Locock variation *
+rnbqkb1r/ppp2ppp/8/4P3/3P2n1/4p3/PPP3PP/RNBQKBNR w KQkq -
+Philidor: Philidor counter-gambit, del Rio attack *
+rnbqkb1r/ppp2ppp/8/4p2Q/1n6/2N5/PPPP1PPP/R1B1KBNR w KQkq -
+Scotch: Horwitz attack *
+rnbqkb1r/ppp2ppp/8/4p3/1n2P3/2NP4/PP3PPP/R1BQKBNR b KQkq -
+Sicilian: Labourdonnais-L\"owenthal (Kalashnikov) variation *
+rnbqkb1r/ppp2ppp/8/4p3/1n6/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+Sicilian, Sz\'en (`anti-Taimanov') variation *
+rnbqkb1r/ppp2ppp/8/4p3/8/2n3P1/PP1PPP1P/R1BQKBNR w KQkq -
+Sicilian: accelerated fianchetto, exchange variation *
+rnbqkb1r/ppp2ppp/8/8/4p3/2P2N2/P1PP1PPP/R1BQKB1R w KQkq -
+Scotch: Mieses variation *
+rnbqkb1r/ppp3p1/8/3ppPPp/8/7P/PPPP1K2/RNBQ1BNR w kq -
+KGA: Allgaier, Thorold variation *
+rnbqkb1r/ppp3pN/3p3n/5p2/2BpP3/8/PPP2PPP/RNBQK2R b KQkq -
+Philidor: L\'opez counter-gambit, Jaenisch variation
+rnbqkb1r/ppp3pp/5n2/3ppP2/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Rosentreter gambit *
+rnbqkb1r/ppp3pp/5p2/3np3/8/3P1N2/PP2PPPP/RNBQKB1R w KQkq -
+Sicilian: Prins (Moscow) variation *
+rnbqkb1r/ppp3pp/8/3pPp2/3Pn3/2N2Q2/PPP3PP/R1B1KBNR b KQkq -
+Vienna gambit: Heyde variation
+rnbqkb1r/ppp3pp/8/3pPp2/4n3/2N2Q2/PPPP2PP/R1B1KBNR w KQkq f6
+Vienna gambit: Bardeleben variation
+rnbqkb1r/ppp3pp/8/3ppPP1/4n3/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: S\o rensen gambit *
+rnbqkb1r/pppn1ppp/4p3/3pP3/3P2Q1/2N5/PPP2PPP/R1B1KBNR b KQkq -
+French: Steinitz, Gledhill attack
+rnbqkb1r/pppnpppp/4P3/3p4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: Spielmann variation
+rnbqkb1r/pppp1p1p/5n2/4N3/2B1PppP/8/PPPP2P1/RNBQK2R b KQkq -
+KGA: Kieseritsky, Berlin defense, 6.Bc4
+rnbqkb1r/pppp1p1p/5n2/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Berlin defense
+rnbqkb1r/pppp1p1p/5n2/6N1/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Allgaier, Schlechter defense
+rnbqkb1r/pppp1p1p/5np1/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English: Bremen system with ...g6
+rnbqkb1r/pppp1p1p/5np1/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Konstantinopolsky opening *
+rnbqkb1r/pppp1ppp/2n5/8/2P1PP2/8/PP4PP/RNBQKBNR w KQkq -
+Budapest: Alekhine, Abonyi variation
+rnbqkb1r/pppp1ppp/4p3/8/2PPn3/5N2/PP2PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkb1r/pppp1ppp/4pn2/6B1/2PP4/8/PP2PPPP/RN1QKBNR b KQkq -
+Neo-Indian (Seirawan) attack
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+Queen's pawn: Torre attack
+rnbqkb1r/pppp1ppp/4pn2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+English: Mikenas-Carls variation
+rnbqkb1r/pppp1ppp/4pn2/8/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Catalan opening
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppp1ppp/4pn2/8/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Queen's pawn: Yusupov-Rubinstein system
+rnbqkb1r/pppp1ppp/5n2/4p1B1/8/3P4/PPP1PPPP/RN1QKBNR b KQkq -
+R\'eti: Wade defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Petrov: Italian variation
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Berlin defense
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1PP2/8/PPPP2PP/RNBQK1NR b KQkq -
+Bishop's opening: Greco gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2BPP3/8/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Ponziani gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/1P6/P2PPPPP/RNBQKBNR b KQkq -
+Sicilian: Katalimov variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+English: Carls' Bremen system
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+English opening
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Sicilian *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/4P3/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Sicilian: Nimzovich-Rubinstein variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+Sicilian: Hungarian variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PPQPPPPP/RNB1KBNR b KQkq -
+Sicilian: Quinteros variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/P7/1P1PPPPP/RNBQKBNR b KQkq -
+Sicilian: O'Kelly variation *
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense declined
+rnbqkb1r/pppp1ppp/5n2/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Tennison (Lemberg, Zukertort) gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Petrov: modern (Steinitz) attack
+rnbqkb1r/pppp1ppp/5n2/4p3/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QP counter-gambit (elephant gambit) *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Petrov three knights game
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+Vienna: Paulsen-Mieses variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+King's pawn game *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+Vienna: Falkbeer variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Philidor's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov's defense
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+Damiano's defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+Greco defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight opening *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+Gunderam defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/P1N5/1PPP1PPP/R1BQKBNR b KQkq -
+Vienna: Mengarini variation
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Vienna gambit
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Latvian counter-gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: 2...Nf6
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/2N5/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Colorado counter *
+rnbqkb1r/pppp1ppp/5n2/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+R\'eti: Pirc-Lisitsin gambit *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkb1r/pppp1ppp/5n2/4p3/Q1P5/8/PP1PPPPP/RNB1KBNR b KQkq -
+Sicilian: Stiletto (Althouse) variation *
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/2N5/PPPP2PP/R1BQK1NR b KQkq -
+KGA: bishop's gambit, Bogolyubov variation
+rnbqkb1r/pppp1ppp/5n2/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Cozio (Morphy) defense
+rnbqkb1r/pppp1ppp/5n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R b KQkq -
+Bishop's opening/Petrov: Urusov gambit
+rnbqkb1r/pppp1ppp/5n2/8/3pP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+QP counter-gambit: Maroczy gambit *
+rnbqkb1r/pppp1ppp/5n2/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Schallop defense
+rnbqkb1r/pppp1ppp/8/2n1p3/8/3P1N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: Paulsen attack *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Petrov: Damiano variation *
+rnbqkb1r/pppp1ppp/8/4N3/4n3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Petrov: Damiano variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1P1n1/8/PP3PPP/RNBQKBNR b KQkq -
+Budapest: Alekhine variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest: Fajarowicz variation
+rnbqkb1r/pppp1ppp/8/4P3/2P1n3/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Budapest: Fajarowicz, Steiner variation
+rnbqkb1r/pppp1ppp/8/4P3/2P2Bn1/8/PP2PPPP/RN1QKBNR b KQkq -
+Budapest: Rubinstein variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Budapest: Adler variation
+rnbqkb1r/pppp1ppp/8/4P3/2P3n1/8/PP2PPPP/RNBQKBNR w KQkq -
+Budapest defense
+rnbqkb1r/pppp1ppp/8/4P3/3Qn3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Petrov: modern attack, main line
+rnbqkb1r/pppp1ppp/8/4P3/3pn3/5N2/PPP1QPPP/RNB1KB1R b KQkq -
+Petrov: modern attack, Steinitz variation
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+Boden-Kieseritsky gambit
+rnbqkb1r/pppp1ppp/8/4p3/2B1n3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+Vienna game
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Petrov: modern attack, Symmetrical variation
+rnbqkb1r/pppp1ppp/8/4p3/4nP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+Latvian: Fraser defense *
+rnbqkb1r/pppp1ppp/8/4p3/8/3P1N2/PPP2nPP/RNBQKB1R w KQkq -
+Petrov: Cochrane gambit *
+rnbqkb1r/pppp2p1/5n2/4pP1p/6P1/8/PPPP1P1P/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2p1/8/4pPPp/3Pn3/8/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n2P/8/PPPP1P2/RNBQKBNR b KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/2N5/PPPP1P1P/R1BQKBNR b KQkq -
+KGA: Kieseritsky, Neumann defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/3P4/PPP2P1P/RNBQKBNR b KQkq -
+KGA: Kieseritsky, Kolisch defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPP1PBP/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Paulsen defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPBP1P/RNBQK1NR b KQkq -
+KGA: Kieseritsky, Polerio defense *
+rnbqkb1r/pppp2p1/8/4pPPp/4n3/8/PPPPQP1P/RNB1KBNR b KQkq -
+KGA: Kieseritsky, Salvio (Rosenthal) defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/5N2/PPPP1P1P/RNBQKB1R b KQkq -
+KGA: Allgaier, Schlechter defense *
+rnbqkb1r/pppp2p1/8/4pPPp/6n1/8/PPPP1P1P/RNBQKBNR w KQkq -
+KGA: Allgaier gambit *
+rnbqkb1r/pppp2p1/8/4pPnp/3P4/5N2/PPP2P1P/RNBQKB1R b KQkq -
+KGA: Kieseritsky, Berlin defense, Rivi\`ere variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+Bird's opening: Lasker variation *
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+Dutch defense
+rnbqkb1r/pppp2pp/4pn2/5p2/3P4/6PN/PPP1PPBP/RNBQK2R b KQkq -
+Dutch defense, Blackburne variation
+rnbqkb1r/pppp2pp/5n2/4N3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: corkscrew counter-gambit
+rnbqkb1r/pppp2pp/5n2/4p3/2B1p3/3P4/PPP2PPP/RNBQK1NR w KQkq -
+KGD: classical, Soldatenkov variation *
+rnbqkb1r/pppp2pp/5n2/4pP2/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!]) *
+rnbqkb1r/pppp2pp/5n2/4pP2/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGA: Gianutio counter-gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KGA: Fischer defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGA: Schallop defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/7P/PPPP1PP1/RNBQKBNR b KQkq -
+KGA: Becker defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's knight's gambit *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPBPPP/RNBQK1NR b KQkq -
+KGA: Cunningham defense *
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPPNPPP/RNBQKB1R b KQkq -
+KGA: Bonsch-Osmolovsky variation *
+rnbqkb1r/pppp2pp/5n2/4pp2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, Tartakower variation *
+rnbqkb1r/pppp2pp/5n2/5P2/3p4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KGA: Abbazia defense, modern variation *
+rnbqkb1r/ppppnppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Keres variation (2.Ne2) *
+rnbqkb1r/ppppnppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alapin's opening *
+rnbqkb1r/ppppnppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Steinitz defense
+rnbqkb1r/ppppnppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Bonsch-Osmolovsky variation
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch with c4 & Nc3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+Dutch with c4 & g3
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp1pp/5n2/5p2/3P2P1/2N5/PPP1PP1P/R1BQKBNR b KQkq -
+Dutch, Spielmann gambit
+rnbqkb1r/ppppp1pp/5n2/5p2/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+R\'eti: Lisitsin gambit deferred
+rnbqkb1r/ppppp1pp/5n2/6B1/3Pp3/2N5/PPP2PPP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Staunton's line
+rnbqkb1r/ppppp1pp/5n2/8/3Pp1P1/2N5/PPP2P1P/R1BQKBNR b KQkq -
+Dutch: Staunton gambit, Tartakower variation
+rnbqkb1r/ppppp1pp/5n2/8/4pPP1/2N5/PPPP3P/R1BQKBNR b KQkq -
+Bird's opening, Swiss gambit
+rnbqkb1r/ppppp1pp/5n2/8/6P1/3B4/PPP2P1P/RNBQK1NR b KQkq -
+Bird: From gambit, Lasker variation *
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+Dutch: Leningrad variation
+rnbqkb1r/ppppp2p/5np1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR w KQkq -
+Dutch defense
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp2P/2N5/PPP2PP1/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Alekhine variation
+rnbqkb1r/ppppp2p/5np1/6B1/3Pp3/2N2P2/PPP3PP/R2QKBNR b KQkq -
+Dutch: Staunton gambit, Lasker variation
+rnbqkb1r/ppppp2p/5ppn/8/2PPP3/8/PP3PPP/RNBQKBNR w KQkq -
+Hippopotamus defense
+rnbqkb1r/ppppp2p/6pn/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+Dutch defense: Bladel variation
+rnbqkb1r/pppppp1p/5np1/3P4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+King's Indian: Anti-Gr\"unfeld
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: Torre attack
+rnbqkb1r/pppppp1p/5np1/8/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, Spassky's variation *
+rnbqkb1r/pppppp1p/5np1/8/1P6/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack, R\'eti-Smyslov variation
+rnbqkb1r/pppppp1p/5np1/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+King's Indian defense, 3.Nc3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+King's Indian, 3.Nf3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+King's Indian: 3.g3
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack (with ...c5) *
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+King's Indian defense
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PPQ1PPPP/RNB1KBNR b KQkq -
+Queen's pawn: Mengarini attack
+rnbqkb1r/pppppp1p/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+King's Indian: London system
+rnbqkb1r/pppppp1p/5np1/8/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+King's Indian: East Indian defense
+rnbqkb1r/pppppp1p/5np1/8/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+King's Indian: fianchetto without c4
+rnbqkb1r/pppppp1p/5np1/8/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+R\'eti: King's Indian attack (Barcza system) *
+rnbqkb1r/pppppp1p/5np1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Benko's opening: reversed Alekhine *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack *
+rnbqkb1r/pppppp1p/5np1/8/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkb1r/ppppppnp/6p1/4P3/3P2P1/8/PPP2P1P/RNBQKBNR w KQkq -
+Norwegian defense
+rnbqkb1r/pppppppp/1n6/2P1P3/8/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack
+rnbqkb1r/pppppppp/1n6/4P3/2P5/1P6/P2P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Steiner variation
+rnbqkb1r/pppppppp/5n2/6B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Trompovsky attack (Ruth, Opo\v censk\'y opening)
+rnbqkb1r/pppppppp/5n2/8/1PP5/8/P2PPPPP/RNBQKBNR b KQkq -
+English orang-utan
+rnbqkb1r/pppppppp/5n2/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Alekhine's defense: Krejcik variation
+rnbqkb1r/pppppppp/5n2/8/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English opening
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English, 1...Nf6 (Anglo-Indian defense)
+rnbqkb1r/pppppppp/5n2/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn: London system
+rnbqkb1r/pppppppp/5n2/8/3P1P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+Canard opening
+rnbqkb1r/pppppppp/5n2/8/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Queen's pawn: Bronstein gambit
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/3P4/5P2/PPP1P1PP/RNBQKBNR b KQkq -
+Paleface attack
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkb1r/pppppppp/5n2/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Mar\'oczy variation
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/5n2/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+R\'eti v Dutch *
+rnbqkb1r/pppppppp/5n2/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+R\'eti: Herrstr\"om gambit *
+rnbqkb1r/pppppppp/5n2/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Indian variation
+rnbqkb1r/pppppppp/5n2/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/5n2/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+R\'eti opening *
+rnbqkb1r/pppppppp/7n/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: T\"ubingen variation
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Amar (Paris) opening *
+rnbqkb1r/pppppppp/8/3nP3/2P5/8/PP1P1PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/3nP3/8/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+Alekhine's defense: Welling variation
+rnbqkb1r/pppppppp/8/3nP3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Alekhine's defense: S\"amisch attack
+rnbqkb1r/pppppppp/8/3nP3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense
+rnbqkb1r/pppppppp/8/4P3/4n3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation
+rnbqkb1r/pppppppp/8/8/3Pn3/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+D\"ory defense
+rnbqkbnr/1p1p1p1p/p3p1p1/8/3NP3/3B4/PPP2PPP/RNBQK2R w KQkq -
+Sicilian: Kan, Swiss cheese variation
+rnbqkbnr/1p1p1ppp/p3p3/8/2PNP3/8/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Kan, Mar\'oczy bind (R\'eti variation)
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+Sicilian: Kan, 5.Nc3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+Sicilian: Kan, 5.Bd3
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Kan variation
+rnbqkbnr/1p1ppppp/p7/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: O'Kelly variation
+rnbqkbnr/1pp1pppp/p7/8/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Alekhine defense
+rnbqkbnr/1pp1pppp/p7/8/2pPP3/5N2/PP3PPP/RNBQKB1R b KQkq -
+QGA: Alekhine defense, Borisenko-Furman variation
+rnbqkbnr/1pp2ppp/p3p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Janowski variation
+rnbqkbnr/1ppp1ppp/p3p3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+St. George defense
+rnbqkbnr/1ppp1ppp/p7/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Mengarini's opening *
+rnbqkbnr/1pppppp1/8/p6p/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Crab opening *
+rnbqkbnr/1pppppp1/p6p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Global opening *
+rnbqkbnr/1ppppppp/8/p7/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Corn stalk defense
+rnbqkbnr/1ppppppp/8/p7/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Ware (Meadow Hay) opening *
+rnbqkbnr/1ppppppp/p7/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+St. George (Baker) defense
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anderssen's opening *
+rnbqkbnr/2p1pppp/p7/1p6/2pP4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+QGA: Haberditz variation
+rnbqkbnr/2pp1ppp/P7/4p3/8/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Carlsbad variation *
+rnbqkbnr/2pp1ppp/p7/1P2p3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Marshall variation *
+rnbqkbnr/p1p1pppp/8/1p6/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QGA: Ericson variation
+rnbqkbnr/p1p2ppp/1p2p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Alapin variation
+rnbqkbnr/p1pp1ppp/1p2p3/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Keres defense
+rnbqkbnr/p1pp1ppp/1p6/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: R\'eti (Spielmann) variation *
+rnbqkbnr/p1pp1ppp/1p6/8/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Welling variation *
+rnbqkbnr/p1pp1ppp/8/1p2p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit *
+rnbqkbnr/p1pp1ppp/8/1p6/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bryan counter-gambit
+rnbqkbnr/p1pp2pp/1p6/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Orsini gambit *
+rnbqkbnr/p1pppppp/1p6/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Polish variation *
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: English variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: classical variation *
+rnbqkbnr/p1pppppp/1p6/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: English defense
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: modern variation *
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Owen defense
+rnbqkbnr/p1pppppp/1p6/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: Dutch variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack: symmetrical variation *
+rnbqkbnr/p1pppppp/1p6/8/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: symmetrical variation
+rnbqkbnr/p1pppppp/1p6/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Nimzovich-Larsen attack: Indian variation *
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack *
+rnbqkbnr/p1pppppp/8/1p6/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Jaenisch gambit
+rnbqkbnr/p1pppppp/8/1p6/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Polish defense
+rnbqkbnr/p1pppppp/8/1p6/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Polish variation
+rnbqkbnr/p1pppppp/8/1p6/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Polish: Outflank variation *
+rnbqkbnr/p1pppppp/8/1p6/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Polish: T\"ubingen variation *
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Polish (Sokolsky) opening *
+rnbqkbnr/p2p1ppp/1p6/2p5/4p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Steiner variation *
+rnbqkbnr/p2p1ppp/8/1Pp1p3/8/8/PP1PPPPP/RNBQKBNR w KQkq c6
+Sicilian: wing gambit, Santasiere variation *
+rnbqkbnr/p2p1ppp/8/1pp5/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+Center game, Kieseritsky variation
+rnbqkbnr/p2ppppp/1p6/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Katalimov variation
+rnbqkbnr/p2ppppp/8/1pp5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+English orang-utan *
+rnbqkbnr/p3pppp/2p5/1p1p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze counter-attack
+rnbqkbnr/p4ppp/2p5/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense, Wheeler gambit *
+rnbqkbnr/p4ppp/8/1pP5/N2p4/8/PP2PPPP/R1BQKBNR w KQkq b6
+QGD: Tarrasch defense, Tarrasch gambit
+rnbqkbnr/pp1p1ppp/2p5/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Philidor counter-attack
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Alapin's variation (2.c3) *
+rnbqkbnr/pp1p1ppp/2p5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Lopez opening *
+rnbqkbnr/pp1p1ppp/2p5/8/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Ruy L\'opez defense
+rnbqkbnr/pp1p1ppp/4p3/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/4p3/2pP4/4P3/8/PPP2PPP/RNBQKBNR b KQkq -
+Old Benoni: Franco-Benoni defense
+rnbqkbnr/pp1p1ppp/4p3/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+English: Adorjan defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Mafia defense
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-Caro-Kann defense *
+rnbqkbnr/pp1p1ppp/8/2p1p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense, Steiner variation *
+rnbqkbnr/pp1p1ppp/8/2p5/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/2P2N2/PP2PPPP/RNBQKB1R b KQkq -
+Scandinavian gambit *
+rnbqkbnr/pp1p1ppp/8/2p5/3p4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+Scandinavian: Icelandic gambit *
+rnbqkbnr/pp1p1ppp/8/2pPp3/8/8/PPP1PPPP/RNBQKBNR w KQkq e6
+Old Benoni defense
+rnbqkbnr/pp1p1ppp/8/4p3/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Andreaschek gambit
+rnbqkbnr/pp1p1ppp/8/8/2p1p3/1N6/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: two pawns' (Lasker's) attack *
+rnbqkbnr/pp1pp1pp/8/2p2p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Mujannah opening *
+rnbqkbnr/pp1pp1pp/8/2pP1p2/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni: Mujannah formation
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian: Hungarian variation
+rnbqkbnr/pp1ppppp/2p5/8/1P6/8/P1PPPPPP/RNBQKBNR w KQkq -
+Polish: Outflank variation
+rnbqkbnr/pp1ppppp/2p5/8/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Caro-Kann: Hillbilly attack
+rnbqkbnr/pp1ppppp/2p5/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+Caro-Kann: anti-Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp1ppppp/2p5/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: closed (Breyer) variation
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Saragossa opening *
+rnbqkbnr/pp1ppppp/8/2p5/1P2P3/8/P1PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit
+rnbqkbnr/pp1ppppp/8/2p5/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+English: Jaenisch gambit *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English: symmetrical variation *
+rnbqkbnr/pp1ppppp/8/2p5/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: symmetrical variation
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp1ppppp/8/2p5/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Sicilian: closed
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+Sicilian: Alapin's variation (2.c3)
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+Sicilian: Steinitz variation
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Sicilian defense
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Sicilian: Keres variation (2.Ne2)
+rnbqkbnr/pp1ppppp/8/2p5/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Sicilian: Grand Prix attack
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+English: Anglo-Dutch defense *
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: English variation
+rnbqkbnr/pp1ppppp/8/2p5/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+English: Caro-Kann defensive system *
+rnbqkbnr/pp1ppppp/8/2p5/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+English, 1...Nf6 (Anglo-Indian defense) *
+rnbqkbnr/pp1ppppp/8/2p5/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+English opening *
+rnbqkbnr/pp1ppppp/8/8/1p2P3/P7/2PP1PPP/RNBQKBNR b KQkq -
+Sicilian: wing gambit, Marshall variation
+rnbqkbnr/pp1ppppp/8/8/1pP1P3/8/P2P1PPP/RNBQKBNR b KQkq c3
+Sicilian: wing gambit, Santasiere variation
+rnbqkbnr/pp1ppppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Sicilian: Smith-Morra gambit
+rnbqkbnr/pp1ppppp/8/8/4P3/p7/2PP1PPP/RNBQKBNR w KQkq -
+Sicilian: wing gambit, Carlsbad variation
+rnbqkbnr/pp2p1pp/5p2/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld defense *
+rnbqkbnr/pp2pp1p/2p3p1/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+Caro-Kann: Gurgenidze system
+rnbqkbnr/pp2pp1p/3p2p1/2pP4/8/2N5/PPP1PPPP/R1BQKBNR w KQkq -
+Old Benoni: Schmid's system
+rnbqkbnr/pp2pp1p/6p1/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Neo-Gr\"unfeld (Kemeri) defense *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+Dutch with c4 & g3 *
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+Dutch: Leningrad variation *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+Catalan opening *
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: 3.g3 *
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense: exchange variation
+rnbqkbnr/pp2pppp/2p5/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: exchange variation
+rnbqkbnr/pp2pppp/2p5/3p2P1/8/8/PPPPPPBP/RNBQK1NR b KQkq -
+Grob: spike attack
+rnbqkbnr/pp2pppp/2p5/3p4/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+Caro-Kann: anti-anti-Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/1P3N2/P2PPPPP/RNBQKB1R b KQkq -
+English: Caro-Kann defensive system
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD Slav: 3.Nf3
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/5P2/PPP3PP/RNBQKBNR b KQkq -
+Caro-Kann: Tartakower (fantasy) variation
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+Caro-Kann: 3.Nd2
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+Caro-Kann: two knights variation
+rnbqkbnr/pp2pppp/2p5/3p4/4P3/2N2Q2/PPPP1PPP/R1B1KBNR b KQkq -
+Caro-Kann: Goldman (Spielmann) variation
+rnbqkbnr/pp2pppp/2p5/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Caro-Kann: advance variation
+rnbqkbnr/pp2pppp/2p5/8/2pPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD Slav defense, Alekhine variation
+rnbqkbnr/pp2pppp/2p5/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+Caro-Kann defense
+rnbqkbnr/pp2pppp/2p5/8/3Pp3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+Caro-Kann: Rasa-Studier gambit
+rnbqkbnr/pp2pppp/3p4/1Bp5/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Sicilian: Canal-Sokolsky (Nimzovich-Rossolimo, Moscow) attack
+rnbqkbnr/pp2pppp/3p4/2p5/1P2P3/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+Sicilian: wing gambit deferred
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+Old Benoni defense
+rnbqkbnr/pp2pppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+Sicilian, Chekhover variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/2P2N2/PP3PPP/RNBQKB1R b KQkq -
+Sicilian: Tartakower variation
+rnbqkbnr/pp2pppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian
+rnbqkbnr/pp2pppp/8/1Bpp4/8/4P3/PPPP1PPP/RNBQK1NR b KQkq -
+Queen's pawn: Franco-Indian (Keres) defense *
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's gambit accepted *
+rnbqkbnr/pp2pppp/8/2p1N3/2Pp4/8/PP1PPPPP/RNBQKB1R b KQkq -
+Vulture defense *
+rnbqkbnr/pp2pppp/8/2p1N3/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Fajarowicz variation *
+rnbqkbnr/pp2pppp/8/2p3N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense *
+rnbqkbnr/pp2pppp/8/2p5/1P1p4/5NP1/P1PPPP1P/RNBQKB1R b KQkq -
+King's Indian: Danube gambit *
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/3P1N2/PP2PPPP/RNBQKB1R b KQkq -
+Benoni defense, Hromodka system *
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/2PpP3/5N2/PP1P1PPP/RNBQKB1R b KQkq e3
+Czech Benoni defense *
+rnbqkbnr/pp2pppp/8/2p5/3p4/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+King's Indian: Anti-Gr\"unfeld *
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Benoni defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+QGD: symmetrical (Austrian) defense *
+rnbqkbnr/pp2pppp/8/2pp4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: symmetrical (Austrian) defense
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+QGD: Grau (Sahovic) defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P1B2/8/PPP1PPPP/RN1QKBNR w KQkq -
+Queen's pawn, Mason variation, Steinitz counter-gambit
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+QGD: Chigorin defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+QGD Slav defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QGD: Marshall defense *
+rnbqkbnr/pp2pppp/8/2pp4/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Queen's pawn game, Krause variation
+rnbqkbnr/pp2pppp/8/2pp4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined *
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QGD: Albin counter-gambit *
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest defense declined *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/4P3/PPPP2PP/RNBQKBNR b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R b KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P2P3/P1PP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Keres defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+Queen's Indian accelerated *
+rnbqkbnr/pp2pppp/8/2pp4/8/2N2N2/PPPPPPPP/R1BQKB1R b KQkq -
+Kevitz-Trajkovich defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Old Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn game *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+King's Indian defense *
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack (with ...c5)
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/pp2pppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+Caro-Kann: Panov-Botvinnik attack
+rnbqkbnr/pp2pppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+QGD Slav defense: exchange variation *
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+Benk\"o gambit half accepted *
+rnbqkbnr/pp2pppp/8/8/2Pp4/p4N2/3PPPPP/RNBQKB1R w KQkq -
+Benk\"o gambit accepted *
+rnbqkbnr/pp3ppp/2p1p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+English: Kurajica defense
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: semi-Slav
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: semi-Slav, Marshall gambit
+rnbqkbnr/pp3ppp/2p1p3/8/2pP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+QGD: semi-Slav, Noteboom variation
+rnbqkbnr/pp3ppp/2p5/3B4/4Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Anderssen variation
+rnbqkbnr/pp3ppp/2p5/3Pp3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+Danish gambit: S\o rensen defense *
+rnbqkbnr/pp3ppp/2p5/3Pp3/5P2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Nimzovich counter-gambit
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/pp3ppp/2p5/3Pp3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Danish gambit *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3p4/2PPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/pp3ppp/2p5/3pp3/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD Slav: Winawer counter-gambit
+rnbqkbnr/pp3ppp/2pp4/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+English, Keres variation
+rnbqkbnr/pp3ppp/3p4/2pPp3/4P3/8/PPP2PPP/RNBQKBNR w KQkq -
+Semi-Benoni (`blockade variation')
+rnbqkbnr/pp3ppp/4p3/2PpP3/8/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance, Steinitz variation
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Sicilian: Marshall variation
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open variation
+rnbqkbnr/pp3ppp/4p3/2pp4/4P3/2N3P1/PPPP1P1P/R1BQKBNR w KQkq -
+Sicilian: closed, Korchnoi variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/1P6/5N2/P1PP1PPP/RNBQKB1R b KQkq -
+French: Wing gambit
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P2Q1/8/PPP2PPP/RNB1KBNR b KQkq -
+French: advance, Nimzovich variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/2P5/PP3PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/pp3ppp/4p3/2ppP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+French: advance, Nimzovich system
+rnbqkbnr/pp3ppp/4p3/3P4/3p4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch, von Hennig-Schara gambit
+rnbqkbnr/pp3ppp/4p3/8/2Bp4/5N2/PPPN1PPP/R1BQK2R w KQkq -
+French: Tarrasch, Eliskases variation
+rnbqkbnr/pp3ppp/8/1Npp4/8/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Kiel variation *
+rnbqkbnr/pp3ppp/8/2Ppp3/5P2/8/PPP1P1PP/RNBQKBNR b KQkq -
+QGA: Schwartz defense *
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QGA: 3.e4 *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/3P4/PPP2PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine variation, Balogh gambit *
+rnbqkbnr/pp3ppp/8/2p1p1N1/4p3/8/PPPP1PPP/RNBQKB1R w KQkq -
+Budapest: Alekhine variation *
+rnbqkbnr/pp3ppp/8/2pp4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+QGD: Tarrasch defense
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QGD: Tarrasch defense, 4.cd ed
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Panov-Botvinnik attack *
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, open, 4.ed ed
+rnbqkbnr/pp3ppp/8/2pp4/3PP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+QGD: Tarrasch defense, Marshall gambit
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: exchange variation *
+rnbqkbnr/pp3ppp/8/2ppp3/5P2/4P3/PPPP2PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit deferred *
+rnbqkbnr/pp3ppp/8/2ppp3/8/5PPN/PPPPP2P/RNBQKB1R b KQkq -
+Hippopotamus defense *
+rnbqkbnr/pp3ppp/8/3p4/2pP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+Caro-Kann: Panov-Botvinnik, Gunderam attack *
+rnbqkbnr/pp4pp/8/2p1pp2/8/2N5/PPPP1PPP/RNBQKB1R b KQkq -
+Budapest: Alekhine, Abonyi variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p1P1/1N1P4/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, Planinc variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+Alekhine's defense: four pawns attack, fianchetto variation *
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+Alekhine's defense: four pawns attack *
+rnbqkbnr/pp4pp/8/2pp1p2/4pB2/1N1P4/PPP1PPPP/RN1QKB1R b KQkq -
+Alekhine's defense: four pawns attack, Trifunovi\'c variation *
+rnbqkbnr/pp4pp/8/2pp4/4p3/1NN5/PPP1PPPP/R1BQKB1R b KQkq -
+Alekhine's defense: four pawns attack, 6...Nc6 *
+rnbqkbnr/ppp1p1pp/3p4/5p2/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+(Dutch:) Balogh defense
+rnbqkbnr/ppp1p1pp/5p2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Paleface attack *
+rnbqkbnr/ppp1p1pp/8/3p1p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Canard opening *
+rnbqkbnr/ppp1p1pp/8/5p2/2pPP3/8/PP3PPP/RNBQKBNR w KQkq -
+QGA: Schwartz defense
+rnbqkbnr/ppp1p2p/5p2/3p2p1/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Gedult attack *
+rnbqkbnr/ppp1pp1p/6p1/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch defense *
+rnbqkbnr/ppp1pp1p/6p1/3p4/8/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+R\'eti: King's Indian attack
+rnbqkbnr/ppp1pp1p/8/3p2p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Krejcik gambit *
+rnbqkbnr/ppp1pp1p/8/3p2p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Queen's pawn: Bronstein gambit *
+rnbqkbnr/ppp1ppp1/7p/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch, Korchnoi attack *
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Old Indian defense
+rnbqkbnr/ppp1pppp/3p4/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's Pawn
+rnbqkbnr/ppp1pppp/3p4/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/3p4/8/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Mieses opening *
+rnbqkbnr/ppp1pppp/8/3p2B1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Levitsky attack (Queen's bishop attack)
+rnbqkbnr/ppp1pppp/8/3p4/1P6/5N2/P1PPPPPP/RNBQKB1R b KQkq -
+Santasiere's folly
+rnbqkbnr/ppp1pppp/8/3p4/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish defense *
+rnbqkbnr/ppp1pppp/8/3p4/2P2P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Mujannah opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/3p4/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp1pppp/8/3p4/3P1B2/8/PPP1PPPP/RN1QKBNR b KQkq -
+Queen's pawn, Mason variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+Queen's pawn: Chigorin variation
+rnbqkbnr/ppp1pppp/8/3p4/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn game
+rnbqkbnr/ppp1pppp/8/3p4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Blackmar gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+Tennison (Lemberg, Zukertort) gambit
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn: Charlick (Englund) gambit *
+rnbqkbnr/ppp1pppp/8/3p4/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Scandinavian (center counter) defense
+rnbqkbnr/ppp1pppp/8/3p4/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+Bird's opening: Williams gambit
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch *
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird's opening
+rnbqkbnr/ppp1pppp/8/3p4/8/1P3N2/P1PPPPPP/RNBQKB1R b KQkq -
+R\'eti: Nimzovich-Larsen attack
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Queen's pawn: English defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: classical variation
+rnbqkbnr/ppp1pppp/8/3p4/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Queen's pawn: Lundin (Kevitz-Mikenas) defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+R\'eti: old Indian attack
+rnbqkbnr/ppp1pppp/8/3p4/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's Pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Queen's pawn game *
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti opening
+rnbqkbnr/ppp1pppp/8/3p4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+R\'eti: King's Indian attack (Barcza system)
+rnbqkbnr/ppp1pppp/8/3p4/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Modern defense *
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Queen's pawn *
+rnbqkbnr/ppp1pppp/8/8/2Pp1P2/8/PP1PP1PP/RNBQKBNR b KQkq -
+Old Benoni: Mujannah formation *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/3P4/PP2PPPP/RNBQKBNR b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti: advance variation
+rnbqkbnr/ppp1pppp/8/8/2PpP3/8/PP1P1PPP/RNBQKBNR b KQkq e3
+Old Benoni defense *
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+R\'eti accepted
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGA: 3.Nf3
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit accepted
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QGA: 3.e4
+rnbqkbnr/ppp2p1p/3p2p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Larsen variation
+rnbqkbnr/ppp2p1p/3p4/4N3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Kolisch defense
+rnbqkbnr/ppp2p1p/8/3p2p1/4p3/6P1/PPPPPPNP/RNBQKB1R b KQkq -
+Norwegian defense *
+rnbqkbnr/ppp2p1p/8/3p4/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 w kq -
+KGA: Muzio gambit, Brentano defense
+rnbqkbnr/ppp2p1p/8/3pN3/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, Brentano (Campbell) defense
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+English opening
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Philidor's defense
+rnbqkbnr/ppp2ppp/3p4/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: Indian opening *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann: closed (Breyer) variation *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: King's Indian attack *
+rnbqkbnr/ppp2ppp/3p4/4p3/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense: Mar\'oczy variation *
+rnbqkbnr/ppp2ppp/3p4/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: exchange variation
+rnbqkbnr/ppp2ppp/3p4/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Fischer defense
+rnbqkbnr/ppp2ppp/3pp3/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Lengfellner system
+rnbqkbnr/ppp2ppp/4p3/3P4/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: exchange variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+English opening: Agincourt variation
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+QGD: 3.Nc3
+rnbqkbnr/ppp2ppp/4p3/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Queen's gambit declined
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+French: Paulsen variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+French: Schlechter variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/4B3/PPP2PPP/RN1QKBNR b KQkq -
+French: Alapin variation
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+French: Tarrasch
+rnbqkbnr/ppp2ppp/4p3/3p4/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+French: Two knights variation
+rnbqkbnr/ppp2ppp/4p3/3p4/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+French: Pelikan variation
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+French: advance variation
+rnbqkbnr/ppp2ppp/4p3/8/3Pp3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+French: Rubinstein variation
+rnbqkbnr/ppp2ppp/8/1B1P4/4pP2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGD: Falkbeer, Nimzovich variation
+rnbqkbnr/ppp2ppp/8/3P4/3N4/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Paulsen attack
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/3P4/PPP3PP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 4.d3
+rnbqkbnr/ppp2ppp/8/3P4/4pP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 3...e4
+rnbqkbnr/ppp2ppp/8/3Pp3/5P2/8/PPPP2PP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+Center game *
+rnbqkbnr/ppp2ppp/8/3p4/1P1Np3/8/P1PPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: O'Sullivan gambit *
+rnbqkbnr/ppp2ppp/8/3p4/2B1P3/8/PB3PPP/RN1QK1NR w KQkq -
+Danish gambit: Schlechter defense
+rnbqkbnr/ppp2ppp/8/3p4/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, Bledow variation
+rnbqkbnr/ppp2ppp/8/3p4/3N4/8/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian: Marshall variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+Alekhine's defense *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: advance variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+French: exchange variation *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Scandinavian defense *
+rnbqkbnr/ppp2ppp/8/3p4/3p4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+Scandinavian: Richter variation *
+rnbqkbnr/ppp2ppp/8/3p4/3pP3/2P5/PP3PPP/RNBQKBNR w KQkq -
+Danish gambit: S\o rensen defense
+rnbqkbnr/ppp2ppp/8/3p4/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Abbazia defense (classical defense, modern defense[!])
+rnbqkbnr/ppp2ppp/8/3pP3/8/8/PPPPP1PP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Smith-Morra gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Blackmar gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+QP counter-gambit (elephant gambit)
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGD: Falkbeer, Milner-Barry variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KGD: Falkbeer, Tartakower variation
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/3P4/PPP1P1PP/RNBQKBNR b KQkq -
+(Dutch:) Balogh defense *
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N2P2/PPPPP1PP/R1BQKBNR b KQkq -
+KP: Neo-Mongoloid defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P2N2/PP1PPPPP/RNBQKB1R b KQkq -
+Caro-Masi defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/2P5/PP1PPPPP/RNBQKBNR w KQkq -
+Caro-Kann defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+Pirc defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/3PP3/PPP2PPP/RNBQKBNR b KQkq -
+Lengfellner system *
+rnbqkbnr/ppp2ppp/8/3pp3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Fried fox defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/BP6/P1PPPPPP/RN1QKBNR b KQkq -
+Guatemala defense *
+rnbqkbnr/ppp2ppp/8/3pp3/8/P3P3/1PPP1PPP/RNBQKBNR b KQkq -
+St. George defense *
+rnbqkbnr/ppp2ppp/8/4P3/2Pp4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QGD: Albin counter-gambit
+rnbqkbnr/ppp2ppp/8/4p3/2Pp4/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+Old Benoni: Franco-Benoni defense *
+rnbqkbnr/ppp2ppp/8/4p3/2PpP3/3P4/PP3PPP/RNBQKBNR b KQkq -
+Semi-Benoni (`blockade variation') *
+rnbqkbnr/ppp2ppp/8/8/2pPp3/4P3/PP3PPP/RNBQKBNR w KQkq -
+French: advance, Steinitz variation *
+rnbqkbnr/ppp3pp/3p4/4Pp2/3p4/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer, 4.d3 *
+rnbqkbnr/ppp3pp/3p4/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+Philidor: L\'opez counter-gambit
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/2N2N2/PPP2PPP/R1BQKB1R b KQkq -
+Philidor: Philidor counter-gambit, Zukertort variation
+rnbqkbnr/ppp3pp/3p4/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+Philidor: Philidor counter-gambit
+rnbqkbnr/ppp3pp/4P3/3p2N1/4p3/8/PPP2PPP/RNBQKB1R b KQkq -
+Philidor: Philidor counter-gambit, del Rio attack
+rnbqkbnr/ppp3pp/4p3/3p1p2/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+French: Tarrasch, Haberditz variation
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+Caro-Kann: Tartakower (fantasy) variation *
+rnbqkbnr/ppp3pp/5p2/3pp3/3P4/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+Blackmar-Diemer gambit *
+rnbqkbnr/ppp3pp/8/3Ppp2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Halasz gambit *
+rnbqkbnr/ppp3pp/8/3pN3/2B1p3/8/PPPP1PPP/RNBQK2R w KQkq -
+Latvian: Polerio variation
+rnbqkbnr/ppp3pp/8/3ppP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Villemson (Steinitz) gambit *
+rnbqkbnr/ppp3pp/8/3ppp2/8/6P1/PPPPPPBP/RNBQK1NR w KQkq -
+Robatsch defense: three pawns attack *
+rnbqkbnr/ppp3pp/8/4pp2/3p4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+KGD: Falkbeer, 5.de *
+rnbqkbnr/pppp1B1p/8/8/4Ppp1/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: Lolli gambit (wild Muzio gambit)
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+English: Adorjan defense
+rnbqkbnr/pppp1p1p/6p1/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Steinitz variation *
+rnbqkbnr/pppp1p1p/8/4N3/2B1Ppp1/8/PPPP2PP/RNBQK2R b KQkq -
+KGA: Salvio gambit
+rnbqkbnr/pppp1p1p/8/4N3/3PPpp1/8/PPP3PP/RNBQKB1R b KQkq -
+KGA: S\o rensen gambit
+rnbqkbnr/pppp1p1p/8/6N1/4PppP/8/PPPP2P1/RNBQKB1R b KQkq -
+KGA: Allgaier gambit
+rnbqkbnr/pppp1p1p/8/6p1/2B1Pp2/5N2/PPPP2PP/RNBQK2R b KQkq -
+KGA: King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/3PPp2/5N2/PPP3PP/RNBQKB1R b KQkq -
+KGA: Rosentreter gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp1P/5N2/PPPP2P1/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/2N2N2/PPPP2PP/R1BQKB1R b KQkq -
+KGA: Quaade gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/2N2N2/PPPP2PP/R1BQK2R b KQkq -
+KGA: MacDonnell gambit
+rnbqkbnr/pppp1p1p/8/8/2B1Ppp1/5N2/PPPP2PP/RNBQ1RK1 b kq -
+KGA: Muzio gambit
+rnbqkbnr/pppp1p1p/8/8/2BPPpp1/5N2/PPP3PP/RNBQK2R b KQkq -
+KGA: Ghulam Kassim gambit
+rnbqkbnr/pppp1p2/8/4N2p/4PppP/8/PPPP2P1/RNBQKB1R w KQkq -
+KGA: Kieseritsky, long whip (Stockwhip, classical) defense
+rnbqkbnr/pppp1pp1/7p/8/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Becker defense
+rnbqkbnr/pppp1ppp/4p3/4P3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+French: Steinitz attack
+rnbqkbnr/pppp1ppp/4p3/8/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+French defense, Steiner variation
+rnbqkbnr/pppp1ppp/4p3/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/4p3/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn
+rnbqkbnr/pppp1ppp/4p3/8/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/1P6/P1PP1PPP/RNBQKBNR b KQkq -
+French: R\'eti (Spielmann) variation
+rnbqkbnr/pppp1ppp/4p3/8/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+French: King's Indian attack
+rnbqkbnr/pppp1ppp/4p3/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+French defense
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+French: Chigorin variation
+rnbqkbnr/pppp1ppp/4p3/8/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+French: Labourdonnais variation
+rnbqkbnr/pppp1ppp/4p3/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Van't Kruijs opening *
+rnbqkbnr/pppp1ppp/8/4N3/4p3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense: Mokele Mbembe (B\"ucker) variation *
+rnbqkbnr/pppp1ppp/8/4p2Q/4P3/8/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Patzer opening
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+Bishop's opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+English, Nimzovich variation
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+Sicilian defense *
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Scandinavian (center counter) defense *
+rnbqkbnr/pppp1ppp/8/4p3/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Queen's pawn: Charlick (Englund) gambit
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+Vienna game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+KP: Lopez opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+KP: Indian opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+King's knight opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5P2/PPPP2PP/RNBQKBNR b KQkq -
+KP: King's head opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KP: Napoleon's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn game *
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's pawn game
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPPNPPP/RNBQKB1R b KQkq -
+Alapin's opening
+rnbqkbnr/pppp1ppp/8/4p3/4P3/P7/1PPP1PPP/RNBQKBNR b KQkq -
+KP: Mengarini's opening
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+King's gambit
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Fred *
+rnbqkbnr/pppp1ppp/8/4p3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: From gambit
+rnbqkbnr/pppp1ppp/8/4p3/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob) *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Owen defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: modern variation
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+KP: Nimzovich defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+Dunst (Sleipner,Heinrichsen) opening
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Caro-Kann defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+Mieses opening
+rnbqkbnr/pppp1ppp/8/4p3/8/3P4/PPPNPPPP/R1BQKBNR b KQkq -
+Valencia opening
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+French defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+Benko's opening: reversed Alekhine
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Barnes defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/5P2/PPPPPKPP/RNBQ1BNR b kq -
+Hammerschlag (Fried fox/Pork chop opening)
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Robatsch (modern) defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Carr's defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+King's pawn opening *
+rnbqkbnr/pppp1ppp/8/4p3/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Lemming defense *
+rnbqkbnr/pppp1ppp/8/4p3/8/P1N5/1PPPPPPP/R1BQKBNR b KQkq -
+Battambang opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P6P/1PPPPPP1/RNBQKBNR b KQkq -
+Global opening
+rnbqkbnr/pppp1ppp/8/4p3/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+St. George (Baker) defense *
+rnbqkbnr/pppp1ppp/8/4p3/P6P/8/1PPPPPP1/RNBQKBNR b KQkq -
+Crab opening
+rnbqkbnr/pppp1ppp/8/4p3/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Corn stalk defense *
+rnbqkbnr/pppp1ppp/8/8/2B1Pp2/8/PPPP2PP/RNBQK1NR b KQkq -
+KGA: bishop's gambit
+rnbqkbnr/pppp1ppp/8/8/2P1p3/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+English, Nimzovich, Flohr variation
+rnbqkbnr/pppp1ppp/8/8/3Np3/8/PPPPPPPP/RNBQKB1R b KQkq -
+Alekhine's defense *
+rnbqkbnr/pppp1ppp/8/8/3PPp2/8/PPP3PP/RNBQKBNR b KQkq -
+KGA: Villemson (Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/3QP3/8/PPP2PPP/RNB1KBNR b KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+Scandinavian defense *
+rnbqkbnr/pppp1ppp/8/8/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+Danish gambit
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+Center game
+rnbqkbnr/pppp1ppp/8/8/3pPP2/8/PPP3PP/RNBQKBNR b KQkq -
+Halasz gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp1P/8/PPPP2P1/RNBQKBNR b KQkq -
+KGA: Pawn's gambit (Stamma gambit)
+rnbqkbnr/pppp1ppp/8/8/4Pp2/1P6/P1PP2PP/RNBQKBNR b KQkq -
+KGA: Orsini gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+KGA: Keres (Mason-Steinitz) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/3B4/PPPP2PP/RNBQK1NR b KQkq -
+KGA: Schurig gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+King's knight's gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5Q2/PPPP2PP/RNB1KBNR b KQkq -
+KGA: Breyer gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP1KPP/RNBQ1BNR b kq -
+KGA: Tumbleweed gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+King's gambit accepted
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPB1PP/RNBQK1NR b KQkq -
+KGA: Lesser bishop's (Petroff-Jaenisch-Tartakower) gambit
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPPQ1PP/RNB1KBNR b KQkq -
+KGA: Carrera (Basman) gambit
+rnbqkbnr/pppp1ppp/8/8/4p3/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Steinitz attack *
+rnbqkbnr/pppp1ppp/8/8/4p3/8/PPPPPPPP/RNBQKBNR b KQkq -
+Alekhine's defense: Brooklyn defense *
+rnbqkbnr/pppp2p1/8/4pP1p/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KGA: Pawn's gambit (Stamma gambit) *
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+Dutch defense, Rubinstein variation
+rnbqkbnr/pppp2pp/4p3/5p2/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+Dutch defense
+rnbqkbnr/pppp2pp/4p3/5p2/2PPP3/8/PP3PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit deferred
+rnbqkbnr/pppp2pp/4p3/5p2/3P2P1/3Q4/PPP1PP1P/RNB1KBNR b KQkq -
+Dutch, Von Pretzel gambit
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Damiano's defense
+rnbqkbnr/pppp2pp/5p2/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP: King's head opening *
+rnbqkbnr/pppp2pp/8/4Pp2/3p4/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer, 3...e4 *
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's gambit accepted *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/3P4/PPP2PPP/RNBQK1NR b KQkq -
+Bishop's opening: Calabrese counter-gambit, Jaenisch variation
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+Latvian gambit, 3.Bc4
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+KGD: classical variation *
+rnbqkbnr/pppp2pp/8/4pp2/2B1P3/8/PPPP1PPP/RNBQK1NR w KQkq -
+Bishop's opening: Calabrese counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/2P1P3/8/PP1P1PPP/RNBQKBNR b KQkq -
+KGD: Mafia defense *
+rnbqkbnr/pppp2pp/8/4pp2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+Sicilian: Grand Prix attack *
+rnbqkbnr/pppp2pp/8/4pp2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Bird's opening: Williams gambit *
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+KGD: 2...Nf6 *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+Latvian counter-gambit
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5Q2/PPPP1PPP/RNB1KBNR b KQkq -
+KGD: Norwalde variation *
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+King's gambit *
+rnbqkbnr/pppp2pp/8/4pp2/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+French: Labourdonnais variation *
+rnbqkbnr/pppp2pp/8/5p2/2B1Pp2/8/PPPP2PP/RNBQK1NR w KQkq -
+KGA: bishop's gambit, L\'opez-Gianutio counter-gambit
+rnbqkbnr/pppp2pp/8/5p2/3pP3/2P5/PP3PPP/RNBQKBNR b KQkq -
+KGD: Nimzovich counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KGD: Falkbeer counter-gambit *
+rnbqkbnr/pppp2pp/8/5p2/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KGA: Gianutio counter-gambit
+rnbqkbnr/pppp3p/6p1/4pp2/4P3/8/PPPPQPPP/RNB1KBNR b KQkq -
+KGD: Keene's defense *
+rnbqkbnr/ppppp1pp/5p2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Barnes defense
+rnbqkbnr/ppppp1pp/5p2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Gedult's opening *
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English: Anglo-Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P2P1/8/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch, Krejcik gambit
+rnbqkbnr/ppppp1pp/8/5p2/3P4/3Q4/PPP1PPPP/RNB1KBNR b KQkq -
+Dutch, Manhattan (Alapin, Ulvestad) variation
+rnbqkbnr/ppppp1pp/8/5p2/3P4/6P1/PPP1PP1P/RNBQKBNR b KQkq -
+Dutch defense
+rnbqkbnr/ppppp1pp/8/5p2/3P4/7P/PPP1PPP1/RNBQKBNR b KQkq -
+Dutch, Korchnoi attack
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Dutch
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+R\'eti: Pirc-Lisitsin gambit
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+Bird: From gambit *
+rnbqkbnr/ppppp1pp/8/5p2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Fred
+rnbqkbnr/ppppp1pp/8/5p2/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Bird: Hobbs gambit *
+rnbqkbnr/ppppp1pp/8/5p2/8/1P6/P1PPPPPP/RNBQKBNR w KQkq -
+Nimzovich-Larsen attack: Dutch variation
+rnbqkbnr/ppppp1pp/8/5p2/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti v Dutch
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Bird's opening *
+rnbqkbnr/ppppp1pp/8/5pB1/3P4/8/PPP1PPPP/RN1QKBNR b KQkq -
+Dutch, 2.Bg5 variation
+rnbqkbnr/ppppp1pp/8/8/3Pp3/8/PPP2PPP/RNBQKBNR w KQkq -
+Dutch: Staunton gambit
+rnbqkbnr/pppppp1p/6p1/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+English opening
+rnbqkbnr/pppppp1p/6p1/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+Modern defense
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Robatsch (modern) defense
+rnbqkbnr/pppppp1p/6p1/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Lasker simul special *
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Benko's opening *
+rnbqkbnr/pppppp1p/8/6p1/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Reversed Grob (Borg/Basman defense/macho Grob)
+rnbqkbnr/pppppp1p/8/6p1/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+Bird: Hobbs gambit
+rnbqkbnr/pppppp1p/8/6p1/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+R\'eti: Herrstr\"om gambit
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Grob's attack *
+rnbqkbnr/ppppppp1/7p/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+Carr's defense
+rnbqkbnr/ppppppp1/7p/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening *
+rnbqkbnr/ppppppp1/8/7p/8/6P1/PPPPPP1P/RNBQKBNR w KQkq -
+Lasker simul special
+rnbqkbnr/ppppppp1/8/7p/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+Anti-Borg (Desprez) opening *
+rnbqkbnr/pppppppp/8/4P3/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+Alekhine's defense: Brooklyn defense
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+Polish (Sokolsky) opening
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+English opening
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+Queen's pawn
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+King's pawn opening
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+Bird's opening
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+Grob's attack
+rnbqkbnr/pppppppp/8/8/7P/8/PPPPPPP1/RNBQKBNR b KQkq -
+Anti-Borg (Desprez) opening
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+Nimzovich-Larsen attack
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+Dunst (Sleipner, Heinrichsen) opening
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+Saragossa opening
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+Mieses opening
+rnbqkbnr/pppppppp/8/8/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+Van't Kruijs opening
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+R\'eti opening
+rnbqkbnr/pppppppp/8/8/8/5P2/PPPPP1PP/RNBQKBNR b KQkq -
+Gedult's opening
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+Benko's opening
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+Amar (Paris) opening
+rnbqkbnr/pppppppp/8/8/8/7P/PPPPPPP1/RNBQKBNR b KQkq -
+Clemenz (Mead's, Basman's or de Klerk's) opening
+rnbqkbnr/pppppppp/8/8/8/N7/PPPPPPPP/R1BQKBNR b KQkq -
+Durkin's attack
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+Anderssen's opening
+rnbqkbnr/pppppppp/8/8/P7/8/1PPPPPPP/RNBQKBNR b KQkq -
+Ware (Meadow Hay) opening
+rnbqkr2/pppp1pQp/8/2b1P3/3P4/5N2/PPP3PP/RNB1KB1n b KQq -
+Latvian: Behting variation *
+rnbqkr2/ppppbp1p/5N2/4Q3/8/8/PPPP1nPP/R1B1KBNR b KQq -
+Blackburne shilling gambit *
+rnbqr1k1/1p1p1ppp/pbp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Suetin variation *
+rnbqr1k1/1p3pp1/2p2n1p/p1bpp3/4P3/PBNP1N2/1PP1QPPP/R1B1K2R w KQ -
+Giuoco Piano: Tarrasch variation *
+rnbqr1k1/1pb2ppp/2p2n2/p2pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B1K2R w KQ -
+Ruy Lopez: closed, Balla variation *
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, anti-Marshall 8.a4 *
+rnbqr1k1/p1pp1ppp/5n2/1p2p3/1bP1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQ -
+Sicilian: Nimzovich-Rossolimo attack, Gurgenidze variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+Ruy Lopez: closed, Smyslov defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Flohr-Zaitsev system (Lenzerheide variation) *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.h3 *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP4/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Ragozin-Petrosian (`Keres') variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NPBN2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Kholmov variation *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+Ruy Lopez: closed, Breyer defense *
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/PP2P3/2NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (9...a5) variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4P3/1P1p4/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall, Herman Steiner variation *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P1PP3/P1N2N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: Marshall counter-attack *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 8.c3 *
+rnbqr1k1/pp1p1ppp/1bp2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (with ...d6) *
+rnbqr1k1/pp3p1p/1bp3pQ/3p4/1P1N4/P1PB4/5PPP/R1B2RK1 b - -
+Ruy Lopez: Marshall, main line, 14...Qh3 *
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+Benoni: classical, 9...Re8
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+Benoni: classical, 9...Re8, 10.Nd2
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+Benoni: four pawns attack, main line
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 w - -
+Ruy Lopez: closed, Breyer, 10.d4 *
+rnbqr1k1/pp3pp1/1bp2n1p/3pp3/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Breyer, Borisenko variation *
+rnbqr1k1/pp3pp1/1bp4p/3pp2n/1P2P3/P2P1N2/2PNBPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Breyer, Simagin variation *
+rnbqr1k1/pp3ppB/3b1n2/3pN1B1/3p1P2/8/PPP3PP/RN1Q1RK1 b - -
+Petrov: classical attack, Marshall trap *
+rnbqr1k1/pp3ppp/1bp2n2/3pp1B1/1P2P3/P1NP1N2/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: closed, Bogolyubov variation *
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, 9.d4 *
+rnbqr1k1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P1BPPP/R2QK2R w KQ -
+Ruy Lopez: open, 9...Be7, 10.Re1 *
+rnbqr1k1/pp3ppp/1bp5/3nN3/1P1PN3/P3B3/2P1BPPP/R2Q1RK1 b - -
+Ruy Lopez: open, Breslau variation *
+rnbqr1k1/pp3ppp/1bpp1n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Pilnik variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1B1/3P1P2/2N5/PPP1B1PP/R2QK2R w KQ -
+Petrov: classical attack, Krause variation *
+rnbqr1k1/pp3ppp/3b1n2/2ppN1BB/3P1P2/2N5/PPP3PP/R2QK2R b KQ -
+Petrov: classical attack, Mar\'oczy variation *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/1PP1P3/P1NP1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Borisenko defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NP2P3/P1PP1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Rossolimo defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 b - -
+Ruy Lopez: closed, Chigorin defense *
+rnbqr1k1/ppb2pp1/2p2n1p/3pp3/NPP1P3/P2P4/3NBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, Keres (...Nd7) defense *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed (9...Na5) *
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NPP1P3/P2P1N2/4BPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed (10...c5) *
+rnbqr1k1/ppbp1ppp/2p2n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+Ruy Lopez: closed, Lutikov variation *
+rnbqr1k1/ppp2ppp/1b3n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R w KQ -
+Ruy Lopez: closed, 7...d6, 8.d4 *
+rnbqr1k1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R w KQ -
+Petrov: classical attack, Chigorin variation *
+rnbqr1k1/ppp2ppp/5n2/2PP4/2B5/2N1B3/PPP2PpP/R2QK2R w KQ -
+two knights: Max Lange attack, Schlechter variation *
+rnbqr1k1/ppp2ppp/8/2PP4/2B3n1/2N1BpP1/PPP2P1P/R2QK2R b KQ -
+two knights: Max Lange attack, Loman defense *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/1BPPBPPP/R2QK2R b KQ -
+Ruy Lopez: Trajkovi\'c counter-attack *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 b - -
+Ruy Lopez: closed, 7...O-O *
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+Ruy Lopez: closed *
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+Ruy Lopez: closed, Averbach variation *
+rnbr2k1/1pq1ppbp/5np1/p1pp4/3P4/1PP1PN2/P2NBPPP/R1BQ1RK1 w - -
+Catalan: closed, Zagoryansky variation *
+rnbr2k1/pp2qppp/5n2/2b1N3/3Pp3/P1N1B3/2PQBPPP/R4RK1 b - -
+Ruy Lopez: open, Howell attack, Ekstr\"om variation *
+rnq1kb1r/pp3ppp/4pn2/3p1b2/3P4/NQ2PN2/PP1B1PPP/R3KB1R b KQkq -
+QGD Slav: Landau variation
blob - /dev/null
blob + b0cee3cdd90d0ddf70b7568be4b15cbbd93a7cd1 (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/nic000.idx
+1r1qr1k1/p1n2pbp/bp1p1np1/2pP2B1/P1N1P3/2N2P2/1P2B1PP/R2Q1R1K b - -
+BI.06
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NPP/PP2PPB1/R1BQ1RK1 w - -
+KI.70
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP2P/2N1BP2/PPQ1N1P1/R3KB1R b KQ -
+KI.33
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1Q2PP/R1N1KB1R b KQ -
+KI.34
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.35
+1rbq1rk1/4ppbp/p2p1np1/nppP4/2P5/1PN3P1/PBQNPPBP/R4RK1 b - -
+KI.66
+1rbq1rk1/pp2ppbp/2np1np1/2p5/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+EO.13*
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+EO.15*
+1rbqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQk -
+EO.16*
+1rbqr1k1/1p1n1pbp/p2p1np1/2pP4/P1N5/2N3PP/1P2PPB1/R1BQ1RK1 b - -
+BI.21
+2bq1rk1/1p1nbppp/r1n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.01*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 b - -
+SI.28*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+SI.30*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R w KQ -
+SI.29*
+2rqkb1r/pp2pppp/2n2n2/2Pp3b/8/4PN1P/PPP1BPP1/RNBQ1RK1 b k -
+QO.07*
+2rqkb1r/pp2pppp/5n2/3p4/3P4/1P5P/P1P1QPP1/RNB2RK1 b k -
+QO.06*
+2rqkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/PBP1BPP1/RN1Q1RK1 b k -
+QO.09*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QO.11*
+3rkb1r/1pq2ppp/p1n1pn2/2p2b2/Q2P4/2N1PN2/PP2BPPP/R1B2RK1 b k -
+QO.02*
+r1b1k2r/ppp2pp1/3q1nn1/3p4/7p/2P4P/PP1NPPP1/R2QKBNR w KQkq -
+CK.12*
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+SI.24
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QO.15
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.10*
+r1b1kb1r/ppqppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+EO.58*
+r1b1kbnr/1p2pppp/p1q5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.20*
+r1b1kbnr/pp3ppp/2n5/2p1q3/4p3/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+EO.55*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+NI.21*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.22*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.23*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.24*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.40
+r1b2rk1/1p1nqppp/2n5/p3p3/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.14*
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+RL.24
+r1b2rk1/pp2bppp/2n1pn2/q2p4/2P2B2/P1N1PN2/1PQ2PPP/3RKB1R w K -
+QO.02
+r1b2rk1/pp2ppbp/2n2np1/2pq4/8/1P2PN2/PB1PBPPP/RN1QK2R w KQ -
+EO.39*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/2P5/1P2P3/PB1PBPPP/RN1Q1RK1 b - -
+QI.13*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/5P2/1P2P3/PBPPB1PP/RN1Q1RK1 b - -
+QI.12*
+r1b2rk1/ppq1ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+QI.11*
+r1b2rk1/ppq2ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 w - -
+NI.01
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+KI.09
+r1bq1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+BI.15
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/1P1P1NP1/P1N2PBP/R1BQR1K1 b - -
+BI.07*
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/3P2P1/PPNN1PBP/R1BQR1K1 b - -
+BI.08*
+r1bq1rk1/1p1nb1pp/2n5/p3pp2/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.02*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.03*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2PpN3/3P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.04*
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.22*
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQ1RK1 b - -
+BI.15*
+r1bq1rk1/1p2ppb1/2n3pp/p1n5/2Pp4/P2P1NP1/1P1N1PBP/1RBQR1K1 w - -
+BI.21*
+r1bq1rk1/1p3pp1/2n2b1p/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R2Q1RK1 b - -
+BI.10*
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+SL.05*
+r1bq1rk1/1p3ppp/p1nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.02*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.71
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.22
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+RL.20
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+RL.21
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+RL.23
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+RL.18
+r1bq1rk1/3nppbp/p1pp1np1/1p6/2PPP3/2NBBP2/PP2N1PP/R2Q1RK1 w - -
+KI.46
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PPQ2PPP/R1B2RK1 b - -
+NI.01*
+r1bq1rk1/p1p2ppp/5n2/3p2B1/1b6/2NB4/PPP2PPP/R2Q1RK1 b - -
+SO.03
+r1bq1rk1/p3bp1p/2n2np1/1pp1p3/3pPP1N/3P2P1/PPP1N1BP/R1BQ1RK1 b - -
+KI.04*
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.05*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.42
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 b - -
+KI.10
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 w - -
+KI.63
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+KI.62
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.03
+r1bq1rk1/pp1nbppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.07*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP1N1PBP/R1BQR1K1 b - -
+BI.05*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.09*
+r1bq1rk1/pp1pppbp/2n2np1/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+EO.01*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+EO.40*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQ -
+EO.48*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.27*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.27
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+EO.41*
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N3P1/PP2PPBP/R1BQ1RK1 b - -
+EO.26
+r1bq1rk1/pp2bppp/2n1p3/2pn4/3PP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+TD.02
+r1bq1rk1/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.12*
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+TD.03
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.04
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+KI.15*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.14*
+r1bq1rk1/pp2bppp/2n2n2/4p1B1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b - -
+BI.16*
+r1bq1rk1/pp2bppp/2n5/2pp4/3P4/5NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.01
+r1bq1rk1/pp2bppp/2nn4/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.01*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w - -
+SI.28
+r1bq1rk1/pp2nppp/2nb4/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.36*
+r1bq1rk1/pp2ppb1/2n2npp/2pp4/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b - -
+KI.70*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.68*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.68
+r1bq1rk1/pp2ppbp/2n2np1/2p5/N1Pp4/3P1NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.67*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.69*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+QI.09*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 w - -
+KI.72*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2PP1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.75*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+KI.71*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+KI.74*
+r1bq1rk1/pp2ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 b - -
+QI.10*
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+TD.04*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.24*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+BI.23*
+r1bq1rk1/pp2ppbp/2n3p1/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.26*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+GI.06
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+SI.18
+r1bq1rk1/pp2ppbp/3p1np1/n1pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.67
+r1bq1rk1/pp2ppbp/5np1/3p4/2PP4/2N5/PP2BPPP/R1BQ1RK1 b - -
+TD.01*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.62*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQR1K1 b - -
+KI.61*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b - -
+KI.63*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.64*
+r1bq1rk1/pp3pbp/2n2np1/3pp3/2PN4/2N1P3/PP2BPPP/R1BQ1RK1 w - -
+TD.02*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+NI.03*
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/P1NBPN2/1P3PPP/R1BQ1RK1 b - -
+NI.02
+r1bq1rk1/pp3ppp/2n2n2/1Bbp4/8/1P2PN2/P4PPP/RNBQ1RK1 b - -
+NI.04*
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 w - -
+NI.05*
+r1bq1rk1/ppp1b1pp/2n5/3npp2/8/P1NPPN2/1PQ2PPP/R1B1KB1R b KQ -
+SI.24*
+r1bq1rk1/ppp1bppp/2n2n2/3pp1B1/8/3P1NP1/PPP1PPBP/RN1Q1RK1 b - -
+PU.01*
+r1bq1rk1/ppp1n1bp/3p2p1/3Ppp1n/1PP1P3/2N2NP1/P3BP1P/R1BQ1RK1 w - -
+KI.04
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/1PP1P3/2N2N2/P3BPPP/R1BQ1RK1 b - -
+KI.05
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N2N2/PP1BBPPP/R2Q1RK1 b - -
+KI.06
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP1NBPPP/R1BQ1RK1 b - -
+KI.07
+r1bq1rk1/ppp1npbp/3p1np1/3Pp3/2P1P3/2N5/PP2BPPP/R1BQNRK1 b - -
+KI.03
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.72
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQK2R w KQ -
+KI.73
+r1bq1rk1/ppp1ppbp/2np1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.36
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2P5/2NP1NP1/PP2PPBP/1RBQ1RK1 b - -
+EO.13
+r1bq1rk1/ppp2pbp/2np1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+KI.08
+r1bq1rk1/ppp2ppp/1n3n2/8/1b1P4/2NB4/PP2NPPP/R1BQK2R b KQ -
+FR.23*
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+KI.12
+r1bq1rk1/pppn1pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+KI.16
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.65
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N1BN2/PP2BPPP/R2Q1RK1 b - -
+KI.13
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+KI.14
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQR1K1 b - -
+KI.11
+r1bq1rk1/pppn1pbp/3p1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+KI.64
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/2RQKB1R b K -
+QO.11
+r1bq1rk1/pppnbppp/4pn2/3p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.12
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2N2P2/PP2B1PP/R1BQNRK1 w - -
+KI.02
+r1bq1rk1/pppnn1bp/3p2p1/3Ppp2/2P1P3/2NN4/PP2BPPP/R1BQ1RK1 w - -
+KI.01
+r1bq1rk1/pppnppbp/3p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.48
+r1bq1rk1/pppp1ppp/2n2n2/4p3/1bP5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.01
+r1bqk1nr/1p3ppp/p1nbp3/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+NI.08*
+r1bqk1nr/p4ppp/2p5/2bpp3/8/6P1/PPP1PPBP/RNBQK2R w KQkq -
+GI.05*
+r1bqk1nr/pp1n1ppp/2pb4/3p4/2PPp3/4P3/PP1N1PPP/RNBQKB1R w KQkq -
+FR.17*
+r1bqk1nr/pp1p1pbp/2n1p1p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.29*
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.30*
+r1bqk1nr/pp1p1pbp/2n3p1/2p1p3/4P3/2NP2P1/PPP2PBP/R1BQK1NR b KQkq -
+EO.18*
+r1bqk1nr/pp1pppbp/2n3p1/1Bp5/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+EO.11*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR b KQkq -
+EO.30
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N1P1P1/PP1P1PBP/R1BQK1NR b KQkq -
+EO.29
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.28
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.31*
+r1bqk1nr/pp1pppbp/2n3p1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.31
+r1bqk1nr/pp1pppbp/2n3p1/2p5/4P3/5NP1/PPPP1PBP/RNBQK2R b KQkq -
+EO.14*
+r1bqk1nr/pp1pppbp/2n3p1/8/2P5/8/PPN1PPPP/RNBQKB1R b KQkq -
+EO.37*
+r1bqk1nr/pp1pppbp/2n3p1/8/2PN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+EO.35
+r1bqk1nr/pp1pppbp/2n3p1/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+EO.38*
+r1bqk1nr/pp1pppbp/2n3p1/8/3N4/6P1/PPP1PP1P/RNBQKB1R w KQkq -
+EO.53*
+r1bqk1nr/pp2bppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.27*
+r1bqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+SI.45
+r1bqk1nr/pp3pbp/2n1p1p1/2pp4/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.78*
+r1bqk1nr/pp3pbp/2n3p1/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.29*
+r1bqk1nr/pp4pp/2n5/4pp2/1bPp4/3P2P1/PP1N1PBP/RNBQK2R b KQkq -
+BI.33*
+r1bqk1nr/pp4pp/2nb4/2p1pp2/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.60*
+r1bqk1nr/ppp1ppbp/2np2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KF.03
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P1P3/2N3P1/PP1P1PBP/R1BQK1NR w KQkq -
+EO.18
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2N1P1P1/PP1PNPBP/R1BQK2R b KQkq -
+EO.17
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/1RBQK1NR b Kkq -
+EO.16
+r1bqk1nr/ppp2pbp/2np2p1/4p3/2P5/2NP2P1/PP2PPBP/R1BQK1NR b KQkq -
+SI.45*
+r1bqk1nr/ppp2ppp/8/2bpn3/8/2P5/PP1NPPPP/R1BQKBNR w KQkq -
+CK.09*
+r1bqk1nr/pppn1pbp/3p2p1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+KF.01
+r1bqk1nr/pppnppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KF.02
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.19
+r1bqk1nr/pppp1pbp/2n3p1/4p3/2P5/2N3P1/PP1PPPBP/1RBQK1NR b Kkq -
+EO.15
+r1bqk1nr/pppp1ppp/2n5/2b1p3/1PB1P3/5N2/P1PP1PPP/RNBQK2R b KQkq -
+IG.05
+r1bqk1nr/pppp1ppp/2n5/2b1p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+IG.02
+r1bqk1nr/pppp1ppp/2n5/2b1p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+VG.02*
+r1bqk1nr/pppp1ppp/2n5/2b5/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SO.05
+r1bqk2r/1p4pp/2nb1n2/p3pp2/2Pp4/P2P2P1/1P1N1PBP/RNBQ1RK1 w kq -
+BI.32*
+r1bqk2r/1pp1bppp/p1np1n2/4p3/B3P3/5N2/PPPP1PPP/RNBQR1K1 w kq -
+RL.16
+r1bqk2r/1pppbppp/p1B2n2/4p3/4P3/5N2/PPPP1PPP/RNBQ1RK1 b kq -
+RL.14
+r1bqk2r/1pppbppp/p1n2n2/4p3/B2PP3/5N2/PPP2PPP/RNBQ1RK1 b kq -
+RL.15
+r1bqk2r/1pppbppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+RL.13
+r1bqk2r/2p1bppp/p1np1n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 w kq -
+RL.19
+r1bqk2r/2ppbppp/p1n2n2/1p2p3/4P3/1B3N2/PPPP1PPP/RNBQR1K1 b kq -
+RL.17
+r1bqk2r/p4ppp/2pbpn2/2pp4/2P5/2NPPN2/PP3PPP/R1BQK2R b KQkq -
+NI.14*
+r1bqk2r/pp1pnpbp/2n1p1p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQkq -
+EO.17*
+r1bqk2r/pp1pppbp/2n2np1/2p5/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.28*
+r1bqk2r/pp1pppbp/2n2np1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQkq -
+EO.19*
+r1bqk2r/pp1pppbp/2n2np1/8/2P5/2N5/PPN1PPPP/R1BQKB1R b KQkq -
+EO.36*
+r1bqk2r/pp1pppbp/2n2np1/8/3N4/6P1/PPP1PPBP/RNBQK2R w KQkq -
+EO.51*
+r1bqk2r/pp1pppbp/2n2np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+EO.03*
+r1bqk2r/pp2b1pp/2n2n2/2p1pp2/2Pp4/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+KI.57*
+r1bqk2r/pp2b1pp/2n2n2/2p2p2/2PPp3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.56*
+r1bqk2r/pp2b1pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b kq -
+BI.29*
+r1bqk2r/pp2b1pp/2n2n2/4ppB1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b kq -
+BI.30*
+r1bqk2r/pp2b1pp/2n5/2pnpp2/8/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.59*
+r1bqk2r/pp2bppp/2n1p3/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.41
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.17*
+r1bqk2r/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 b kq -
+KI.16*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1N2/PPPNBPPP/R1BQK2R w KQkq -
+OI.01*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 b kq -
+KI.18*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/4P3/3P2P1/PPPN1PBP/R1BQK1NR w KQkq -
+KF.01*
+r1bqk2r/pp2bppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.19*
+r1bqk2r/pp2bppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.17*
+r1bqk2r/pp2npbp/2n3p1/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.28*
+r1bqk2r/pp2nppp/2n1p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R w KQkq -
+FR.13
+r1bqk2r/pp2nppp/2nb4/1B1p4/8/1N3N2/PPP2PPP/R1BQ1RK1 w kq -
+FR.23
+r1bqk2r/pp2nppp/2nbp3/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 b kq -
+NI.09*
+r1bqk2r/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+KI.73*
+r1bqk2r/pp3ppp/2n1pn2/2bp4/1P6/2P1PN2/P2N1PPP/R1BQKB1R b KQkq -
+SL.09*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQ1RK1 w kq -
+NI.07*
+r1bqk2r/pp3ppp/2nbpn2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQ1RK1 w kq -
+NI.06*
+r1bqk2r/pp3ppp/2nbpn2/3p4/2PN4/2N1P3/PP3PPP/R1BQKB1R w KQkq -
+TD.07*
+r1bqk2r/pp3ppp/2nppn2/2p5/2PP4/2PBPN2/P4PPP/R1BQK2R w KQkq -
+NI.14
+r1bqk2r/ppp1bppp/1nn5/4p3/4P3/P2P1N2/1P2BPPP/RNBQK2R b KQkq -
+SI.11*
+r1bqk2r/ppp1bppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+PU.03*
+r1bqk2r/ppp1bppp/2n5/3np3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+SI.22*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.10*
+r1bqk2r/ppp1bppp/2n5/3np3/8/P2PPN2/1P3PPP/RNBQKB1R b KQkq -
+SI.23*
+r1bqk2r/ppp1bppp/2n5/3p4/3Pn3/3B1N2/PPP2PPP/RNBQ1RK1 w kq -
+RG.06
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/2NPPN2/PP3PPP/R1BQKB1R b KQkq -
+SI.26*
+r1bqk2r/ppp2ppp/2n5/2bnp3/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.13*
+r1bqk2r/ppp3pp/2nb1n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+PU.02*
+r1bqk2r/pppnbppp/3p1n2/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQkq -
+OI.01
+r1bqk2r/pppp1ppp/2n2n2/3Np3/1bP5/5NP1/PP1PPP1P/R1BQKB1R b KQkq -
+EO.02
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b1PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+SO.01
+r1bqk2r/pppp1ppp/2n2n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+KP.03*
+r1bqk2r/pppp1ppp/2n2n2/4p3/1bP5/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.05
+r1bqkb1r/1p1n1ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.06
+r1bqkb1r/1p2pppp/2n2n2/p1Pp4/5B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+SL.04*
+r1bqkb1r/1p3ppp/p1np1n2/1N2p1B1/4P3/2N5/PPP2PPP/R2QKB1R w KQkq -
+SI.36
+r1bqkb1r/1p3ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R b kq -
+SI.29
+r1bqkb1r/1ppp1ppp/p1n2n2/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.12
+r1bqkb1r/1ppp1ppp/p1n5/4p3/B3n3/5N2/PPPP1PPP/RNBQ1RK1 w kq -
+RL.27
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/2N1P3/PP2NPPP/R1BQK2R b KQkq -
+FR.13*
+r1bqkb1r/2p2ppp/p1p2n2/3p4/2PPp3/4P3/PP2NPPP/RNBQK2R w KQkq -
+FR.12*
+r1bqkb1r/5p1p/p1np4/1p1Npp2/4P3/N7/PPP2PPP/R2QKB1R w KQkq -
+SI.38
+r1bqkb1r/5ppp/p1np1n2/1p2p1B1/4P3/N1N5/PPP2PPP/R2QKB1R w KQkq -
+SI.37
+r1bqkb1r/p2n1ppp/2p1pn2/1p6/2BP4/2N1PN2/PP3PPP/R1BQK2R w KQkq -
+SL.09
+r1bqkb1r/p4ppp/5n2/3pp3/8/4P3/PP3PPP/RNBQKB1R w KQkq -
+TD.08*
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.27*
+r1bqkb1r/pp1npppp/2n5/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+BI.40*
+r1bqkb1r/pp1p1ppp/2n1pn2/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+EO.05*
+r1bqkb1r/pp1p1ppp/2n1pn2/1N6/2P5/2N5/PP2PPPP/R1BQKB1R b KQkq -
+EO.33
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+EO.34*
+r1bqkb1r/pp1p1ppp/2n1pn2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.06*
+r1bqkb1r/pp1p1ppp/2n1pn2/8/2PN4/2N3P1/PP2PP1P/R1BQKB1R b KQkq -
+EO.32
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/2P5/1P3N2/P2PPPPP/RNBQKB1R w KQkq -
+EO.43*
+r1bqkb1r/pp1p1ppp/2n2n2/2p1p3/8/1P2PN2/PBPP1PPP/RN1QKB1R b KQkq -
+EO.60*
+r1bqkb1r/pp1p1ppp/2n2n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.35
+r1bqkb1r/pp1ppp1p/2n2np1/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.04*
+r1bqkb1r/pp1ppp1p/5np1/1Bp5/3nP3/2N2N2/PPPP1PPP/R1BQK2R w KQkq -
+EO.02*
+r1bqkb1r/pp1ppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+EO.59*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+EO.21*
+r1bqkb1r/pp1ppppp/2n2n2/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+EO.09*
+r1bqkb1r/pp1ppppp/2n2n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+EO.42*
+r1bqkb1r/pp1ppppp/2n2n2/8/3N4/6P1/PPP1PP1P/RNBQKB1R b KQkq -
+EO.52*
+r1bqkb1r/pp1ppppp/2n2n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R b KQkq -
+SI.34
+r1bqkb1r/pp1ppppp/n4n2/2P5/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.18*
+r1bqkb1r/pp2n1pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.52*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R w KQkq -
+NI.16*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R w KQkq -
+NI.13*
+r1bqkb1r/pp2nppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.10*
+r1bqkb1r/pp2pp1p/2n2np1/2pp4/4P3/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+OI.02*
+r1bqkb1r/pp2pp1p/2n2np1/3p4/2PP4/2N5/PP3PPP/R1BQKBNR w KQkq -
+TD.09*
+r1bqkb1r/pp2pp1p/2n2np1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R w KQkq -
+BI.39*
+r1bqkb1r/pp2pp1p/2n3p1/2pn4/8/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.32*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.27*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+NI.26*
+r1bqkb1r/pp2pppp/2n2n2/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.28*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+TD.05*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+SL.03*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R b KQkq -
+GI.07*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.08*
+r1bqkb1r/pp2pppp/2n2n2/2pp4/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+KI.76*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+TD.11*
+r1bqkb1r/pp2pppp/2n2n2/3p4/2Pp4/4PN2/PP3PPP/RNBQKB1R w KQkq -
+TD.12*
+r1bqkb1r/pp2pppp/2n5/1Bpn4/8/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+EO.44*
+r1bqkb1r/pp2pppp/2n5/2n5/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.26*
+r1bqkb1r/pp2pppp/2n5/2p5/1n6/2N1PN2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.33*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.35*
+r1bqkb1r/pp2pppp/2n5/2pn4/8/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+EO.49
+r1bqkb1r/pp2pppp/2np1n2/2p5/4P3/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+EO.07*
+r1bqkb1r/pp2pppp/2np1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+SI.27
+r1bqkb1r/pp2pppp/2np1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.25
+r1bqkb1r/pp3pp1/2n2n1p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.20*
+r1bqkb1r/pp3ppp/2n1p3/2pn4/3P4/2NBPN2/PP3PPP/R1BQK2R b KQkq -
+TD.07
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/2P5/5NP1/PP1PPPBP/RNBQ1RK1 b kq -
+KI.77*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/2P1PN2/PP3PPP/RNBQKB1R w KQkq -
+SL.08*
+r1bqkb1r/pp3ppp/2n1pn2/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 b kq -
+GI.09*
+r1bqkb1r/pp3ppp/2n1pn2/3p4/2PP4/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+TD.06*
+r1bqkb1r/pp3ppp/2n2n2/2pp4/3P4/2N1PN2/PP3PPP/R1BQKB1R w KQkq -
+TD.06
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+KI.21*
+r1bqkb1r/pp3ppp/2n2n2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.22*
+r1bqkb1r/pp3ppp/2n2n2/4p3/2Pp4/3P1NP1/PP3PBP/RNBQK2R b KQkq -
+BI.20*
+r1bqkb1r/pp3ppp/2n5/2pn4/4N3/4P3/PP1P1PPP/R1BQKBNR b KQkq -
+EO.54*
+r1bqkb1r/pp3ppp/2nppn2/8/2BNP3/2N5/PPP2PPP/R1BQK2R w KQkq -
+SI.26
+r1bqkb1r/pp3ppp/2nppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+SI.22
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/1PPp4/3P1NP1/P3PPBP/RNBQ1RK1 b kq -
+KI.55*
+r1bqkb1r/pp4pp/2n2n2/2p1pp2/2P5/3PBNP1/PP3PBP/RN1Q1RK1 b kq -
+KI.58*
+r1bqkb1r/pp4pp/2n2n2/4pp2/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 b kq -
+BI.31*
+r1bqkb1r/ppn1pppp/2n5/2p5/8/2N2NP1/PP1PPPBP/R1BQK2R w KQkq -
+EO.36
+r1bqkb1r/ppp2p1p/2n5/3np1p1/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+SI.20*
+r1bqkb1r/ppp2ppp/2n2n2/1B1pp3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+SO.01*
+r1bqkb1r/ppp2ppp/2n2n2/3pp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+PU.10*
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+SI.35*
+r1bqkb1r/ppp2ppp/2n5/3np3/4P3/3P1N2/PP3PPP/RNBQKB1R b KQkq -
+SI.03*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N1P3/PPQP1PPP/R1B1KBNR b KQkq -
+SI.40*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+SI.34*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.03
+r1bqkb1r/ppp2ppp/2n5/3np3/8/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+SI.25*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3P1NP1/PP2PP1P/RNBQKB1R b KQkq -
+SI.15*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/3PPN2/PP3PPP/RNBQKB1R b KQkq -
+SI.19*
+r1bqkb1r/ppp2ppp/2n5/3np3/8/P2P1N2/1P2PPPP/RNBQKB1R b KQkq -
+SI.14*
+r1bqkb1r/ppp2ppp/5n2/3Pp3/3n4/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+SO.02*
+r1bqkb1r/ppp2ppp/5n2/3pn3/8/2P5/PP1NPPPP/R1BQKBNR w KQkq -
+CK.08*
+r1bqkb1r/ppp3pp/2n2n2/3ppp2/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+PU.06*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/3PPN2/PP3PPP/RNBQKB1R w KQkq -
+SI.21*
+r1bqkb1r/ppp3pp/2n5/3npp2/8/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.12*
+r1bqkb1r/pppn1ppp/3p1n2/4p1B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+OI.03
+r1bqkb1r/pppn1ppp/3p1n2/4p3/2PP4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+OI.02
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+FR.22*
+r1bqkb1r/pppn1ppp/5n2/3p4/2PP4/8/PP3PPP/RNBQKBNR w KQkq -
+FR.21*
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/2N2N2/PPPP1PPP/R1BQK2R b KQkq -
+KP.03
+r1bqkb1r/pppp1ppp/2n2n2/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.07
+r1bqkb1r/pppp1ppp/2n2n2/3N4/3pP3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+SO.02
+r1bqkb1r/pppp1ppp/2n2n2/4p1N1/2B1P3/8/PPPP1PPP/RNBQK2R b KQkq -
+KP.01
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+IG.01
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.06
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2N2NP1/PP1PPP1P/R1BQKB1R b KQkq -
+EO.04
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2P5/2NP1N2/PP2PPPP/R1BQKB1R b KQkq -
+EO.07
+r1bqkb1r/pppp1ppp/2n2n2/4p3/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+EO.08
+r1bqkb1r/pppp1ppp/2n2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.06*
+r1bqkb1r/pppp1ppp/2n2n2/8/2BpP3/5N2/PPP2PPP/RNBQK2R w KQkq -
+KP.02
+r1bqkb1r/ppppnppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.04
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/2P2N2/PP1P1PPP/RNBQK2R b KQkq -
+RL.11
+r1bqkbnr/1pp2ppp/p1np4/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.10
+r1bqkbnr/1ppp1ppp/p1B5/4p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.08
+r1bqkbnr/1ppp1ppp/p1n5/4p3/B3P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.09
+r1bqkbnr/2p2ppp/p1p5/3p4/2PPp3/4P3/PP3PPP/RNBQK1NR w KQkq -
+FR.11*
+r1bqkbnr/4pppp/p1p5/2pp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.19*
+r1bqkbnr/4pppp/p1p5/2pp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.18*
+r1bqkbnr/p4ppp/2p5/2pp4/8/4PQ2/PPP2PPP/RNB1KB1R w KQkq -
+EO.56*
+r1bqkbnr/p4ppp/2p5/3pp3/8/6P1/PPP1PP1P/RNBQKB1R w KQkq -
+GI.04*
+r1bqkbnr/pp1npppp/2p5/8/2BPN3/8/PPP2PPP/R1BQK1NR b KQkq -
+CK.09
+r1bqkbnr/pp1npppp/2p5/8/3PN3/5N2/PPP2PPP/R1BQKB1R b KQkq -
+CK.08
+r1bqkbnr/pp1p1ppp/2n1p3/4P3/2P1Q3/2N5/PP3PPP/R1B1KBNR b KQkq -
+EO.55
+r1bqkbnr/pp1p1ppp/2n1p3/8/2PN4/8/PP2PPPP/RNBQKB1R w KQkq -
+EO.50
+r1bqkbnr/pp1p1ppp/2n1p3/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SI.39
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+EO.57*
+r1bqkbnr/pp1p1ppp/2n5/2p1p3/8/2P2N2/PP1PPPPP/RNBQKB1R w KQkq -
+EO.61*
+r1bqkbnr/pp1p1ppp/4p3/4n3/2PN4/2N5/PP3PPP/R1BQKB1R w KQkq -
+EO.54
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/2P5/2N1PN2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.34
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+EO.20*
+r1bqkbnr/pp1ppp1p/2n3p1/2p5/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+EO.12*
+r1bqkbnr/pp1ppp1p/2n3p1/8/3NP3/8/PPP2PPP/RNBQKB1R w KQkq -
+SI.33
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+EO.22*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+EO.10*
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+SI.31
+r1bqkbnr/pp1ppppp/2n5/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+EO.23*
+r1bqkbnr/pp1ppppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SI.32
+r1bqkbnr/pp2pp1p/2n3p1/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.29*
+r1bqkbnr/pp2pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R b KQkq -
+NI.30*
+r1bqkbnr/pp2pppp/2n5/2pp4/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+TD.10*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/2P1P3/PP3PPP/RNBQKBNR b KQkq -
+SL.06*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+QO.16*
+r1bqkbnr/pp2pppp/2n5/2pp4/3P4/5NP1/PPP1PP1P/RNBQKB1R b KQkq -
+GI.03*
+r1bqkbnr/pp2pppp/2n5/2pp4/5P2/5N2/PPPPP1PP/RNBQKB1R w KQkq -
+HD.05*
+r1bqkbnr/pp2pppp/2n5/2pp4/8/3P1N2/PPP1PPPP/RNBQKB1R w KQkq -
+OI.04*
+r1bqkbnr/pp2pppp/2n5/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+BI.44*
+r1bqkbnr/pp2pppp/2n5/8/2Pp4/B4NP1/3PPP1P/RN1QKB1R b KQkq -
+BI.41*
+r1bqkbnr/pp3pp1/2n4p/2ppp3/8/3P1NP1/PPP1PPBP/RNBQ1RK1 b kq -
+KI.30*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.15*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/1P2PN2/P1PP1PPP/RNBQK2R b KQkq -
+NI.12*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQ1RK1 b kq -
+NI.11*
+r1bqkbnr/pp3ppp/2n1p3/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.17*
+r1bqkbnr/pp3ppp/2n5/2p1p3/2Pp4/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+RE.13
+r1bqkbnr/pp3ppp/2n5/2p1p3/2PpP3/3P1N2/PP3PPP/RNBQKB1R w KQkq -
+OI.05*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+TD.09
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+CK.03*
+r1bqkbnr/pp3ppp/2n5/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R w KQkq -
+FR.22
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/2NP2P1/PPP1PPBP/R1BQK1NR b KQkq -
+KF.03*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+KI.31*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPP1PPBP/RNBQK1NR w KQkq -
+KF.04*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/3P2P1/PPPNPPBP/R1BQK1NR b KQkq -
+KF.02*
+r1bqkbnr/pp3ppp/2n5/2ppp3/8/5NP1/PPPPPPBP/RNBQ1RK1 b kq -
+KI.32*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/3P1NP1/PPP1PPBP/RNBQK2R w KQkq -
+KI.54*
+r1bqkbnr/pp4pp/2n2p2/2ppp3/8/P2P1NP1/1PP1PPBP/RNBQK2R b KQkq -
+KI.53*
+r1bqkbnr/pp4pp/2n5/5p2/2Ppp3/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.34*
+r1bqkbnr/ppp1pppp/2n5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+VO.06
+r1bqkbnr/ppp1pppp/2n5/8/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+OI.08*
+r1bqkbnr/ppp2pp1/6n1/3p3p/8/2P3B1/PP2PPPP/RN1QKBNR w KQkq -
+CK.11*
+r1bqkbnr/ppp2ppp/2n1p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.15
+r1bqkbnr/ppp2ppp/2n5/1B1p4/2PPp3/4P3/PP3PPP/RNBQK1NR b KQkq -
+FR.10*
+r1bqkbnr/ppp2ppp/2n5/1B1p4/3Pp3/4P3/PPP2PPP/RNBQK1NR w KQkq -
+FR.09*
+r1bqkbnr/ppp2ppp/2n5/1B1pp3/3P4/4P3/PPP2PPP/RNBQK1NR b KQkq -
+FR.08*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+CK.05*
+r1bqkbnr/ppp2ppp/2n5/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.04*
+r1bqkbnr/ppp2ppp/2n5/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R b KQkq -
+PU.07*
+r1bqkbnr/ppp2ppp/2np4/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.02
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP2PP1P/RNBQKB1R b KQkq -
+CK.07*
+r1bqkbnr/ppp2ppp/8/3p4/8/2P2P2/PP3PPP/RNBQKB1R b KQkq -
+CK.06*
+r1bqkbnr/ppp2ppp/8/3pn3/5B2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+CK.10*
+r1bqkbnr/ppp2ppp/8/3pn3/8/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.07*
+r1bqkbnr/ppp3pp/2n2p2/3pp3/8/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+PU.04*
+r1bqkbnr/ppp3pp/2n5/3ppp2/8/3P1NP1/PPP1PPBP/RNBQK2R b KQkq -
+PU.05*
+r1bqkbnr/pppn1ppp/8/3p4/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+FR.20*
+r1bqkbnr/pppn1ppp/8/3p4/2PQ4/4P3/PP3PPP/RNB1KBNR b KQkq -
+FR.19*
+r1bqkbnr/pppn1ppp/8/3p4/3Pp3/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+FR.16*
+r1bqkbnr/pppn1ppp/8/3pp3/2PP4/4P3/PP3PPP/RNBQKBNR b KQkq -
+FR.18*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/2N1P3/PPP2PPP/R1BQKBNR b KQkq -
+FR.15*
+r1bqkbnr/pppn1ppp/8/3pp3/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.14*
+r1bqkbnr/pppp1p1p/2n3p1/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.03
+r1bqkbnr/pppp1p1p/2n3p1/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+VG.01*
+r1bqkbnr/pppp1ppp/2n5/1B2p3/4P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+RL.01
+r1bqkbnr/pppp1ppp/2n5/4p3/2B1P3/5N2/PPPP1PPP/RNBQK2R b KQkq -
+IG.03
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+EO.21
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+EO.20
+r1bqkbnr/pppp1ppp/2n5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.44*
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+KP.06
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/2P2N2/PP1P1PPP/RNBQKB1R b KQkq -
+KP.05
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/3P1N2/PPP2PPP/RNBQKB1R b KQkq -
+KP.07
+r1bqkbnr/pppp1ppp/2n5/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VG.04*
+r1bqkbnr/pppp1ppp/2n5/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SO.04
+r1bqkbnr/pppp1ppp/2n5/8/3Q4/8/PPP1PPPP/RNB1KBNR w KQkq -
+SD.02*
+r1bqkbnr/pppp1ppp/2n5/8/3pP3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+SO.06
+r1bqkbnr/pppp1ppp/2n5/8/Q7/8/PPP1PPPP/RNB1KBNR b KQkq -
+SD.01*
+r1bqkbnr/pppp1ppp/8/1B2p3/3nP3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.05
+r1bqkbnr/pppp2pp/2n5/1B2pp2/4P3/5N2/PPPP1PPP/RNBQK2R w KQkq -
+RL.06
+r1bqkbnr/pppp2pp/2n5/4pp2/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+VG.03*
+r1bqkbnr/pppppppp/2n5/8/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+VO.05
+r1bqkbnr/pppppppp/2n5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VO.04
+r1bqkbnr/pppppppp/2n5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.15*
+r1bqnrk1/pp2b1pp/2n2p2/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.02*
+r1bqnrk1/pp2bppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.03*
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N5/1P1NBPPP/R1BQ1RK1 w - -
+BI.03
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3P3/R1N5/1P1NBPPP/2BQ1RK1 b - -
+BI.01
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P3PP2/2N5/1P1NB1PP/R1BQ1RK1 b - -
+BI.02
+r1bqr1k1/1p1n1pbp/p2p1np1/2pP4/P7/2N3P1/1P1NPPBP/R1BQ1RK1 w - -
+BI.22
+r1bqr1k1/p1n2pbp/1p1p1np1/2pP4/P3P3/2N2P2/1P1NB1PP/R1BQ1RK1 w - -
+BI.07
+r1bqr1k1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 w - -
+KI.61
+r1bqr1k1/pp1n1pbp/3p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+BI.05
+r1bqr1k1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.11*
+r1bqr1k1/pp3pbp/3p1np1/2pPn3/P3P3/2N5/1P1NBPPP/R1BQ1RK1 w - -
+BI.04
+r1bqr1k1/pp3pbp/n2p1np1/2pP4/4P3/2N5/PP1NBPPP/R1BQ1RK1 w - -
+BI.09
+r1bqr1k1/ppbn1pp1/2p2n1p/3pp3/NPP1P3/P2P1N2/2Q1BPPP/R1B2RK1 w - -
+RL.24*
+r1bqr1k1/ppnn1pbp/3p2p1/2pP4/P3P3/2N2P2/1P1NB1PP/R1BQ1RK1 w - -
+BI.08
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.10*
+r1bqrbk1/pp3ppp/2n2n2/2ppp3/P3P3/2PP1NP1/1P1N1PBP/R1BQ1RK1 b - -
+KI.09*
+r1n1kb1r/pp1q2pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 w kq -
+KI.34*
+r2q1r1k/1p2b1pp/2n2p2/p1n1p3/2Pp2b1/BP1P1NP1/P1N2PBP/1R1QR1K1 w - -
+BI.06*
+r2q1rk1/1bp1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.26
+r2q1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2B1P/1P3PP1/R1BQ1RK1 w - -
+BI.10
+r2q1rk1/1p2bppp/2n2n2/p3p1B1/2Pp2b1/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.13*
+r2q1rk1/1p2bppp/2n2n2/p3pbB1/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.12*
+r2q1rk1/1p2bppp/2n2n2/p3pbB1/2Pp4/P2P1NP1/1P3PBP/RN1QR1K1 b - -
+BI.11*
+r2q1rk1/p3nppp/4b3/2bpp3/8/2N3P1/PP2PPBP/R1BQ1RK1 w - -
+GI.06*
+r2q1rk1/pp1bbppp/2n2n2/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.06*
+r2q1rk1/pp2bppp/2n1bn2/2ppp3/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+KI.08*
+r2q1rk1/pp2bppp/2n1bn2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.13*
+r2q1rk1/pp2n1pp/2nbbp2/2ppp3/1P6/P1PP1NP1/3NPPBP/R1BQ1RK1 b - -
+KI.46*
+r2q1rk1/pp2ppbp/2n2np1/3p4/2PP2b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+TD.03*
+r2q1rk1/ppp2ppp/2nb4/1B6/3P2b1/5N2/P1P2PPP/R1BQ1RK1 w - -
+SO.03*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3P1NPP/PP2PPB1/RNBQ1RK1 b kq -
+KI.23*
+r2qk1nr/pp2bppp/2n5/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 b kq -
+KI.24*
+r2qk1nr/pp2bppp/2n5/2ppp3/2P3b1/3P1NP1/PP2PPBP/RNBQ1RK1 b kq -
+KI.25*
+r2qk1nr/pp2bppp/2n5/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.26*
+r2qk1nr/pp4pp/2nbbp2/2p1p3/1P1pP3/2PP1NP1/P4PBP/RNBQ1RK1 b kq -
+KI.38*
+r2qk1nr/pp4pp/2nbbp2/4p3/3pP3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.37*
+r2qk2r/2p2ppp/p1n1b3/1pbpP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 w kq -
+RL.30
+r2qk2r/pp2b1pp/2n2n2/6N1/2Ppp1b1/1Q4P1/PP3PBP/RNB1R1K1 b kq -
+BI.28*
+r2qk2r/pp2n1pp/2nbbp2/2pp4/2P1p3/PP1P1NP1/4PPBP/RNBQ1RK1 w kq -
+KI.44*
+r2qkb1r/1p1b1ppp/p1nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w kq -
+SI.30
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1B3N2/PPP1QPPP/RNB2RK1 b kq -
+RL.28
+r2qkb1r/2p2ppp/p1n1b3/1p1pP3/4n3/1BP2N2/PP3PPP/RNBQ1RK1 b kq -
+RL.29
+r2qkb1r/pp1n1ppp/2n5/4p2b/2Pp4/P2P1NPP/1P3PB1/RNBQK2R w KQkq -
+BI.18*
+r2qkb1r/pp1n1ppp/2p1pn2/3p1b2/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 b kq -
+RE.02
+r2qkb1r/pp1n1ppp/2p1pn2/3p4/2P3b1/1P3NP1/PB1PPPBP/RN1Q1RK1 b kq -
+RE.01
+r2qkb1r/pp2n1pp/2n1bp2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.43*
+r2qkb1r/pp2pppp/2n2n2/2pp4/3P2b1/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.08*
+r2qkb1r/pp2pppp/2n2n2/2pp4/4P1b1/3P1N2/PPPN1PPP/R1BQKB1R w KQkq -
+OI.03*
+r2qkb1r/pp2pppp/2n2n2/8/2Pp2b1/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.25*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/2PP4/4PN2/PP2BPPP/RNBQ1RK1 b kq -
+QO.03*
+r2qkb1r/pp3ppp/2n1pn2/2pp1b2/3P4/4PN2/PPP1BPPP/RNBQ1RK1 w kq -
+QO.04*
+r2qkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/P1P1BPP1/RNBQ1RK1 b kq -
+QO.10*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 b kq -
+QO.12*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/3P4/4PB1P/PPP2PP1/RNBQ1RK1 b kq -
+QO.14*
+r2qkb1r/pp3ppp/2n1pn2/2pp4/Q2P2b1/2P1PN2/PP1N1PPP/R1B1KB1R b KQkq -
+QO.15*
+r2qkb1r/pp3ppp/2n1pn2/3p4/3P4/1P3B1P/P1P2PP1/RNBQ1RK1 b kq -
+QO.08*
+r2qkb1r/pp3ppp/2n1pn2/5b2/2Bp4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QO.01*
+r2qkb1r/pp3ppp/2n2n2/2Ppp3/1P4b1/2P1PN2/P4PPP/RNBQKB1R b KQkq -
+SL.07*
+r2qkb1r/pp3ppp/2n2n2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.19*
+r2qkb1r/pp4pp/2n1bn2/2pp4/4pB2/1NN1P3/PPP2PPP/R2QKB1R w KQkq -
+AL.06*
+r2qkb1r/ppp2ppp/1nn1p3/4Pb2/2PP4/2N1BN2/PP4PP/R2QKB1R b KQkq -
+AL.06
+r2qkb1r/ppp2ppp/2n1b3/3np3/8/3P1NP1/PP2PPBP/RNBQK2R b KQkq -
+SI.16*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/2NP1N2/PP2PPPP/R1BQKB1R w KQkq -
+SI.27*
+r2qkb1r/ppp2ppp/2n5/3np3/6b1/P2P1N2/1P2PPPP/RNBQKB1R w KQkq -
+SI.04*
+r2qkb1r/ppp2ppp/2n5/4p3/1n2P1b1/P1NP1N2/1P3PPP/R1BQKB1R b KQkq -
+SI.36*
+r2qkb1r/ppp2ppp/n1n5/4p3/1P2P1b1/P1NP1N2/5PPP/R1BQKB1R b KQkq -
+SI.37*
+r2qkb1r/ppp2ppp/n7/4p3/1P1nPP2/P1NP4/5P1P/R1BQKB1R b KQkq -
+SI.38*
+r2qkb1r/ppp3pp/2n1bp2/3np3/8/3P1NP1/PP2PPBP/RNBQK2R w KQkq -
+SI.17*
+r2qkb1r/ppp3pp/2n5/3npp2/1P4b1/P2PPN2/5PPP/RNBQKB1R b KQkq -
+SI.07*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P1N1PPP/R1BQKB1R b KQkq -
+SI.06*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1P2BPPP/RNBQK2R b KQkq -
+SI.09*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/P2PPN2/1PQ2PPP/RNB1KB1R b KQkq -
+SI.05*
+r2qkb1r/ppp3pp/2n5/3npp2/6b1/PQ1PPN2/1P3PPP/RNB1KB1R b KQkq -
+SI.08*
+r2qkbnr/pp1nppp1/2p4p/7P/3P4/3Q1NN1/PPP2PP1/R1B1K2R b KQkq -
+CK.12
+r2qkbnr/pp2pppp/2n5/1Bpp4/6b1/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.25*
+r2qkbnr/pp2pppp/2n5/2pp4/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+QO.13*
+r2qkbnr/pp2pppp/2n5/3p1b2/3P4/2P5/PP2BPPP/RNBQK1NR b KQkq -
+QO.05*
+r2qkbnr/pp3ppp/2n5/4pb2/2Pp4/3P1NP1/PP3P1P/RNBQKB1R w KQkq -
+BI.35*
+r2qkbnr/pp4pp/2n1bp2/2p1p3/3pP3/3P1NP1/PPP2PBP/RNBQ1RK1 w kq -
+KI.41*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/1P1P1NP1/P1P1PPBP/RNBQ1RK1 b kq -
+KI.45*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 b kq -
+KI.36*
+r2qkbnr/pp4pp/2n1bp2/2ppp3/8/3P1NP1/PPPNPPBP/R1BQ1RK1 b kq -
+KI.48*
+r2qkbnr/pp4pp/2n2p2/2p1p3/2Pp2b1/3P1NP1/PP2PPBP/RNBQ1RK1 w kq -
+KI.50*
+r2qkbnr/pp4pp/2n2p2/2ppp3/6b1/3P1NP1/PPP1PPBP/RNBQ1RK1 w kq -
+KI.51*
+r2qkbnr/pp4pp/2n2p2/4p3/2Pp2b1/3P1NP1/PP3PBP/RNBQK2R w KQkq -
+BI.37*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP1BPPP/RNBQK2R b KQkq -
+FR.06*
+r2qkbnr/ppp2ppp/2n5/3pp3/3P2b1/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+FR.05*
+r2qkbnr/ppp2ppp/2n5/3pp3/6b1/3P1NP1/PPP1PP1P/RNBQKB1R w KQkq -
+PU.09*
+r3k2r/pppq2pp/2n1bp2/2bnp3/8/2NP1NP1/PP2PPBP/R1BQ1RK1 w kq -
+SI.18*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b kq -
+KI.42*
+r3kb1r/pp1qn1pp/2n1bp2/2ppp3/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b kq -
+KI.35*
+r3kb1r/pp3ppp/1qn1bn2/3pp1B1/8/6P1/PPPNPPBP/RN1Q1RK1 w kq -
+GI.11*
+r3kb1r/ppq1n1p1/2n1bp2/2ppp2p/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 w kq -
+KI.33*
+r3kbnr/pp1q2pp/2n1bp2/2p1p3/3pP2N/3P2P1/PPP2PBP/RNBQ1RK1 w kq -
+KI.40*
+r3kbnr/pp1q2pp/2n1bp2/2ppp3/8/P2P1NP1/1PP1PPBP/RNBQ1RK1 w kq -
+KI.47*
+r3kbnr/pp1q2pp/2n1bp2/4p3/3pP3/3P1NP1/PP3PBP/RNBQ1RK1 w kq -
+KI.39*
+r3kbnr/pp1q2pp/2n2p2/2p1p3/2Pp2b1/3PPNP1/PP3PBP/RNBQ1RK1 w kq -
+KI.49*
+r4rk1/pbqnppbp/1pn3p1/2p5/NPPp4/P2P1NP1/4PPBP/1RBQ1RK1 w - -
+KI.66*
+rn1q1rk1/1p3pbp/p2p1np1/2pP2B1/P3P1b1/2N2N2/1P2BPPP/R2Q1RK1 b - -
+BI.13
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3P3/2N5/1P1NQPPP/R1B2RK1 b - -
+BI.14
+rn1q1rk1/1p3pbp/p2p1np1/2pP4/P3PBb1/2N2N2/1P2BPPP/R2Q1RK1 b - -
+BI.12
+rn1q1rk1/pb1p1pbp/1p2pnp1/2p5/3P4/1P2PN2/PBP1BPPP/RN1Q1RK1 w - -
+RE.08*
+rn1q1rk1/pb1pbppp/1p2p3/2p5/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 w - -
+QI.13
+rn1q1rk1/pb1pppbp/1p3np1/2p3B1/3P4/2P1PN2/PP1N1PPP/R2QKB1R w KQ -
+RE.01*
+rn1q1rk1/pb1pppbp/1p3np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 b - -
+EO.47*
+rn1q1rk1/pb1pppbp/1p3np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1Q1RK1 w - -
+EO.47
+rn1q1rk1/pb1pppbp/1p3np1/2p5/3P1B2/2P1PN2/PP1N1PPP/R2QKB1R w KQ -
+RE.02*
+rn1q1rk1/pbp1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/2RQKB1R w K -
+QO.09
+rn1q1rk1/pbp1bppp/1p2pn2/3p4/2P5/1P2PNP1/PB1P1PBP/RN1Q1RK1 b - -
+RE.08
+rn1q1rk1/pbppb1pp/1p2p3/5p2/2PP4/2Q2NP1/PP2PPBP/R1B2RK1 w - -
+QI.12
+rn1q1rk1/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+QI.10
+rn1q1rk1/pbppbppp/1p2p3/8/2PPn3/2N2NP1/PPQ1PPBP/R1B2RK1 b - -
+QI.11
+rn1q1rk1/pbppbppp/1p2pn2/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+QI.09
+rn1q1rk1/pbppbppp/1p3n2/3p4/2P5/5NP1/PP2PPBP/RNBQ1RK1 w - -
+QI.08
+rn1q1rk1/pp3pbp/3p1np1/2pP4/4P1b1/2N2N2/PP2BPPP/R1BQ1RK1 w - -
+BI.16
+rn1q1rk1/pp3pbp/3p1np1/2pP4/4PPb1/2N2N2/PP2B1PP/R1BQK2R w KQ -
+BI.30
+rn1q1rk1/pp3pbp/3pbnp1/2p5/2P1PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+KI.58
+rn1q1rk1/ppp1ppbp/3p1np1/8/3PP1b1/2N2N2/PPP1BPPP/R1BQ1RK1 w - -
+PU.01
+rn1q1rk1/pppnppbp/6p1/8/3PP1b1/1QN1BN2/PP3PPP/R3KB1R b KQ -
+GI.11
+rn1qk2r/pb1pbppp/1p2pn2/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.40
+rn1qk2r/pb1pbppp/1p2pn2/8/2PQ4/2N2NP1/PP2PPBP/R1B2RK1 b kq -
+EO.39
+rn1qk2r/pb1pppbp/1p3np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w kq -
+EO.48
+rn1qk2r/pb1pppbp/1p3np1/2p5/3P4/2P2NP1/PP2PPBP/RNBQK2R w KQkq -
+RE.03*
+rn1qk2r/pbppbppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R w KQkq -
+QI.07
+rn1qk2r/pp3ppp/2p1pn2/5b2/PbBP4/2N1PN2/1P3PPP/R1BQ1RK1 b kq -
+SL.05
+rn1qk2r/ppp1bppp/1n1pp3/4P2b/2PP4/5N1P/PP2BPP1/RNBQ1RK1 w kq -
+AL.01
+rn1qkb1r/3ppp1p/b4np1/2pP4/8/2N5/PP2PPPP/R1BQKBNR w KQkq -
+BI.41
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N2NP1/PP2PP1P/R1BQKB1R b KQkq -
+BI.39
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+BI.40
+rn1qkb1r/4pp1p/b2p1np1/2pP4/8/6P1/PP2PPBP/RNBQK1NR w KQkq -
+BI.42
+rn1qkb1r/p1pp1ppp/bp2pn2/8/2PP4/5NP1/PP2PP1P/RNBQKB1R w KQkq -
+QI.05
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R w KQkq -
+EO.60
+rn1qkb1r/pbpp1ppp/1p2pn2/8/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+QI.06
+rn1qkb1r/pp2pppp/2p2n2/3p1b2/2P5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.06
+rn1qkb1r/pp2pppp/2p2n2/3p4/2P3b1/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.05
+rn1qkb1r/pp2pppp/2p2n2/5b2/P1pP4/2N2N2/1P2PPPP/R1BQKB1R w KQkq -
+SL.04
+rn1qkb1r/ppp1pppp/3p4/3nP3/3P2b1/5N2/PPP2PPP/RNBQKB1R w KQkq -
+AL.03
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QP.05*
+rn1qkb1r/ppp1pppp/5n2/3p1b2/8/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+QP.03*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QP.04*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPP1P/RNBQKB1R w KQkq -
+QP.02*
+rn1qkb1r/ppp1pppp/5n2/3p4/6b1/5NP1/PPPPPPBP/RNBQK2R b KQkq -
+QP.01*
+rn1qkb1r/ppp2ppp/3pp3/3nP3/3P2b1/5N2/PPP1BPPP/RNBQK2R w KQkq -
+AL.02
+rn1qkb1r/ppp2ppp/4pn2/8/2BP2b1/4PN2/PP3PPP/RNBQK2R w KQkq -
+QG.06
+rn1qkbnr/pbpp1ppp/1p2p3/8/3PP3/3B4/PPP2PPP/RNBQK1NR w KQkq -
+VO.03
+rn1qkbnr/pbpppppp/1p6/8/3PP3/3B4/PPP2PPP/RNBQK1NR b KQkq -
+VO.02
+rn1qkbnr/pp2pppp/2p3b1/8/3P3P/6N1/PPP2PP1/R1BQKBNR b KQkq -
+CK.11
+rn1qkbnr/pp2pppp/2p5/3pPb2/3P4/8/PPP2PPP/RNBQKBNR w KQkq -
+CK.04
+rn1qkbnr/pp2pppp/2p5/5b2/3PN3/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.10
+rn1qr1k1/1p3pbp/p2p1np1/2pP4/P3PBb1/2N2N2/1P2BPPP/R2Q1RK1 w - -
+BI.11
+rnb1k1nr/pp2ppbp/6p1/q1Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+CA.02*
+rnb1kb1r/1p3ppp/pq1ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.08
+rnb1kb1r/1pq2ppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.05
+rnb1kb1r/ppp2ppp/4pq2/8/2PP4/2P5/P4PPP/R1BQKBNR b KQkq -
+EO.56
+rnb1kb1r/ppp2ppp/5n2/3qp3/8/3P4/PP2PPPP/RNBQKBNR w KQkq -
+SI.02*
+rnb1kbnr/pp3ppp/4p3/2pq4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.19
+rnb1kbnr/ppp1pppp/8/3q4/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SD.02
+rnb1kbnr/ppp1pppp/8/q7/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+SD.01
+rnb1r1k1/pp3pbp/1q4p1/2pPP1B1/6n1/2N2N2/PP2B1PP/R2QK2R w KQ -
+BI.28
+rnb2rk1/p1p1qpp1/1p5p/3p4/3P4/5N2/PP2PPPP/2RQKB1R w K -
+QO.06
+rnb2rk1/pp2ppbp/2pp1np1/q7/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.74
+rnb2rk1/ppp1qppp/1b3n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+RL.28*
+rnbq1rk1/1p1n1pbp/p2p2p1/2pP4/P3PP2/2NB1N2/1P4PP/R1BQK2R b KQ -
+BI.32
+rnbq1rk1/1pp1ppbp/p2p1np1/8/2PPP3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.47
+rnbq1rk1/2p1bppp/p2p1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.25
+rnbq1rk1/4ppbp/pp1p1np1/2p1P3/2PP4/2NBBP2/PP2N1PP/R2QK2R b KQ -
+KI.44
+rnbq1rk1/p1p1bpp1/1p2pn1p/3p4/2PP3B/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.10
+rnbq1rk1/p1p1ppbp/1p1p1np1/8/2PPP3/2N1BP2/PP4PP/R2QKBNR w KQ -
+KI.45
+rnbq1rk1/p1p2pp1/1p3b1p/3p4/3P4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.08
+rnbq1rk1/p2pppbp/1p3np1/2p5/3P4/4PN2/PPP1BPPP/RNBQ1RK1 w - -
+RE.09*
+rnbq1rk1/p3ppbp/3p1np1/1ppP4/2P1PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+KI.55
+rnbq1rk1/p4pbp/2pp1np1/1p1Pp3/2P1P3/2NBBP2/PP4PP/R2QK1NR w KQ -
+KI.38
+rnbq1rk1/p4ppp/1p2pn2/8/1bBP4/2N2N2/PP3PPP/R1BQ1RK1 w - -
+NI.04
+rnbq1rk1/pp1p1ppp/4pn2/2P5/1bP5/2N5/PPQ1PPPP/R1B1KBNR w KQ -
+NI.21
+rnbq1rk1/pp1p1ppp/4pn2/2p5/1bPP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+NI.07
+rnbq1rk1/pp1pppbp/5np1/2p5/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+KI.77
+rnbq1rk1/pp2bpp1/5n1p/2pp4/4p2B/1N1PP3/PPP1BPPP/RN1QK2R b KQ -
+AL.01*
+rnbq1rk1/pp2bppp/4pn2/2pp4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.03
+rnbq1rk1/pp2ppb1/3p1npp/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.23
+rnbq1rk1/pp2ppbp/2pp1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.75
+rnbq1rk1/pp2ppbp/3p1np1/2p3B1/2PPP3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.25
+rnbq1rk1/pp2ppbp/3p1np1/2p5/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.69
+rnbq1rk1/pp2ppbp/3p1np1/2pP2B1/2P1P3/2N2P2/PP4PP/R2QKBNR b KQ -
+KI.50
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1P3/2N5/PP3PPP/R1BQKBNR w KQ -
+RE.13*
+rnbq1rk1/pp2ppbp/3p1np1/2pP4/2P1PP2/2NB4/PP4PP/R1BQK1NR b KQ -
+KI.60
+rnbq1rk1/pp2ppbp/3p1np1/8/2PNPP2/2N5/PP2B1PP/R1BQK2R b KQ -
+KI.59
+rnbq1rk1/pp2ppbp/5np1/2Pp4/8/4PN2/PPP1BPPP/RNBQ1RK1 b - -
+CA.05*
+rnbq1rk1/pp2ppbp/5np1/2p5/3P4/1P3N2/PBPPBPPP/RN1Q1RK1 b - -
+QI.08*
+rnbq1rk1/pp2ppbp/5np1/2pp4/3P4/5NP1/PPP1PPBP/RNBQ1RK1 w - -
+GI.02*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3P1NP1/PPP1P1BP/RNBQ1RK1 b - -
+HD.06*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/3PPN2/PPP1B1PP/RNBQ1RK1 b - -
+HD.01*
+rnbq1rk1/pp2ppbp/5np1/2pp4/5P2/4PN2/PPPPB1PP/RNBQ1RK1 w - -
+HD.02*
+rnbq1rk1/pp2ppbp/5np1/2pp4/8/3P1NP1/PPP1PPBP/RNBQ1RK1 w - -
+KI.79*
+rnbq1rk1/pp3pbp/3p1np1/2pP4/2N5/2N5/PP2PPPP/R1BQKB1R w KQ -
+BI.26
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+BI.17
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4P3/2NB4/PP2NPPP/R1BQ1RK1 b - -
+BI.36
+rnbq1rk1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP4PP/R1BQKB1R w KQ -
+BI.31
+rnbq1rk1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+BI.24
+rnbq1rk1/pp3pbp/3p1np1/2ppP3/2P2P2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+KI.56
+rnbq1rk1/pp3pbp/3p1np1/3Pp3/4P3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.39
+rnbq1rk1/pp3pbp/3p1np1/3Pp3/4P3/2NBBP2/PP4PP/R2QK1NR b KQ -
+KI.37
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N2P2/PP1Q2PP/R3KBNR b KQ -
+KI.49
+rnbq1rk1/pp3pbp/3ppnp1/2pP2B1/2P1P3/2N5/PP2BPPP/R2QK1NR w KQ -
+KI.24
+rnbq1rk1/pp3pbp/3ppnp1/2pP4/2P1PP2/2N2N2/PP2B1PP/R1BQK2R b KQ -
+KI.57
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1P1Pp3/P1N1B3/2P2PPP/R2QKB1R w KQ -
+RL.29*
+rnbq1rk1/pp3ppp/1bp2n2/4N3/1PBPp3/P1N1B3/2P2PPP/R2QK2R b KQ -
+RL.30*
+rnbq1rk1/pp3ppp/4pn2/2bP4/5B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QO.01
+rnbq1rk1/pp3ppp/4pn2/2bp4/2P5/P3PN2/1P3PPP/RNBQKB1R b KQ -
+QG.07*
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBP3/PP2NPPP/R1BQK2R w KQ -
+NI.09
+rnbq1rk1/pp3ppp/4pn2/2pp4/1bPP4/2NBPN2/PP3PPP/R1BQ1RK1 b - -
+NI.05
+rnbq1rk1/ppp1b1pp/3ppn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+HD.01
+rnbq1rk1/ppp1bpp1/4pn1p/8/2pP3B/2N2N2/PP2PPPP/2RQKB1R w K -
+QO.07
+rnbq1rk1/ppp1bppp/4pn2/3p4/2P5/1P3NP1/P2PPPBP/RNBQ1RK1 b - -
+RE.09
+rnbq1rk1/ppp1bppp/4pn2/3p4/2PP1B2/2N1PN2/PP3PPP/R2QKB1R b KQ -
+QO.04
+rnbq1rk1/ppp1bppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+CA.05
+rnbq1rk1/ppp1p1bp/3p1np1/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 w - -
+HD.06
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N2P2/PP4PP/R2QKBNR b KQ -
+KI.51
+rnbq1rk1/ppp1ppbp/3p1np1/6B1/2PPP3/2N5/PP2BPPP/R2QK1NR b KQ -
+KI.26
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PP4/2N1P1P1/PP3PBP/R1BQK1NR b KQ -
+KI.78
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+KI.79
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N1P/PP3PP1/R1BQKB1R b KQ -
+KI.20
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+KI.19
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R w KQ -
+KI.21
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP2N1PP/R1BQKB1R b KQ -
+KI.52
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N3P1/PP3PBP/R1BQK1NR b KQ -
+KI.29
+rnbq1rk1/ppp1ppbp/3p1np1/8/2PPP3/2N4P/PP3PP1/R1BQKBNR w KQ -
+KI.30
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2N2N2/PPP3PP/R1BQKB1R w KQ -
+PU.06
+rnbq1rk1/ppp1ppbp/3p1np1/8/3PPP2/2NB1N2/PPP3PP/R1BQK2R b KQ -
+PU.02
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R w KQ -
+GI.09
+rnbq1rk1/ppp1ppbp/5np1/3p4/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+GI.02
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N1BP2/PP4PP/R2QKBNR b KQ -
+KI.41
+rnbq1rk1/ppp2pbp/3p1np1/3Pp3/2P1P3/2N2N2/PP2BPPP/R1BQK2R b KQ -
+KI.17
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N1BP2/PP2N1PP/R2QKB1R b KQ -
+KI.43
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+KI.15
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N2N2/PP2BPPP/R1BQK2R w KQ -
+KI.18
+rnbq1rk1/ppp2pbp/3p1np1/4p3/2PPP3/2N3P1/PP2NPBP/R1BQK2R b KQ -
+KI.28
+rnbq1rk1/ppp2pbp/3p2p1/3Pp2n/2P1P3/2N1BP2/PP1Q2PP/R3KBNR b KQ -
+KI.40
+rnbq1rk1/ppp2pp1/4pb1p/3p4/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQ -
+QO.14
+rnbq1rk1/ppp2ppp/3b1n2/3pN3/3P4/2N5/PPP1BPPP/R1BQK2R b KQ -
+RG.06*
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/2NBPN2/PP3PPP/R1BQK2R b KQ -
+NI.06
+rnbq1rk1/ppp2ppp/4pn2/3p4/1bPP4/P1NBP3/1P3PPP/R1BQK1NR b KQ -
+NI.08
+rnbq1rk1/ppp2ppp/5n2/b2pp3/4P3/P1N2N2/1PPPBPPP/R1BQK2R w KQ -
+RL.15*
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQ -
+NI.10
+rnbq1rk1/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQ -
+NI.11
+rnbq1rk1/pppp1ppp/4pn2/8/2PP4/P1Q5/1P2PPPP/R1B1KBNR b KQ -
+NI.20
+rnbq1rk1/pppp1ppp/5n2/4p3/1bP5/2N3P1/PP1PPPBP/R1BQK1NR w KQ -
+EO.11
+rnbq1rk1/pppp1ppp/5n2/4p3/4P3/P1b2N2/1PPPBPPP/R1BQK2R w KQ -
+RL.14*
+rnbq1rk1/pppp1ppp/5n2/b3N3/4P3/P1N5/1PPP1PPP/R1BQKB1R b KQ -
+RL.27*
+rnbq1rk1/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPPBPPP/R1BQK2R b KQ -
+RL.13*
+rnbq1rk1/ppppb1pp/4pn2/5p2/2PP4/5NP1/PP2PPBP/RNBQ1RK1 b - -
+HD.02
+rnbq1rk1/ppppppbp/5np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQ -
+KI.32
+rnbqk1nr/pp2bppp/2p5/3p4/3P1B2/2N5/PP2PPPP/R2QKBNR w KQkq -
+QO.05
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/2PP1N2/PP2P1PP/RNBQKB1R b KQkq -
+HD.04*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/4PN2/PPPP2PP/RNBQKB1R w KQkq -
+HD.03*
+rnbqk1nr/pp2ppbp/6p1/2pp4/5P2/5NP1/PPPPP1BP/RNBQK2R b KQkq -
+HD.07*
+rnbqk1nr/pp2ppbp/6p1/8/2Pp4/B2P1NP1/4PP1P/RN1QKB1R b KQkq -
+BI.42*
+rnbqk1nr/pp3ppp/4p3/2ppP3/1b1P4/2N5/PPP2PPP/R1BQKBNR w KQkq -
+FR.10
+rnbqk1nr/pp3ppp/4p3/2ppP3/3P4/P1P5/2P2PPP/R1BQKBNR b KQkq -
+FR.11
+rnbqk1nr/ppp1ppbp/3p2p1/8/2PPP3/2N5/PP3PPP/R1BQKBNR b KQkq -
+KF.04
+rnbqk1nr/ppp1ppbp/6p1/3p4/5P2/6P1/PPPPP2P/RNBQKBNR w KQkq -
+HD.09*
+rnbqk1nr/ppp2ppp/3b4/3pp3/8/1P2P3/PBPP1PPP/RN1QKBNR b KQkq -
+VO.03*
+rnbqk1nr/ppp2ppp/3b4/3pp3/8/1P6/PBPPPPPP/RN1QKBNR w KQkq -
+VO.02*
+rnbqk1nr/ppp2ppp/4p3/3p4/1b1PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+FR.08
+rnbqk1nr/ppp2ppp/4p3/3pP3/1b1P4/2N5/PPP2PPP/R1BQKBNR b KQkq -
+FR.09
+rnbqk1nr/pppp1ppp/8/2b1p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+IG.04*
+rnbqk1nr/ppppppbp/6p1/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KF.05
+rnbqk2r/1p2bppp/p2p1n2/4p3/4P3/1NN5/PPP1BPPP/R1BQK2R w KQkq -
+SI.11
+rnbqk2r/1p2bppp/p2ppn2/6B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.09
+rnbqk2r/1p3pb1/p2p1npp/2pP4/4P2B/2N5/PP1N1PPP/R2QKB1R b KQkq -
+BI.18
+rnbqk2r/1pp1ppbp/p2p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR w KQkq -
+KI.53
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+NI.13
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+NI.12
+rnbqk2r/p1pp1ppp/1p2pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+NI.26
+rnbqk2r/p1pp1ppp/5n2/1pb1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR w KQkq -
+IG.05*
+rnbqk2r/pp1n1pbp/3p2p1/1BpP4/4PP2/2N5/PP4PP/R1BQK1NR w KQkq -
+BI.33
+rnbqk2r/pp1p1ppp/2p2n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR w KQkq -
+RL.11*
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP2NPPP/R1BQKB1R b KQkq -
+NI.16
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N1P3/PP3PPP/R1BQKBNR w KQkq -
+NI.15
+rnbqk2r/pp1p1ppp/4pn2/2p5/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+NI.22
+rnbqk2r/pp1p1ppp/4pn2/2p5/2PP4/P1P5/4PPPP/R1BQKBNR w KQkq -
+NI.19
+rnbqk2r/pp1p1ppp/4pn2/8/1bPN4/2N5/PP2PPPP/R1BQKB1R w KQkq -
+EO.44
+rnbqk2r/pp1pppbp/5np1/2P5/8/4PN2/PPP2PPP/RNBQKB1R b KQkq -
+RE.10*
+rnbqk2r/pp1pppbp/5np1/2p3B1/3P4/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+RE.05*
+rnbqk2r/pp1pppbp/5np1/2p5/3P1B2/2P2N2/PP2PPPP/RN1QKB1R b KQkq -
+RE.06*
+rnbqk2r/pp1pppbp/5np1/2p5/3P4/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+RE.11*
+rnbqk2r/pp1pppbp/5np1/8/2PN4/2N5/PP2PPPP/R1BQKB1R b KQkq -
+EO.49*
+rnbqk2r/pp2nppp/4p3/2ppP3/3P4/P1P2N2/2P2PPP/R1BQKB1R b KQkq -
+FR.12
+rnbqk2r/pp2ppbp/2p2np1/3p4/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQkq -
+RE.03
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1B3/PPP2PPP/R2QKB1R w KQkq -
+SI.16
+rnbqk2r/pp2ppbp/3p1np1/8/3NP3/2N1BP2/PPP3PP/R2QKB1R b KQkq -
+SI.17
+rnbqk2r/pp2ppbp/5np1/2Pp4/8/4PN2/PPP2PPP/RNBQKB1R w KQkq -
+CA.03*
+rnbqk2r/pp2ppbp/5np1/2pp4/3P4/4PN2/PPP1BPPP/RNBQK2R w KQkq -
+CA.04*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPP1PPP/RN1QKB1R w KQkq -
+QI.06*
+rnbqk2r/pp2ppbp/5np1/2pp4/8/1P2PN2/PBPPBPPP/RN1QK2R b KQkq -
+QI.07*
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2N2/PP3PPP/R2QKB1R b KQkq -
+BI.19
+rnbqk2r/pp3pbp/3p1np1/2pP2B1/4P3/2N2P2/PP4PP/R2QKBNR b KQkq -
+BI.37
+rnbqk2r/pp3pbp/3p1np1/2pP4/4P3/2N2N2/PP3PPP/R1BQKB1R w KQkq -
+BI.20
+rnbqk2r/pp3pbp/3p1np1/2pPP3/5P2/2N5/PP4PP/R1BQKBNR b KQkq -
+BI.34
+rnbqk2r/pp3ppp/4pn2/2bp2B1/8/4PN2/PPP2PPP/RN1QKB1R b KQkq -
+QG.06*
+rnbqk2r/ppp1bppp/4pn2/3p2B1/2PP4/2N5/PP2PPPP/R2QKBNR w KQkq -
+QO.13
+rnbqk2r/ppp1bppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR w KQkq -
+FR.06
+rnbqk2r/ppp1bppp/4pn2/3p4/2PP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+CA.04
+rnbqk2r/ppp1bppp/5n2/3p2B1/3Np3/3PP3/PPP2PPP/RN1QKB1R b KQkq -
+AL.02*
+rnbqk2r/ppp1bppp/8/3p4/3Pn3/3B1N2/PPP2PPP/RNBQK2R w KQkq -
+RG.05
+rnbqk2r/ppp1ppbp/3p1np1/8/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+KI.76
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2N2/PP3PPP/R1BQKB1R b KQkq -
+KI.22
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N2P2/PP4PP/R1BQKBNR b KQkq -
+KI.54
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP2BPPP/R1BQK1NR b KQkq -
+KI.27
+rnbqk2r/ppp1ppbp/3p1np1/8/2PPP3/2N5/PP3PPP/R1BQKBNR w KQkq -
+KI.31
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP1BPPP/R1BQK2R b KQkq -
+PU.03
+rnbqk2r/ppp1ppbp/3p1np1/8/3PP3/2N2N2/PPP2PPP/R1BQKB1R w KQkq -
+PU.10
+rnbqk2r/ppp1ppbp/3p1np1/8/3PPP2/2N5/PPP3PP/R1BQKBNR w KQkq -
+PU.05
+rnbqk2r/ppp1ppbp/5np1/3p2B1/2PP4/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+GI.08
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/1QN2N2/PP2PPPP/R1B1KB1R b KQkq -
+GI.10
+rnbqk2r/ppp1ppbp/5np1/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+GI.07
+rnbqk2r/ppp1ppbp/6p1/3n4/8/2N2NP1/PP1PPPBP/R1BQK2R b KQkq -
+EO.51
+rnbqk2r/ppp1ppbp/6p1/8/2BPP3/2P5/P4PPP/R1BQK1NR b KQkq -
+GI.05
+rnbqk2r/ppp2ppp/3b1n2/3pN3/3P4/8/PPP1BPPP/RNBQK2R b KQkq -
+RG.05*
+rnbqk2r/ppp2ppp/3b4/3np3/8/P3P3/1P1P1PPP/RNBQKBNR w KQkq -
+SI.42*
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+NI.27
+rnbqk2r/ppp2ppp/4pn2/3p4/1bPP4/2N5/PPQ1PPPP/R1B1KBNR w KQkq -
+NI.23
+rnbqk2r/ppp2ppp/5n2/2bPp3/8/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+KP.02*
+rnbqk2r/pppp1pbp/5np1/4p3/2P5/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.14
+rnbqk2r/pppp1ppp/4pn2/6B1/1bPP4/2N5/PP2PPPP/R2QKBNR b KQkq -
+NI.25
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.59
+rnbqk2r/pppp1ppp/4pn2/8/1bP5/2N2N2/PPQPPPPP/R1B1KB1R b KQkq -
+EO.58
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N1P3/PP3PPP/R1BQKBNR b KQkq -
+NI.17
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+NI.28
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N3P1/PP2PP1P/R1BQKBNR b KQkq -
+NI.29
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+NI.30
+rnbqk2r/pppp1ppp/4pn2/8/1bPP4/2N5/PPQ1PPPP/R1B1KBNR b KQkq -
+NI.24
+rnbqk2r/pppp1ppp/4pn2/8/2PP4/P1P5/4PPPP/R1BQKBNR b KQkq -
+NI.18
+rnbqk2r/pppp1ppp/5n2/2b1p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+IG.02*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+IG.01*
+rnbqk2r/pppp1ppp/5n2/2b1p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+IG.03*
+rnbqk2r/pppp1ppp/5n2/3Np3/1b2P3/8/PPPP1PPP/R1BQKBNR b KQkq -
+RL.05*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N2N2/PPPP1PPP/R1BQKB1R b KQkq -
+RL.07*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+RL.03*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+RL.01*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2N5/PPPPNPPP/R1BQKB1R b KQkq -
+RL.04*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2P3/2NP4/PPP2PPP/R1BQKBNR b KQkq -
+RL.02*
+rnbqk2r/pppp1ppp/5n2/4p3/1b2PP2/2N5/PPPP2PP/R1BQKBNR b KQkq -
+RL.06*
+rnbqk2r/pppp1ppp/5n2/4p3/4P3/P1b5/1PPP1PPP/R1BQKBNR w KQkq -
+RL.08*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N2N2/1PPP1PPP/R1BQKB1R b KQkq -
+RL.12*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1N5/1PPP1PPP/R1BQKBNR w KQkq -
+RL.09*
+rnbqk2r/pppp1ppp/5n2/b3p3/4P3/P1NP4/1PP2PPP/R1BQKBNR b KQkq -
+RL.10*
+rnbqk2r/pppp1ppp/8/2b1p3/4P1n1/2N2N2/PPPP1PPP/R1BQKB1R w KQkq -
+KP.01*
+rnbqk2r/ppppp1bp/5np1/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+HD.07
+rnbqk2r/ppppppbp/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+QP.01
+rnbqk2r/ppppppbp/5np1/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R w KQkq -
+QP.03
+rnbqkb1r/1p2pppp/p2p1n2/6B1/3NP3/2N5/PPP2PPP/R2QKB1R b KQkq -
+SI.04
+rnbqkb1r/1p2pppp/p2p1n2/8/2BNP3/2N5/PPP2PPP/R1BQK2R b KQkq -
+SI.13
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP1BPPP/R1BQK2R b KQkq -
+SI.10
+rnbqkb1r/1p2pppp/p2p1n2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.14
+rnbqkb1r/1p2pppp/p2p1n2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+SI.12
+rnbqkb1r/1p2pppp/p4n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+QI.04*
+rnbqkb1r/1p3ppp/p2ppn2/8/3NP3/2N5/PPP1BPPP/R1BQK2R w KQkq -
+SI.23
+rnbqkb1r/1p3ppp/p3pn2/2p5/2BP4/4PN2/PP3PPP/RNBQ1RK1 w kq -
+QG.07
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/2N5/PP2PPPP/R1BQKBNR b KQkq -
+BI.44
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/4P3/PP3PPP/RNBQKBNR b KQkq -
+BI.43
+rnbqkb1r/3ppppp/p4n2/1PpP4/8/8/PP2PPPP/RNBQKBNR w KQkq -
+BI.45
+rnbqkb1r/5ppp/p2ppn2/1p4B1/3NPP2/2N5/PPP3PP/R2QKB1R w KQkq -
+SI.07
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QI.03
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+QI.02
+rnbqkb1r/p1pp1ppp/1p2pn2/8/2PP4/P4N2/1P2PPPP/RNBQKB1R b KQkq -
+QI.04
+rnbqkb1r/p2ppp1p/1p3np1/2p5/3P4/2P2N2/PP2PPPP/RNBQKB1R w KQkq -
+RE.04*
+rnbqkb1r/p2ppppp/1p3n2/2p5/2P1P3/2N2N2/PP1P1PPP/R1BQKB1R b KQkq -
+EO.43
+rnbqkb1r/p2ppppp/5n2/1ppP4/2P5/8/PP2PPPP/RNBQKBNR w KQkq -
+BI.46
+rnbqkb1r/p2ppppp/5n2/1ppP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.17*
+rnbqkb1r/p4ppp/2p1pn2/1p4B1/2pPP3/2N2N2/PP3PPP/R2QKB1R w KQkq -
+SL.07
+rnbqkb1r/pp1n1ppp/4p3/2ppP3/3P4/2PB4/PP1N1PPP/R1BQK1NR b KQkq -
+FR.17
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/2P5/2N3P1/PP1PPP1P/R1BQKBNR w KQkq -
+EO.12
+rnbqkb1r/pp1p1ppp/2p2n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.05*
+rnbqkb1r/pp1p1ppp/4pn2/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.16*
+rnbqkb1r/pp1p1ppp/4pn2/8/2PN4/6P1/PP2PP1P/RNBQKB1R b KQkq -
+EO.45
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/2P5/PP2PPPP/RNBQKBNR w KQkq -
+RE.07*
+rnbqkb1r/pp1ppp1p/5np1/2p5/3P4/4P3/PPP2PPP/RNBQKBNR w KQkq -
+RE.12*
+rnbqkb1r/pp1ppp1p/5np1/2pP4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+RE.14*
+rnbqkb1r/pp1ppp1p/5np1/2pP4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+RE.15*
+rnbqkb1r/pp1ppppp/2p2n2/8/2P1P3/2N5/PP1P1PPP/R1BQKBNR b KQkq -
+EO.61
+rnbqkb1r/pp1ppppp/5n2/2P5/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+RE.19*
+rnbqkb1r/pp1ppppp/5n2/2p5/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+OI.06
+rnbqkb1r/pp1ppppp/5n2/2pP4/2P5/8/PP2PPPP/RNBQKBNR b KQkq -
+BI.38
+rnbqkb1r/pp1ppppp/5n2/2pP4/8/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+OI.08
+rnbqkb1r/pp1ppppp/5n2/8/2PN4/8/PP2PPPP/RNBQKB1R b KQkq -
+EO.46
+rnbqkb1r/pp1ppppp/8/3nP3/3p4/2P5/PP3PPP/RNBQKBNR w KQkq -
+SI.47
+rnbqkb1r/pp2p1pp/2pp1n2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR w KQkq -
+HD.04
+rnbqkb1r/pp2pp1p/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.07
+rnbqkb1r/pp2pp1p/3p1np1/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.15
+rnbqkb1r/pp2pp1p/5np1/2pp4/8/BP2PN2/P1PP1PPP/RN1QKB1R b KQkq -
+QI.05*
+rnbqkb1r/pp2pp1p/6p1/2pn4/8/4PN2/PP1P1PPP/RNBQKB1R w KQkq -
+EO.45*
+rnbqkb1r/pp2pppp/2p2n2/3p4/2P5/1P3NP1/P2PPP1P/RNBQKB1R b KQkq -
+RE.04
+rnbqkb1r/pp2pppp/2p2n2/3p4/2PP4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+SL.03
+rnbqkb1r/pp2pppp/5n2/2Pp4/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QG.05*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R b KQkq -
+QI.02*
+rnbqkb1r/pp2pppp/5n2/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+QI.01*
+rnbqkb1r/pp2pppp/5n2/3p4/2PP4/2N5/PP3PPP/R1BQKBNR b KQkq -
+CK.03
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+SL.02*
+rnbqkb1r/pp2pppp/5n2/3p4/3P4/5N2/PP2PPPP/RNBQKB1R w KQkq -
+SL.02
+rnbqkb1r/pp2pppp/8/2pn4/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+EO.50*
+rnbqkb1r/pp2pppp/8/2pn4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.42
+rnbqkb1r/pp2pppp/8/2pn4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.38
+rnbqkb1r/pp2pppp/8/2pn4/8/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+EO.46*
+rnbqkb1r/pp3p1p/3p1np1/2pP2B1/8/2N2N2/PP2PPPP/R2QKB1R b KQkq -
+BI.25
+rnbqkb1r/pp3p1p/3p1np1/2pP4/4PB2/2N5/PP3PPP/R2QKBNR b KQkq -
+BI.35
+rnbqkb1r/pp3p1p/3p1np1/2pP4/8/2N5/PP1NPPPP/R1BQKB1R b KQkq -
+BI.27
+rnbqkb1r/pp3ppp/2p1pn2/3p4/2PP4/2N1PN2/PP3PPP/R1BQKB1R b KQkq -
+SL.08
+rnbqkb1r/pp3ppp/2p2p2/8/3P4/8/PPP2PPP/R1BQKBNR w KQkq -
+CK.06
+rnbqkb1r/pp3ppp/3p1n2/2pPp3/2P1P3/2N5/PP3PPP/R1BQKBNR b KQkq -
+OI.05
+rnbqkb1r/pp3ppp/3p1n2/4p3/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.03
+rnbqkb1r/pp3ppp/3ppn2/8/3NP1P1/2N5/PPP2P1P/R1BQKB1R b KQkq -
+SI.20
+rnbqkb1r/pp3ppp/3ppn2/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.19
+rnbqkb1r/pp3ppp/3ppn2/8/3NPP2/2N5/PPP3PP/R1BQKB1R b KQkq -
+SI.21
+rnbqkb1r/pp3ppp/4p3/8/3PP3/5N2/P4PPP/R1BQKB1R b KQkq -
+TD.08
+rnbqkb1r/pp3ppp/4pn2/2Pp4/8/5N2/PPP1PPPP/RNBQKB1R w KQkq -
+QG.08*
+rnbqkb1r/pp3ppp/4pn2/2pP4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+TD.12
+rnbqkb1r/pp3ppp/4pn2/2pp4/2PP4/2N2N2/PP2PPPP/R1BQKB1R w KQkq -
+TD.05
+rnbqkb1r/pp3ppp/4pn2/2pp4/8/1P2PN2/P1PP1PPP/RNBQKB1R w KQkq -
+QI.03*
+rnbqkb1r/ppn1pppp/8/2p5/8/2N3P1/PP1PPPBP/R1BQK1NR w KQkq -
+EO.37
+rnbqkb1r/ppp1pp1p/3p1np1/6B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+PU.09
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N2P2/PPP3PP/R1BQKBNR b KQkq -
+PU.04
+rnbqkb1r/ppp1pp1p/3p1np1/8/3PP3/2N5/PPP2PPP/R1BQKBNR w KQkq -
+PU.07
+rnbqkb1r/ppp1pp1p/3p2p1/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R w KQkq -
+AL.04
+rnbqkb1r/ppp1pp1p/5np1/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+GI.03
+rnbqkb1r/ppp1pp1p/6p1/3n4/8/2N2N2/PP1PPPPP/R1BQKB1R w KQkq -
+EO.52
+rnbqkb1r/ppp1pp1p/6p1/3n4/8/2N3P1/PP1PPPBP/R1BQK1NR b KQkq -
+EO.53
+rnbqkb1r/ppp1pp1p/6p1/8/3PP3/2P5/P4PPP/R1BQKBNR b KQkq -
+GI.04
+rnbqkb1r/ppp1pppp/1n1P4/8/2PP4/8/PP3PPP/RNBQKBNR b KQkq -
+AL.08
+rnbqkb1r/ppp1pppp/1n1p4/4P3/2PP1P2/8/PP4PP/RNBQKBNR b KQkq -
+AL.07
+rnbqkb1r/ppp1pppp/3p1n2/8/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+OI.04
+rnbqkb1r/ppp1pppp/3p1n2/8/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+PU.08
+rnbqkb1r/ppp1pppp/3p4/3nP3/3P4/5N2/PPP2PPP/RNBQKB1R b KQkq -
+AL.05
+rnbqkb1r/ppp1pppp/5n2/3P4/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+SD.03
+rnbqkb1r/ppp1pppp/5n2/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.06*
+rnbqkb1r/ppp1pppp/5n2/8/2pP4/4PN2/PP3PPP/RNBQKB1R b KQkq -
+QG.08
+rnbqkb1r/ppp2ppp/3p1n2/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+KP.07*
+rnbqkb1r/ppp2ppp/3p4/8/3Pn3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+RG.04
+rnbqkb1r/ppp2ppp/4pn2/3p2B1/3PP3/2N5/PPP2PPP/R2QKBNR b KQkq -
+FR.05
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P1P3/2N5/PP1P1PPP/R1BQKBNR w KQkq -
+EO.57
+rnbqkb1r/ppp2ppp/4pn2/3p4/2P5/5NP1/PP1PPPBP/RNBQK2R b KQkq -
+RE.11
+rnbqkb1r/ppp2ppp/4pn2/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+QO.16
+rnbqkb1r/ppp2ppp/4pn2/3pP3/3P4/8/PPPN1PPP/R1BQKBNR b KQkq -
+FR.16
+rnbqkb1r/ppp2ppp/4pn2/8/2p5/5NP1/PP1PPPBP/RNBQK2R w KQkq -
+RE.10
+rnbqkb1r/ppp2ppp/4pn2/8/2pP4/5NP1/PP2PPBP/RNBQK2R b KQkq -
+CA.03
+rnbqkb1r/ppp2ppp/4pn2/8/Q1pP4/6P1/PP2PPBP/RNB1K1NR b KQkq -
+CA.02
+rnbqkb1r/ppp2ppp/5n2/3Pp3/8/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SO.06*
+rnbqkb1r/ppp2ppp/5n2/3p2B1/3Np3/3P4/PPP1PPPP/RN1QKB1R b KQkq -
+AL.03*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P2P1/PPP1PP1P/RNBQKB1R b KQkq -
+AL.04*
+rnbqkb1r/ppp2ppp/5n2/3p4/3Np3/3P4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.05*
+rnbqkb1r/ppp2ppp/5n2/3pN3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+RG.02*
+rnbqkb1r/ppp2ppp/5n2/3pN3/8/3P4/PPP2PPP/RNBQKB1R w KQkq -
+RG.04*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4P3/3P4/PPP2PPP/RNBQKBNR w KQkq -
+KP.08*
+rnbqkb1r/ppp2ppp/5n2/3pp3/4PP2/2N5/PPPP2PP/R1BQKBNR w KQkq -
+VG.03
+rnbqkb1r/ppp2ppp/8/3np3/2B5/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+SO.05*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N1P3/PP1P1PPP/R1BQKBNR b KQkq -
+SI.39*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N3P1/PP1PPP1P/R1BQKBNR b KQkq -
+SI.33*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+SI.32*
+rnbqkb1r/ppp2ppp/8/3np3/8/2N5/PPPP1PPP/R1BQKBNR w KQkq -
+SO.04*
+rnbqkb1r/ppp2ppp/8/3np3/8/4P3/PP1P1PPP/RNBQKBNR w KQkq -
+SI.41*
+rnbqkb1r/pppp1ppp/4pn2/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.04
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QI.01
+rnbqkb1r/pppp1ppp/4pn2/8/2PP4/6P1/PP2PP1P/RNBQKBNR b KQkq -
+CA.01
+rnbqkb1r/pppp1ppp/4pn2/8/3P1B2/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.05
+rnbqkb1r/pppp1ppp/5n2/4N3/4P3/8/PPPP1PPP/RNBQKB1R b KQkq -
+RG.03
+rnbqkb1r/pppp1ppp/5n2/4p3/2B1P3/2N5/PPPP1PPP/R1BQK1NR b KQkq -
+VG.02
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N2N2/PP1PPPPP/R1BQKB1R b KQkq -
+EO.09
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+SI.31*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+EO.10
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/3P4/PP2PPPP/RNBQKBNR b KQkq -
+SI.01*
+rnbqkb1r/pppp1ppp/5n2/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.43*
+rnbqkb1r/pppp1ppp/5n2/4p3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/2N3P1/PPPP1P1P/R1BQKBNR b KQkq -
+VG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+RG.01*
+rnbqkb1r/pppp1ppp/5n2/4p3/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+RG.01
+rnbqkb1r/pppp1ppp/5n2/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+KP.09*
+rnbqkb1r/pppp1ppp/5n2/4p3/8/2N5/PPPPPPPP/R1BQKBNR w KQkq -
+VO.05*
+rnbqkb1r/pppp1ppp/8/4P3/6n1/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.13*
+rnbqkb1r/pppp1ppp/8/4p3/3Pn3/5N2/PPP2PPP/RNBQKB1R w KQkq -
+RG.02
+rnbqkb1r/pppp1ppp/8/4p3/4n3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+RG.03*
+rnbqkb1r/pppp2pp/4pn2/5p2/2PP4/6P1/PP2PPBP/RNBQK1NR b KQkq -
+HD.03
+rnbqkb1r/pppp2pp/5n2/4pP2/6P1/8/PPPP1P1P/RNBQKBNR b KQkq -
+KG.01*
+rnbqkb1r/pppp2pp/5n2/4pP2/8/8/PPPP1PPP/RNBQKBNR w KQkq -
+KG.02*
+rnbqkb1r/ppppp1pp/5n2/5p2/2PP4/2N5/PP2PPPP/R1BQKBNR b KQkq -
+HD.05
+rnbqkb1r/ppppp2p/5np1/5p2/2PP4/6P1/PP2PP1P/RNBQKBNR w KQkq -
+HD.08
+rnbqkb1r/pppppp1p/5np1/6B1/3P4/5N2/PPP1PPPP/RN1QKB1R b KQkq -
+QP.02
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+GI.01
+rnbqkb1r/pppppp1p/5np1/8/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+KI.80
+rnbqkb1r/pppppppp/5n2/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+QP.10*
+rnbqkb1r/pppppppp/5n2/8/3P4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+QP.06
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QP.09*
+rnbqkb1r/pppppppp/5n2/8/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+QP.07
+rnbqkb1r/pppppppp/5n2/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+AL.10
+rnbqkb1r/pppppppp/5n2/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+QP.11*
+rnbqkb1r/pppppppp/7n/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.16*
+rnbqkb1r/pppppppp/8/3nP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+AL.09
+rnbqkbnr/1p1p1ppp/p3p3/8/3NP3/3B4/PPP2PPP/RNBQK2R b KQkq -
+SI.42
+rnbqkbnr/1ppppppp/p7/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.14*
+rnbqkbnr/p1pppppp/1p6/8/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+EO.63
+rnbqkbnr/p1pppppp/1p6/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+VO.01
+rnbqkbnr/p1pppppp/1p6/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.08*
+rnbqkbnr/p1pppppp/8/1p6/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.10*
+rnbqkbnr/pp1p1ppp/2p5/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+SI.46*
+rnbqkbnr/pp1p1ppp/4p3/8/3NP3/8/PPP2PPP/RNBQKB1R b KQkq -
+SI.41
+rnbqkbnr/pp1p1ppp/8/2p1p3/4P3/6P1/PPPP1P1P/RNBQKBNR b KQkq -
+EO.62*
+rnbqkbnr/pp1ppp1p/6p1/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+EO.24*
+rnbqkbnr/pp1ppppp/2p5/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+CK.01
+rnbqkbnr/pp1ppppp/2p5/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.12*
+rnbqkbnr/pp1ppppp/8/2p5/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+OI.09
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+SI.44
+rnbqkbnr/pp1ppppp/8/2p5/4P3/2P5/PP1P1PPP/RNBQKBNR b KQkq -
+SI.46
+rnbqkbnr/pp1ppppp/8/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+SI.43
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+EO.25*
+rnbqkbnr/pp1ppppp/8/2p5/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+SI.48
+rnbqkbnr/pp1ppppp/8/2p5/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+HD.14*
+rnbqkbnr/pp1ppppp/8/2p5/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+EO.63*
+rnbqkbnr/pp1ppppp/8/2p5/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.10
+rnbqkbnr/pp1ppppp/8/2p5/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+EO.64*
+rnbqkbnr/pp2pp1p/6p1/2pp4/5P2/5NP1/PPPPP2P/RNBQKB1R b KQkq -
+HD.08*
+rnbqkbnr/pp2pp1p/6p1/2pp4/8/4PN2/PPPP1PPP/RNBQKB1R w KQkq -
+CA.01*
+rnbqkbnr/pp2pppp/2p5/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.07
+rnbqkbnr/pp2pppp/2p5/3p4/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+SL.01
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+CK.05
+rnbqkbnr/pp2pppp/2p5/3p4/3PP3/8/PPP2PPP/RNBQKBNR w KQkq -
+CK.02
+rnbqkbnr/pp2pppp/3p4/2p5/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+SI.01
+rnbqkbnr/pp2pppp/3p4/8/3QP3/5N2/PPP2PPP/RNB1KB1R b KQkq -
+SI.02
+rnbqkbnr/pp2pppp/8/2Pp4/8/8/PPP1PPPP/RNBQKBNR b KQkq -
+QG.03*
+rnbqkbnr/pp2pppp/8/2p5/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+BI.46*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+BI.38*
+rnbqkbnr/pp2pppp/8/2p5/2Pp4/5NP1/PP1PPP1P/RNBQKB1R w KQkq -
+RE.14
+rnbqkbnr/pp2pppp/8/2pp4/2P5/5N2/PP1PPPPP/RNBQKB1R b KQkq -
+OI.06*
+rnbqkbnr/pp2pppp/8/2pp4/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+SL.01*
+rnbqkbnr/pp2pppp/8/2pp4/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+QG.02*
+rnbqkbnr/pp2pppp/8/2pp4/4P3/5N2/PPPP1PPP/RNBQKB1R b KQkq -
+QG.01*
+rnbqkbnr/pp2pppp/8/2pp4/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.10*
+rnbqkbnr/pp2pppp/8/2pp4/8/3P4/PPP1PPPP/RNBQKBNR w KQkq -
+OI.07*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+GI.01*
+rnbqkbnr/pp2pppp/8/2pp4/8/5NP1/PPPPPP1P/RNBQKB1R b KQkq -
+KI.80*
+rnbqkbnr/pp2pppp/8/8/1pPp4/P4N2/3PPPPP/RNBQKB1R b KQkq -
+BI.45*
+rnbqkbnr/pp3ppp/2p1p3/3p4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+SL.06
+rnbqkbnr/pp3ppp/2p5/3P4/3Np3/8/PP1PPPPP/RNBQKB1R b KQkq -
+SI.47*
+rnbqkbnr/pp3ppp/4p3/2pp4/2PP4/2N5/PP2PPPP/R1BQKBNR w KQkq -
+TD.10
+rnbqkbnr/pp3ppp/4p3/2pp4/3PP3/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.18
+rnbqkbnr/pp3ppp/4p3/8/1pPp4/P4N2/3PPPPP/RNBQKB1R w KQkq -
+BI.43*
+rnbqkbnr/pp3ppp/8/2Ppp3/8/8/PPP1PPPP/RNBQKBNR w KQkq -
+QG.04*
+rnbqkbnr/pp3ppp/8/2pp4/3P4/2N2N2/PP2PPPP/R1BQKB1R b KQkq -
+TD.11
+rnbqkbnr/pp3ppp/8/2pp4/3P4/5N2/PPPN1PPP/R1BQKB1R b KQkq -
+FR.21
+rnbqkbnr/pp3ppp/8/2pp4/3P4/8/PPPN1PPP/R1BQKBNR w KQkq -
+FR.20
+rnbqkbnr/pp3ppp/8/2pp4/8/1N1p4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.08*
+rnbqkbnr/pp4pp/8/2pp1p2/4p3/1N1P4/PPP1PPPP/RNBQKB1R w KQkq -
+AL.07*
+rnbqkbnr/ppp1pppp/3p4/8/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+OI.07
+rnbqkbnr/ppp1pppp/3p4/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.13*
+rnbqkbnr/ppp1pppp/8/3p4/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+OI.09*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QP.08*
+rnbqkbnr/ppp1pppp/8/3p4/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+QP.08
+rnbqkbnr/ppp1pppp/8/3p4/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+HD.12*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+QP.07*
+rnbqkbnr/ppp1pppp/8/3p4/8/5N2/PPPPPPPP/RNBQKB1R w KQkq -
+QP.09
+rnbqkbnr/ppp1pppp/8/3p4/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+QO.17*
+rnbqkbnr/ppp1pppp/8/8/1PPp4/5N2/P2PPPPP/RNBQKB1R b KQkq -
+RE.17
+rnbqkbnr/ppp1pppp/8/8/2Pp4/4PN2/PP1P1PPP/RNBQKB1R b KQkq -
+RE.16
+rnbqkbnr/ppp1pppp/8/8/2Pp4/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.15
+rnbqkbnr/ppp1pppp/8/8/2p5/5N2/PP1PPPPP/RNBQKB1R w KQkq -
+RE.19
+rnbqkbnr/ppp1pppp/8/8/2p5/N4N2/PP1PPPPP/R1BQKB1R b KQkq -
+RE.18
+rnbqkbnr/ppp1pppp/8/8/2pP4/5N2/PP2PPPP/RNBQKB1R b KQkq -
+QG.05
+rnbqkbnr/ppp1pppp/8/8/2pP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.03
+rnbqkbnr/ppp1pppp/8/8/2pPP3/8/PP3PPP/RNBQKBNR b KQkq -
+QG.04
+rnbqkbnr/ppp2ppp/3p4/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR w KQkq -
+EO.22
+rnbqkbnr/ppp2ppp/3p4/4p3/3PP3/5N2/PPP2PPP/RNBQKB1R b KQkq -
+KP.08
+rnbqkbnr/ppp2ppp/3p4/4p3/8/4P3/PPPP1PPP/RNBQKBNR w KQkq -
+FR.02*
+rnbqkbnr/ppp2ppp/4p3/3p4/2P5/5NP1/PP1PPP1P/RNBQKB1R b KQkq -
+RE.12
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/2N5/PPP2PPP/R1BQKBNR b KQkq -
+FR.04
+rnbqkbnr/ppp2ppp/4p3/3p4/3PP3/8/PPPN1PPP/R1BQKBNR b KQkq -
+FR.14
+rnbqkbnr/ppp2ppp/4p3/3pP3/3P4/8/PPP2PPP/RNBQKBNR b KQkq -
+FR.03
+rnbqkbnr/ppp2ppp/4p3/8/3PN3/8/PPP2PPP/R1BQKBNR b KQkq -
+FR.07
+rnbqkbnr/ppp2ppp/8/3Pp3/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+KP.04*
+rnbqkbnr/ppp2ppp/8/3p4/3Np3/8/PPPPPPPP/RNBQKB1R w KQkq -
+AL.09*
+rnbqkbnr/ppp2ppp/8/3p4/3Pp3/4P3/PPP2PPP/RNBQKBNR w KQkq -
+FR.03*
+rnbqkbnr/ppp2ppp/8/3p4/3PpB2/2P5/PP2PPPP/RN1QKBNR b KQkq -
+CK.04*
+rnbqkbnr/ppp2ppp/8/3pp3/2PP4/8/PP2PPPP/RNBQKBNR w KQkq -
+QG.02
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2N5/PPP1PPPP/R1BQKBNR b KQkq -
+VO.06*
+rnbqkbnr/ppp2ppp/8/3pp3/3P4/2P5/PP2PPPP/RNBQKBNR b KQkq -
+CK.02*
+rnbqkbnr/ppp2ppp/8/3pp3/4PP2/8/PPPP2PP/RNBQKBNR w KQkq -
+KG.04
+rnbqkbnr/ppp2ppp/8/3pp3/5P2/8/PPPPP1PP/RNBQKBNR w KQkq -
+HD.11*
+rnbqkbnr/ppp2ppp/8/3pp3/8/3P1N2/PPP1PPPP/RNBQKB1R b KQkq -
+PU.08*
+rnbqkbnr/ppp2ppp/8/3pp3/8/6P1/PPPPPPBP/RNBQK1NR b KQkq -
+KF.05*
+rnbqkbnr/pppp1p1p/6p1/4p3/2P1P3/8/PP1P1PPP/RNBQKBNR w KQkq -
+EO.62
+rnbqkbnr/pppp1p1p/8/6p1/4Pp2/5N2/PPPP2PP/RNBQKB1R w KQkq -
+KG.01
+rnbqkbnr/pppp1ppp/4p3/8/4P3/3P4/PPP2PPP/RNBQKBNR b KQkq -
+FR.02
+rnbqkbnr/pppp1ppp/4p3/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+FR.01
+rnbqkbnr/pppp1ppp/8/4p3/2B1P3/8/PPPP1PPP/RNBQK1NR b KQkq -
+IG.04
+rnbqkbnr/pppp1ppp/8/4p3/2P5/2N5/PP1PPPPP/R1BQKBNR b KQkq -
+EO.23
+rnbqkbnr/pppp1ppp/8/4p3/2P5/6P1/PP1PPP1P/RNBQKBNR b KQkq -
+EO.24
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+SI.48*
+rnbqkbnr/pppp1ppp/8/4p3/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+EO.25
+rnbqkbnr/pppp1ppp/8/4p3/4P3/2N5/PPPP1PPP/R1BQKBNR b KQkq -
+VG.04
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+KP.10*
+rnbqkbnr/pppp1ppp/8/4p3/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KP.10
+rnbqkbnr/pppp1ppp/8/4p3/4PP2/8/PPPP2PP/RNBQKBNR b KQkq -
+KG.05
+rnbqkbnr/pppp1ppp/8/4p3/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+VO.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+VO.04*
+rnbqkbnr/pppp1ppp/8/4p3/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+CK.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/4P3/PPPP1PPP/RNBQKBNR b KQkq -
+FR.01*
+rnbqkbnr/pppp1ppp/8/4p3/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+AL.10*
+rnbqkbnr/pppp1ppp/8/4p3/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+KF.06*
+rnbqkbnr/pppp1ppp/8/4p3/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.17*
+rnbqkbnr/pppp1ppp/8/8/3p4/5N2/PPP1PPPP/RNBQKB1R b KQkq -
+SD.03*
+rnbqkbnr/pppp1ppp/8/8/3pP3/8/PPP2PPP/RNBQKBNR w KQkq -
+KP.04
+rnbqkbnr/pppp1ppp/8/8/4Pp2/5N2/PPPP2PP/RNBQKB1R b KQkq -
+KG.02
+rnbqkbnr/pppp1ppp/8/8/4Pp2/8/PPPP2PP/RNBQKBNR w KQkq -
+KG.03
+rnbqkbnr/pppp2pp/8/4pP2/8/8/PPPP1PPP/RNBQKBNR b KQkq -
+KG.03*
+rnbqkbnr/pppp2pp/8/4pp2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+KG.04*
+rnbqkbnr/pppp2pp/8/4pp2/4P3/5N2/PPPP1PPP/RNBQKB1R w KQkq -
+KP.09
+rnbqkbnr/pppp2pp/8/4pp2/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KG.05*
+rnbqkbnr/ppppp1pp/8/5p2/2P5/8/PP1PPPPP/RNBQKBNR w KQkq -
+HD.14
+rnbqkbnr/ppppp1pp/8/5p2/2PP4/8/PP2PPPP/RNBQKBNR b KQkq -
+HD.10
+rnbqkbnr/ppppp1pp/8/5p2/3P4/8/PPP1PPPP/RNBQKBNR w KQkq -
+HD.12
+rnbqkbnr/ppppp1pp/8/5p2/3PP3/8/PPP2PPP/RNBQKBNR b KQkq -
+HD.11
+rnbqkbnr/ppppp1pp/8/5p2/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.07*
+rnbqkbnr/ppppp1pp/8/6N1/4p3/8/PPPP1PPP/RNBQKB1R b KQkq -
+HD.13
+rnbqkbnr/ppppp2p/6p1/5p2/3P4/6P1/PPP1PPBP/RNBQK1NR b KQkq -
+HD.09
+rnbqkbnr/pppppp1p/6p1/8/4P3/8/PPPP1PPP/RNBQKBNR w KQkq -
+KF.06
+rnbqkbnr/pppppp1p/6p1/8/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.09*
+rnbqkbnr/pppppp1p/8/6p1/8/8/PPPPPPPP/RNBQKBNR w KQkq -
+VO.11*
+rnbqkbnr/pppppppp/8/8/1P6/8/P1PPPPPP/RNBQKBNR b KQkq -
+VO.10
+rnbqkbnr/pppppppp/8/8/2P5/8/PP1PPPPP/RNBQKBNR b KQkq -
+EO.64
+rnbqkbnr/pppppppp/8/8/3P4/8/PPP1PPPP/RNBQKBNR b KQkq -
+QO.17
+rnbqkbnr/pppppppp/8/8/4P3/8/PPPP1PPP/RNBQKBNR b KQkq -
+VO.17
+rnbqkbnr/pppppppp/8/8/5P2/8/PPPPP1PP/RNBQKBNR b KQkq -
+VO.07
+rnbqkbnr/pppppppp/8/8/6P1/8/PPPPPP1P/RNBQKBNR b KQkq -
+VO.11
+rnbqkbnr/pppppppp/8/8/8/1P6/P1PPPPPP/RNBQKBNR b KQkq -
+VO.08
+rnbqkbnr/pppppppp/8/8/8/2N5/PPPPPPPP/R1BQKBNR b KQkq -
+VO.15
+rnbqkbnr/pppppppp/8/8/8/2P5/PP1PPPPP/RNBQKBNR b KQkq -
+VO.12
+rnbqkbnr/pppppppp/8/8/8/3P4/PPP1PPPP/RNBQKBNR b KQkq -
+VO.13
+rnbqkbnr/pppppppp/8/8/8/5N2/PPPPPPPP/RNBQKB1R b KQkq -
+QP.11
+rnbqkbnr/pppppppp/8/8/8/6P1/PPPPPP1P/RNBQKBNR b KQkq -
+VO.09
+rnbqkbnr/pppppppp/8/8/8/7N/PPPPPPPP/RNBQKB1R b KQkq -
+VO.16
+rnbqkbnr/pppppppp/8/8/8/P7/1PPPPPPP/RNBQKBNR b KQkq -
+VO.14
+rnbqr1k1/1ppp1ppp/1b3n2/p3p3/1P2P3/P1N2N2/2PPBPPP/R1BQ1RK1 w - -
+RL.18*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N1P/2P1BPP1/R1BQ1RK1 b - -
+RL.22*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/1BP1BPPP/R2Q1RK1 b - -
+RL.26*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.21*
+rnbqr1k1/pp1p1pp1/1bp2n1p/4p3/1P2P3/P2P1N2/2P1BPPP/RNBQ1RK1 b - -
+RL.25*
+rnbqr1k1/pp3pbp/3p1np1/2pP4/4PP2/2N2N2/PP2B1PP/R1BQK2R w KQ -
+BI.29
+rnbqr1k1/pp3pbp/3p1np1/2pP4/8/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+BI.23
+rnbqr1k1/pp3ppp/1bp2n2/3pp3/1P2P3/P1NP1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.20*
+rnbqr1k1/ppbp1pp1/2p2n1p/4p3/NP2P3/P2P1N2/2P1BPPP/R1BQ1RK1 w - -
+RL.23*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1N2N2/2PPBPPP/R1BQK2R w KQ -
+RL.17*
+rnbqr1k1/pppp1ppp/1b3n2/4p3/1P2P3/P1NP1N2/2P1BPPP/R1BQK2R b KQ -
+RL.19*
+rnbqr1k1/pppp1ppp/5n2/b3p3/4P3/P1NP1N2/1PP1BPPP/R1BQK2R b KQ -
+RL.16*
blob - /dev/null
blob + b0cee3cdd90d0ddf70b7568be4b15cbbd93a7cd1 (mode 644)
--- /dev/null
+++ FICS.DIST/data/book/nic999.idx
+1r1qr1k1/p1n2pbp/bp1p1np1/2pP2B1/P1N1P3/2N2P2/1P2B1PP/R2Q1R1K b - -
+BI.06
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NPP/PP2PPB1/R1BQ1RK1 w - -
+KI.70
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP2P/2N1BP2/PPQ1N1P1/R3KB1R b KQ -
+KI.33
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1Q2PP/R1N1KB1R b KQ -
+KI.34
+1rbq1rk1/1pp1ppbp/p1np1np1/8/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.35
+1rbq1rk1/4ppbp/p2p1np1/nppP4/2P5/1PN3P1/PBQNPPBP/R4RK1 b - -
+KI.66
+1rbq1rk1/pp2ppbp/2np1np1/2p5/4P3/2NP1NP1/PPP2PBP/R1BQ1RK1 w - -
+EO.13*
+1rbqk1nr/pp1pppbp/2n3p1/2p5/4P3/2N3P1/PPPP1PBP/R1BQK1NR w KQk -
+EO.15*
+1rbqk1nr/pp2ppbp/2np2p1/2p5/4P3/2NP2P1/PPP2PBP/R1BQK1NR w KQk -
+EO.16*
+1rbqr1k1/1p1n1pbp/p2p1np1/2pP4/P1N5/2N3PP/1P2PPB1/R1BQ1RK1 b - -
+BI.21
+2bq1rk1/1p1nbppp/r1n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.01*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/2NPPN2/PP2BPPP/R1BQ1RK1 b - -
+SI.28*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P1B1PPP/R2QKB1R b KQ -
+SI.30*
+2kr1b1r/pppq1ppp/2n5/3np3/6b1/P1NPPN2/1P3PPP/R1BQKB1R w KQ -
+SI.29*
+2rqkb1r/pp2pppp/2n2n2/2Pp3b/8/4PN1P/PPP1BPP1/RNBQ1RK1 b k -
+QO.07*
+2rqkb1r/pp2pppp/5n2/3p4/3P4/1P5P/P1P1QPP1/RNB2RK1 b k -
+QO.06*
+2rqkb1r/pp3ppp/2n1pn2/2pp3b/3P4/1P2PN1P/PBP1BPP1/RN1Q1RK1 b k -
+QO.09*
+2rqkb1r/pp3ppp/2n1pn2/2pp4/3P2b1/4PN2/PPPNBPPP/R1BQ1RK1 w k -
+QO.11*
+3rkb1r/1pq2ppp/p1n1pn2/2p2b2/Q2P4/2N1PN2/PP2BPPP/R1B2RK1 b k -
+QO.02*
+r1b1k2r/ppp2pp1/3q1nn1/3p4/7p/2P4P/PP1NPPP1/R2QKBNR w KQkq -
+CK.12*
+r1b1kb1r/1pq2ppp/p1nppn2/8/3NPP2/2N5/PPP1B1PP/R1BQ1RK1 w kq -
+SI.24
+r1b1kb1r/pp1n1ppp/2p1pn2/q2p2B1/2PP4/2N1PN2/PP3PPP/R2QKB1R w KQkq -
+QO.15
+r1b1kb1r/pp2pppp/1qn2n2/2pp4/3P4/5NP1/PPP1PPBP/RNBQK2R w KQkq -
+GI.10*
+r1b1kb1r/ppqppppp/2n2n2/1Bp5/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+EO.58*
+r1b1kbnr/1p2pppp/p1q5/2pp4/8/4PN2/PPPP1PPP/RNBQ1RK1 w kq -
+NI.20*
+r1b1kbnr/pp3ppp/2n5/2p1q3/4p3/2N1P3/PP1P1PPP/R1BQKBNR w KQkq -
+EO.55*
+r1b1kbnr/ppq1pppp/2n5/1Bp5/2p5/4PN2/PP1P1PPP/RNBQ1RK1 b kq -
+NI.21*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/2P5/4PN2/PP1P1PPP/RNBQK2R b KQkq -
+NI.22*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/3P4/4PN2/PPP2PPP/RNBQK2R b KQkq -
+NI.23*
+r1b1kbnr/ppq1pppp/2n5/1Bpp4/8/4PN2/PPPP1PPP/RNBQK2R w KQkq -
+NI.24*
+r1b1kbnr/ppqp1ppp/2n1p3/8/3NP3/2N5/PPP2PPP/R1BQKB1R w KQkq -
+SI.40
+r1b2rk1/1p1nqppp/2n5/p3p3/2Pp4/P2P1NP1/1P3PBP/RN1Q1RK1 w - -
+BI.14*
+r1b2rk1/2q1bppp/p2p1n2/npp1p3/3PP3/2P2N1P/PPBN1PP1/R1BQR1K1 b - -
+RL.24
+r1b2rk1/pp2bppp/2n1pn2/q2p4/2P2B2/P1N1PN2/1PQ2PPP/3RKB1R w K -
+QO.02
+r1b2rk1/pp2ppbp/2n2np1/2pq4/8/1P2PN2/PB1PBPPP/RN1QK2R w KQ -
+EO.39*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/2P5/1P2P3/PB1PBPPP/RN1Q1RK1 b - -
+QI.13*
+r1b2rk1/pp2ppbp/2q2np1/2pp4/5P2/1P2P3/PBPPB1PP/RN1Q1RK1 b - -
+QI.12*
+r1b2rk1/ppq1ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 w - -
+QI.11*
+r1b2rk1/ppq2ppp/2n1pn2/2p5/2BP4/P1P1PN2/5PPP/R1BQ1RK1 w - -
+NI.01
+r1bq1rk1/1p1n1pbp/2pp1np1/p3p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 w - -
+KI.09
+r1bq1rk1/1p1n1pbp/p2p1np1/2pP4/P3P3/2N2N2/1P2BPPP/R1BQ1RK1 w - -
+BI.15
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/1P1P1NP1/P1N2PBP/R1BQR1K1 b - -
+BI.07*
+r1bq1rk1/1p1nb1pp/2n2p2/p3p3/2Pp4/3P2P1/PPNN1PBP/R1BQR1K1 b - -
+BI.08*
+r1bq1rk1/1p1nb1pp/2n5/p3pp2/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 w - -
+BI.02*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.03*
+r1bq1rk1/1p1nbppp/2n5/p3p3/2PpN3/3P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.04*
+r1bq1rk1/1p1nppbp/2n3p1/p7/2Pp4/P2P1NP1/1P1N1PBP/R1BQR1K1 b - -
+BI.22*
+r1bq1rk1/1p2bppp/2n2n2/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R1BQ1RK1 b - -
+BI.15*
+r1bq1rk1/1p2ppb1/2n3pp/p1n5/2Pp4/P2P1NP1/1P1N1PBP/1RBQR1K1 w - -
+BI.21*
+r1bq1rk1/1p3pp1/2n2b1p/p3p3/2Pp4/P2P1NP1/1P1N1PBP/R2Q1RK1 b - -
+BI.10*
+r1bq1rk1/1p3ppp/2n1pn2/pBbp4/5B2/2P1PN2/PP3PPP/RN1QK2R w KQ -
+SL.05*
+r1bq1rk1/1p3ppp/p1nbpn2/1Bpp4/2PP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.02*
+r1bq1rk1/1pp1ppbp/p1np1np1/8/2PP4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.71
+r1bq1rk1/2p1bpp1/p1np1n1p/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 w - -
+RL.22
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/3PP3/1BP2N2/PP3PPP/RNBQR1K1 b - -
+RL.20
+r1bq1rk1/2p1bppp/p1np1n2/1p2p3/4P3/1BP2N1P/PP1P1PP1/RNBQR1K1 b - -
+RL.21
+r1bq1rk1/2p1bppp/p2p1n2/np2p3/4P3/2P2N1P/PPBP1PP1/RNBQR1K1 b - -
+RL.23
+r1bq1rk1/2ppbppp/p1n2n2/1p2p3/P3P3/1B3N2/1PPP1PPP/RNBQR1K1 b - -
+RL.18
+r1bq1rk1/3nppbp/p1pp1np1/1p6/2PPP3/2NBBP2/PP2N1PP/R2Q1RK1 w - -
+KI.46
+r1bq1rk1/5ppp/p1p1pn2/2bp4/2P5/2N1PN2/PPQ2PPP/R1B2RK1 b - -
+NI.01*
+r1bq1rk1/p1p2ppp/5n2/3p2B1/1b6/2NB4/PPP2PPP/R2Q1RK1 b - -
+SO.03
+r1bq1rk1/p3bp1p/2n2np1/1pp1p3/3pPP1N/3P2P1/PPP1N1BP/R1BQ1RK1 b - -
+KI.04*
+r1bq1rk1/p3bppp/2n2n2/1pp1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.05*
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N1BP2/PP1QN1PP/R3KB1R w KQ -
+KI.42
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2N2/PP3PPP/R1BQRBK1 b - -
+KI.10
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NP1/PP3PBP/R1BQ1RK1 w - -
+KI.63
+r1bq1rk1/pp1n1pbp/2pp1np1/4p3/2PPP3/2N2NPP/PP3PB1/R1BQ1RK1 b - -
+KI.62
+r1bq1rk1/pp1n1ppp/4pn2/2p5/1bBP4/2N1PN2/PP3PPP/R1BQ1RK1 w - -
+NI.03
+r1bq1rk1/pp1nbppp/2n5/2p1p3/3pP3/3P1NP1/PPP1NPBP/R1BQ1RK1 w - -
+KI.07*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/3P1NP1/PP1N1PBP/R1BQR1K1 b - -
+BI.05*
+r1bq1rk1/pp1nbppp/2n5/4p3/2Pp4/N2P1NP1/PP3PBP/R1BQR1K1 b - -
+BI.09*
+r1bq1rk1/pp1pppbp/2n2np1/1Bp5/4P3/2N2N2/PPPP1PPP/R1BQ1RK1 w - -
+EO.01*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P2PN2/PB1PBPPP/RN1QK2R b KQ -
+EO.40*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/1P3NP1/PB1PPPBP/RN1QK2R b KQ -
+EO.48*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 b - -
+EO.27*
+r1bq1rk1/pp1pppbp/2n2np1/2p5/2P5/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.27
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N1P3/PP2BPPP/R1BQK2R b KQ -
+EO.41*
+r1bq1rk1/pp1pppbp/2n2np1/8/2PN4/2N3P1/PP2PPBP/R1BQ1RK1 b - -
+EO.26
+r1bq1rk1/pp2bppp/2n1p3/2pn4/3PP3/2N2NP1/PP3PBP/R1BQ1RK1 b - -
+TD.02
+r1bq1rk1/pp2bppp/2n2n2/2p1p3/3pP3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.12*
+r1bq1rk1/pp2bppp/2n2n2/2pp2B1/3P4/2N2NP1/PP2PPBP/R2Q1RK1 b - -
+TD.03
+r1bq1rk1/pp2bppp/2n2n2/2pp4/3P4/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.04
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPP2PBP/RNBQ1RK1 w - -
+KI.15*
+r1bq1rk1/pp2bppp/2n2n2/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.14*
+r1bq1rk1/pp2bppp/2n2n2/4p1B1/2Pp4/3P1NP1/PP3PBP/RN1Q1RK1 b - -
+BI.16*
+r1bq1rk1/pp2bppp/2n5/2pp4/3P4/5NP1/PP2PPBP/R1BQ1RK1 w - -
+TD.01
+r1bq1rk1/pp2bppp/2nn4/2p1p3/3pPP2/3P2P1/PPPNN1BP/R1BQ1RK1 b - -
+KI.01*
+r1bq1rk1/pp2bppp/2nppn2/6B1/3NP3/2N5/PPPQ1PPP/2KR1B1R w - -
+SI.28
+r1bq1rk1/pp2nppp/2nb4/4p3/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.36*
+r1bq1rk1/pp2ppb1/2n2npp/2pp4/8/P1NP1NP1/1PP1PPBP/1RBQ1RK1 b - -
+KI.70*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.68*
+r1bq1rk1/pp2ppbp/2n2np1/2p5/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.68
+r1bq1rk1/pp2ppbp/2n2np1/2p5/N1Pp4/3P1NP1/PP2PPBP/R1BQ1RK1 b - -
+KI.67*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/2P5/3P1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.69*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 b - -
+KI.65*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/1P2PN2/PBPPBPPP/RN1Q1RK1 w - -
+QI.09*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2NP1NP1/PPP1PPBP/R1BQ1RK1 w - -
+KI.72*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/2PP1NP1/PP2PPBP/RNBQ1RK1 w - -
+KI.75*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/8/P1NP1NP1/1PP1PPBP/R1BQ1RK1 b - -
+KI.71*
+r1bq1rk1/pp2ppbp/2n2np1/2pp4/Q7/2PP1NP1/PP2PPBP/RNB2RK1 b - -
+KI.74*
+r1bq1rk1/pp2ppbp/2n2np1/2ppN3/8/1P2P3/PBPPBPPP/RN1Q1RK1 b - -
+QI.10*
+r1bq1rk1/pp2ppbp/2n2np1/3p4/2PP4/2N2N2/PP2BPPP/R1BQ1RK1 b - -
+TD.04*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQ1RK1 w - -
+BI.24*
+r1bq1rk1/pp2ppbp/2n2np1/8/2Pp4/3P1NP1/PP3PBP/RNBQR1K1 b - -
+BI.23*
+r1bq1rk1/pp2ppbp/2n3p1/2pn4/8/2N2NP1/PP1PPPBP/R1BQ1RK1 w - -
+EO.26*
+r1bq1rk1/pp2ppbp/2n3p1/8/2BPP3/4B3/P3NPPP/R2Q1RK1 b - -
+GI.06
+r1bq1rk1/pp2ppbp/2np1np1/8/2BNP3/2N1BP2/PPPQ2PP/R3K2R b KQ -
+SI.18
+r1bq1rk1/pp2ppbp/3p1np1/n1pP4/2P5/2N2NP1/PP2PPBP/R1BQ1RK1 w - -
+KI.67
+r1bq1rk1/pp2ppbp/5np1/3p4/2PP4/2N5/PP2BPPP/R1BQ1RK1 b - -
+TD.01*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 w - -
+KI.62*
+r1bq1rk1/pp3pb1/2n2npp/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQR1K1 b - -
+KI.61*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/2PP1NP1/PP1N1PBP/R1BQ1RK1 b - -
+KI.63*
+r1bq1rk1/pp3pbp/2n2np1/2ppp3/4P3/3P1NP1/PPPN1PBP/R1BQ1RK1 w - -
+KI.64*
+r1bq1rk1/pp3pbp/2n2np1/3pp3/2PN4/2N1P3/PP2BPPP/R1BQ1RK1 w - -
+TD.02*
+r1bq1rk1/pp3ppp/2n1pn2/1Bbp4/2P5/4PN2/PP1N1PPP/R1BQ1RK1 b - -
+NI.03*
+r1bq1rk1/pp3ppp/2n1pn2/2pp4/1bPP4/P1NBPN2/1P3PPP/R1BQ1RK1 b - -
+NI.02
+r1bq1rk1/pp3ppp/2n2n2/1Bbp4/8/1P2PN2/P4PPP/RNBQ1RK1 b - -
+NI.04*
+r1bq1rk1/pp3ppp/2nbpn2/1Bpp4/2PP4/4PN2/PP3PPP/RNBQ1RK1 w - -