diff --git a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Book.java b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Book.java index 781ab47..f49e04c 100644 --- a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Book.java +++ b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Book.java @@ -178,18 +178,19 @@ public final String getAllBookMoves(Position pos) { } /** Creates the book.bin file. */ - public static void main(String[] args) throws IOException { + public static void main(String[] args) { List binBook = createBinBook(); - FileOutputStream out = new FileOutputStream("../src/book.bin"); - int bookLen = binBook.size(); - byte[] binBookA = new byte[bookLen]; - for (int i = 0; i < bookLen; i++) - binBookA[i] = binBook.get(i); - out.write(binBookA); - out.close(); + try (FileOutputStream out = new FileOutputStream("../src/book.bin")) { + int bookLen = binBook.size(); + byte[] binBookA = new byte[bookLen]; + for (int i = 0; i < bookLen; i++) binBookA[i] = binBook.get(i); + out.write(binBookA); + } catch (IOException e) { + e.printStackTrace(); } - - public static List createBinBook() { + } + + public static List createBinBook() { List binBook = new ArrayList<>(0); try { InputStream inStream = Object.class.getResourceAsStream("/book.txt"); diff --git a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/ComputerPlayer.java b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/ComputerPlayer.java index 6213a9a..5d8880f 100644 --- a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/ComputerPlayer.java +++ b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/ComputerPlayer.java @@ -213,7 +213,7 @@ private Move findSemiRandomMove(Search sc, MoveGen.MoveList moves) { for (int mi = 0; mi < moves.size; mi++) { sum += moveProbWeight(moves.m[mi].score, bestScore); } - int rnd = rndGen.nextInt(sum); + int rnd = sum == 0 ? 0 : rndGen.nextInt(sum); for (int mi = 0; mi < moves.size; mi++) { int weight = moveProbWeight(moves.m[mi].score, bestScore); if (rnd < weight) { diff --git a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Evaluate.java b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Evaluate.java index d81b69c..08bea1b 100644 --- a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Evaluate.java +++ b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/Evaluate.java @@ -1131,7 +1131,7 @@ private static int kpkEval(int wKing, int bKing, int wPawn, boolean whiteMove) { int bytePos = index / 8; int bitPos = index % 8; - boolean draw = ((kpkTable[bytePos]) & (1 << bitPos)) == 0; + boolean draw = ((kpkTable[bytePos] & 0xff) & (1 << bitPos)) == 0; if (draw) return 0; return qV - pV / 4 * (7-Position.getY(wPawn)); @@ -1148,7 +1148,7 @@ private static int krkpEval(int wKing, int bKing, int bPawn, boolean whiteMove) index = index * 48 + bPawn - 8; index = index * 8 + Position.getY(wKing); byte mask = krkpTable[index]; - boolean canWin = (mask & (1 << Position.getX(wKing))) != 0; + boolean canWin = (mask & 0xff & (1 << Position.getX(wKing))) != 0; int score = rV - pV + Position.getY(bPawn) * pV / 4; if (canWin) diff --git a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/TreeLogger.java b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/TreeLogger.java index 9d6ce15..de52bd1 100644 --- a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/TreeLogger.java +++ b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/chess/TreeLogger.java @@ -29,6 +29,8 @@ import java.nio.channels.FileChannel.MapMode; import java.util.ArrayList; import java.util.Collections; +import java.util.Objects; + import org.petero.cuckoo.engine.chess.TranspositionTable.TTEntry; public final class TreeLogger { @@ -161,7 +163,7 @@ private static int indexToFileOffs(int index) { /** Compute endIndex for all StartNode entries. */ private void computeForwardPointers() { - if ((mapBuf.get(127) & (1<<7)) != 0) + if ((mapBuf.get(127) & 0xff & (1<<7)) != 0) return; System.out.print("Computing forward pointers...\n"); StartEntry se = new StartEntry(); @@ -213,6 +215,7 @@ private boolean readEntry(int index, StartEntry se, EndEntry ee) { int otherIndex = bb.getInt(0); boolean isStartEntry = (otherIndex == -1) || (otherIndex > index); if (isStartEntry) { + Objects.requireNonNull(se); se.endIndex = otherIndex; se.parentIndex = bb.getInt(4); int m = bb.getShort(8); @@ -222,6 +225,7 @@ private boolean readEntry(int index, StartEntry se, EndEntry ee) { se.ply = bb.get(14); se.depth = bb.get(15); } else { + Objects.requireNonNull(ee); ee.startIndex = otherIndex; ee.score = bb.getShort(4); ee.scoreType = bb.getShort(6); diff --git a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/guibase/ChessController.java b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/guibase/ChessController.java index ec80969..b347111 100644 --- a/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/guibase/ChessController.java +++ b/cuckoo-engine/src/main/java/org/petero/cuckoo/engine/guibase/ChessController.java @@ -183,62 +183,60 @@ public void setPGN(String pgn) throws ChessParseError { // Parse tag section Position pos = TextIO.readFEN(TextIO.START_POS_FEN); - Scanner sc = new Scanner(pgn); - sc.useDelimiter("\\s+"); - while (sc.hasNext("\\[.*")) { + try (Scanner sc = new Scanner(pgn)) { + sc.useDelimiter("\\s+"); + while (sc.hasNext("\\[.*")) { String tagName = sc.next(); if (tagName.length() > 1) { - tagName = tagName.substring(1); + tagName = tagName.substring(1); } else { - tagName = sc.next(); + tagName = sc.next(); } String tagValue = sc.findWithinHorizon(".*\\]", 0); tagValue = tagValue.trim(); - if (tagValue.charAt(0) == '"') - tagValue = tagValue.substring(1); - if (tagValue.charAt(tagValue.length()-1) == ']') - tagValue = tagValue.substring(0, tagValue.length() - 1); - if (tagValue.charAt(tagValue.length()-1) == '"') - tagValue = tagValue.substring(0, tagValue.length() - 1); + if (tagValue.charAt(0) == '"') tagValue = tagValue.substring(1); + if (tagValue.charAt(tagValue.length() - 1) == ']') + tagValue = tagValue.substring(0, tagValue.length() - 1); + if (tagValue.charAt(tagValue.length() - 1) == '"') + tagValue = tagValue.substring(0, tagValue.length() - 1); if (tagName.equals("FEN")) { - pos = TextIO.readFEN(tagValue); + pos = TextIO.readFEN(tagValue); } - } - game.processString("new"); - game.pos = pos; + } + game.processString("new"); + game.pos = pos; - // Handle (ignore) recursive annotation variations - { + // Handle (ignore) recursive annotation variations + { StringBuilder out = new StringBuilder(); sc.useDelimiter(""); int level = 0; while (sc.hasNext()) { - String c = sc.next(); - if (c.equals("(")) { - level++; - } else if (c.equals(")")) { - level--; - } else if (level == 0) { - out.append(c); - } + String c = sc.next(); + if (c.equals("(")) { + level++; + } else if (c.equals(")")) { + level--; + } else if (level == 0) { + out.append(c); + } } pgn = out.toString(); + } } - sc.close(); // Parse move text section - sc = new Scanner(pgn); - sc.useDelimiter("\\s+"); - while (sc.hasNext()) { + try (Scanner sc = new Scanner(pgn)) { + sc.useDelimiter("\\s+"); + while (sc.hasNext()) { String strMove = sc.next(); strMove = strMove.replaceFirst("\\$?[0-9]*\\.*([^?!]*)[?!]*", "$1"); if (strMove.isEmpty()) continue; Optional m = TextIO.stringToMove(game.pos, strMove); - if (m.isEmpty()) - break; + if (m.isEmpty()) break; game.processString(strMove); + } } - sc.close(); } public final boolean humansTurn() { @@ -404,6 +402,7 @@ public synchronized void stopComputerThinking() { computerThread.join(); } catch (InterruptedException ex) { System.out.printf("Could not stop thread%n"); + computerThread.interrupt(); } computerThread = null; updateGUI(); diff --git a/cuckoo-gui/src/main/java/org/petero/cuckoo/gui/AppletGUI.java b/cuckoo-gui/src/main/java/org/petero/cuckoo/gui/AppletGUI.java index 0694cd2..73c5c92 100644 --- a/cuckoo-gui/src/main/java/org/petero/cuckoo/gui/AppletGUI.java +++ b/cuckoo-gui/src/main/java/org/petero/cuckoo/gui/AppletGUI.java @@ -28,6 +28,7 @@ import java.awt.*; import java.io.Serial; +import java.lang.reflect.InvocationTargetException; /** * The main class for the chess GUI. @@ -42,7 +43,7 @@ public class AppletGUI extends JFrame implements GUIInterface { String moveListStr = ""; String thinkingStr = ""; - public AppletGUI(String title) throws HeadlessException { + public AppletGUI(String title) { super(title); ctrl = new ChessController(this); try { @@ -52,8 +53,11 @@ public AppletGUI(String title) throws HeadlessException { ctrl.newGame(playerWhite.isSelected(), TT_LOG_SIZE, true); ctrl.startGame(); }); - } catch (Exception ex) { - ex.printStackTrace(); + } catch (InvocationTargetException e) { + e.printStackTrace(); + } catch (InterruptedException e) { + Thread.currentThread().interrupt(); + e.printStackTrace(); } } diff --git a/cuckoo-uci/src/main/java/org/petero/cuckoo/uci/EngineControl.java b/cuckoo-uci/src/main/java/org/petero/cuckoo/uci/EngineControl.java index 5349d8b..ddf248f 100644 --- a/cuckoo-uci/src/main/java/org/petero/cuckoo/uci/EngineControl.java +++ b/cuckoo-uci/src/main/java/org/petero/cuckoo/uci/EngineControl.java @@ -46,6 +46,9 @@ * @author petero */ public class EngineControl { + + private static final Random random = new Random(); + final PrintStream os; Thread engineThread; @@ -163,7 +166,7 @@ public final void stopSearch() { } public final void newGame() { - randomSeed = new Random().nextLong(); + randomSeed = random.nextLong(); tt.clear(); } @@ -200,7 +203,7 @@ public final void computeTimeLimit(SearchParams sPar) { final int margin = Math.min(1000, time * 9 / 10); int timeLimit = (time + inc * (moves - 1) - margin) / moves; minTimeLimit = (int) (timeLimit * 0.85); - maxTimeLimit = (int) (minTimeLimit * (Math.max(2.5, Math.min(4.0, moves / 2)))); + maxTimeLimit = (int) (minTimeLimit * (Math.max(2.5, Math.min(4.0, moves / 2.0)))); // Leave at least 1s on the clock, but can't use negative time minTimeLimit = clamp(minTimeLimit, time - margin); @@ -236,7 +239,7 @@ private void startThread(final int minTimeLimit, final int maxTimeLimit, int max } tt.nextGeneration(); final int srchmaxDepth = maxDepth; - engineThread = new Thread(() -> { + engineThread = Thread.ofVirtual().start(() -> { Move m = null; if (ownBook && !analyseMode) { Book book = new Book(false); @@ -283,7 +286,7 @@ private void stopThread() { try { myThread.join(); } catch (InterruptedException ex) { - throw new RuntimeException(); + myThread.interrupt(); } } }