76 lines
2.2 KiB
Dart
76 lines
2.2 KiB
Dart
import 'dart:collection';
|
|
|
|
import 'package:omnichess/classes/position.dart';
|
|
import 'package:omnichess/constants/piece.dart';
|
|
import 'package:omnichess/functions/legal_moves.dart';
|
|
|
|
class BestMoveSearcher {
|
|
|
|
bool _isRunning = false;
|
|
bool _isStopped = false;
|
|
|
|
Future<int> getPositionBaseValue(Position position) async {
|
|
if (await LegalMoves.isCheckmate(position)) {
|
|
return position.isWhiteTurn
|
|
? -(1 << 63) // min int (white is checkmated)
|
|
: ((1 << 63) - 1); // max int (black is checkmated)
|
|
}
|
|
int value = 0;
|
|
for (int i = 0; i < 64; i++) {
|
|
value += switch (position.board[i]) {
|
|
Piece.whiteQueen => 900,
|
|
Piece.whiteRook => 500,
|
|
Piece.whiteBishop => 300,
|
|
Piece.whiteKnight => 300,
|
|
Piece.whitePawn => 100,
|
|
Piece.blackQueen => -900,
|
|
Piece.blackRook => -500,
|
|
Piece.blackBishop => -300,
|
|
Piece.blackKnight => -300,
|
|
Piece.blackPawn => -100,
|
|
_ => 0,
|
|
};
|
|
}
|
|
return value;
|
|
}
|
|
|
|
Future<String?> search(Position position) async {
|
|
_isRunning = true;
|
|
(int, String, Position)? bestMove;
|
|
Queue<(int, String, Position)> evaluatedMoves = Queue();
|
|
await for (final (String, Position) move in LegalMoves.getLegalMoves(position)) {
|
|
final (int, String, Position) evaluatedMove = (await getPositionBaseValue(move.$2), move.$1, move.$2);
|
|
if (
|
|
null == bestMove ||
|
|
(bestMove.$1 < evaluatedMove.$1 && position.isWhiteTurn) ||
|
|
(bestMove.$1 > evaluatedMove.$1 && !position.isWhiteTurn)
|
|
) {
|
|
bestMove = evaluatedMove;
|
|
}
|
|
evaluatedMoves.add(evaluatedMove);
|
|
await Future.delayed(Duration.zero);
|
|
if (_isStopped) {
|
|
break;
|
|
}
|
|
// TODO evaluate checkmate
|
|
}
|
|
if (evaluatedMoves.isEmpty) {
|
|
_isRunning = false;
|
|
_isStopped = false;
|
|
return null;
|
|
}
|
|
// TODO search
|
|
// IDEA implement a BFS with pruning on the ones that give suboptimal values
|
|
_isRunning = false;
|
|
_isStopped = false;
|
|
return bestMove?.$2;
|
|
}
|
|
|
|
Future<void> stop() async {
|
|
if (!_isRunning) {
|
|
return;
|
|
}
|
|
_isStopped = true;
|
|
}
|
|
|
|
} |