flutter: 改为使用 position fen 后面附加 moves 的方式传递给引擎
This commit is contained in:
parent
b56990d7c0
commit
fe1f1d1816
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
Loading…
Reference in New Issue