barrysw19.calculon.uci.UCIInterface.java Source code

Java tutorial

Introduction

Here is the source code for barrysw19.calculon.uci.UCIInterface.java

Source

/**
 * Calculon - A Java chess-engine.
 *
 * Copyright (C) 2008-2009 Barry Smith
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
 * implied. See the License for the specific language governing
 * permissions and limitations under the License.
 */
package barrysw19.calculon.uci;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.PrintStream;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import barrysw19.calculon.engine.ChessEngine;
import barrysw19.calculon.notation.PGNUtils;
import barrysw19.calculon.engine.BitBoard;
import barrysw19.calculon.notation.FENUtils;

import org.apache.commons.lang.StringUtils;

public class UCIInterface {
    private static Logger log = Logger.getLogger(UCIInterface.class.getName());

    private Map<String, Command> commands = new HashMap<String, Command>();
    private PrintStream out;
    private volatile boolean terminate = false;
    //   private boolean debug = false;

    private BitBoard board = new BitBoard();

    public static void main(String[] args) {
        UCIInterface uciInterface = new UCIInterface();

        try {
            uciInterface.startInterface();
        } catch (Exception x) {
            log.log(Level.SEVERE, "UCI Error", x);
        }
    }

    private UCIInterface() {
        out = System.out;
        commands.put("uci", new CommandUCI());
        commands.put("isready", new CommandIsReady());
        commands.put("debug", new CommandDebug());
        commands.put("setoption", new CommandSetOption());
        commands.put("register", new CommandRegister());
        commands.put("ucinewgame", new CommandUciNewGame());
        commands.put("position", new CommandPosition());
        commands.put("go", new CommandGo());
        commands.put("stop", new CommandStop());
        commands.put("ponderhit", new CommandPonderhit());
        commands.put("quit", new CommandQuit());
    }

    private void startInterface() throws IOException {
        BufferedReader input = new BufferedReader(new InputStreamReader(System.in));
        String command;
        while ((command = input.readLine()) != null) {
            log.fine("UCI(in): '" + command + "'");
            List<String> splitCommand = new ArrayList<String>(Arrays.asList(StringUtils.split(command)));
            if (splitCommand.size() == 0) {
                log.warning("Empty command received from interface");
                continue;
            }
            Command exec = commands.get(splitCommand.get(0));
            if (exec == null) {
                log.warning("Unknown/unsupported command: " + command);
                continue;
            }
            splitCommand.remove(0);
            exec.execute(splitCommand);
            if (terminate) {
                break;
            }
        }
    }

    void send(String s) {
        out.println(s);
        log.fine("UCI(out): '" + s + "'");
    }

    public void terminate() {
        this.terminate = true;
    }

    public void setDebug(boolean debug) {
        //      this.debug = debug;
    }

    public static Logger getLog() {
        return log;
    }

    // ------------------------------------- Commands ---------------------------

    private class CommandGo implements Command {

        public void execute(List<String> args) {
            ChessEngine node = new ChessEngine();

            String bestMove = node.getPreferredMove(board);
            String pgnMove = PGNUtils.translateMove(board, bestMove);
            send("info pv " + pgnMove);
            send("bestmove " + pgnMove);
        }
    }

    private class CommandQuit implements Command {

        public void execute(List<String> args) {
            UCIInterface.this.terminate();
        }
    }

    private class CommandUciNewGame implements Command {

        public void execute(List<String> args) {
            // Not implemented
        }
    }

    private class CommandStop implements Command {

        public void execute(List<String> args) {
            // Not implemented
        }
    }

    private class CommandRegister implements Command {

        public void execute(List<String> args) {
            // Not required
        }
    }

    private class CommandPosition implements Command {

        public void execute(List<String> args) {
            if (args.size() < 1) {
                UCIInterface.log.info("Bad 'position' command");
                return;
            }

            if ("startpos".equals(args.get(0))) {
                UCIInterface.this.board.initialise();
                args.remove(0);
            } else if ("fen".equals(args.get(0))) {
                String fen = new StringBuilder().append(args.get(1)).append(" ").append(args.get(2)).append(" ")
                        .append(args.get(3)).append(" ").append(args.get(4)).append(" ").append(args.get(5))
                        .append(" ").append(args.get(6)).toString();

                FENUtils.loadPosition(fen, UCIInterface.this.board);
                args.remove(0);
                args.remove(0);
                args.remove(0);
                args.remove(0);
                args.remove(0);
                args.remove(0);
                args.remove(0);
            }
            if (args.size() == 0) {
                return;
            }
            if ("moves".equals(args.get(0))) {
                args.remove(0);
                while (args.size() > 0) {
                    if (!"...".equals(args.get(0))) {
                        board.makeMove(board.getMove(args.get(0).toUpperCase()));
                    }
                    args.remove(0);
                }
            }
            log.fine("Position: " + FENUtils.generate(board));
        }
    }

    private class CommandPonderhit implements Command {

        public void execute(List<String> args) {
            // TODO Auto-generated method stub
        }
    }

    private class CommandDebug implements Command {

        public void execute(List<String> args) {
            if (args.size() < 1) {
                UCIInterface.log.info("Bad 'debug' command");
                return;
            }

            if ("on".equals(args.get(0))) {
                UCIInterface.this.setDebug(true);
            }
            if ("off".equals(args.get(0))) {
                UCIInterface.this.setDebug(false);
            }
        }
    }

    private class CommandIsReady implements Command {

        public void execute(List<String> args) {
            UCIInterface.this.send("readyok");
        }
    }

    private class CommandSetOption implements Command {

        public void execute(List<String> args) {
            // Not required
        }
    }

    private class CommandUCI implements Command {

        public void execute(List<String> args) {
            UCIInterface.this.send("id name Calculon 0.1");
            UCIInterface.this.send("id author Vox");
            UCIInterface.this.send("uciok");
        }
    }
}