From 6ed17677ed3ddd502bfb22335eb474a06dd4767e Mon Sep 17 00:00:00 2001 From: dykstrom Date: Sat, 8 Dec 2018 16:26:56 +0100 Subject: [PATCH 1/2] Ported to Java 11. --- .travis.yml | 3 +- README.md | 11 +- pom.xml | 34 +- .../dykstrom/ronja/common/book/BookMove.java | 17 +- .../ronja/common/book/OpeningBookParser.java | 152 +- .../dykstrom/ronja/common/model/Square.java | 1 - .../ronja/common/parser/PgnParser.java | 14 +- .../ronja/common/parser/SanParser.java | 14 +- .../ronja/engine/utils/AppConfig.java | 2 +- src/main/scripts/book.csv | 1354 +++++++++++++++++ src/main/scripts/history.html | 6 + src/main/scripts/ronja.properties | 2 +- .../common/book/OpeningBookConversionIT.java | 188 +++ .../common/book/OpeningBookParserIT.java | 127 +- .../common/book/OpeningBookParserTest.java | 115 ++ .../ronja/common/book/XmlBookMove.java | 0 .../ronja/common/parser/PgnParserTest.java | 19 +- .../ronja/common/utils/ArrayUtilsTest.java | 4 +- .../engine/core/FullMoveGeneratorTest.java | 1 - .../ronja/engine/core/SlowFinderTest.java | 2 +- .../ronja/engine/ui/CommandParserTest.java | 17 +- .../se/dykstrom/ronja/engine/ui/RonjaIT.java | 149 ++ .../ronja/engine/ui/XBoardProtocolIT.java | 24 +- .../ronja/engine/utils/AppConfigTest.java | 3 +- .../se/dykstrom/ronja/test/TestUtils.java | 29 +- 25 files changed, 2026 insertions(+), 262 deletions(-) create mode 100644 src/main/scripts/book.csv create mode 100644 src/test/java/se/dykstrom/ronja/common/book/OpeningBookConversionIT.java create mode 100644 src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserTest.java rename src/{main => test}/java/se/dykstrom/ronja/common/book/XmlBookMove.java (100%) create mode 100644 src/test/java/se/dykstrom/ronja/engine/ui/RonjaIT.java diff --git a/.travis.yml b/.travis.yml index dc62a1d..94d2a22 100644 --- a/.travis.yml +++ b/.travis.yml @@ -1,4 +1,3 @@ language: java jdk: - - oraclejdk8 -script: "mvn verify" + - openjdk11 diff --git a/README.md b/README.md index 1491825..bc7b639 100644 --- a/README.md +++ b/README.md @@ -7,9 +7,14 @@ An XBoard/WinBoard chess engine written in Java. Ronja is a chess engine. It provides only a simple, character based user interface. It is highly recommended that you run it from a chess GUI like [XBoard/WinBoard](https://www.gnu.org/software/xboard) or -[Arena](http://www.playwitharena.com). You will also need -Java 8 installed to run Ronja. The Java runtime can be downloaded -from [Oracle](https://java.com/download). +[Arena](http://www.playwitharena.com). You will also need a Java runtime +installed to run Ronja. + +Ronja version 0.7.0 and earlier requires Java 8; download it +[here](https://java.com/download). + +Ronja version 0.8.0 and later requires Java 11; download it +[here](https://jdk.java.net/11). ## Installation diff --git a/pom.xml b/pom.xml index 2700a78..37deee5 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ se.dykstrom.ronja ronja - 0.7.1-SNAPSHOT + 0.8.0-SNAPSHOT UTF-8 @@ -21,16 +21,16 @@ org.apache.maven.plugins maven-compiler-plugin - 3.7.0 + 3.8.0 - 1.8 - 1.8 + 11 + 11 org.apache.maven.plugins maven-jar-plugin - 3.0.2 + 3.1.0 @@ -43,7 +43,7 @@ org.apache.maven.plugins maven-surefire-plugin - 2.20.1 + 2.22.1 -Djava.util.logging.config.class=se.dykstrom.ronja.test.LoggingConfig @@ -51,7 +51,7 @@ org.apache.maven.plugins maven-failsafe-plugin - 2.20.1 + 2.22.0 -Djava.util.logging.config.class=se.dykstrom.ronja.test.LoggingConfig @@ -109,6 +109,24 @@ + + javax.xml.bind + jaxb-api + 2.3.1 + test + + + com.sun.xml.bind + jaxb-core + 2.3.0.1 + test + + + com.sun.xml.bind + jaxb-impl + 2.3.0.1 + test + junit junit @@ -124,7 +142,7 @@ org.apache.commons commons-lang3 - 3.7 + 3.8.1 test diff --git a/src/main/java/se/dykstrom/ronja/common/book/BookMove.java b/src/main/java/se/dykstrom/ronja/common/book/BookMove.java index b4a3487..276b312 100644 --- a/src/main/java/se/dykstrom/ronja/common/book/BookMove.java +++ b/src/main/java/se/dykstrom/ronja/common/book/BookMove.java @@ -17,6 +17,8 @@ package se.dykstrom.ronja.common.book; +import java.util.Objects; + /** * Represents an opening book move with the actual move, and its weight in the opening book. * @@ -34,7 +36,7 @@ public BookMove(int move, int weight) { @Override public String toString() { - return Integer.toString(move); + return move + "/" + weight; } public int getMove() { @@ -54,4 +56,17 @@ public int getWeight() { public BookMove withWeight(int weight) { return new BookMove(move, weight); } + + @Override + public boolean equals(Object o) { + if (this == o) return true; + if (o == null || getClass() != o.getClass()) return false; + BookMove that = (BookMove) o; + return this.move == that.move && this.weight == that.weight; + } + + @Override + public int hashCode() { + return Objects.hash(move, weight); + } } diff --git a/src/main/java/se/dykstrom/ronja/common/book/OpeningBookParser.java b/src/main/java/se/dykstrom/ronja/common/book/OpeningBookParser.java index b0e5633..1459d77 100644 --- a/src/main/java/se/dykstrom/ronja/common/book/OpeningBookParser.java +++ b/src/main/java/se/dykstrom/ronja/common/book/OpeningBookParser.java @@ -17,42 +17,26 @@ package se.dykstrom.ronja.common.book; -import static java.util.stream.Collectors.toSet; +import se.dykstrom.ronja.common.model.Position; +import se.dykstrom.ronja.common.parser.IllegalMoveException; +import se.dykstrom.ronja.common.parser.MoveParser; import java.io.File; import java.io.IOException; +import java.nio.file.Files; import java.text.ParseException; import java.util.*; import java.util.logging.Logger; -import javax.xml.bind.JAXBContext; -import javax.xml.bind.JAXBException; -import javax.xml.bind.Unmarshaller; - -import se.dykstrom.ronja.common.model.Position; -import se.dykstrom.ronja.common.parser.IllegalMoveException; -import se.dykstrom.ronja.common.parser.MoveParser; +import static java.util.Arrays.asList; +import static java.util.stream.Collectors.toList; +import static java.util.stream.Collectors.toSet; /** - * A class for parsing the Ronja opening book file. The opening book file should - * be an XML file containing a tree of 'move' elements that represent the moves - * in the different opening lines. The moves are specified in coordinate - * algebraic notation, and are associated with a weight. A move with weight 0 - * will never be played, but it can still have sub moves in the opening line - * tree. This is an example of an opening book file: - * - * - * - * - * - * - * - * - * - * - * - * - * + * A class for parsing the Ronja opening book file. The opening book file is a CSV file + * containing one line for each opening line. Each line contains three fields separated + * by semicolons: a number of moves leading to a position, a book move and its weight, + * and a comment describing the position after the book move. * * @author Johan Dykstrom */ @@ -60,40 +44,28 @@ public class OpeningBookParser { private static final Logger TLOG = Logger.getLogger(OpeningBookParser.class.getName()); - /** Positions and corresponding moves. */ - private static Map> positions; - - // ------------------------------------------------------------------------ - /** * Loads the opening book file. * * @param file The opening book file. * @return The opening book. - * @throws ParseException If the opening book file cannot be loaded. + * @throws IOException If the opening book file cannot be read. * @throws ParseException If the opening book file cannot be parsed. */ public static OpeningBook parse(File file) throws IOException, ParseException { - positions = new HashMap<>(); + Map> positions; long start = System.currentTimeMillis(); try { - JAXBContext context = JAXBContext.newInstance(XmlBookMove.class); - Unmarshaller unmarshaller = context.createUnmarshaller(); - XmlBookMove topMove = (XmlBookMove) unmarshaller.unmarshal(file); - for (XmlBookMove move : topMove.getSubMoves()) { - parseMove(new LinkedList<>(), move); - } - } catch (JAXBException e) { - TLOG.severe("Failed to load file '" + file.getName() + "': " + e); - if (e.getLinkedException() instanceof IOException) { - throw (IOException) e.getLinkedException(); - } else { - throw new ParseException("Failed to load file '" + file.getName() + "'", 0); - } - } catch (NumberFormatException e) { - TLOG.severe("Failed to load file '" + file.getName() + "': " + e); - throw new ParseException("Failed to load file '" + file.getName() + "'", 0); + // Read all lines and remove empty lines and comments + List lines = Files.lines(file.toPath()) + .map(String::trim) + .filter(line -> !line.isEmpty() && !line.startsWith("#")) + .collect(toList()); + positions = parseLines(lines); + } catch (IOException e) { + TLOG.severe("Failed to open file '" + file.getName() + "': " + e); + throw e; } long stop = System.currentTimeMillis(); TLOG.info("Loaded opening book in " + (stop - start) + " ms"); @@ -106,51 +78,51 @@ public static OpeningBook parse(File file) throws IOException, ParseException { } /** - * Parses a move, adds it to the opening book as a possible move in the - * current position, and parses all sub moves recursively. If the given - * move is invalid, this move and all of its sub moves are ignored, but - * the rest of the opening book is still read. + * Parses all non-empty lines that were read from the opening book file. * - * @param moves The list of moves made so far in this opening line. - * @param xmlMove An XML move read from the opening book file. + * @param lines The opening lines to parse. + * @return A map of positions and book moves. */ - private static void parseMove(LinkedList moves, XmlBookMove xmlMove) { - // Get attribute values - String move = xmlMove.getCan(); - int weight = xmlMove.getWeight(); - - // Add this move to the opening book - try { - add(moves, move, weight); - } catch (IllegalMoveException ime) { - TLOG.warning("Illegal move [" + move + ", " + weight + "] in opening line " + moves + ": " + ime); - return; - } + static Map> parseLines(List lines) throws ParseException { + Map> positions = new HashMap<>(); - // If we could add this move OK, continue to parse each sub move recursively - moves.addLast(move); - for (XmlBookMove subMove : xmlMove.getSubMoves()) { - parseMove(moves, subMove); - } - moves.removeLast(); - } + for (String line : lines) { + String[] fields = line.split(";", -1); + if (fields.length != 3) { + throw new ParseException("Syntax error on line '" + line + "'", 0); + } - /** - * Adds the supplied move as a possible move in the current position. - * - * @param moves The list of moves made so far in this opening line. - * @param move The move to add, in coordinate algebraic notation. - * @param weight The weight of the move in this position. - * @throws IllegalMoveException If any of the moves in the move list, or the new move, is illegal. - */ - private static void add(List moves, String move, int weight) throws IllegalMoveException { - // Set up a new position - Position position = Position.of(moves); + String[] moves = fields[0].trim().split(" "); + String bookMove = fields[1].trim(); + // Ignore the comment field + + // Create book position from available moves + Position position; + try { + if (moves.length == 1 && moves[0].isBlank()) { + position = Position.START; + } else { + position = Position.of(asList(moves)); + } + } catch (IllegalMoveException e) { + TLOG.warning("Illegal move in opening line " + Arrays.toString(moves) + ": " + e); + continue; + } - // Get the list of possible moves for this position - List list = positions.computeIfAbsent(position, key -> new ArrayList<>()); + // Get/create the list of possible moves for this position + List list = positions.computeIfAbsent(position, key -> new ArrayList<>()); + + // Create book move and add to list + try { + String[] moveAndWeight = bookMove.split(("/")); + list.add(new BookMove(MoveParser.parse(moveAndWeight[0], position), Integer.parseInt(moveAndWeight[1]))); + } catch (IllegalMoveException e) { + TLOG.warning("Illegal move in opening line " + Arrays.toString(moves) + ": " + bookMove); + } catch (NumberFormatException e) { + TLOG.warning("Illegal weight in opening line " + Arrays.toString(moves) + ": " + bookMove); + } + } - // Create the new move and add it to the list - list.add(new BookMove(MoveParser.parse(move, position), weight)); + return positions; } } diff --git a/src/main/java/se/dykstrom/ronja/common/model/Square.java b/src/main/java/se/dykstrom/ronja/common/model/Square.java index b2ce87a..ea58fae 100644 --- a/src/main/java/se/dykstrom/ronja/common/model/Square.java +++ b/src/main/java/se/dykstrom/ronja/common/model/Square.java @@ -95,7 +95,6 @@ public class Square { public static final long E8 = 1L << 60L; public static final long F8 = 1L << 61L; public static final long G8 = 1L << 62L; - @SuppressWarnings("NumericOverflow") public static final long H8 = 1L << 63L; private static final String SQUARES = diff --git a/src/main/java/se/dykstrom/ronja/common/parser/PgnParser.java b/src/main/java/se/dykstrom/ronja/common/parser/PgnParser.java index 5fad2f1..c14add1 100644 --- a/src/main/java/se/dykstrom/ronja/common/parser/PgnParser.java +++ b/src/main/java/se/dykstrom/ronja/common/parser/PgnParser.java @@ -17,7 +17,10 @@ package se.dykstrom.ronja.common.parser; -import static se.dykstrom.ronja.common.utils.ArrayUtils.toArray; +import se.dykstrom.ronja.common.model.Color; +import se.dykstrom.ronja.common.model.Game; +import se.dykstrom.ronja.common.model.Position; +import se.dykstrom.ronja.engine.utils.AppConfig; import java.net.InetAddress; import java.net.UnknownHostException; @@ -26,10 +29,7 @@ import java.util.regex.Matcher; import java.util.regex.Pattern; -import se.dykstrom.ronja.common.model.Color; -import se.dykstrom.ronja.common.model.Game; -import se.dykstrom.ronja.common.model.Position; -import se.dykstrom.ronja.engine.utils.AppConfig; +import static se.dykstrom.ronja.common.utils.ArrayUtils.toArray; /** * A class that can parse and format files specified in Portable Game Notation (PGN). @@ -38,8 +38,8 @@ */ public final class PgnParser { - private static final DateTimeFormatter DF = DateTimeFormatter.ofPattern("yyyy-MM-dd"); - private static final DateTimeFormatter TF = DateTimeFormatter.ofPattern("HH:mm:ss"); + private static final DateTimeFormatter DF = DateTimeFormatter.ISO_LOCAL_DATE; + private static final DateTimeFormatter TF = DateTimeFormatter.ofPattern("HH:mm"); private static final String BACKSLASH_REPLACEMENT = Matcher.quoteReplacement("\\\\"); private static final String QUOTE_REPLACEMENT = Matcher.quoteReplacement("\\\""); diff --git a/src/main/java/se/dykstrom/ronja/common/parser/SanParser.java b/src/main/java/se/dykstrom/ronja/common/parser/SanParser.java index 43b16db..87addc0 100644 --- a/src/main/java/se/dykstrom/ronja/common/parser/SanParser.java +++ b/src/main/java/se/dykstrom/ronja/common/parser/SanParser.java @@ -232,8 +232,8 @@ private static String formatCastlingMove(int move) { } private static String formatPawnMove(int move, Position position) { - String fromFile = formatFromFile(move, position); - String capture = formatCapture(move, position); + String fromFile = formatFromFile(move); + String capture = formatCapture(move); String toSquare = formatToSquare(move); String promotion = formatPromotion(move); String check = formatCheck(move, position); @@ -243,7 +243,7 @@ private static String formatPawnMove(int move, Position position) { private static String formatPieceMove(int move, Position position) { String piece = Character.toString(Piece.toSymbol(Move.getPiece(move))); String fromFileOrRank = fileOrRank(move, position); - String capture = formatCapture(move, position); + String capture = formatCapture(move); String toSquare = formatToSquare(move); String check = formatCheck(move, position); return piece + fromFileOrRank + capture + toSquare + check; @@ -266,7 +266,7 @@ private static String fileOrRank(int move, Position position) { } else if (isRankUnique(fromSquare, allFromSquares)) { return Integer.toString(getRank(fromSquare)); } else { - return Character.toString(getFileChar(fromSquare)) + Integer.toString(getRank(fromSquare)); + return Character.toString(getFileChar(fromSquare)) + getRank(fromSquare); } } else { return ""; @@ -320,11 +320,11 @@ static boolean isRankUnique(Long fromSquare, Set allFromSquares) { * Formats the from file for a pawn move. Returns the from file for capture moves, * or an empty string for normal moves. */ - private static String formatFromFile(int move, Position position) { + private static String formatFromFile(int move) { return Move.isCapture(move) ? Character.toString(getFileChar(Move.getFrom(move))) : ""; } - private static String formatCapture(int move, Position position) { + private static String formatCapture(int move) { return Move.isCapture(move) ? "x" : ""; } @@ -334,7 +334,7 @@ private static String formatToSquare(int move) { private static String formatPromotion(int move) { if (Move.isPromotion(move)) { - return "=" + Character.toString(Piece.toSymbol(Move.getPromoted(move))); + return "=" + Piece.toSymbol(Move.getPromoted(move)); } else { return ""; } diff --git a/src/main/java/se/dykstrom/ronja/engine/utils/AppConfig.java b/src/main/java/se/dykstrom/ronja/engine/utils/AppConfig.java index c1f8f0e..82c7398 100644 --- a/src/main/java/se/dykstrom/ronja/engine/utils/AppConfig.java +++ b/src/main/java/se/dykstrom/ronja/engine/utils/AppConfig.java @@ -93,7 +93,7 @@ public static String getBookFilename() { bookFilename = getStringProperty(PROPERTY_BOOK_FILE); } if (bookFilename == null) { - bookFilename = getString(PROPERTY_BOOK_FILE, "book.xml"); + bookFilename = getString(PROPERTY_BOOK_FILE, "book.csv"); } return bookFilename; } diff --git a/src/main/scripts/book.csv b/src/main/scripts/book.csv new file mode 100644 index 0000000..19816b0 --- /dev/null +++ b/src/main/scripts/book.csv @@ -0,0 +1,1354 @@ +# Copyright (C) 2018 Johan Dykstrom + +# 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 3 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, see . + +;a2a3/0;A00 Anderssen Opening +a2a3;e7e5/100; + +;a2a4/0;A00 Ware Opening +a2a4;e7e5/100; + +;b1a3/0;A00 Durkin's Attack +b1a3;e7e5/100; + +;b1c3/0;A00 Dunst Opening +b1c3;d7d5/100; + +;b2b3/0;A01 Nimzovich-Larsen Attack +b2b3;e7e5/100; + +;b2b4/0;A00 Sokolsky Opening +b2b4;e7e5/100; + +;c2c3/0;A00 Saragossa Opening +c2c3;d7d5/100; + +;c2c4/0;A10 English Opening +c2c4;g8f6/100;A15 English Opening, Anglo-Indian Defence +c2c4 g8f6;b1c3/100; +c2c4 g8f6 b1c3;g7g6/100; +c2c4 g8f6 b1c3;e7e6/100; +c2c4;e7e5/100;A20 English Opening +c2c4 e7e5;b1c3/100; +c2c4 e7e5 b1c3;g8f6/100; +c2c4 e7e5 b1c3;b8c6/100; + +;d2d3/0;A00 Mieses Opening +d2d3;d7d5/100; + +;d2d4/50;A40 Queen's Pawn Opening +d2d4;d7d5/100;D00 Queen's Pawn Game +d2d4 d7d5;c2c4/100;D06 Queen's Gambit +d2d4 d7d5 c2c4;e7e6/100;D30 Queen's Gambit Declined +d2d4 d7d5 c2c4 e7e6;g1f3/100; +d2d4 d7d5 c2c4 e7e6 g1f3;g8f6/100; +d2d4 d7d5 c2c4 e7e6 g1f3 g8f6;b1c3/100; +d2d4 d7d5 c2c4 e7e6;b1c3/100; +d2d4 d7d5 c2c4 e7e6 b1c3;g8f6/100; +d2d4 d7d5 c2c4 e7e6 b1c3 g8f6;c1g5/100; +d2d4 d7d5 c2c4 e7e6 b1c3;c7c6/100; +d2d4 d7d5 c2c4 e7e6 b1c3 c7c6;g1f3/100; +d2d4 d7d5 c2c4;c7c6/100;D10 Queen's Gambit Declined, Slav Defence +d2d4 d7d5 c2c4 c7c6;g1f3/100; +d2d4 d7d5 c2c4 c7c6 g1f3;g8f6/100; +d2d4 d7d5 c2c4 c7c6 g1f3 g8f6;b1c3/100; +d2d4 d7d5 c2c4 c7c6;b1c3/50; +d2d4 d7d5 c2c4 c7c6 b1c3;g8f6/100; +d2d4 d7d5 c2c4 c7c6 b1c3 g8f6;g1f3/100; +d2d4 d7d5 c2c4 c7c6 b1c3 g8f6;e2e3/100; +d2d4 d7d5 c2c4;d5c4/50;D20 Queen's Gambit Accepted +d2d4 d7d5 c2c4 d5c4;g1f3/100; +d2d4 d7d5 c2c4 d5c4 g1f3;g8f6/100; +d2d4 d7d5 c2c4 d5c4 g1f3 g8f6;e2e3/100; +d2d4 d7d5 c2c4 d5c4 g1f3 g8f6 e2e3;e7e6/100; +d2d4 d7d5 c2c4 d5c4 g1f3 g8f6 e2e3 e7e6;f1c4/100; +d2d4 d7d5;g1f3/100; +d2d4 d7d5 g1f3;g8f6/100; +d2d4 d7d5 g1f3 g8f6;c2c4/100; +d2d4;g8f6/100;A45 Queen's Pawn Game +d2d4 g8f6;c2c4/100; +d2d4 g8f6 c2c4;e7e6/150; +d2d4 g8f6 c2c4 e7e6;b1c3/100; +d2d4 g8f6 c2c4 e7e6 b1c3;f8b4/100;E20 Nimzo-Indian Defence +d2d4 g8f6 c2c4 e7e6 b1c3 f8b4;e2e3/100; +d2d4 g8f6 c2c4 e7e6 b1c3 f8b4;d1c2/100;E32 Nimzo-Indian, Classical Variation +d2d4 g8f6 c2c4 e7e6;g1f3/100; +d2d4 g8f6 c2c4 e7e6 g1f3;b7b6/42;E12 Queen's Indian Defence +d2d4 g8f6 c2c4 e7e6 g1f3 b7b6;g2g3/100;E15 Queen's Indian, 4.g3 +d2d4 g8f6 c2c4 e7e6 g1f3 b7b6 g2g3;c8a6/100; +d2d4 g8f6 c2c4 e7e6 g1f3 b7b6 g2g3 c8a6;b2b3/100; +d2d4 g8f6 c2c4 e7e6 g1f3 b7b6 g2g3;c8b7/100; +d2d4 g8f6 c2c4 e7e6 g1f3 b7b6 g2g3 c8b7;f1g2/100; +d2d4 g8f6 c2c4 e7e6 g1f3;d7d5/23; +d2d4 g8f6 c2c4 e7e6 g1f3 d7d5;b1c3/100; +d2d4 g8f6 c2c4 e7e6 g1f3;f8b4/18;E11 Bogo-Indian Defence +d2d4 g8f6 c2c4 e7e6 g1f3 f8b4;c1d2/100; +d2d4 g8f6 c2c4 e7e6 g1f3;c7c5/11; +d2d4 g8f6 c2c4 e7e6 g1f3 c7c5;d4d5/100; +d2d4 g8f6 c2c4;g7g6/150;E60 King's Indian Defence +d2d4 g8f6 c2c4 g7g6;b1c3/100; +d2d4 g8f6 c2c4 g7g6 b1c3;f8g7/88; +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7;e2e4/100;E70 King's Indian, 4.e4 +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4;d7d6/100; +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6;g1f3/100; +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 g1f3;e8g8/100; +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6;f2f3/100;E80 King's Indian, Saemisch Variation +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 f2f3;e8g8/100; +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6;g1f3/100; +d2d4 g8f6 c2c4 g7g6 b1c3 f8g7 e2e4 d7d6 g1f3;e8g8/100; +d2d4 g8f6 c2c4 g7g6 b1c3;d7d5/37;D80 Gruenfeld Defence +d2d4 g8f6 c2c4 g7g6 b1c3 d7d5;c4d5/100; +d2d4 g8f6 c2c4 g7g6 b1c3 d7d5 c4d5;f6d5/100;D85 Gruenfeld, Exchange Variation +d2d4 g8f6 c2c4 g7g6 b1c3 d7d5 c4d5 f6d5;e2e4/100; +d2d4 g8f6 c2c4 g7g6 b1c3 d7d5;g1f3/100;D90 Gruenfeld, Three Knights Variation +d2d4 g8f6 c2c4;c7c5/50;A56 Benoni Defence +d2d4 g8f6 c2c4 c7c5;d4d5/100; +d2d4 g8f6;g1f3/100; +d2d4 g8f6 g1f3;g7g6/100;A48 King's Indian, East Indian Defence +d2d4 g8f6 g1f3 g7g6;c2c4/100;E60 King's Indian, 3.Nf3 +d2d4 g8f6 g1f3 g7g6 c2c4;f8g7/100; +d2d4 g8f6 g1f3 g7g6 c2c4 f8g7;b1c3/100; +d2d4 g8f6 g1f3 g7g6 c2c4 f8g7;g2g3/100; +d2d4 g8f6 g1f3;e7e6/100; +d2d4 g8f6 g1f3 e7e6;c2c4/100; +d2d4 g8f6 g1f3 e7e6 c2c4;b7b6/100;E12 Queen's Indian Defence +d2d4;e7e6/50;A40 Queen's Pawn Game +d2d4 e7e6;c2c4/100; +d2d4 e7e6;g1f3/100; +d2d4 e7e6;e2e4/100;C00 French Defence +d2d4 e7e6 e2e4;d7d5/100; +d2d4;f7f5/10;A80 Dutch +d2d4 f7f5;g2g3/110; +d2d4 f7f5 g2g3;g8f6/100; +d2d4 f7f5 g2g3 g8f6;f1g2/100; +d2d4 f7f5;c2c4/80; +d2d4 f7f5 c2c4;g8f6/100; +d2d4 f7f5 c2c4 g8f6;b1c3/100; +d2d4 f7f5;g1f3/60; +d2d4 f7f5 g1f3;g8f6/100; +d2d4 f7f5 g1f3 g8f6;g2g3/100; +d2d4;g7g6/0;A40 Modern Defence +d2d4 g7g6;c2c4/100; +d2d4 g7g6 c2c4;f8g7/100; +d2d4 g7g6 c2c4 f8g7;b1c3/100; +d2d4 g7g6 c2c4 f8g7 b1c3;d7d6/100; +d2d4 g7g6 c2c4 f8g7 b1c3 d7d6;e2e4/100; +d2d4;d7d6/0;A41 Queen's Pawn Game +d2d4 d7d6;g1f3/100; +d2d4 d7d6;c2c4/100;A41 Old Indian Defence +d2d4 d7d6 c2c4;e7e5/100; +d2d4 d7d6 c2c4 e7e5;g1f3/100; +d2d4 d7d6 c2c4 e7e5;d4e5/50; +d2d4 d7d6;e2e4/100; +d2d4 d7d6 e2e4;g8f6/100; +d2d4 d7d6 e2e4 g8f6;b1c3/100;B07 Pirc Defence +d2d4 d7d6 e2e4;g7g6/100; +d2d4 d7d6 e2e4 g7g6;b1c3/100; +d2d4;c7c5/0;A43 Old Benoni Defence +d2d4 c7c5;d4d5/100; + +;e2e3/0;A00 Van't Kruijs Opening +e2e3;e7e5/100; +e2e3 e7e5;d2d4/100; +e2e3 e7e5 d2d4;e5d4/100; +e2e3 e7e5;c2c4/100; +e2e3 e7e5 c2c4;g8f6/100; +e2e3;d7d5/100; +e2e3 d7d5;b2b3/100; +e2e3 d7d5 b2b3;g8f6/100; +e2e3 d7d5;c2c4/100; +e2e3 d7d5 c2c4;g8f6/100; + +;e2e4/100;B00 King's Pawn Opening +e2e4;e7e5/100;C20 King's Pawn Game +e2e4 e7e5;g1f3/100;C40 King's Knight Opening +e2e4 e7e5 g1f3;b8c6/100;Queen's Knight Variation +e2e4 e7e5 g1f3 b8c6;f1b5/100;C60 Ruy Lopez +e2e4 e7e5 g1f3 b8c6 f1b5;a7a6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6;b5a4/100;C70 Ruy Lopez +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4;g8f6/100;C77 Ruy Lopez, Morphy Defence +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6;e1g1/100;C78 Ruy Lopez, 5.O-O +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1;f8e7/40;C84 Ruy Lopez, Closed Defence +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7;f1e1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1;b7b5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5;a4b3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f8e7 f1e1 b7b5 a4b3 d7d6 c2c3 e8g8;h2h3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1;b7b5/10; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 b7b5;a4b3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1;f6e4/7;C80 Ruy Lopez, Open Defence +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4 d2d4;b7b5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 e1g1 f6e4 d2d4 b7b5;a4b3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6;d2d3/0;C77 Ruy Lopez, Anderssen Variation +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d2d3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d2d3 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d2d3;b7b5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 g8f6 d2d3 b7b5;a4b3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4;d7d6/0;C71 Ruy Lopez, Modern Steinitz Defence +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 c2c3;c8d7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 c2c3 c8d7;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 c2c3 c8d7;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 e1g1;c8d7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 e1g1 c8d7;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6;a4c6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 a4c6;b7c6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 d7d6 a4c6 b7c6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4;b7b5/0;C70 Ruy Lopez, Caro Variation +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 b7b5;a4b3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 b7b5 a4b3;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 b7b5 a4b3 g8f6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 b7b5 a4b3;c6a5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5a4 b7b5 a4b3 c6a5;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6;b5c6/100;C68 Ruy Lopez, Exchange Variation +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6;d7c6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1;f7f6/100;C69 Ruy Lopez, Exchange, Gligoric Variation +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 e5d4;f3d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 e5d4 f3d4;c6c5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 e5d4 f3d4 c6c5;d4b3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4;c8g4/50; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4;d4e5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 d4e5;d8d1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 d4e5 d8d1;f1d1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 d4e5 d8d1 f1d1;f6e5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 c2c3;f8d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 c2c3 f8d6;c1e3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 c2c3 f8d6 c1e3;g8e7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f7f6 d2d4 c8g4 c2c3 f8d6 c1e3;d8e7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1;c8g4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 c8g4;h2h3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1;d8d6/50; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 d8d6;b1a3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 d8d6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1;f8d6/50; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 e1g1 f8d6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6;b1c3/30;C68 Ruy Lopez, Exchange, Keres Variation +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 b1c3;f7f6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 b1c3 f7f6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 b1c3;f8d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 b1c3 f8d6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6;d2d4/30; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 d2d4 e5d4;d1d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 d2d4 e5d4 d1d4;d8d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 a7a6 b5c6 d7c6 d2d4 e5d4 d1d4 d8d4;f3d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5;g8f6/15;C65 Ruy Lopez, Berlin Defence +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6;e1g1/100;C65 Ruy Lopez, Berlin Defence, 4.O-O +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1;f6e4/100;C67 Ruy Lopez, Berlin Defence, Open Variation +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4 d2d4;e4d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4 d2d4 e4d6;b5c6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4;f1e1/20; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4 f1e1;e4d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 e1g1 f6e4 f1e1 e4d6;f3e5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6;d2d3/30; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6 c2c3;g7g6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6 c2c3;f8e7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6 c2c3;c8d7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6 e1g1;g7g6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6 e1g1;f8e7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 d7d6 e1g1;c8d7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3;f8c5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 f8c5;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 f8c5 c2c3;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 f8c5;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 f8c5 e1g1;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 f8c5;b5c6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 g8f6 d2d3 f8c5 b5c6;d7c6/100; +e2e4 e7e5 g1f3 b8c6 f1b5;f7f5/5;C63 Ruy Lopez, Schliemann Defence +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5;b1c3/100;C63 Ruy Lopez, Schliemann Defence, Berger Variation +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3;f5e4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4;c3e4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4 c3e4;d7d5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4 c3e4 d7d5;f3e5/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4 c3e4;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4 c3e4 g8f6;d1e2/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 b1c3 f5e4 c3e4 g8f6;e4f6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5;d2d3/50; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 d2d3;f5e4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 d2d3 f5e4;d3e4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 d2d3 f5e4 d3e4;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f7f5 d2d3 f5e4 d3e4 g8f6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5;d7d6/0;C62 Ruy Lopez, Old Steinitz Defence +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 d2d4;c8d7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 d2d4 c8d7;b1c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 d2d4 c8d7;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 d2d4 e5d4;f3d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 e1g1;c8d7/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 e1g1 c8d7;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 e1g1;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 e1g1 g8f6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 d7d6 e1g1 g8f6;f1e1/100; +e2e4 e7e5 g1f3 b8c6 f1b5;f8c5/0;C64 Ruy Lopez, Classical Defence +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 e1g1;c6d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 e1g1 c6d4;f3d4/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 e1g1;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 e1g1 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 e1g1;g8f6/100;C65 Ruy Lopez, Berlin Defence, Beverwijk Variation +e2e4 e7e5 g1f3 b8c6 f1b5 f8c5 e1g1 g8f6;c2c3/100; +e2e4 e7e5 g1f3 b8c6;f1c4/100;C50 Italian Game +e2e4 e7e5 g1f3 b8c6 f1c4;f8c5/100;C50 Giuoco Piano +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d4 e5d4;c3d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d4 e5d4;e4e5/50; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6;d2d3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d3 d7d6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d3;a7a6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 g8f6 d2d3 a7a6;c4b3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3;d7d6/10; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 d7d6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 d7d6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 d7d6 d2d4 e5d4;c3d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3;d8e7/10;C53 Giuoco Piano, Close Variation +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 d8e7;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 d8e7 e1g1;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 c2c3 d8e7 e1g1 d7d6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5;d2d3/50;C50 Giuoco Pianissimo +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3 d7d6;c4b3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3 d7d6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3;a7a6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3 a7a6;c4b3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3 a7a6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c2c3 e8g8;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3 d7d6;c1g5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3;h7h6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3 h7h6;c1e3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3 h7h6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 b1c3 e8g8;c1g5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 e1g1;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 e1g1 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 e1g1;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 e1g1 e8g8;c1g5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6;c1g5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c1g5;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c1g5 d7d6;h2h3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c1g5 d7d6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c1g5;h7h6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 g8f6 c1g5 h7h6;g5h4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 d7d6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 d7d6 b1c3;c8g4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 d2d3 d7d6 b1c3 c8g4;h2h3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5;e1g1/50; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6;d2d3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d3 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d3;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d3 e8g8;c1g5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6;b1c3/50; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 b1c3;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 b1c3 e8g8;d2d3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 b1c3;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 b1c3 d7d6;d2d3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 b1c3 d7d6;h2h3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6;d2d4/50; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d4;c5d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d4 c5d4;f3d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8c5 e1g1 g8f6 d2d4 e5d4;e4e5/100; +e2e4 e7e5 g1f3 b8c6 f1c4;g8f6/100;C55 Two Knights Defence +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6;d2d3/100;C55 Two Knights Defence (Modern Bishop's Opening) +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3;f8e7/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 f8e7;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 f8e7 e1g1;e8g8/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 f8e7 e1g1 e8g8;f1e1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3;f8c5/100;C50 Giuoco Pianissimo +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3;h7h6/50; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 h7h6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 h7h6 e1g1;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d3 h7h6 e1g1 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6;f3g5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5;d7d5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5 d7d5;e4d5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5 d7d5 e4d5;c6a5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5 d7d5 e4d5 c6a5;c4b5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5 d7d5 e4d5;f6d5/50; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 f3g5 d7d5 e4d5 f6d5;g5f7/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6;b1c3/100;C46 Four Knights, Italian Variation +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3;f8c5/100;C50 Giuoco Piano, Four Knights Variation +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3;f6e4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4;c3e4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4 c3e4;d7d5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4 c3e4 d7d5;c4d5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4 c3e4 d7d5;c4d3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4;c4f7/50; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4 c4f7;e8f7/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 b1c3 f6e4 c4f7 e8f7;c3e4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d4 e5d4;e4e5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 g8f6 d2d4 e5d4;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4;f8e7/0;C50 Hungarian Defence +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7;d2d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 d2d4;d7d6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 d2d4 d7d6;d4e5/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 d2d4;e5d4/100;C44 Scotch Gambit, Benima Defence +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 d2d4 e5d4;f3d4/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 d2d4 e5d4;c2c3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7;e1g1/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 e1g1;g8f6/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 e1g1 g8f6;d2d3/100; +e2e4 e7e5 g1f3 b8c6 f1c4 f8e7 e1g1 g8f6;b1c3/100; +e2e4 e7e5 g1f3 b8c6;d2d4/30;C44 Scotch Opening +e2e4 e7e5 g1f3 b8c6 d2d4;e5d4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4;f3d4/100;C45 Scotch game +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4;f8c5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5;c1e3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 c1e3;d8f6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 c1e3 d8f6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5;d4c6/50; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 d4c6;d8f6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 d4c6 d8f6;d1d2/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 d4c6;b7c6/25; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 d4c6 b7c6;f1d3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5;d4b3/50;C45 Scotch, Potter Variation +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 d4b3;c5b6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 f8c5 d4b3 c5b6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4;g8f6/100;C45 Scotch, Schmidt Variation +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6;d4c6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6 d4c6;b7c6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6 d4c6 b7c6;e4e5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6 b1c3;f8b4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 g8f6 b1c3 f8b4;d4c6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4;c6d4/50; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4;d1d4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4;d7d6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4 d7d6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4 d7d6;f1c4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4;g8f6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4 g8f6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4 g8f6;e4e5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f3d4 c6d4 d1d4 g8f6;c1g5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4;f1c4/30;C44 Scotch Gambit +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4;g8f6/100;C44 Scotch Gambit, Dubois-Reti Defence +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 g8f6;e4e5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 g8f6 e4e5;d7d5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 g8f6 e4e5 d7d5;c4b5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 g8f6;e1g1/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 g8f6 e1g1;f6e4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 g8f6 e1g1 f6e4;f1e1/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4;f8c5/50; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 f8c5;c2c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 f8c5 c2c3;g8f6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 f8c5 c2c3 g8f6;c3d4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 f8c5;e1g1/50; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 f8c5 e1g1;d7d6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 f1c4 f8c5 e1g1 d7d6;c2c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4;c2c3/10;C44 Scotch, Goering Gambit +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3;d4c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d4c3;f1c4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d4c3 f1c4;d7d6/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d4c3 f1c4 d7d6;b1c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d4c3;b1c3/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d4c3 b1c3;f8b4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d4c3 b1c3 f8b4;f1c4/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3;d7d5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d7d5;e4d5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d7d5 e4d5;d8d5/100; +e2e4 e7e5 g1f3 b8c6 d2d4 e5d4 c2c3 d7d5 e4d5 d8d5;c3d4/100; +e2e4 e7e5 g1f3 b8c6;b1c3/30;C46 Three Knights Game +e2e4 e7e5 g1f3;g8f6/10;C42 Petrov's Defence +e2e4 e7e5 g1f3 g8f6;f3e5/100; +e2e4 e7e5 g1f3 g8f6 f3e5;d7d6/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6;e5f3/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3;f6e4/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3 f6e4;d2d4/100;C42 Petrov, Classical Attack +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3 f6e4 d2d4;d6d5/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d7d6 e5f3 f6e4 d2d4 d6d5;f1d3/100; +e2e4 e7e5 g1f3 g8f6 f3e5;d8e7/0; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7;e5f3/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7 e5f3;f6e4/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7 e5f3 f6e4;f1e2/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7 e5f3 f6e4;d1e2/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7;d2d4/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7 d2d4;d7d6/100; +e2e4 e7e5 g1f3 g8f6 f3e5 d8e7 d2d4 d7d6;e5f3/100; +e2e4 e7e5 g1f3 g8f6 f3e5;f6e4/0;C42 Petrov, Damiano Variation +e2e4 e7e5 g1f3 g8f6 f3e5 f6e4;d1e2/100; +e2e4 e7e5 g1f3 g8f6 f3e5 f6e4 d1e2;d8e7/100; +e2e4 e7e5 g1f3 g8f6 f3e5 f6e4 d1e2 d8e7;e2e4/100; +e2e4 e7e5 g1f3 g8f6;b1c3/50;C42 Petrov Three Knights Game +e2e4 e7e5 g1f3;d7d6/0;C41 Philidor's Defence +e2e4 e7e5 g1f3 d7d6;d2d4/100; +e2e4 e7e5 g1f3 d7d6 d2d4;e5d4/100;C41 Philidor, Exchange Variation +e2e4 e7e5 g1f3 d7d6 d2d4 e5d4;f3d4/100; +e2e4 e7e5 g1f3 d7d6 d2d4;g8f6/50;C41 Philidor, Nimzovich Variation +e2e4 e7e5 g1f3 d7d6 d2d4 g8f6;b1c3/100; +e2e4 e7e5 g1f3 d7d6 d2d4 g8f6;d4e5/100; +e2e4 e7e5 g1f3 d7d6 d2d4;b8d7/50;C41 Philidor, Hanham Variation +e2e4 e7e5 g1f3 d7d6 d2d4 b8d7;f1c4/100; +e2e4 e7e5;b1c3/10;C25 Vienna Game +e2e4 e7e5 b1c3;g8f6/100;C26 Vienna, Falkbeer Variation +e2e4 e7e5 b1c3 g8f6;f2f4/100; +e2e4 e7e5 b1c3 g8f6 f2f4;d7d5/100;C29 Vienna Gambit +e2e4 e7e5 b1c3 g8f6 f2f4 d7d5;f4e5/100; +e2e4 e7e5 b1c3 g8f6 f2f4 d7d5 f4e5;f6e4/100; +e2e4 e7e5 b1c3 g8f6 f2f4 d7d5 f4e5 f6e4;g1f3/100; +e2e4 e7e5 b1c3 g8f6;f1c4/100;C26 Vienna Game +e2e4 e7e5 b1c3 g8f6 f1c4;b8c6/100; +e2e4 e7e5 b1c3 g8f6 f1c4 b8c6;d2d3/100; +e2e4 e7e5 b1c3 g8f6 f1c4 b8c6 d2d3;f8b4/100; +e2e4 e7e5 b1c3 g8f6 f1c4 b8c6 d2d3 f8b4;g1e2/100; +e2e4 e7e5 b1c3 g8f6 f1c4;f8c5/100; +e2e4 e7e5 b1c3 g8f6 f1c4 f8c5;d2d3/100; +e2e4 e7e5 b1c3 g8f6 f1c4 f8c5 d2d3;d7d6/100; +e2e4 e7e5 b1c3 g8f6 f1c4 f8c5 d2d3 d7d6;f2f4/100; +e2e4 e7e5 b1c3 g8f6;g1f3/100;C42 Petrov Three Knights Game +e2e4 e7e5 b1c3 g8f6 g1f3;b8c6/100;C46 Four Knights Game +e2e4 e7e5 b1c3 g8f6 g1f3;f8b4/100; +e2e4 e7e5 b1c3 g8f6 g1f3 f8b4;f3e5/100; +e2e4 e7e5 b1c3 g8f6 g1f3 f8b4 f3e5;e8g8/100; +e2e4 e7e5 b1c3 g8f6 g1f3 f8b4 f3e5 e8g8;f1e2/100; +e2e4 e7e5 b1c3 g8f6 g1f3 f8b4;f1c4/100; +e2e4 e7e5 b1c3 g8f6 g1f3 f8b4 f1c4;e8g8/100; +e2e4 e7e5 b1c3 g8f6 g1f3 f8b4 f1c4 e8g8;e1g1/100; +e2e4 e7e5 b1c3 g8f6;g2g3/100;C26 Vienna, Paulsen-Mieses Variation +e2e4 e7e5 b1c3 g8f6 g2g3;d7d5/100; +e2e4 e7e5 b1c3 g8f6 g2g3 d7d5;e4d5/100; +e2e4 e7e5 b1c3 g8f6 g2g3 d7d5 e4d5;f6d5/100; +e2e4 e7e5 b1c3 g8f6 g2g3 d7d5 e4d5 f6d5;f1g2/100; +e2e4 e7e5 b1c3 g8f6 g2g3;f8c5/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5;f1g2/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5 f1g2;d7d6/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5 f1g2 d7d6;g1e2/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5 f1g2;b8c6/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5 f1g2 b8c6;g1e2/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5 f1g2;e8g8/100; +e2e4 e7e5 b1c3 g8f6 g2g3 f8c5 f1g2 e8g8;g1e2/100; +e2e4 e7e5 b1c3;b8c6/50;C25 Vienna Game, Max Lange Defence +e2e4 e7e5 b1c3 b8c6;f1c4/100; +e2e4 e7e5 b1c3 b8c6 f1c4;g8f6/150;C28 Vienna Game +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6;d2d3/100; +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6 d2d3;f8b4/100; +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6 d2d3 f8b4;g1e2/100; +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6 d2d3;c6a5/100; +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6 d2d3 c6a5;g1e2/100; +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6 d2d3;f8c5/100; +e2e4 e7e5 b1c3 b8c6 f1c4 g8f6 d2d3 f8c5;f2f4/100; +e2e4 e7e5 b1c3 b8c6 f1c4;f8c5/50; +e2e4 e7e5 b1c3 b8c6 f1c4 f8c5;d1g4/100; +e2e4 e7e5 b1c3 b8c6 f1c4 f8c5 d1g4;g7g6/100; +e2e4 e7e5 b1c3 b8c6 f1c4 f8c5;d2d3/100; +e2e4 e7e5 b1c3 b8c6 f1c4 f8c5 d2d3;d7d6/100; +e2e4 e7e5 b1c3 b8c6;f2f4/50;C25 Vienna Gambit +e2e4 e7e5 b1c3 b8c6 f2f4;e5f4/100; +e2e4 e7e5 b1c3 b8c6 f2f4 e5f4;g1f3/100; +e2e4 e7e5 b1c3 b8c6;g2g3/50;C25 Vienna, Paulsen Variation +e2e4 e7e5 b1c3 b8c6 g2g3;f8c5/100; +e2e4 e7e5 b1c3 b8c6 g2g3 f8c5;f1g2/100; +e2e4 e7e5 b1c3 b8c6 g2g3;g8f6/100; +e2e4 e7e5 b1c3 b8c6 g2g3 g8f6;f1g2/100; +e2e4 e7e5 b1c3 b8c6;g1f3/50;C46 Three knights Game +e2e4 e7e5 b1c3 b8c6 g1f3;g8f6/100;C46 Four knights Game +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6;f1b5/100;C48 Four Knights, Spanish Variation +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5;f8b4/100;C49 Four Knights, Double Ruy Lopez +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 f8b4;e1g1/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 f8b4 e1g1;e8g8/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 f8b4 e1g1 e8g8;d2d3/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5;c6d4/100;C48 Four Knights, Rubinstein Counter-gambit +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 c6d4;b5a4/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 c6d4 b5a4;f8c5/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 c6d4 b5a4 f8c5;f3e5/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 c6d4;f3d4/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 c6d4 f3d4;e5d4/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 f1b5 c6d4 f3d4 e5d4;e4e5/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6;d2d4/100;C47 Four Knights, Scotch Variation +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 d2d4;e5d4/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 d2d4 e5d4;f3d4/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 d2d4 e5d4 f3d4;f8b4/100; +e2e4 e7e5 b1c3 b8c6 g1f3 g8f6 d2d4 e5d4 f3d4 f8b4;d4c6/100; +e2e4 e7e5;f2f4/10;C30 King's Gambit +e2e4 e7e5 f2f4;e5f4/100;C33 King's Gambit Accepted +e2e4 e7e5 f2f4 e5f4;g1f3/100;King's Knight Gambit +e2e4 e7e5 f2f4 e5f4 g1f3;g7g5/100; +e2e4 e7e5 f2f4 e5f4 g1f3 g7g5;h2h4/100; +e2e4 e7e5 f2f4 e5f4 g1f3 g7g5;f1c4/100; +e2e4 e7e5 f2f4 e5f4 g1f3;d7d5/50;C36 King's Gambit Accepted, Abbazia Defence +e2e4 e7e5 f2f4 e5f4 g1f3 d7d5;e4d5/100; +e2e4 e7e5 f2f4 e5f4 g1f3;d7d6/50;C34 King's Gambit Accepted, Fischer Defence +e2e4 e7e5 f2f4 e5f4 g1f3 d7d6;d2d4/100; +e2e4 e7e5 f2f4 e5f4 g1f3 d7d6;f1c4/100; +e2e4 e7e5 f2f4 e5f4;f1c4/100;King's Bishop Gambit +e2e4 e7e5 f2f4 e5f4 f1c4;g8f6/100;C33 King's Gambit Accepted, Bishop's Gambit, Cozio Defence +e2e4 e7e5 f2f4 e5f4 f1c4 g8f6;b1c3/100;C33 King's Gambit Accepted, Bishop's Gambit, Bogolyubov Variation +e2e4 e7e5 f2f4 e5f4 f1c4 g8f6 b1c3;c7c6/100; +e2e4 e7e5 f2f4 e5f4 f1c4 g8f6 b1c3 c7c6;c4b3/100; +e2e4 e7e5 f2f4 e5f4 f1c4 g8f6 b1c3 c7c6;d2d4/100; +e2e4 e7e5 f2f4 e5f4 f1c4;d8h4/100; +e2e4 e7e5 f2f4 e5f4 f1c4 d8h4;e1f1/100; +e2e4 e7e5 f2f4 e5f4 f1c4 d8h4 e1f1;d7d6/100; +e2e4 e7e5 f2f4 e5f4 f1c4 d8h4 e1f1 d7d6;g1f3/100; +e2e4 e7e5 f2f4 e5f4 f1c4 d8h4 e1f1 d7d6;b1c3/100; +e2e4 e7e5 f2f4 e5f4 f1c4;d7d5/100;C33 King's Gambit Accepted, Bishop's Gambit, Bledow Variation +e2e4 e7e5 f2f4 e5f4 f1c4 d7d5;c4d5/100; +e2e4 e7e5 f2f4 e5f4 f1c4 d7d5;e4d5/100; +e2e4 e7e5 f2f4;f8c5/30;C30 King's Gambit Declined, Classical Variation +e2e4 e7e5 f2f4 f8c5;g1f3/100; +e2e4 e7e5 f2f4 f8c5 g1f3;d7d6/100; +e2e4 e7e5 f2f4 f8c5 g1f3 d7d6;c2c3/100; +e2e4 e7e5 f2f4 f8c5 g1f3 d7d6;f1c4/100; +e2e4 e7e5 f2f4 f8c5 g1f3 d7d6;b1c3/100; +e2e4 e7e5 f2f4;d7d5/30;C31 King's Gambit Declined, Falkbeer Counter-gambit +e2e4 e7e5 f2f4 d7d5;e4d5/100; +e2e4 e7e5 f2f4 d7d5 e4d5;e5e4/100; +e2e4 e7e5 f2f4 d7d5 e4d5 e5e4;d2d3/100; +e2e4 e7e5 f2f4 d7d5 e4d5 e5e4;b1c3/50; +e2e4 e7e5 f2f4 d7d5 e4d5;e5f4/50; +e2e4 e7e5 f2f4 d7d5 e4d5 e5f4;g1f3/100; +e2e4 e7e5 f2f4 d7d5 e4d5;c7c6/50;C31 King's Gambit Declined, Nimzovich Counter-gambit +e2e4 e7e5 f2f4 d7d5 e4d5 c7c6;b1c3/100; +e2e4 e7e5 f2f4;d7d6/0; +e2e4 e7e5 f2f4 d7d6;g1f3/100; +e2e4 e7e5 f2f4 d7d6 g1f3;b8c6/100; +e2e4 e7e5 f2f4 d7d6 g1f3 b8c6;f1c4/100; +e2e4 e7e5 f2f4;b8c6/0; +e2e4 e7e5 f2f4 b8c6;g1f3/100; +e2e4 e7e5 f2f4 b8c6 g1f3;d7d6/100; +e2e4 e7e5 f2f4 b8c6 g1f3 d7d6;f1c4/100; +e2e4 e7e5;f1c4/0;C23 Bishop's Opening +e2e4 e7e5 f1c4;g8f6/100;C24 Bishop's Opening, Berlin Defence +e2e4 e7e5 f1c4 g8f6;d2d3/100; +e2e4 e7e5 f1c4 g8f6 d2d3;b8c6/100; +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6;g1f3/100;C55 Two Knights Defence (Modern Bishop's Opening) +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6 g1f3;f8e7/100; +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6 g1f3;f8c5/100;C50 Giuoco Pianissimo +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6;b1c3/100; +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6 b1c3;f8b4/100; +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6 b1c3;c6a5/100; +e2e4 e7e5 f1c4 g8f6 d2d3 b8c6 b1c3;f8c5/100; +e2e4 e7e5;d2d4/0; +e2e4 e7e5 d2d4;e5d4/100;C21 Centre Game +e2e4 e7e5 d2d4 e5d4;d1d4/100; +e2e4 e7e5 d2d4 e5d4 d1d4;b8c6/100; +e2e4;e7e6/100;C00 French Defence +e2e4 e7e6;d2d4/100; +e2e4 e7e6 d2d4;d7d5/100; +e2e4 e7e6 d2d4 d7d5;b1c3/75;C10 French Defence, Main Line +e2e4 e7e6 d2d4 d7d5 b1c3;f8b4/100;C15 French, Winawer Variation +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4;e4e5/100;C17 French, Winawer, Advance Variation +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5;a2a3/100;C17 French, Winawer, Advance, 5. a3 +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3;b4c3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3;b2c3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3;d8c7/100;French, Winawer, 6... c7 +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7;d1g4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4;f7f5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5;g4g3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3;b8c6/100;French, Winawer, Moskalenko Variation +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 g1f3;c5d4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 g1f3 c5d4;c3d4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 g1f3 c5d4 c3d4;g8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 g1f3 c5d4 c3d4 g8e7;c1d2/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 g1f3 c5d4 c3d4 g8e7 c1d2;e8g8/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6;f1e3/0; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 f1e3;c7a5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 f1e3 c7a5;c1d2/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 b8c6 f1e3 c7a5 c1d2;g7g6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3;c5d4/50; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 c5d4;c3d4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3 d8c7 d1g4 f7f5 g4g3 c5d4 c3d4;g8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3;g8e7/50; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4c3 b2c3;d8a5/50; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3;b4a5/10; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4a5;b2b4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 a2a3 b4a5 b2b4;c5d4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5;c1d2/10;C17 French, Winawer, Advance, Bogolyubov Variation +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2;g8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 g8e7;c3b5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 g8e7 c3b5;b4d2/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 g8e7;a2a3/50; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 g8e7 a2a3;b4c3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2;c5d4/50; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 c5d4;c3b5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 c5d4 c3b5;b4c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2;b8c6/50; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 b8c6;c3b5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 c1d2 b8c6 c3b5;b4d2/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5;d1g4/10;C17 French, Winawer, Advance, Russian Variation +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 d1g4;g8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 d1g4 g8e7;d4c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 c7c5 d1g4 g8e7 d4c5;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5;g8e7/0; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 e4e5 g8e7;a2a3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4;c1d2/0; +e2e4 e7e6 d2d4 d7d5 b1c3 f8b4 c1d2;d5e4/100; +e2e4 e7e6 d2d4 d7d5 b1c3;g8f6/100;C11 French Defence, Classical Variation +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6;e4e5/100;C11 French, Steinitz Variation +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5;f6d7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7;f2f4/80; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6;c1e3/100;C11 French, Steinitz, Boleslavsky variation +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3;c5d4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3 c5d4;f3d4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3 c5d4 f3d4;f8c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3;a7a6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3 a7a6;d1d2/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 f2f4 c7c5 g1f3 b8c6 c1e3 a7a6 d1d2;b7b5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7;c3e2/10; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 c3e2;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 c3e2 c7c5;c2c3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 c3e2 c7c5 c2c3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7;g1f3/10; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 g1f3;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 g1f3 c7c5;d4c5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 e4e5 f6d7 g1f3 c7c5 d4c5;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6;c1g5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5;f8e7/70; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7;e4e5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5;f6d7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7;g5e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7 g5e7;d8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7;h2h4/100;French, Alekhine-Chatard Attack +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7 h2h4;e7g5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7 h2h4 e7g5;h4g5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8e7 e4e5 f6d7 h2h4 e7g5 h4g5;d8g5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5;d5e4/60;C11 French, Burn Variation +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4;c3e4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4;f8e7/45; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 f8e7;g5f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 f8e7 g5f6;e7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 f8e7 g5f6;g7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4;b8d7/15; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 b8d7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 d5e4 c3e4 b8d7 g1f3;h7h6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5;f8b4/50;C12 French, MacCutcheon Variation +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8b4;e4e5/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8b4 e4e5;h7h6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 g8f6 c1g5 f8b4 e4e5 h7h6;g5d2/100; +e2e4 e7e6 d2d4 d7d5 b1c3;d5e4/50;C10 French, Rubinstein Variation +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4;c3e4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4;b8d7/70; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3;g8f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6;e4f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 e4f6;d7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6;c1g5/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 c1g5;f8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 c1g5 f8e7;e4f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 c1g5 f8e7 e4f6;e7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6;f1d3/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 b8d7 g1f3 g8f6 f1d3;f6e4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4;c8d7/35; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3;d7c6/100;C10 French, Fort Knox Variation +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3 d7c6;f1d3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3 d7c6 f1d3;b8d7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3 d7c6 f1d3 b8d7;e1g1/200; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3 d7c6 f1d3 b8d7 e1g1;g8f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3 d7c6 f1d3 b8d7;d1e2/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 c8d7 g1f3 d7c6 f1d3 b8d7 d1e2;g8f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4;g8f6/15; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6;e4f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 e4f6;d8f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 e4f6 d8f6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 e4f6;g7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 e4f6 g7f6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6;c1g5/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5;f8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7;g5f6/40; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7 g5f6;e7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7 g5f6;g7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7;e4f6/10; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7 e4f6;e7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7 e4f6 e7f6;g5f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 f8e7 e4f6 e7f6 g5f6;d8f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5;b8d7/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3;h7h6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3 h7h6;e4f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3 h7h6 e4f6;d7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3;f8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3 f8e7;e4f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3 f8e7 e4f6;d7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 g1f3 f8e7 e4f6;e7f6/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7;e4f6/50; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 e4f6;d7f6/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 c1g5 b8d7 e4f6 d7f6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6;f1d3/25; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3;b8d7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3 b8d7;d1e2/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3 b8d7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3;f8e7/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3 f8e7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3;f6e4/100; +e2e4 e7e6 d2d4 d7d5 b1c3 d5e4 c3e4 g8f6 f1d3 f6e4;d3e4/100; +e2e4 e7e6 d2d4 d7d5 b1c3;b8c6/0; +e2e4 e7e6 d2d4 d7d5 b1c3 b8c6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1c3 b8c6;e4e5/50; +e2e4 e7e6 d2d4 d7d5;b1d2/50;C03 French Defence, Tarrasch Variation +e2e4 e7e6 d2d4 d7d5 b1d2;g8f6/220;C05 French, Tarrasch, Closed Variation +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6;e4e5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5;f6d7/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7;f1d3/110; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 f1d3;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 f1d3 c7c5;c2c3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7;c2c3/40; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 c2c3;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 c2c3 c7c5;f1d3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 c2c3 c7c5;f2f4/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7;f2f4/40; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 f2f4;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 e4e5 f6d7 f2f4 c7c5;c2c3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6;f1d3/0; +e2e4 e7e6 d2d4 d7d5 b1d2 g8f6 f1d3;c7c5/100; +e2e4 e7e6 d2d4 d7d5 b1d2;c7c5/140;C07 French, Tarrasch, Open Variation +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5;e4d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5;e6d5/100;C08 French, Tarrasch, Open, 4.ed ed +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 e6d5;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 e6d5 g1f3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 e6d5 g1f3;g8f6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 e6d5;f1b5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 e6d5 f1b5;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 e6d5 f1b5;c8d7/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5;d8d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 d8d5;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 d8d5 g1f3;c5d4/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 d8d5 g1f3 c5d4;f1c4/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 e4d5 d8d5 g1f3 c5d4 f1c4;d5d6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5;g1f3/50; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 b8c6;e4d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 b8c6 e4d5;e6d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 b8c6;f1b5/50; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 b8c6 f1b5;a7a6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 b8c6 f1b5;c5d4/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3;c5d4/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 c5d4;e4d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 c5d4 e4d5;d8d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 c5d4;f3d4/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 c5d4 f3d4;b8c6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3;g8f6/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 g8f6;e4d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 g8f6 e4d5;e6d5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 g8f6;e4e5/100; +e2e4 e7e6 d2d4 d7d5 b1d2 c7c5 g1f3 g8f6 e4e5;f6d7/100; +e2e4 e7e6 d2d4 d7d5 b1d2;d5e4/60;C10 French, Rubinstein Variation +e2e4 e7e6 d2d4 d7d5 b1d2 d5e4;d2e4/100; +e2e4 e7e6 d2d4 d7d5 b1d2;b8c6/0;C03 French, Tarrasch, Guimard Variation +e2e4 e7e6 d2d4 d7d5 b1d2 b8c6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 b8c6 g1f3;g8f6/100;C04 French, Tarrasch, Guimard Main Line +e2e4 e7e6 d2d4 d7d5 b1d2 b8c6 g1f3 g8f6;e4e5/100; +e2e4 e7e6 d2d4 d7d5 b1d2;f8e7/0; +e2e4 e7e6 d2d4 d7d5 b1d2 f8e7;g1f3/100; +e2e4 e7e6 d2d4 d7d5 b1d2 f8e7;f1d3/100; +e2e4 e7e6 d2d4 d7d5 b1d2;a7a6/0; +e2e4 e7e6 d2d4 d7d5 b1d2 a7a6;g1f3/100; +e2e4 e7e6 d2d4 d7d5;e4e5/30;French Defence, Advance Variation +e2e4 e7e6 d2d4 d7d5 e4e5;c7c5/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5;c2c3/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6;g1f3/100;C02 French, Advance, Paulsen Attack +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6 g1f3;d8b6/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6 g1f3;c8d7/50;C02 French, Advance, Euwe Variation +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6;c1e3/0; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6 c1e3;d8b6/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6;f1b5/0; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6 f1b5;d8b6/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 b8c6 f1b5;c8d7/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3;d8b6/10; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 d8b6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 d8b6 g1f3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 c2c3 d8b6 g1f3;c8d7/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5;g1f3/0;C02 French, Advance, Nimzovich System +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 g1f3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5;d4c5/0;C02 French, Advance, Steinitz Variation +e2e4 e7e6 d2d4 d7d5 e4e5 c7c5 d4c5;f8c5/100; +e2e4 e7e6 d2d4 d7d5;e4d5/20;C01 French, Exchange Variation +e2e4 e7e6 d2d4 d7d5 e4d5;e6d5/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5;f1d3/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3;f8d6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 f8d6;g1f3/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 f8d6 g1f3;g8e7/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 f8d6 g1f3;g8f6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 f8d6;g1e2/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 f8d6 g1e2;g8e7/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3;b8c6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 b8c6;c2c3/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 f1d3 b8c6 c2c3;f8d6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5;g1f3/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3;f8d6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 f8d6;f1d3/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 f8d6 f1d3;g8e7/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 f8d6;c2c4/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 f8d6 c2c4;c7c6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3;g8f6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6;f1d3/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3;f8d6/100; +e2e4 e7e6 d2d4 d7d5 e4d5 e6d5 g1f3 g8f6 f1d3;f8e7/100; +e2e4 e7e6 d2d4 d7d5;f1d3/0;C00 French, Schlechter Variation +e2e4 e7e6 d2d4 d7d5 f1d3;d5e4/100; +e2e4 e7e6 d2d4 d7d5 f1d3 d5e4;d3e4/100; +e2e4 e7e6 d2d4 d7d5 f1d3 d5e4 d3e4;g8f6/100; +e2e4 e7e6 d2d4 d7d5;c1e3/0;C00 French, Alapin Variation +e2e4 e7e6 d2d4 d7d5 c1e3;d5e4/100; +e2e4 e7e6;d2d3/0;C00 French, King's Indian Attack +e2e4 e7e6 d2d3;d7d5/100; +e2e4 e7e6 d2d3 d7d5;b1d2/100; +e2e4 e7e6 d2d3 d7d5 b1d2;g8f6/100; +e2e4 e7e6 d2d3 d7d5 b1d2 g8f6;g1f3/100; +e2e4 e7e6 d2d3 d7d5 b1d2 g8f6 g1f3;c7c5/100; +e2e4 e7e6 d2d3 d7d5 b1d2 g8f6;g2g3/100; +e2e4 e7e6 d2d3 d7d5 b1d2 g8f6 g2g3;d5e4/100; +e2e4 e7e6 d2d3 d7d5 b1d2 g8f6 g2g3;c7c5/100; +e2e4 e7e6 d2d3 d7d5 b1d2;c7c5/100; +e2e4 e7e6 d2d3 d7d5 b1d2 c7c5;g1f3/100; +e2e4 e7e6 d2d3 d7d5 b1d2 c7c5 g1f3;b8c6/100; +e2e4 e7e6 d2d3 d7d5 b1d2 c7c5;g2g3/100; +e2e4 e7e6 d2d3 d7d5 b1d2 c7c5 g2g3;b8c6/100; +e2e4 e7e6;g1f3/0; +e2e4 e7e6 g1f3;d7d5/100; +e2e4 e7e6 g1f3 d7d5;b1c3/100;C00 French, Two knights Variation +e2e4 e7e6 g1f3 d7d5 b1c3;g8f6/100; +e2e4 e7e6 g1f3 d7d5 b1c3 g8f6;e4e5/100; +e2e4 e7e6 g1f3 d7d5 b1c3 g8f6 e4e5;f6d7/100; +e2e4 e7e6 g1f3 d7d5 b1c3 g8f6 e4e5 f6d7;d2d4/100; +e2e4 e7e6 g1f3 d7d5 b1c3 g8f6 e4e5 f6d7 d2d4;c7c5/100; +e2e4 e7e6 g1f3 d7d5;e4e5/100; +e2e4 e7e6 g1f3 d7d5 e4e5;c7c5/100; +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5;b2b4/100;C00 French, Wing Gambit +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5 b2b4;c5b4/100; +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5 b2b4 c5b4;a2a3/100; +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5 b2b4 c5b4 a2a3;b8c6/100; +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5 b2b4 c5b4 a2a3;b4a3/100; +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5 b2b4 c5b4;d2d4/100; +e2e4 e7e6 g1f3 d7d5 e4e5 c7c5 b2b4 c5b4 d2d4;b8c6/100; +e2e4 e7e6 g1f3 d7d5;e4d5/100; +e2e4 e7e6 g1f3 d7d5 e4d5;e6d5/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5;d2d4/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4;f8d6/300; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 f8d6;f1d3/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 f8d6 f1d3;g8e7/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 f8d6;c2c4/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 f8d6 c2c4;c7c6/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4;g8f6/300; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 g8f6;f1d3/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 g8f6 f1d3;f8d6/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4;c8g4/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 c8g4;f1e2/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 c8g4 f1e2;f8d6/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 c8g4;h2h3/100; +e2e4 e7e6 g1f3 d7d5 e4d5 e6d5 d2d4 c8g4 h2h3;g4h5/100; +e2e4 e7e6;d1e2/0;C00 French, Chigorin Variation +e2e4 e7e6 d1e2;c7c5/100; +e2e4 e7e6 d1e2 c7c5;g1f3/100; +e2e4 e7e6 d1e2 c7c5 g1f3;b8c6/100; +e2e4 e7e6 d1e2 c7c5;g2g3/100; +e2e4 e7e6 d1e2 c7c5 g2g3;b8c6/100; +e2e4 e7e6 d1e2 c7c5;f2f4/100; +e2e4 e7e6 d1e2 c7c5 f2f4;b8c6/100; +e2e4 e7e6;b1c3/0; +e2e4 e7e6 b1c3;d7d5/100; +e2e4;c7c5/100;B20 Sicilian Defence +e2e4 c7c5;g1f3/100;B27 Sicilian Defence, King's Knight Variation +e2e4 c7c5 g1f3;d7d6/200; +e2e4 c7c5 g1f3 d7d6;d2d4/100; +e2e4 c7c5 g1f3 d7d6 d2d4;c5d4/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4;f3d4/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4;g8f6/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6;b1c3/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3;a7a6/80;B90 Sicilian, Najdorf +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 a7a6;f1e2/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 a7a6;c1g5/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 a7a6;f1e3/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 a7a6;f1c4/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3;g7g6/30;B70 Sicilian, Dragon Variation +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 g7g6;c1e3/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3;b8c6/20; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 b8c6;c1g5/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 b8c6;f1c4/100; +e2e4 c7c5 g1f3 d7d6 d2d4 c5d4 f3d4 g8f6 b1c3 b8c6;f1e2/100; +e2e4 c7c5 g1f3;b8c6/150; +e2e4 c7c5 g1f3 b8c6;d2d4/100; +e2e4 c7c5 g1f3 b8c6 d2d4;c5d4/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4;f3d4/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4;g8f6/50; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6;b1c3/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3;e7e5/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 e7e5;d4b5/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3;d7d6/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6;c1g5/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6;f1c4/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g8f6 b1c3 d7d6;f1e2/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4;g7g6/20; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6;b1c3/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6 b1c3;f8g7/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6 b1c3 f8g7;c1e3/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6;c2c4/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4;f8g7/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4 f8g7;c1e3/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4;g8f6/50; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 g7g6 c2c4 g8f6;b1c3/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4;e7e5/10; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 e7e5;d4b5/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 e7e5 d4b5;d7d6/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 e7e5 d4b5 d7d6;b1c3/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 e7e5 d4b5 d7d6;c2c4/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 e7e5 d4b5;a7a6/100; +e2e4 c7c5 g1f3 b8c6 d2d4 c5d4 f3d4 e7e5 d4b5 a7a6;b5d6/100; +e2e4 c7c5 g1f3 b8c6;f1b5/100;B30 Sicilian, Nimzovich-Rossolimo Attack (Without ...d6) +e2e4 c7c5 g1f3 b8c6 f1b5;g7g6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6;e1g1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1;f8g7/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7;c2c3/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 c2c3;g8f6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 c2c3 g8f6;f1e1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7;f1e1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 f1e1;g8f6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 f1e1 g8f6;e4e5/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 f1e1 g8f6;c2c3/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 f1e1;e7e5/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 e1g1 f8g7 f1e1 e7e5;b5c6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6;b5c6/50; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6;d7c6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6 d7c6;d2d3/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6 d7c6 d2d3;f8g7/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6 d7c6 d2d3 f8g7;h2h3/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6;b7c6/50; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6 b7c6;e1g1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6 b7c6 e1g1;f8g7/100; +e2e4 c7c5 g1f3 b8c6 f1b5 g7g6 b5c6 b7c6 e1g1 f8g7;f1e1/100; +e2e4 c7c5 g1f3 b8c6 f1b5;e7e6/50; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6;e1g1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1;g8e7/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7;f1e1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7 f1e1;a7a6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7 f1e1 a7a6;b5f1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7 f1e1 a7a6;b5c6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7;c2c3/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7 c2c3;a7a6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 e1g1 g8e7 c2c3 a7a6;b5a4/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6;b5c6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6;b7c6/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6 b7c6;d2d3/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6 b7c6 d2d3;g8e7/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6 b7c6 d2d3 g8e7;d1e2/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6 b7c6;e1g1/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6 b7c6 e1g1;g8e7/100; +e2e4 c7c5 g1f3 b8c6 f1b5 e7e6 b5c6 b7c6 e1g1 g8e7;d2d3/100; +e2e4 c7c5 g1f3 b8c6;b1c3/100; +e2e4 c7c5 g1f3 b8c6 b1c3;g7g6/100; +e2e4 c7c5 g1f3 b8c6 b1c3 g7g6;d2d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 g7g6 d2d4;c5d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 g7g6 d2d4 c5d4;f3d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 g7g6 d2d4 c5d4 f3d4;f8g7/100; +e2e4 c7c5 g1f3 b8c6 b1c3 g7g6 d2d4 c5d4 f3d4 f8g7;c1e3/100; +e2e4 c7c5 g1f3 b8c6 b1c3;d7d6/100; +e2e4 c7c5 g1f3 b8c6 b1c3 d7d6;d2d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 d7d6 d2d4;c5d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 d7d6 d2d4 c5d4;f3d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3;e7e6/100; +e2e4 c7c5 g1f3 b8c6 b1c3 e7e6;d2d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 e7e6 d2d4;c5d4/100; +e2e4 c7c5 g1f3 b8c6 b1c3 e7e6 d2d4 c5d4;f3d4/100; +e2e4 c7c5 g1f3;e7e6/100; +e2e4 c7c5 g1f3 e7e6;d2d4/100; +e2e4 c7c5 g1f3 e7e6 d2d4;c5d4/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4;f3d4/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4;a7a6/100;B41 Sicilian, Kan Variation +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 a7a6;f1d3/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 a7a6;b1c3/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4;g8f6/100;B40 Sicilian, Anderssen Variation +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 g8f6;b1c3/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4;b8c6/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6;b1c3/100;B45 Sicilian, Taimanov Variation +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3;d8c7/100;B47 Sicilian, Taimanov (Bastrikov) Variation +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3 d8c7;f1e2/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3 d8c7;c1e3/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3;a7a6/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3 a7a6;f1e2/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3 a7a6;c1e3/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3;d7d6/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3 d7d6;f1e2/100; +e2e4 c7c5 g1f3 e7e6 d2d4 c5d4 f3d4 b8c6 b1c3 d7d6;c1e3/100; +e2e4 c7c5;c2c3/50;B22 Sicilian Defence, Alapin Variation +e2e4 c7c5 c2c3;d7d5/100; +e2e4 c7c5 c2c3 d7d5;e4d5/100; +e2e4 c7c5 c2c3 d7d5 e4d5;d8d5/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5;d2d4/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4;g8f6/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 g8f6;g1f3/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 g8f6 g1f3;c8g4/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 g8f6 g1f3 c8g4;f1e2/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 g8f6 g1f3;e7e6/50; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 g8f6 g1f3 e7e6;f1e2/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4;b8c6/50; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 b8c6;g1f3/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 b8c6 g1f3;c8g4/100; +e2e4 c7c5 c2c3 d7d5 e4d5 d8d5 d2d4 b8c6 g1f3 c8g4;f1e2/100; +e2e4 c7c5 c2c3;g8f6/100; +e2e4 c7c5 c2c3 g8f6;e4e5/100; +e2e4 c7c5 c2c3 g8f6 e4e5;f6d5/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5;d2d4/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4;c5d4/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4;g1f3/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 g1f3;b8c6/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 g1f3 b8c6;c3d4/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 g1f3 b8c6;f1c4/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 g1f3;e7e6/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 g1f3 e7e6;c3d4/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4;c3d4/50; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 c3d4;d7d6/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 c3d4 d7d6;g1f3/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 c3d4;e7e6/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 c3d4 e7e6;g1f3/100; +e2e4 c7c5 c2c3 g8f6 e4e5 f6d5 d2d4 c5d4 c3d4 e7e6;b1c3/100; +e2e4 c7c5 c2c3;e7e6/50; +e2e4 c7c5 c2c3 e7e6;d2d4/100; +e2e4 c7c5 c2c3 e7e6 d2d4;d7d5/100; +e2e4 c7c5 c2c3 e7e6 d2d4 d7d5;e4e5/100; +e2e4 c7c5 c2c3 e7e6 d2d4 d7d5;e4d5/100; +e2e4 c7c5 c2c3;d7d6/50; +e2e4 c7c5 c2c3 d7d6;d2d4/100; +e2e4 c7c5 c2c3 d7d6 d2d4;g8f6/100; +e2e4 c7c5 c2c3 d7d6 d2d4 g8f6;f1d3/100; +e2e4 c7c5 c2c3 d7d6 d2d4;c5d4/100; +e2e4 c7c5 c2c3 d7d6 d2d4 c5d4;c3d4/100; +e2e4 c7c5;b1c3/50;B23 Sicilian Defence, Closed +e2e4 c7c5 b1c3;b8c6/100; +e2e4 c7c5 b1c3 b8c6;g2g3/100; +e2e4 c7c5 b1c3 b8c6 g2g3;g7g6/100; +e2e4 c7c5 b1c3 b8c6 g2g3 g7g6;f1g2/100; +e2e4 c7c5 b1c3 b8c6 g2g3 g7g6 f1g2;f8g7/100; +e2e4 c7c5 b1c3 b8c6 g2g3 g7g6 f1g2 f8g7;d2d3/100; +e2e4 c7c5 b1c3 b8c6;f2f4/100;B21 Sicilian, Grand Prix Attack +e2e4 c7c5 b1c3 b8c6 f2f4;g7g6/100; +e2e4 c7c5 b1c3 b8c6 f2f4 g7g6;g1f3/100; +e2e4 c7c5 b1c3 b8c6 f2f4;e7e6/50; +e2e4 c7c5 b1c3 b8c6 f2f4 e7e6;g1f3/100; +e2e4 c7c5 b1c3;e7e6/20; +e2e4 c7c5 b1c3 e7e6;g2g3/100; +e2e4 c7c5 b1c3 e7e6 g2g3;d7d5/100; +e2e4 c7c5 b1c3 e7e6 g2g3 d7d5;e4d5/100; +e2e4 c7c5 b1c3 e7e6 g2g3;b8c6/100; +e2e4 c7c5 b1c3 e7e6 g2g3 b8c6;f1g2/100; +e2e4 c7c5 b1c3 e7e6;g1f3/100; +e2e4 c7c5 b1c3 e7e6 g1f3;a7a6/100; +e2e4 c7c5 b1c3 e7e6 g1f3 a7a6;d2d4/100; +e2e4 c7c5 b1c3 e7e6 g1f3;b8c6/100; +e2e4 c7c5 b1c3 e7e6 g1f3 b8c6;d2d4/100; +e2e4 c7c5 b1c3 e7e6;f2f4/100; +e2e4 c7c5 b1c3 e7e6 f2f4;d7d5/100; +e2e4 c7c5 b1c3 e7e6 f2f4 d7d5;g1f3/100; +e2e4 c7c5 b1c3 e7e6 f2f4;b8c6/100; +e2e4 c7c5 b1c3 e7e6 f2f4 b8c6;g1f3/100; +e2e4 c7c5 b1c3;d7d6/20; +e2e4 c7c5 b1c3 d7d6;g2g3/100; +e2e4 c7c5 b1c3 d7d6 g2g3;b8c6/100; +e2e4 c7c5 b1c3 d7d6 g2g3 b8c6;f1g2/100; +e2e4 c7c5 b1c3 d7d6;f2f4/100; +e2e4 c7c5 b1c3 d7d6 f2f4;b8c6/100; +e2e4 c7c5 b1c3 d7d6 f2f4 b8c6;g1f3/100; +e2e4 c7c5;d2d4/0;B21 Sicilian, Smith-Morra Gambit +e2e4 c7c5 d2d4;c5d4/100; +e2e4 c7c5;f2f4/0;B21 Sicilian, Grand Prix Attack +e2e4 c7c5 f2f4;b8c6/100; +e2e4 c7c5;d2d3/0; +e2e4 c7c5 d2d3;b8c6/100; +e2e4 c7c5;b2b3/0; +e2e4 c7c5 b2b3;b8c6/100; +e2e4 c7c5;c2c4/0; +e2e4 c7c5 c2c4;b8c6/100; +e2e4;c7c6/30;B10 Caro-Kann Defence +e2e4 c7c6;d2d4/100; +e2e4 c7c6 d2d4;d7d5/100; +e2e4 c7c6 d2d4 d7d5;b1c3/27;B15 Caro-Kann Defence, Traditional +e2e4 c7c6 d2d4 d7d5 b1c3;d5e4/100; +e2e4 c7c6 d2d4 d7d5 b1c3 d5e4;c3e4/100; +e2e4 c7c6 d2d4 d7d5;e4d5/25;B13 Caro-Kann, Exchange Variation +e2e4 c7c6 d2d4 d7d5 e4d5;c6d5/100; +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5;c2c4/100;B13 Caro-Kann, Panov-Botvinnik Attack +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5 c2c4;g8f6/100; +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5 c2c4 g8f6;b1c3/100; +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5;f1d3/50; +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5 f1d3;b8c6/100; +e2e4 c7c6 d2d4 d7d5 e4d5 c6d5 f1d3 b8c6;c2c3/100; +e2e4 c7c6 d2d4 d7d5;e4e5/22;B12 Caro-Kann, Advance Variation +e2e4 c7c6 d2d4 d7d5 e4e5;c8f5/100; +e2e4 c7c6 d2d4 d7d5 e4e5 c8f5;g1f3/100; +e2e4 c7c6 d2d4 d7d5 e4e5 c8f5 g1f3;e7e6/100; +e2e4 c7c6 d2d4 d7d5 e4e5 c8f5 g1f3 e7e6;f1e2/100; +e2e4 c7c6 d2d4 d7d5;b1d2/12;B12 Caro-Kann, 3.Nd2 +e2e4 c7c6 d2d4 d7d5 b1d2;d5e4/100; +e2e4 c7c6 d2d4 d7d5 b1d2 d5e4;d2e4/100; +e2e4;d7d6/0;B07 Pirc Defence +e2e4 d7d6;d2d4/100; +e2e4 d7d6 d2d4;g8f6/100; +e2e4 d7d6 d2d4 g8f6;b1c3/100; +e2e4 d7d6 d2d4 g8f6 b1c3;g7g6/100; +e2e4 d7d6 d2d4 g8f6 b1c3 g7g6;f2f4/100; +e2e4 d7d6 d2d4 g8f6 b1c3 g7g6 f2f4;f8g7/100; +e2e4 d7d6 d2d4 g8f6 b1c3 g7g6 f2f4 f8g7;g1f3/100; +e2e4 d7d6 d2d4 g8f6 b1c3 g7g6;g1f3/100;B08 Pirc, Classical (Two Knights) System +e2e4 d7d6 d2d4 g8f6 b1c3 g7g6 g1f3;f8g7/100; +e2e4 d7d6 d2d4 g8f6 b1c3 g7g6 g1f3 f8g7;f1e2/100; +e2e4 d7d6 d2d4 g8f6;e4e5/0; +e2e4 d7d6 d2d4 g8f6 e4e5;d6e5/100; +e2e4 d7d6 d2d4 g8f6 e4e5 d6e5;d4e5/100; +e2e4 d7d6 d2d4 g8f6 e4e5 d6e5 d4e5;d8d1/100; +e2e4 d7d6 d2d4;g7g6/100; +e2e4 d7d6 d2d4 g7g6;b1c3/100; +e2e4;d7d5/0;B01 Scandinavian Defence +e2e4 d7d5;e4d5/100; +e2e4 d7d5 e4d5;d8d5/100; +e2e4 d7d5 e4d5 d8d5;b1c3/100; +e2e4 d7d5 e4d5 d8d5 b1c3;d5a5/100; +e2e4 d7d5 e4d5 d8d5 b1c3 d5a5;d2d4/100; +e2e4 d7d5 e4d5;g8f6/100; +e2e4 d7d5 e4d5 g8f6;d2d4/100; +e2e4 d7d5 e4d5 g8f6 d2d4;f6d5/100; +e2e4 d7d5 e4d5 g8f6 d2d4 f6d5;c2c4/100; +e2e4 d7d5 e4d5 g8f6 d2d4 f6d5;g1f3/100; +e2e4;g7g6/0;B06 Robatsch (Modern) Defence +e2e4 g7g6;d2d4/100; +e2e4 g7g6 d2d4;f8g7/100; +e2e4 g7g6 d2d4 f8g7;b1c3/100; +e2e4;g8f6/0;B02 Alekhine's Defence +e2e4 g8f6;e4e5/100; +e2e4 g8f6 e4e5;f6d5/100; +e2e4 g8f6 e4e5 f6d5;d2d4/100; +e2e4;b8c6/0;B00 Nimzovich Defence +e2e4 b8c6;g1f3/100; +e2e4 b8c6;d2d4/100; +e2e4;b7b6/0;B00 Owen Defence +e2e4 b7b6;d2d4/100; +e2e4;a7a6/0;B00 St. George Defence +e2e4 a7a6;d2d4/100; + +;f2f3/0;A00 Gedult's Opening +f2f3;e7e5/100; + +;f2f4/10;A02 Bird's Opening +f2f4;d7d5/100;A02 Bird's Opening, Dutch Variation +f2f4 d7d5;g1f3/100;Bird's Opening, Lasker Variation +f2f4 d7d5 g1f3;g8f6/100; +f2f4 d7d5 g1f3 g8f6;e2e3/100; +f2f4 d7d5 g1f3 g8f6 e2e3;g7g6/100; +f2f4 d7d5 g1f3 g8f6 e2e3;c7c5/100; +f2f4 d7d5 g1f3 g8f6 e2e3;c8g4/100; +f2f4 d7d5 g1f3 g8f6;g2g3/100; +f2f4 d7d5 g1f3 g8f6 g2g3;g7g6/100; +f2f4 d7d5 g1f3 g8f6 g2g3 g7g6;f1g2/100; +f2f4 d7d5 g1f3;g7g6/50; +f2f4 d7d5 g1f3 g7g6;e2e3/100; +f2f4 d7d5 g1f3 g7g6 e2e3;f8g7/100; +f2f4 d7d5 g1f3 g7g6 e2e3 f8g7;f1e2/100; +f2f4 d7d5 g1f3 g7g6;g2g3/100; +f2f4 d7d5 g1f3 g7g6 g2g3;f8g7/100; +f2f4 d7d5 g1f3 g7g6 g2g3 f8g7;f1g2/100; +f2f4;g8f6/100;A02 Bird's Opening +f2f4 g8f6;g1f3/100; +f2f4 g8f6 g1f3;g7g6/100; +f2f4 g8f6 g1f3 g7g6;g2g3/100; +f2f4 g8f6 g1f3 g7g6 g2g3;f8g7/100; +f2f4 g8f6 g1f3 g7g6 g2g3 f8g7;f1g2/100; +f2f4 g8f6 g1f3 g7g6;b2b3/100; +f2f4 g8f6 g1f3 g7g6 b2b3;f8g7/100; +f2f4;g7g6/50; +f2f4 g7g6;g1f3/100; +f2f4 g7g6 g1f3;f8g7/100; +f2f4 g7g6 g1f3 f8g7;g2g3/100; +f2f4 g7g6 g1f3 f8g7;e2e3/100; +f2f4;e7e5/50;A02 Bird's Opening, From's Gambit +f2f4 e7e5;f4e5/100;Bird's Opening, From's Gambit Accepted +f2f4 e7e5 f4e5;d7d6/100; +f2f4 e7e5 f4e5 d7d6;e5d6/100; +f2f4 e7e5 f4e5 d7d6 e5d6;f8d6/100; +f2f4 e7e5 f4e5 d7d6 e5d6 f8d6;g1f3/100; +f2f4 e7e5 f4e5 d7d6;g1f3/0; +f2f4 e7e5 f4e5 d7d6 g1f3;d6e5/100; +f2f4 e7e5;e2e4/50;King's Gambit +f2f4 e7e5 e2e4;e5f4/100;King's Gambit Accepted +f2f4 e7e5 e2e4;f8c5/30;King's Gambit Declined, Classical Variation +f2f4 e7e5 e2e4;d7d5/30;King's Gambit Declined, Falkbeer Counter-gambit +f2f4;e7e6/0; +f2f4 e7e6;g1f3/100; +f2f4 e7e6 g1f3;d7d5/100; +f2f4 e7e6 g1f3 d7d5;e2e3/100; +f2f4 e7e6 g1f3 d7d5 e2e3;g8f6/100; +f2f4 e7e6 g1f3 d7d5 e2e3 g8f6;b2b3/100; +f2f4 e7e6 g1f3 d7d5 e2e3;c7c5/100; +f2f4 e7e6 g1f3 d7d5 e2e3 c7c5;b2b3/100; + +;g1f3/0;A04 Reti Opening +g1f3;g8f6/100;A05 Reti Opening +g1f3 g8f6;c2c4/100;A15 English Opening +g1f3 g8f6 c2c4;g7g6/100; +g1f3 g8f6 c2c4;e7e6/100; +g1f3 g8f6 c2c4;c7c5/100; +g1f3 g8f6;g2g3/100; +g1f3 g8f6 g2g3;g7g6/100;A05 Reti, King's Indian Attack +g1f3 g8f6 g2g3 g7g6;f1g2/100; +g1f3 g8f6 g2g3 g7g6 f1g2;f8g7/100; +g1f3 g8f6 g2g3 g7g6 f1g2 f8g7;e1g1/100; +g1f3 g8f6 g2g3 g7g6 f1g2 f8g7 e1g1;e8g8/100; +g1f3 g8f6 g2g3 g7g6 f1g2 f8g7 e1g1 e8g8;c2c4/100; +g1f3 g8f6 g2g3 g7g6 f1g2 f8g7 e1g1 e8g8;d2d3/100; +g1f3 g8f6 g2g3 g7g6 f1g2 f8g7 e1g1 e8g8;d2d4/100; +g1f3 g8f6 g2g3;d7d5/50; +g1f3 g8f6 g2g3 d7d5;f1g2/100; +g1f3 g8f6 g2g3 d7d5 f1g2;c7c6/100; +g1f3 g8f6 g2g3 d7d5 f1g2 c7c6;e1g1/100; +g1f3 g8f6 g2g3 d7d5 f1g2 c7c6 e1g1;c8g4/100; +g1f3 g8f6 g2g3 d7d5 f1g2 c7c6 e1g1;c8f5/100; + +;g1h3/0;A00 Amar Opening +g1h3;d7d5/100; + +;g2g3/0;A00 Benko's Opening +g2g3;d7d5/100; +g2g3 d7d5;f1g2/100; +g2g3 d7d5 f1g2;g8f6/100; +g2g3 d7d5 f1g2 g8f6;g1f3/100; +g2g3 d7d5 f1g2 g8f6;d2d3/100; + +;g2g4/0;A00 Grob's Attack +g2g4;d7d5/100; + +;h2h3/0;A00 Clemenz Opening +h2h3;e7e5/100; + +;h2h4/0;A00 Desprez Opening +h2h4;e7e5/100; diff --git a/src/main/scripts/history.html b/src/main/scripts/history.html index fc7fa62..c6f9ea8 100644 --- a/src/main/scripts/history.html +++ b/src/main/scripts/history.html @@ -7,6 +7,12 @@

Version History

+

0.8.0 (????-??-??)

+
    +
  • Ported engine to Java 11.
  • +
  • Converted opening book to CSV format, since JAXB was removed from Java SE in version 11.
  • +
+

0.7.0 (2018-02-12)

  • Moves are represented by integers instead of a Move class.
  • diff --git a/src/main/scripts/ronja.properties b/src/main/scripts/ronja.properties index b6a4fce..8483a33 100644 --- a/src/main/scripts/ronja.properties +++ b/src/main/scripts/ronja.properties @@ -1,5 +1,5 @@ # Opening book filename -ronja.book.file=book.xml +ronja.book.file=book.csv # Game log filename #ronja.game.file=games.pgn diff --git a/src/test/java/se/dykstrom/ronja/common/book/OpeningBookConversionIT.java b/src/test/java/se/dykstrom/ronja/common/book/OpeningBookConversionIT.java new file mode 100644 index 0000000..f51b82b --- /dev/null +++ b/src/test/java/se/dykstrom/ronja/common/book/OpeningBookConversionIT.java @@ -0,0 +1,188 @@ +/* + * Copyright (C) 2018 Johan Dykstrom + * + * 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 3 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, see . + */ + +package se.dykstrom.ronja.common.book; + +import org.junit.Before; +import org.junit.Test; +import se.dykstrom.ronja.common.model.Position; +import se.dykstrom.ronja.common.parser.IllegalMoveException; +import se.dykstrom.ronja.common.parser.MoveParser; +import se.dykstrom.ronja.test.AbstractTestCase; + +import javax.xml.bind.JAXBContext; +import javax.xml.bind.JAXBException; +import javax.xml.bind.Unmarshaller; +import java.io.*; +import java.nio.file.Files; +import java.text.ParseException; +import java.util.*; +import java.util.logging.Logger; + +import static java.util.stream.Collectors.toSet; +import static org.junit.Assert.*; + +/** + * A JUnit test case that is used to convert the opening book from XML format to CSV format, + * and test that the conversion was successful. + * + * @author Johan Dykstrom + * @see OpeningBookParser + */ +public class OpeningBookConversionIT extends AbstractTestCase { + + private static final Logger TLOG = Logger.getLogger(OpeningBookConversionIT.class.getName()); + + private static final String ORIGINAL_FILE_NAME = "target/scripts/book.xml"; + private static final String CONVERTED_FILE_NAME = "target/scripts/book.csv"; + + private File originalFile; + private File convertedFile; + + private final List convertedLines = new ArrayList<>(); + + @Before + public void setUp() { + originalFile = new File(ORIGINAL_FILE_NAME); + assertTrue(originalFile.exists()); + convertedFile = new File(CONVERTED_FILE_NAME); + } + + @Test + public void shouldConvertFile() throws Exception { + // Read original opening book + System.out.println("Reading " + originalFile + "..."); + Map> originalBook = parseXmlFile(originalFile); + assertFalse(originalBook.isEmpty()); + + // Write opening book in CSV format + System.out.println("Writing " + convertedFile + "..."); + writeConvertedBook(convertedLines, convertedFile); + + // Read converted opening book + System.out.println("Reading " + convertedFile + "..."); + Map> convertedBook = readConvertedBook(convertedFile); + assertFalse(convertedBook.isEmpty()); + + // Compare opening books + System.out.println("Converting..."); + assertEquals(originalBook, convertedBook); + } + + private void writeConvertedBook(List convertedLines, File convertedFile) throws IOException { + try (PrintWriter writer = new PrintWriter(convertedFile)) { + convertedLines.forEach(writer::println); + } + } + + private Map> readConvertedBook(File convertedFile) throws Exception { + return OpeningBookParser.parseLines(Files.readAllLines(convertedFile.toPath())); + } + + // ----------------------------------------------------------------------- + + /** Positions and corresponding moves. */ + private Map> positions; + + /** + * Loads the original XML opening book file. + * + * @param file The opening book file. + * @return A hash map of positions and moves. + * @throws IOException If the opening book file cannot be read. + * @throws ParseException If the opening book file cannot be parsed. + */ + private Map> parseXmlFile(File file) throws IOException, ParseException { + positions = new HashMap<>(); + + long start = System.currentTimeMillis(); + try { + JAXBContext context = JAXBContext.newInstance(XmlBookMove.class); + Unmarshaller unmarshaller = context.createUnmarshaller(); + XmlBookMove topMove = (XmlBookMove) unmarshaller.unmarshal(file); + for (XmlBookMove move : topMove.getSubMoves()) { + parseMove(new LinkedList<>(), move); + } + } catch (JAXBException | NumberFormatException e) { + TLOG.severe("Failed to load file '" + file.getName() + "': " + e); + throw new ParseException("Failed to load file '" + file.getName() + "'", 0); + } catch (IllegalArgumentException e) { + TLOG.severe("Failed to load file '" + file.getName() + "': " + e); + throw new IOException("File not found: " + file.getName(), e); + } + long stop = System.currentTimeMillis(); + TLOG.info("Loaded opening book in " + (stop - start) + " ms"); + + // Do some counting + Set hashCodes = positions.keySet().stream().map(Position::hashCode).collect(toSet()); + TLOG.info("Unique positions: " + positions.size() + ", unique hash codes: " + hashCodes.size()); + + return positions; + } + + /** + * Parses a move, adds it to the opening book as a possible move in the + * current position, and parses all sub moves recursively. If the given + * move is invalid, this move and all of its sub moves are ignored, but + * the rest of the opening book is still read. + * + * @param moves The list of moves made so far in this opening line. + * @param xmlMove An XML move read from the opening book file. + */ + private void parseMove(LinkedList moves, XmlBookMove xmlMove) { + // Get attribute values + String move = xmlMove.getCan(); + int weight = xmlMove.getWeight(); + String name = xmlMove.getName() != null ? xmlMove.getName() : ""; + + // Add this move to the opening book + try { + add(moves, move, weight); + String line = String.join(" ", moves) + ";" + move + "/" + weight + ";" + name; + convertedLines.add(line); + } catch (IllegalMoveException ime) { + TLOG.warning("Illegal move [" + move + ", " + weight + "] in opening line " + moves + ": " + ime); + return; + } + + // If we could add this move OK, continue to parse each sub move recursively + moves.addLast(move); + for (XmlBookMove subMove : xmlMove.getSubMoves()) { + parseMove(moves, subMove); + } + moves.removeLast(); + } + + /** + * Adds the supplied move as a possible move in the current position. + * + * @param moves The list of moves made so far in this opening line. + * @param move The move to add, in coordinate algebraic notation. + * @param weight The weight of the move in this position. + * @throws IllegalMoveException If any of the moves in the move list, or the new move, is illegal. + */ + private void add(List moves, String move, int weight) throws IllegalMoveException { + // Set up a new position + Position position = Position.of(moves); + + // Get the list of possible moves for this position + List list = positions.computeIfAbsent(position, key -> new ArrayList<>()); + + // Create the new move and add it to the list + list.add(new BookMove(MoveParser.parse(move, position), weight)); + } +} diff --git a/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserIT.java b/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserIT.java index 5a88733..b2794b7 100644 --- a/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserIT.java +++ b/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserIT.java @@ -17,25 +17,22 @@ package se.dykstrom.ronja.common.book; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNull; -import static org.junit.Assert.assertThat; -import static org.junit.Assert.assertTrue; -import static se.dykstrom.ronja.test.SizeMatcher.hasSize; +import org.junit.Test; +import se.dykstrom.ronja.common.model.Position; +import se.dykstrom.ronja.common.parser.CanParser; +import se.dykstrom.ronja.common.parser.FenParser; +import se.dykstrom.ronja.test.AbstractTestCase; +import se.dykstrom.ronja.test.TestUtils; import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import java.text.ParseException; import java.util.List; -import org.junit.BeforeClass; -import org.junit.Test; - -import se.dykstrom.ronja.common.parser.CanParser; -import se.dykstrom.ronja.common.parser.FenParser; -import se.dykstrom.ronja.test.AbstractTestCase; -import se.dykstrom.ronja.test.TestUtils; +import static org.junit.Assert.*; +import static se.dykstrom.ronja.test.SizeMatcher.hasSize; /** * This class is for integration testing class {@code OpeningBookParser} using JUnit. @@ -45,23 +42,14 @@ */ public class OpeningBookParserIT extends AbstractTestCase { - private static File bookFile; - - @BeforeClass - public static void setUpClass() throws Exception { - bookFile = TestUtils.createBookFile(); - } - - // ------------------------------------------------------------------------ - @Test - public void testOpeningBookParser_ValidFile() throws Exception { - OpeningBook book = OpeningBookParser.parse(bookFile); + public void shouldParseValidFile() throws Exception { + OpeningBook book = OpeningBookParser.parse(TestUtils.createBookFile()); assertEquals(4, book.size()); List moves = book.findAllMoves(FenParser.parse(FEN_START)); assertEquals(1, moves.size()); - assertEquals("e2e4", CanParser.format(moves.get(0).getMove())); + assertEquals(MOVE_E2E4, moves.get(0).getMove()); moves = book.findAllMoves(FenParser.parse(FEN_E4)); assertThat(moves, hasSize(2)); @@ -74,96 +62,69 @@ public void testOpeningBookParser_ValidFile() throws Exception { } @Test(expected = ParseException.class) - public void testOpeningBookParser_InvalidFile_MissingTag() throws Exception { - File file = File.createTempFile("ronja_tag_", ".xml"); + public void shouldNotParseSyntaxError() throws Exception { + File file = File.createTempFile("ronja_syntax_", ".csv"); file.deleteOnExit(); - try (PrintStream out = new PrintStream(file, "ISO-8859-1")) { - out.println(""); - out.println(""); - out.println(" "); - out.println(" "); - out.println(""); + try (PrintStream out = new PrintStream(file, StandardCharsets.UTF_8)) { + out.println("foo"); } - OpeningBook book = OpeningBookParser.parse(file); - assertNull(book); + OpeningBookParser.parse(file); } @Test - public void testOpeningBookParser_InvalidFile_MissingAttribute() throws Exception { - File file = File.createTempFile("ronja_attribute_", ".xml"); + public void shouldNotIncludeInvalidMove() throws Exception { + // Given + File file = File.createTempFile("ronja_move_", ".csv"); file.deleteOnExit(); - try (PrintStream out = new PrintStream(file, "ISO-8859-1")) { - out.println(""); - out.println(""); - out.println(" "); // Missing can - out.println(" "); - out.println(" "); - out.println(" "); - out.println(""); + try (PrintStream out = new PrintStream(file, StandardCharsets.UTF_8)) { + out.println(";foo/100;Initial position"); } + // When OpeningBook book = OpeningBookParser.parse(file); - assertEquals(1, book.size()); // Initial position + + // Then + assertEquals(1, book.size()); + assertEquals(0, book.findAllMoves(Position.START).size()); } @Test - public void testOpeningBookParser_InvalidFile_InvalidMove() throws Exception { - File file = File.createTempFile("ronja_move_", ".xml"); + public void shouldNotIncludeInvalidWeight() throws Exception { + // Given + File file = File.createTempFile("ronja_weight_", ".csv"); file.deleteOnExit(); - try (PrintStream out = new PrintStream(file, "ISO-8859-1")) { - out.println(""); - out.println(""); - out.println(" "); - out.println(" "); // Invalid move - out.println(" "); - out.println(" "); - out.println(""); + try (PrintStream out = new PrintStream(file, StandardCharsets.UTF_8)) { + out.println(";e2e4/foo;Initial position"); } + // When OpeningBook book = OpeningBookParser.parse(file); - assertEquals(2, book.size()); // Initial position and position after e2e4 - } - - @Test(expected = ParseException.class) - public void testOpeningBookParser_InvalidFile_InvalidWeight() throws Exception { - File file = File.createTempFile("ronja_tag_", ".xml"); - file.deleteOnExit(); - try (PrintStream out = new PrintStream(file, "ISO-8859-1")) { - out.println(""); - out.println(""); - out.println(" "); // Invalid weight - out.println(" "); - out.println(" "); - out.println(""); - } - - OpeningBook book = OpeningBookParser.parse(file); - assertNull(book); + // Then + assertEquals(1, book.size()); + assertEquals(0, book.findAllMoves(Position.START).size()); } @Test - public void testOpeningBookParser_EmptyFile() throws Exception { - File file = File.createTempFile("ronja_empty_", ".xml"); + public void shouldParseEmptyFile() throws Exception { + // Given + File file = File.createTempFile("ronja_empty_", ".csv"); file.deleteOnExit(); - try (PrintStream out = new PrintStream(file, "ISO-8859-1")) { - out.println(""); - out.println(""); - out.println(""); - } - + // When OpeningBook book = OpeningBookParser.parse(file); + + // Then assertEquals(0, book.size()); } @Test(expected = IOException.class) - public void testOpeningBookParser_NoFile() throws Exception { - OpeningBook book = OpeningBookParser.parse(new File("foo.xml")); + public void shouldThrowExceptionWhenMissingFile() throws Exception { + OpeningBook book = OpeningBookParser.parse(new File("does_not_exist.csv")); assertNull(book); } } diff --git a/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserTest.java b/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserTest.java new file mode 100644 index 0000000..d0e2569 --- /dev/null +++ b/src/test/java/se/dykstrom/ronja/common/book/OpeningBookParserTest.java @@ -0,0 +1,115 @@ +/* + * Copyright (C) 2018 Johan Dykstrom + * + * 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 3 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, see . + */ + +package se.dykstrom.ronja.common.book; + +import org.junit.Test; +import se.dykstrom.ronja.common.model.Position; +import se.dykstrom.ronja.common.parser.FenParser; +import se.dykstrom.ronja.test.AbstractTestCase; + +import java.text.ParseException; +import java.util.List; +import java.util.Map; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.junit.Assert.assertEquals; + +/** + * Tests class {@code OpeningBookParser}. + * + * @author Johan Dykstrom + * @see OpeningBookParser + */ +public class OpeningBookParserTest extends AbstractTestCase { + + private static final String START_E4 = ";e2e4/100;King's Pawn Opening"; + private static final String START_D4 = ";d2d4/50;Queen's Pawn Opening"; + private static final String START_E4_E5 = "e2e4;e7e5/100;King's Pawn Game"; + private static final String START_E4_E5_NF3 = "e2e4 e7e5;g1f3/100;"; + private static final String START_E4_E6 = "e2e4;e7e6/100;French Defense"; + private static final String LINE_WITHOUT_COMMENT = ";e2e4/100;"; + private static final String LINE_WITH_SYNTAX_ERROR = "Syntax Error"; + + @Test + public void shouldParseEmptyFile() throws Exception { + // When + Map> positions = OpeningBookParser.parseLines(emptyList()); + + // Then + assertEquals(0, positions.size()); + } + + @Test + public void shouldParseInitialPosition() throws Exception { + // Given + List expectedMoves = asList(new BookMove(MOVE_E2E4, 100), new BookMove(MOVE_D2D4, 50)); + + // When + Map> positions = OpeningBookParser.parseLines(asList(START_E4, START_D4)); + + // Then + assertEquals(1, positions.size()); + assertEquals(expectedMoves, positions.get(FenParser.parse(FEN_START))); + } + + @Test + public void shouldParseAfterE4() throws Exception { + // Given + List expectedMoves = asList(new BookMove(MOVE_E7E5, 100), new BookMove(MOVE_E7E6, 100)); + + // When + Map> positions = OpeningBookParser.parseLines(asList(START_E4_E5, START_E4_E6)); + + // Then + assertEquals(1, positions.size()); + assertEquals(expectedMoves, positions.get(FenParser.parse(FEN_E4))); + } + + @Test + public void shouldParseAfterE4E5() throws Exception { + // Given + List expectedMoves = singletonList(new BookMove(MOVE_G1F3, 100)); + + // When + Map> positions = OpeningBookParser.parseLines(singletonList(START_E4_E5_NF3)); + + // Then + assertEquals(1, positions.size()); + assertEquals(expectedMoves, positions.get(FenParser.parse(FEN_E4_E5))); + } + + @Test + public void shouldParseLineWithoutComment() throws Exception { + // Given + List expectedMoves = singletonList(new BookMove(MOVE_E2E4, 100)); + + // When + Map> positions = OpeningBookParser.parseLines(singletonList(LINE_WITHOUT_COMMENT)); + + // Then + assertEquals(1, positions.size()); + assertEquals(expectedMoves, positions.get(FenParser.parse(FEN_START))); + } + + @Test(expected = ParseException.class) + public void shouldNotParseSyntaxError() throws Exception { + OpeningBookParser.parseLines(singletonList(LINE_WITH_SYNTAX_ERROR)); + } +} diff --git a/src/main/java/se/dykstrom/ronja/common/book/XmlBookMove.java b/src/test/java/se/dykstrom/ronja/common/book/XmlBookMove.java similarity index 100% rename from src/main/java/se/dykstrom/ronja/common/book/XmlBookMove.java rename to src/test/java/se/dykstrom/ronja/common/book/XmlBookMove.java diff --git a/src/test/java/se/dykstrom/ronja/common/parser/PgnParserTest.java b/src/test/java/se/dykstrom/ronja/common/parser/PgnParserTest.java index 58bab0a..2dd34eb 100644 --- a/src/test/java/se/dykstrom/ronja/common/parser/PgnParserTest.java +++ b/src/test/java/se/dykstrom/ronja/common/parser/PgnParserTest.java @@ -17,23 +17,20 @@ package se.dykstrom.ronja.common.parser; -import static org.hamcrest.CoreMatchers.both; -import static org.hamcrest.CoreMatchers.containsString; -import static org.hamcrest.CoreMatchers.not; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertThat; - -import java.time.LocalDateTime; -import java.time.format.DateTimeFormatter; - import org.junit.Test; - import se.dykstrom.ronja.common.book.OpeningBook; import se.dykstrom.ronja.common.model.Color; import se.dykstrom.ronja.common.model.Game; import se.dykstrom.ronja.engine.utils.AppConfig; import se.dykstrom.ronja.test.AbstractTestCase; +import java.time.LocalDateTime; +import java.time.format.DateTimeFormatter; + +import static org.hamcrest.CoreMatchers.*; +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertThat; + /** * This class is for testing class {@code PgnParser} using JUnit. * @@ -44,7 +41,7 @@ public class PgnParserTest extends AbstractTestCase { private static final LocalDateTime DATE = LocalDateTime.of(2016, 2, 18, 14, 31, 0); - private static final DateTimeFormatter DF = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + private static final DateTimeFormatter DF = DateTimeFormatter.ISO_LOCAL_DATE; private static final DateTimeFormatter TF = DateTimeFormatter.ofPattern("HH:mm"); private final Game game = new Game(OpeningBook.DEFAULT); diff --git a/src/test/java/se/dykstrom/ronja/common/utils/ArrayUtilsTest.java b/src/test/java/se/dykstrom/ronja/common/utils/ArrayUtilsTest.java index f59d518..91ef872 100644 --- a/src/test/java/se/dykstrom/ronja/common/utils/ArrayUtilsTest.java +++ b/src/test/java/se/dykstrom/ronja/common/utils/ArrayUtilsTest.java @@ -35,12 +35,12 @@ public class ArrayUtilsTest extends AbstractTestCase { @Test - public void shouldConvertEmptyList() throws Exception { + public void shouldConvertEmptyList() { assertArrayEquals(new int[0], ArrayUtils.toArray(Collections.emptyList())); } @Test - public void shouldConvertList() throws Exception { + public void shouldConvertList() { assertArrayEquals(new int[] {1, 2, 3}, ArrayUtils.toArray(Arrays.asList(1, 2, 3))); } } diff --git a/src/test/java/se/dykstrom/ronja/engine/core/FullMoveGeneratorTest.java b/src/test/java/se/dykstrom/ronja/engine/core/FullMoveGeneratorTest.java index 404141c..b7fc617 100644 --- a/src/test/java/se/dykstrom/ronja/engine/core/FullMoveGeneratorTest.java +++ b/src/test/java/se/dykstrom/ronja/engine/core/FullMoveGeneratorTest.java @@ -116,7 +116,6 @@ public void testPosition_BQC_OK() throws Exception { * Asserts that the list of actual moves contains the same moves as the array of expected moves. * * @param expectedMoves An array of expected moves, in CAN format. - * @param actualMoves The list of actual moves to check. */ private void assertMoves(String[] expectedMoves) { int moveIndex = MOVE_GENERATOR.getMoveIndex(); diff --git a/src/test/java/se/dykstrom/ronja/engine/core/SlowFinderTest.java b/src/test/java/se/dykstrom/ronja/engine/core/SlowFinderTest.java index 70afed3..fe94316 100644 --- a/src/test/java/se/dykstrom/ronja/engine/core/SlowFinderTest.java +++ b/src/test/java/se/dykstrom/ronja/engine/core/SlowFinderTest.java @@ -71,7 +71,7 @@ public void testFindBestMove_MateInFive() throws Exception { */ @Test public void testFindBestMove_DrawInFive() throws Exception { - Integer actual = findBestMoveWithDepth(FEN_DRAW_2_0, 5); + int actual = findBestMoveWithDepth(FEN_DRAW_2_0, 5); assertEquals(Piece.PAWN, Move.getPiece(actual)); assertEquals(Square.B7, Move.getFrom(actual)); assertEquals(Square.B8, Move.getTo(actual)); diff --git a/src/test/java/se/dykstrom/ronja/engine/ui/CommandParserTest.java b/src/test/java/se/dykstrom/ronja/engine/ui/CommandParserTest.java index 4d2f73b..4ffe7e3 100644 --- a/src/test/java/se/dykstrom/ronja/engine/ui/CommandParserTest.java +++ b/src/test/java/se/dykstrom/ronja/engine/ui/CommandParserTest.java @@ -17,20 +17,19 @@ package se.dykstrom.ronja.engine.ui; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; - -import java.io.ByteArrayInputStream; -import java.io.InputStream; -import java.nio.charset.Charset; - import org.junit.Test; - import se.dykstrom.ronja.common.book.OpeningBook; import se.dykstrom.ronja.common.model.Game; import se.dykstrom.ronja.engine.ui.command.*; import se.dykstrom.ronja.test.AbstractTestCase; +import java.io.ByteArrayInputStream; +import java.io.InputStream; +import java.nio.charset.StandardCharsets; + +import static org.junit.Assert.assertEquals; +import static org.junit.Assert.assertNotNull; + /** * This class is for testing class {@code CommandParser} using JUnit. * @@ -101,7 +100,7 @@ public void testMultipleCommands() throws Exception { private void doTest(String commands, Class[] classes, String[] args) throws Exception { assertEquals(classes.length, args.length); - InputStream in = new ByteArrayInputStream(commands.getBytes(Charset.forName("ISO-8859-1"))); + InputStream in = new ByteArrayInputStream(commands.getBytes(StandardCharsets.ISO_8859_1)); CommandParser commandParser = new CommandParser(in, System.out, game); for (int i = 0; i < classes.length; i++) { diff --git a/src/test/java/se/dykstrom/ronja/engine/ui/RonjaIT.java b/src/test/java/se/dykstrom/ronja/engine/ui/RonjaIT.java new file mode 100644 index 0000000..28d040d --- /dev/null +++ b/src/test/java/se/dykstrom/ronja/engine/ui/RonjaIT.java @@ -0,0 +1,149 @@ +/* + * Copyright (C) 2018 Johan Dykstrom + * + * 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 3 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, see . + */ + +package se.dykstrom.ronja.engine.ui; + +import org.junit.After; +import org.junit.Before; +import org.junit.Test; + +import java.io.*; +import java.nio.charset.StandardCharsets; +import java.util.ArrayList; +import java.util.List; + +import static org.junit.Assert.assertNotNull; +import static org.junit.Assert.fail; +import static se.dykstrom.ronja.test.TestUtils.assertContainsRegex; +import static se.dykstrom.ronja.test.TestUtils.containsRegex; + +/** + * This class is for integration testing class {@code Ronja}. + * + * @author Johan Dykstrom + * @see Ronja + */ +public class RonjaIT { + + private final InputStream stdin = System.in; + private final PrintStream stdout = System.out; + + private Thread thread; + private PrintStream commandStream; + private PipedInputStream responseStream; + + @Before + public void setUp() throws Exception { + PipedInputStream redirectedStdin = new PipedInputStream(); + commandStream = new PrintStream(new PipedOutputStream(redirectedStdin), true, StandardCharsets.ISO_8859_1); + System.setIn(redirectedStdin); + + responseStream = new PipedInputStream(); + PrintStream redirectedStdout = new PrintStream(new PipedOutputStream(responseStream), true, StandardCharsets.ISO_8859_1); + System.setOut(redirectedStdout); + + thread = new Thread(new Engine()); + thread.start(); + } + + @After + public void tearDown() throws Exception { + thread.join(1000); + + // Restore System.in and System.out + System.setIn(stdin); + System.setOut(stdout); + } + + @Test + public void shouldQuit() { + commandStream.println("quit"); + } + + @Test + public void testInitSequence() throws Exception { + commandStream.println("xboard"); + commandStream.println("protover 2"); + List list = readAllInput(); + assertContainsRegex("feature done=1", list); + commandStream.println("new"); + commandStream.println("quit"); + } + + @Test + public void shouldAnswerPong() throws Exception { + commandStream.println("xboard"); + commandStream.println("ping 17"); + List list = readAllInput(); + assertContainsRegex("pong 17", list); + commandStream.println("quit"); + } + + @Test + public void shouldPlaySingleMove() throws Exception { + commandStream.println("xboard"); + commandStream.println("protover 2"); + discardAllInput(); + commandStream.println("new"); + commandStream.println("usermove e2e4"); + List list = readAllInput(); + assertContainsRegex("move e7(e5|e6)", list); + commandStream.println("quit"); + } + + /** + * Reads all lines of input that is available from {@code stdin}, and returns this as a list of strings. + */ + private List readAllInput() throws Exception { + List list = new ArrayList<>(); + + BufferedReader reader = new BufferedReader(new InputStreamReader(responseStream, StandardCharsets.ISO_8859_1)); + + // Assume there will be some input + while (!reader.ready()) { + Thread.sleep(1000); + } + while (reader.ready()) { + list.add(reader.readLine()); + } + + // Fail if we discover an exception + if (containsRegex("Exception", list)) { + fail("Engine exception: " + list); + } + + return list; + } + + /** + * Reads all lines of input that is available from {@code stdin}, and throws them away. + */ + private void discardAllInput() throws Exception { + assertNotNull(readAllInput()); + } + + private static class Engine implements Runnable { + @Override + public void run() { + try { + Ronja.main(new String[]{}); + } catch (IOException e) { + fail("Caught exception: " + e); + } + } + } +} diff --git a/src/test/java/se/dykstrom/ronja/engine/ui/XBoardProtocolIT.java b/src/test/java/se/dykstrom/ronja/engine/ui/XBoardProtocolIT.java index 99e28cc..7d34644 100644 --- a/src/test/java/se/dykstrom/ronja/engine/ui/XBoardProtocolIT.java +++ b/src/test/java/se/dykstrom/ronja/engine/ui/XBoardProtocolIT.java @@ -17,13 +17,10 @@ package se.dykstrom.ronja.engine.ui; -import static java.util.regex.Pattern.quote; -import static org.junit.Assert.assertEquals; -import static org.junit.Assert.assertNotNull; -import static org.junit.Assert.fail; -import static se.dykstrom.ronja.test.TestUtils.assertContainsRegex; -import static se.dykstrom.ronja.test.TestUtils.containsRegex; -import static se.dykstrom.ronja.test.TestUtils.waitForSupplier; +import org.junit.*; +import se.dykstrom.ronja.engine.utils.AppConfig; +import se.dykstrom.ronja.test.AbstractTestCase; +import se.dykstrom.ronja.test.TestUtils; import java.io.BufferedReader; import java.io.File; @@ -37,14 +34,9 @@ import java.util.concurrent.TimeUnit; import java.util.logging.Logger; -import org.junit.After; -import org.junit.Before; -import org.junit.BeforeClass; -import org.junit.Test; - -import se.dykstrom.ronja.engine.utils.AppConfig; -import se.dykstrom.ronja.test.AbstractTestCase; -import se.dykstrom.ronja.test.TestUtils; +import static java.util.regex.Pattern.quote; +import static org.junit.Assert.*; +import static se.dykstrom.ronja.test.TestUtils.*; /** * This class is for integration tests related to the XBoard protocol (Chess Engine Communication Protocol). @@ -56,7 +48,7 @@ public class XBoardProtocolIT extends AbstractTestCase { private static final Logger TLOG = Logger.getLogger(XBoardProtocolIT.class.getName()); - private static final DateTimeFormatter DF = DateTimeFormatter.ofPattern("yyyy-MM-dd"); + private static final DateTimeFormatter DF = DateTimeFormatter.ISO_LOCAL_DATE; private static final String ENGINE_NAME = "ENGINE_NAME"; diff --git a/src/test/java/se/dykstrom/ronja/engine/utils/AppConfigTest.java b/src/test/java/se/dykstrom/ronja/engine/utils/AppConfigTest.java index eb4f056..8e42f27 100644 --- a/src/test/java/se/dykstrom/ronja/engine/utils/AppConfigTest.java +++ b/src/test/java/se/dykstrom/ronja/engine/utils/AppConfigTest.java @@ -21,6 +21,7 @@ import java.io.File; import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import org.junit.Before; import org.junit.Test; @@ -50,7 +51,7 @@ public void setUp() throws Exception { File file = new File(TEMP_DIRECTORY, "ronja.properties"); file.deleteOnExit(); - try (PrintStream out = new PrintStream(file, "ISO-8859-1")) { + try (PrintStream out = new PrintStream(file, StandardCharsets.ISO_8859_1)) { out.println(AppConfig.PROPERTY_ENGINE_NAME + "=" + FILE_ENGINE_NAME); } } diff --git a/src/test/java/se/dykstrom/ronja/test/TestUtils.java b/src/test/java/se/dykstrom/ronja/test/TestUtils.java index c50e18c..f24831d 100644 --- a/src/test/java/se/dykstrom/ronja/test/TestUtils.java +++ b/src/test/java/se/dykstrom/ronja/test/TestUtils.java @@ -17,16 +17,17 @@ package se.dykstrom.ronja.test; -import static org.junit.Assert.assertTrue; -import static org.junit.Assert.fail; - import java.io.File; import java.io.IOException; import java.io.PrintStream; +import java.nio.charset.StandardCharsets; import java.util.List; import java.util.concurrent.TimeUnit; import java.util.regex.Pattern; +import static org.junit.Assert.assertTrue; +import static org.junit.Assert.fail; + /** * Utility functions related to testing. * @@ -95,23 +96,17 @@ public static void assertContainsRegex(String regex, List list) { * @return A reference to the created file. */ public static File createBookFile() throws IOException { - File bookFile = File.createTempFile("ronja_", ".xml"); + File bookFile = File.createTempFile("ronja_", ".csv"); bookFile.deleteOnExit(); - try (PrintStream out = new PrintStream(bookFile, "ISO-8859-1")) { - out.println(""); - out.println(""); - out.println(" "); - out.println(" "); - out.println(" "); - out.println(" "); - out.println(" "); - out.println(" "); - out.println(" "); - out.println(" "); - out.println(""); + try (PrintStream out = new PrintStream(bookFile, StandardCharsets.UTF_8)) { + out.println(";e2e4/100;King's Pawn Opening"); + out.println("e2e4;e7e5/50;King's Pawn Game"); + out.println("e2e4 e7e5;g1f3/100;"); + out.println("e2e4;e7e6/50;French Defense"); + out.println("e2e4 e7e6;d2d4/100;"); } - + return bookFile; } } From e91625b2aa5a7885c0e24d7879fdbee5126439a9 Mon Sep 17 00:00:00 2001 From: dykstrom Date: Wed, 12 Dec 2018 18:46:29 +0100 Subject: [PATCH 2/2] Updated documentation. --- src/main/scripts/history.html | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/main/scripts/history.html b/src/main/scripts/history.html index c6f9ea8..55f0afa 100644 --- a/src/main/scripts/history.html +++ b/src/main/scripts/history.html @@ -7,7 +7,7 @@

    Version History

    -

    0.8.0 (????-??-??)

    +

    0.8.0 (2018-12-12)

    • Ported engine to Java 11.
    • Converted opening book to CSV format, since JAXB was removed from Java SE in version 11.