145 lines
4.3 KiB
Dart
145 lines
4.3 KiB
Dart
import "dart:async";
|
|
import "dart:collection";
|
|
import "dart:convert";
|
|
import "dart:io";
|
|
|
|
import "package:omnichess/classes/best_move_searcher.dart";
|
|
import "package:omnichess/classes/position.dart";
|
|
import "package:omnichess/constants/piece.dart";
|
|
|
|
class Omnichess {
|
|
|
|
BestMoveSearcher bestMoveSearcher = BestMoveSearcher();
|
|
String positionCommand = "startpos";
|
|
String? bestMove;
|
|
|
|
bool debug = false;
|
|
|
|
Omnichess();
|
|
|
|
void _positionCommand(Queue<String> inputComponents) {
|
|
positionCommand = inputComponents.join(" ");
|
|
}
|
|
|
|
Future<void> _goCommand(Queue<String> inputComponents) async {
|
|
int? moveTime;
|
|
while (inputComponents.isNotEmpty) {
|
|
final String inputComponent = inputComponents.removeFirst();
|
|
if ("movetime" == inputComponent) {
|
|
moveTime = int.tryParse(inputComponents.firstOrNull ?? "");
|
|
}
|
|
}
|
|
final Position position = Position.fromPositionCommand(positionCommand);
|
|
final String? bestMove = await bestMoveSearcher.search(position, moveTime);
|
|
print("bestmove ${bestMove ?? "(none)"}");
|
|
}
|
|
|
|
Future<void> _stopCommand() async {
|
|
await bestMoveSearcher.stop();
|
|
}
|
|
|
|
Future<bool> elaborate(String line) async {
|
|
final Queue<String> inputComponents = Queue.from(line.split(" "));
|
|
final String command = inputComponents.removeFirst();
|
|
if (command == "uci") {
|
|
print("id name Omnichess");
|
|
print("id author Dany Thach");
|
|
print("uciok");
|
|
return true;
|
|
}
|
|
if (command == "debug") {
|
|
debug = "on" == inputComponents.first;
|
|
return true;
|
|
}
|
|
if (command == "isready") {
|
|
print("readyok");
|
|
return true;
|
|
}
|
|
if (command == "ucinewgame") {
|
|
positionCommand = "startpos";
|
|
return true;
|
|
}
|
|
if (command == "position") {
|
|
_positionCommand(inputComponents);
|
|
return true;
|
|
}
|
|
if (command == "go") {
|
|
await _goCommand(inputComponents);
|
|
return true;
|
|
}
|
|
if (command == "stop") {
|
|
await _stopCommand();
|
|
return true;
|
|
}
|
|
if (command == "quit") {
|
|
return false;
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void debugPrintPosition() {
|
|
final Position position = Position.fromPositionCommand(positionCommand);
|
|
for (int i = 0; i < position.board.length; i++) {
|
|
if (i % 8 == 0) {
|
|
stdout.write("info string ");
|
|
}
|
|
stdout.write(Piece.fenCharacterByPiece[position.board[i]]);
|
|
if (i % 8 == 7) {
|
|
stdout.writeln();
|
|
}
|
|
}
|
|
print(position.isWhiteTurn ? "info string white to move" : "info string black to move");
|
|
if (position.canWhiteCastleKingside) {
|
|
print("info string white can castle kingside");
|
|
}
|
|
if (position.canWhiteCastleQueenside) {
|
|
print("info string white can castle queenside");
|
|
}
|
|
if (position.canBlackCastleKingside) {
|
|
print("info string black can castle kingside");
|
|
}
|
|
if (position.canBlackCastleQueenside) {
|
|
print("info string black can castle queenside");
|
|
}
|
|
if (null != position.enPassantTargetSquare) {
|
|
print("info string en passant possible on ${position.enPassantTargetSquareAlgebraic}");
|
|
}
|
|
print("info string halfmove clock ${position.halfmoveClock}");
|
|
print("info string fullmove number ${position.fullmoveNumber}");
|
|
print("info string position fen ${position.fen}");
|
|
}
|
|
|
|
void loop() async {
|
|
final DateTime now = DateTime.now();
|
|
final String logName = "${now.year}"
|
|
"${now.month.toString().padLeft(2, "0")}"
|
|
"${now.day.toString().padLeft(2, "0")}"
|
|
"-"
|
|
"${now.hour.toString().padLeft(2, "0")}"
|
|
"${now.minute.toString().padLeft(2, "0")}"
|
|
"${now.second.toString().padLeft(2, "0")}"
|
|
"${now.millisecond.toString().padLeft(3, "0")}"
|
|
".log";
|
|
final File log = File("logs/$logName");
|
|
if (!log.existsSync()) {
|
|
log.createSync();
|
|
}
|
|
late StreamSubscription<String> inputSubscription;
|
|
inputSubscription = stdin
|
|
.transform(utf8.decoder)
|
|
.transform(LineSplitter())
|
|
.listen((String line) async {
|
|
log.writeAsStringSync("$line\n", mode: FileMode.append);
|
|
final String input = line.trim();
|
|
final bool keepGoing = await elaborate(input);
|
|
if (!keepGoing) {
|
|
await inputSubscription.cancel();
|
|
}
|
|
if (debug) {
|
|
debugPrintPosition();
|
|
}
|
|
});
|
|
await inputSubscription.asFuture();
|
|
}
|
|
|
|
} |