flutter: 改为使用 position fen 后面附加 moves 的方式传递给引擎

This commit is contained in:
Calcitem 2020-11-22 12:49:33 +08:00
parent b56990d7c0
commit fe1f1d1816
6 changed files with 108 additions and 108 deletions

View File

@ -133,17 +133,19 @@ class NativeEngine extends AiEngine {
}
String getPositionFen(Position position) {
/*
final startPosition = position.lastCapturedPosition;
final moves = position.movesSinceLastCaptured();
final startPosition = position.lastPositionWithRemove;
final moves = position.movesSinceLastRemove();
if (moves.isEmpty) return 'position fen $startPosition';
String posFenStr;
return 'position fen $startPosition moves $moves';
*/
if (moves.isEmpty) {
posFenStr = "position fen $startPosition";
} else {
posFenStr = "position fen $startPosition moves $moves";
}
String fenStr = position.fen();
print("posFenStr: $posFenStr");
return "position fen $fenStr";
return posFenStr;
}
}

View File

@ -177,7 +177,7 @@ class Game {
get blurIndex => _blurIndex;
bool command(String cmd) {
bool doMove(String move) {
int total;
double blackWinRate, whiteWinRate, drawRate;
@ -186,11 +186,11 @@ class Game {
start();
}
print("Computer: $cmd");
print("Computer: $move");
moveHistory.add(cmd);
moveHistory.add(move);
if (!position.command(cmd)) {
if (!position.doMove(move)) {
return false;
}

View File

@ -112,7 +112,7 @@ class Move {
int fromIndex = 0;
int toIndex = 0;
String removed;
String removed = Piece.noPiece;
// 'move' is the UCI engine's move-string
String move;

View File

@ -47,7 +47,7 @@ class Position {
List<String> board = List<String>(sqNumber);
List<String> _grid = List<String>(7 * 7);
GameRecorder _recorder;
GameRecorder recorder;
Map<String, int> pieceCountInHand = {Color.black: 12, Color.white: 12};
Map<String, int> pieceCountOnBoard = {Color.black: 0, Color.white: 0};
@ -103,7 +103,7 @@ class Position {
board = List<String>();
other.board.forEach((piece) => board.add(piece));
_recorder = other._recorder;
recorder = other.recorder;
pieceCountInHand = other.pieceCountInHand;
pieceCountOnBoard = other.pieceCountOnBoard;
@ -172,7 +172,7 @@ class Position {
// TODO
_recorder = GameRecorder(lastPositionWithRemove: fen());
recorder = GameRecorder(lastPositionWithRemove: fen());
}
Position() {
@ -263,7 +263,7 @@ class Position {
rule50.toString() + " " + (1 + (gamePly - sideIsBlack) ~/ 2).toString();
// step counter
//ss += '${_recorder?.halfMove ?? 0} ${_recorder?.fullMove ?? 0}';
//ss += '${recorder?.halfMove ?? 0} ${recorder?.fullMove ?? 0}';
print("fen = " + ss);
@ -294,31 +294,63 @@ class Position {
return true;
}
void doMove(Move m) {
if (!legal(m)) {
return null;
}
bool doMove(String move) {
// TODO
/*
if (sscanf(cmd, "r%1u s%3d t%2u", &ruleIndex, &step, &t) == 3) {
if (ruleIndex <= 0 || ruleIndex > N_RULES) {
return false;
}
return set_position(&RULES[ruleIndex - 1]) >= 0 ? true : false;
}
*/
bool ret = false;
print("position: command = $move");
if (move.length > "Player".length &&
move.substring(0, "Player".length - 1) == "Player") {
if (move["Player".length] == '1') {
return resign(Color.black);
} else {
return resign(Color.white);
}
}
// TODO
if (move == "Threefold Repetition. Draw!") {
return true;
}
if (move == "draw") {
phase = Phase.gameOver;
winner = Color.draw;
score[Color.draw]++;
gameOverReason = GameOverReason.drawReasonThreefoldRepetition;
return true;
}
Move m = Move(move);
switch (m.type) {
case MoveType.remove:
rule50 = 0;
ret = removePiece(m.to);
break;
case MoveType.move:
ret = movePiece(m.from, m.to);
break;
case MoveType.place:
ret = putPiece(m.to);
break;
case MoveType.remove:
rule50 = 0;
ret = removePiece(m.to);
break;
default:
assert(false);
break;
}
if (!ret) {
return;
return false;
}
// Increment ply counters. In particular, rule50 will be reset to zero later on
@ -329,7 +361,9 @@ class Position {
this.move = m;
_recorder.moveIn(move, this);
recorder.moveIn(m, this);
return true;
}
bool posIsOk() {
@ -686,61 +720,6 @@ class Position {
return true;
}
bool command(String cmd) {
// TODO
/*
if (sscanf(cmd, "r%1u s%3d t%2u", &ruleIndex, &step, &t) == 3) {
if (ruleIndex <= 0 || ruleIndex > N_RULES) {
return false;
}
return set_position(&RULES[ruleIndex - 1]) >= 0 ? true : false;
}
*/
print("position: command = $cmd");
if (cmd.length > "Player".length &&
cmd.substring(0, "Player".length - 1) == "Player") {
if (cmd["Player".length] == '1') {
return resign(Color.black);
} else {
return resign(Color.white);
}
}
// TODO
if (cmd == "Threefold Repetition. Draw!") {
return true;
}
if (cmd == "draw") {
phase = Phase.gameOver;
winner = Color.draw;
score[Color.draw]++;
gameOverReason = GameOverReason.drawReasonThreefoldRepetition;
return true;
}
Move move = Move(cmd);
switch (move.type) {
case MoveType.move:
return movePiece(move.from, move.to);
break;
case MoveType.place:
return putPiece(move.to);
break;
case MoveType.remove:
return removePiece(move.to);
break;
default:
assert(false);
break;
}
return false;
}
String getWinner() {
return winner;
}
@ -1468,7 +1447,7 @@ class Position {
bool regret() {
// TODO
final lastMove = _recorder.removeLast();
final lastMove = recorder.removeLast();
if (lastMove == null) return false;
_grid[lastMove.from] = _grid[lastMove.to];
@ -1479,15 +1458,15 @@ class Position {
changeSideToMove();
final counterMarks = GameRecorder.fromCounterMarks(lastMove.counterMarks);
_recorder.halfMove = counterMarks.halfMove;
_recorder.fullMove = counterMarks.fullMove;
recorder.halfMove = counterMarks.halfMove;
recorder.fullMove = counterMarks.fullMove;
if (lastMove.removed != Piece.noPiece) {
//
// NativeEngine
final tempPosition = Position.clone(this);
final moves = _recorder.reverseMovesToPrevRemove();
final moves = recorder.reverseMovesToPrevRemove();
moves.forEach((move) {
//
tempPosition._grid[move.from] = tempPosition._grid[move.to];
@ -1496,7 +1475,7 @@ class Position {
tempPosition._sideToMove = Color.opponent(tempPosition._sideToMove);
});
_recorder.lastPositionWithRemove = tempPosition.fen();
recorder.lastPositionWithRemove = tempPosition.fen();
}
result = GameResult.pending;
@ -1506,21 +1485,26 @@ class Position {
String movesSinceLastRemove() {
//
var moves = '', posAfterLastRemove = 0;
String moves = "";
int posAfterLastRemove = 0;
for (var i = _recorder.movesCount - 1; i >= 0; i--) {
if (_recorder.stepAt(i).removed != Piece.noPiece) break;
print("recorder.movesCount = ${recorder.movesCount}");
for (int i = recorder.movesCount - 1; i >= 0; i--) {
if (recorder.moveAt(i).type == MoveType.remove) break;
posAfterLastRemove = i;
}
for (var i = posAfterLastRemove; i < _recorder.movesCount; i++) {
moves += ' ${_recorder.stepAt(i).move}';
print("[movesSinceLastRemove] posAfterLastRemove = $posAfterLastRemove");
for (int i = posAfterLastRemove; i < recorder.movesCount; i++) {
moves += " ${recorder.moveAt(i).move}";
}
return moves.length > 0 ? moves.substring(1) : '';
}
get manualText => _recorder.buildManualText();
get manualText => recorder.buildManualText();
get side => _sideToMove;
@ -1530,11 +1514,11 @@ class Position {
print("Change sideToMove to $_sideToMove");
}
get halfMove => _recorder.halfMove;
get halfMove => recorder.halfMove;
get fullMove => _recorder.fullMove;
get fullMove => recorder.fullMove;
get lastMove => _recorder.last;
get lastMove => recorder.last;
get lastPositionWithRemove => _recorder.lastPositionWithRemove;
get lastPositionWithRemove => recorder.lastPositionWithRemove;
}

View File

@ -19,6 +19,7 @@
import 'mill.dart';
import 'position.dart';
import 'types.dart';
class GameRecorder {
//
@ -43,9 +44,10 @@ class GameRecorder {
throw 'Error: Invalid Counter Marks: $marks';
}
}
void moveIn(Move move, Position position) {
//
if (move.removed != Piece.noPiece) {
if (move.type == MoveType.remove) {
halfMove = 0;
} else {
halfMove++;
@ -59,7 +61,7 @@ class GameRecorder {
_history.add(move);
if (move.removed != Piece.noPiece) {
if (move.type == MoveType.remove) {
lastPositionWithRemove = position.fen();
}
}
@ -76,7 +78,7 @@ class GameRecorder {
List<Move> moves = [];
for (var i = _history.length - 1; i >= 0; i--) {
if (_history[i].removed != Piece.noPiece) break;
if (_history[i].type == MoveType.remove) break;
moves.add(_history[i]);
}
@ -99,7 +101,7 @@ class GameRecorder {
return manualText;
}
Move stepAt(int index) => _history[index];
Move moveAt(int index) => _history[index];
get movesCount => _history.length;

View File

@ -81,7 +81,7 @@ class _GamePageState extends State<GamePage> {
}
//
bool result = false;
bool ret = false;
switch (position.action) {
case Act.place:
@ -95,7 +95,7 @@ class _GamePageState extends State<GamePage> {
//Audios.playTone('put.mp3');
changeStatus('已落子');
}
result = true;
ret = true;
print("putPiece: [$sq]");
break;
} else {
@ -112,7 +112,7 @@ class _GamePageState extends State<GamePage> {
//
//Audios.playTone('select.mp3');
Game.shared.select(index);
result = true;
ret = true;
print("selectPiece: [$sq]");
changeStatus('请落子');
} else {
@ -127,7 +127,7 @@ class _GamePageState extends State<GamePage> {
if (position.removePiece(sq)) {
//
//Audios.playTone('remove.mp3');
result = true;
ret = true;
print("removePiece: [$sq]");
changeStatus('已吃子');
} else {
@ -143,9 +143,21 @@ class _GamePageState extends State<GamePage> {
break;
}
if (result) {
if (ret) {
Game.shared.moveHistory.add(position.cmdline);
// TODO: Need Others?
// Increment ply counters. In particular, rule50 will be reset to zero later on
// in case of a capture.
++position.gamePly;
++position.rule50;
++position.pliesFromNull;
//position.move = m;
Move m = Move(position.cmdline);
position.recorder.moveIn(m, position);
//
setState(() {});
@ -160,7 +172,7 @@ class _GamePageState extends State<GamePage> {
setState(() {});
return result;
return ret;
}
engineToGo() async {
@ -175,7 +187,7 @@ class _GamePageState extends State<GamePage> {
final Move move = new Move(mv.move);
//Battle.shared.move = move;
Game.shared.command(move.move);
Game.shared.doMove(move.move);
final winner = Game.shared.position.winner;