mirror of
https://github.com/peterosterlund2/droidfish.git
synced 2024-11-27 06:10:28 +01:00
DroidFish: Display chess moves using localized piece names.
This commit is contained in:
parent
986d30991d
commit
5c161d2101
|
@ -48,7 +48,7 @@ public final class MoveGen {
|
|||
|
||||
/**
|
||||
* Generate and return a list of pseudo-legal moves.
|
||||
* Pseudo-legal means that the moves doesn't necessarily defend from check threats.
|
||||
* Pseudo-legal means that the moves don't necessarily defend from check threats.
|
||||
*/
|
||||
public final MoveList pseudoLegalMoves(Position pos) {
|
||||
MoveList moveList = getMoveListObj();
|
||||
|
|
|
@ -108,7 +108,7 @@ wenn Sie es nicht aktiv nutzen.\
|
|||
<string name="filename">Dateiname:</string>
|
||||
<string name="halfmove">Halbzug:</string>
|
||||
<string name="fullmove">Zugnummer:</string>
|
||||
<string name="filter_text">Filtertext</string>
|
||||
<string name="filter_text">Suche…</string>
|
||||
<string name="value_percent">Wert (%):</string>
|
||||
<string name="header_event">Ereignis:</string>
|
||||
<string name="header_site">Ort:</string>
|
||||
|
@ -171,6 +171,7 @@ wenn Sie es nicht aktiv nutzen.\
|
|||
<string name="uci_protocol_error">UCI-Protokollfehler</string>
|
||||
<string name="start_new_game">Neue Partie starten?</string>
|
||||
<string name="strength_cuckoo_hint">Nutzen Sie die CuckooChess-Engine für eine noch geringere Spielstärke.</string>
|
||||
<string name="piece_names">B S L T D K</string>
|
||||
<string name="err_too_few_spaces">Zuwenig Felder</string>
|
||||
<string name="err_invalid_piece">Unzulässige Figur</string>
|
||||
<string name="err_invalid_side">Unzulässige Seite</string>
|
||||
|
|
|
@ -169,6 +169,7 @@ Si está usted utilizando la batería, se recomienda que cambie los ajustes para
|
|||
<string name="uci_protocol_error">Fallo en el protocolo UCI</string>
|
||||
<string name="start_new_game">¿Empezar nueva partida?</string>
|
||||
<string name="strength_cuckoo_hint">Utilice el motor CuckooChess para rebajar aún más el nivel de juego.</string>
|
||||
<string name="piece_names">P C A T D R</string>
|
||||
<string name="err_too_few_spaces">Pocos espacios</string>
|
||||
<string name="err_invalid_piece">Pieza incorrecta</string>
|
||||
<string name="err_invalid_side">Lado incorrecto</string>
|
||||
|
|
|
@ -107,7 +107,7 @@ não estiver usando o programa diretamente.\</string>
|
|||
<string name="filename">Arquivo:</string>
|
||||
<string name="halfmove">Relógio para meio-lance:</string>
|
||||
<string name="fullmove">Contador de lances completos:</string>
|
||||
<string name="filter_text">Pesquisar...</string>
|
||||
<string name="filter_text">Pesquisar…</string>
|
||||
<string name="value_percent">Valor(%):</string>
|
||||
<string name="header_event">Evento:</string>
|
||||
<string name="header_site">Site:</string>
|
||||
|
@ -170,6 +170,7 @@ não estiver usando o programa diretamente.\</string>
|
|||
<string name="uci_protocol_error">Erro de protocolo UCI</string>
|
||||
<string name="start_new_game">Iniciar nova partida?</string>
|
||||
<string name="strength_cuckoo_hint">Use o CuckooChess para um nível ainda menor.</string>
|
||||
<string name="piece_names">P C B T D R</string>
|
||||
<string name="err_too_few_spaces">Poucos espaços</string>
|
||||
<string name="err_invalid_piece">Peça inválida</string>
|
||||
<string name="err_invalid_side">Lado inválido</string>
|
||||
|
@ -238,7 +239,7 @@ não estiver usando o programa diretamente.\</string>
|
|||
<string name="prefs_fullScreenMode_summary">Modo tela cheia oculta a barra de notificações</string>
|
||||
<string name="prefs_wakeLock_title">Desabilita apagar a tela automaticamente</string>
|
||||
<string name="prefs_drawSquareLabels_title">Rótulos nas casas</string>
|
||||
<string name="prefs_drawSquareLabels_summary">Mostrar rótulos nas casas: a-h e 1-8</string>
|
||||
<string name="prefs_drawSquareLabels_summary">Mostrar rótulos nas casas: a–h e 1–8</string>
|
||||
<string name="prefs_scrollSensitivity_title">Velocidade do movimento</string>
|
||||
<string name="prefs_scrollSensitivity_summary">Velocidade do movimento para navegação em partida</string>
|
||||
<string name="prefs_invertScrollDirection_title">Inverter direção do movimento</string>
|
||||
|
|
|
@ -159,6 +159,7 @@
|
|||
<string name="uci_protocol_error">Ошибка UCI протокола</string>
|
||||
<string name="start_new_game">Начать новую партию?</string>
|
||||
<string name="strength_cuckoo_hint">Использовать движок CuckooChess для наименьшего уровня сложности.</string>
|
||||
<string name="piece_names">П К С Л Ф Кр</string>
|
||||
<string name="err_too_few_spaces">Слишком малое пространство</string>
|
||||
<string name="err_invalid_piece">Неверная фигура</string>
|
||||
<string name="err_invalid_side">Неверное местоположение</string>
|
||||
|
|
|
@ -10,6 +10,7 @@
|
|||
<string name="thinking_arrows_default">2</string>
|
||||
<string name="scroll_sensitivity_default">2</string>
|
||||
<string name="book_line_length_default">1000000</string>
|
||||
<string name="viewPieceType_default">1</string>
|
||||
<string name="cpu_warning">\
|
||||
<b>CPU Usage</b>\n\
|
||||
If you leave DroidFish running in the background and <i>GameMode</i> is set to \
|
||||
|
@ -185,6 +186,7 @@ you are not actively using the program.\
|
|||
<string name="invalid_network_port">Invalid network port</string>
|
||||
<string name="start_new_game">Start New Game?</string>
|
||||
<string name="strength_cuckoo_hint">Use the CuckooChess engine for even lower strength.</string>
|
||||
<string name="piece_names">P N B R Q K</string>
|
||||
<string name="err_too_few_spaces">Too few spaces</string>
|
||||
<string name="err_invalid_piece">Invalid piece</string>
|
||||
<string name="err_invalid_side">Invalid side</string>
|
||||
|
@ -323,6 +325,8 @@ you are not actively using the program.\
|
|||
<string name="prefs_viewNAG_summary">Include numeric annotation glyphs (NAGs), such as ! and ?</string>
|
||||
<string name="prefs_viewHeaders_title">Headers</string>
|
||||
<string name="prefs_viewHeaders_summary">Show PGN header lines</string>
|
||||
<string name="prefs_viewPieceType_title">Pieces</string>
|
||||
<string name="prefs_viewPieceType_summary">Control how chess pieces are displayed</string>
|
||||
<string name="prefs_pgn_import">PGN import</string>
|
||||
<string name="prefs_importVariations_title">Variations</string>
|
||||
<string name="prefs_importVariations_summary">Include non-mainline moves</string>
|
||||
|
@ -376,6 +380,14 @@ you are not actively using the program.\
|
|||
<item>6</item>
|
||||
<item>8</item>
|
||||
</string-array>
|
||||
<string-array name="viewPieceType_texts">
|
||||
<item>English letters</item>
|
||||
<item>Local language letters</item>
|
||||
</string-array>
|
||||
<string-array name="viewPieceType_values">
|
||||
<item>0</item>
|
||||
<item>1</item>
|
||||
</string-array>
|
||||
<string-array name="engine_hash_texts">
|
||||
<item>16 MB</item>
|
||||
<item>32 MB</item>
|
||||
|
|
|
@ -513,6 +513,14 @@
|
|||
android:summary="@string/prefs_viewHeaders_summary"
|
||||
android:defaultValue="false">
|
||||
</CheckBoxPreference>
|
||||
<ListPreference
|
||||
android:key="viewPieceType"
|
||||
android:title="@string/prefs_viewPieceType_title"
|
||||
android:summary="@string/prefs_viewPieceType_summary"
|
||||
android:entryValues="@array/viewPieceType_values"
|
||||
android:entries="@array/viewPieceType_texts"
|
||||
android:defaultValue="@string/viewPieceType_default">
|
||||
</ListPreference>
|
||||
</PreferenceCategory>
|
||||
<PreferenceCategory
|
||||
android:title="@string/prefs_pgn_import">
|
||||
|
|
|
@ -126,7 +126,6 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
// FIXME!!! PGN view option: game continuation (for training)
|
||||
// FIXME!!! Remove invalid playerActions in PGN import (should be done in verifyChildren)
|
||||
// FIXME!!! Implement bookmark mechanism for positions in pgn files
|
||||
// FIXME!!! Display chess notation in local language
|
||||
// FIXME!!! Add support for "Chess Leipzig" font
|
||||
// FIXME!!! Implement figurine notation
|
||||
|
||||
|
@ -253,7 +252,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
public void run() {
|
||||
pgnOptions.view.variations = toggleBooleanPref("viewVariations");
|
||||
gameTextListener.clear();
|
||||
ctrl.prefsChanged();
|
||||
ctrl.prefsChanged(false);
|
||||
}
|
||||
});
|
||||
addAction(new UIAction() {
|
||||
|
@ -264,7 +263,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
public void run() {
|
||||
pgnOptions.view.comments = toggleBooleanPref("viewComments");
|
||||
gameTextListener.clear();
|
||||
ctrl.prefsChanged();
|
||||
ctrl.prefsChanged(false);
|
||||
}
|
||||
});
|
||||
addAction(new UIAction() {
|
||||
|
@ -275,7 +274,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
public void run() {
|
||||
pgnOptions.view.headers = toggleBooleanPref("viewHeaders");
|
||||
gameTextListener.clear();
|
||||
ctrl.prefsChanged();
|
||||
ctrl.prefsChanged(false);
|
||||
}
|
||||
});
|
||||
addAction(new UIAction() {
|
||||
|
@ -352,6 +351,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
custom3ButtonActions = new ButtonActions("custom3", CUSTOM3_BUTTON_DIALOG,
|
||||
R.string.select_action);
|
||||
|
||||
TextIO.setPieceNames(getString(R.string.piece_names));
|
||||
initUI(true);
|
||||
|
||||
gameTextListener = new PgnScreenText(pgnOptions);
|
||||
|
@ -808,6 +808,8 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
pgnOptions.view.comments = settings.getBoolean("viewComments", true);
|
||||
pgnOptions.view.nag = settings.getBoolean("viewNAG", true);
|
||||
pgnOptions.view.headers = settings.getBoolean("viewHeaders", false);
|
||||
final int oldViewPieceType = pgnOptions.view.pieceType;
|
||||
pgnOptions.view.pieceType = getIntSetting("viewPieceType", PGNOptions.PT_LOCAL);
|
||||
pgnOptions.imp.variations = settings.getBoolean("importVariations", true);
|
||||
pgnOptions.imp.comments = settings.getBoolean("importComments", true);
|
||||
pgnOptions.imp.nag = settings.getBoolean("importNAG", true);
|
||||
|
@ -821,7 +823,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
cb.setColors();
|
||||
|
||||
gameTextListener.clear();
|
||||
ctrl.prefsChanged();
|
||||
ctrl.prefsChanged(oldViewPieceType != pgnOptions.view.pieceType);
|
||||
}
|
||||
|
||||
private void updateButtons() {
|
||||
|
@ -1829,7 +1831,7 @@ public class DroidFish extends Activity implements GUIInterface {
|
|||
ColorTheme.instance().setTheme(settings, item);
|
||||
cb.setColors();
|
||||
gameTextListener.clear();
|
||||
ctrl.prefsChanged();
|
||||
ctrl.prefsChanged(false);
|
||||
dialog.dismiss();
|
||||
}
|
||||
});
|
||||
|
|
|
@ -20,11 +20,15 @@ package org.petero.droidfish;
|
|||
|
||||
/** Settings controlling PGN import/export */
|
||||
public class PGNOptions {
|
||||
public static final int PT_ENGLISH = 0; // Piece type english letters
|
||||
public static final int PT_LOCAL = 1; // Piece type local language letters
|
||||
|
||||
public static class Viewer {
|
||||
public boolean variations;
|
||||
public boolean comments;
|
||||
public boolean nag;
|
||||
public boolean headers;
|
||||
public int pieceType;
|
||||
}
|
||||
public static class Import {
|
||||
public boolean variations;
|
||||
|
@ -39,6 +43,7 @@ public class PGNOptions {
|
|||
public boolean clockInfo;
|
||||
public boolean pgnPromotions;
|
||||
public boolean moveNrAfterNag;
|
||||
public int pieceType;
|
||||
}
|
||||
|
||||
public Viewer view;
|
||||
|
@ -50,5 +55,6 @@ public class PGNOptions {
|
|||
imp = new Import();
|
||||
exp = new Export();
|
||||
exp.moveNrAfterNag = true;
|
||||
exp.pieceType = PT_ENGLISH;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -114,7 +114,8 @@ public final class DroidBook {
|
|||
}
|
||||
|
||||
/** Return all book moves, both as a formatted string and as a list of moves. */
|
||||
public final synchronized Pair<String,ArrayList<Move>> getAllBookMoves(Position pos) {
|
||||
public final synchronized Pair<String,ArrayList<Move>> getAllBookMoves(Position pos,
|
||||
boolean localized) {
|
||||
StringBuilder ret = new StringBuilder();
|
||||
ArrayList<Move> bookMoveList = new ArrayList<Move>();
|
||||
List<BookEntry> bookMoves = getBook().getBookEntries(pos);
|
||||
|
@ -150,7 +151,7 @@ public final class DroidBook {
|
|||
for (BookEntry be : bookMoves) {
|
||||
Move m = be.move;
|
||||
bookMoveList.add(m);
|
||||
String moveStr = TextIO.moveToString(pos, m, false);
|
||||
String moveStr = TextIO.moveToString(pos, m, false, localized);
|
||||
if (first)
|
||||
first = false;
|
||||
else
|
||||
|
|
|
@ -275,8 +275,8 @@ public class DroidComputerPlayer {
|
|||
}
|
||||
|
||||
/** Return all book moves, both as a formatted string and as a list of moves. */
|
||||
public final Pair<String, ArrayList<Move>> getBookHints(Position pos) {
|
||||
return book.getAllBookMoves(pos);
|
||||
public final Pair<String, ArrayList<Move>> getBookHints(Position pos, boolean localized) {
|
||||
return book.getAllBookMoves(pos, localized);
|
||||
}
|
||||
|
||||
/** Get engine reported name. */
|
||||
|
@ -371,7 +371,9 @@ public class DroidComputerPlayer {
|
|||
Move bookMove = book.getBookMove(sr.currPos);
|
||||
if (bookMove != null) {
|
||||
if (canClaimDraw(sr.currPos, posHashList, posHashListSize, bookMove) == "") {
|
||||
listener.notifySearchResult(sr.searchId, TextIO.moveToString(sr.currPos, bookMove, false), null);
|
||||
listener.notifySearchResult(sr.searchId,
|
||||
TextIO.moveToString(sr.currPos, bookMove, false, false),
|
||||
null);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
@ -803,7 +805,7 @@ public class DroidComputerPlayer {
|
|||
} else if (canClaimDrawRep(pos, posHashList, posHashListSize, posHashListSize)) {
|
||||
drawStr = "draw rep";
|
||||
} else if (move != null) {
|
||||
String strMove = TextIO.moveToString(pos, move, false);
|
||||
String strMove = TextIO.moveToString(pos, move, false, false);
|
||||
posHashList[posHashListSize++] = pos.zobristHash();
|
||||
UndoInfo ui = new UndoInfo();
|
||||
pos.makeMove(move, ui);
|
||||
|
|
|
@ -184,15 +184,22 @@ public class DroidChessController {
|
|||
}
|
||||
|
||||
/** Notify controller that preferences has changed. */
|
||||
public final synchronized void prefsChanged() {
|
||||
public final synchronized void prefsChanged(boolean translateMoves) {
|
||||
if (game == null)
|
||||
translateMoves = false;
|
||||
if (translateMoves)
|
||||
game.tree.translateMoves();
|
||||
updateBookHints();
|
||||
updateMoveList();
|
||||
listener.prefsChanged(searchId);
|
||||
listener.prefsChanged(searchId, translateMoves);
|
||||
if (translateMoves)
|
||||
updateGUI();
|
||||
}
|
||||
|
||||
/** De-serialize from byte array. */
|
||||
public final synchronized void fromByteArray(byte[] data) {
|
||||
game.fromByteArray(data);
|
||||
game.tree.translateMoves();
|
||||
}
|
||||
|
||||
/** Serialize to byte array. */
|
||||
|
@ -221,6 +228,7 @@ public class DroidChessController {
|
|||
// Try read as PGN instead
|
||||
if (!newGame.readPGN(fenPgn, pgnOptions))
|
||||
throw e;
|
||||
newGame.tree.translateMoves();
|
||||
}
|
||||
searchId++;
|
||||
game = newGame;
|
||||
|
@ -554,7 +562,7 @@ public class DroidChessController {
|
|||
public final synchronized CommentInfo getComments() {
|
||||
Node cur = game.tree.currentNode;
|
||||
CommentInfo ret = new CommentInfo();
|
||||
ret.move = cur.moveStr;
|
||||
ret.move = cur.moveStrLocal;
|
||||
ret.preComment = cur.preComment;
|
||||
ret.postComment = cur.postComment;
|
||||
ret.nag = cur.nag;
|
||||
|
@ -571,11 +579,17 @@ public class DroidChessController {
|
|||
updateGUI();
|
||||
}
|
||||
|
||||
/** Return true if localized piece names should be used. */
|
||||
private final boolean localPt() {
|
||||
return pgnOptions.view.pieceType == PGNOptions.PT_LOCAL;
|
||||
}
|
||||
|
||||
/** Engine search information receiver. */
|
||||
private final class SearchListener implements org.petero.droidfish.gamelogic.SearchListener {
|
||||
private int currDepth = 0;
|
||||
private int currMoveNr = 0;
|
||||
private String currMove = "";
|
||||
private Move currMove = null;
|
||||
private String currMoveStr = "";
|
||||
private int currNodes = 0;
|
||||
private int currNps = 0;
|
||||
private int currTime = 0;
|
||||
|
@ -586,8 +600,10 @@ public class DroidChessController {
|
|||
|
||||
private Move ponderMove = null;
|
||||
private ArrayList<PvInfo> pvInfoV = new ArrayList<PvInfo>();
|
||||
private int pvInfoSearchId = -1; // Search ID corresponding to pvInfoV
|
||||
|
||||
public final void clearSearchInfo(int id) {
|
||||
pvInfoSearchId = -1;
|
||||
ponderMove = null;
|
||||
pvInfoV.clear();
|
||||
currDepth = 0;
|
||||
|
@ -620,7 +636,7 @@ public class DroidChessController {
|
|||
buf.append(pvi.pvStr);
|
||||
}
|
||||
final String statStr = (currDepth > 0) ?
|
||||
String.format("d:%d %d:%s t:%.2f n:%d nps:%d", currDepth, currMoveNr, currMove,
|
||||
String.format("d:%d %d:%s t:%.2f n:%d nps:%d", currDepth, currMoveNr, currMoveStr,
|
||||
currTime / 1000.0, currNodes, currNps)
|
||||
: "";
|
||||
final String newPV = buf.toString();
|
||||
|
@ -652,7 +668,8 @@ public class DroidChessController {
|
|||
|
||||
@Override
|
||||
public void notifyCurrMove(int id, Position pos, Move m, int moveNr) {
|
||||
currMove = TextIO.moveToString(pos, m, false);
|
||||
currMove = m;
|
||||
currMoveStr = TextIO.moveToString(pos, m, false, localPt());
|
||||
currMoveNr = moveNr;
|
||||
setSearchInfo(id);
|
||||
}
|
||||
|
@ -661,6 +678,7 @@ public class DroidChessController {
|
|||
@Override
|
||||
public void notifyPV(int id, Position pos, ArrayList<PvInfo> pvInfo, Move ponderMove) {
|
||||
this.ponderMove = ponderMove;
|
||||
this.pvInfoSearchId = id;
|
||||
pvInfoV = (ArrayList<PvInfo>) pvInfo.clone();
|
||||
for (PvInfo pv : pvInfo) {
|
||||
currTime = pv.time;
|
||||
|
@ -671,7 +689,7 @@ public class DroidChessController {
|
|||
Position tmpPos = new Position(pos);
|
||||
UndoInfo ui = new UndoInfo();
|
||||
if (ponderMove != null) {
|
||||
String moveStr = TextIO.moveToString(tmpPos, ponderMove, false);
|
||||
String moveStr = TextIO.moveToString(tmpPos, ponderMove, false, localPt());
|
||||
buf.append(String.format(" [%s]", moveStr));
|
||||
tmpPos.makeMove(ponderMove, ui);
|
||||
}
|
||||
|
@ -680,7 +698,7 @@ public class DroidChessController {
|
|||
break;
|
||||
if (!TextIO.isValid(tmpPos, m))
|
||||
break;
|
||||
String moveStr = TextIO.moveToString(tmpPos, m, false);
|
||||
String moveStr = TextIO.moveToString(tmpPos, m, false, localPt());
|
||||
buf.append(String.format(" %s", moveStr));
|
||||
tmpPos.makeMove(m, ui);
|
||||
}
|
||||
|
@ -706,9 +724,16 @@ public class DroidChessController {
|
|||
setSearchInfo(id);
|
||||
}
|
||||
|
||||
public void prefsChanged(int id) {
|
||||
public void prefsChanged(int id, boolean translateMoves) {
|
||||
if (translateMoves && (id == pvInfoSearchId)) {
|
||||
Position pos = game.currPos();
|
||||
if (currMove != null)
|
||||
notifyCurrMove(id, pos, currMove, currMoveNr);
|
||||
notifyPV(id, pos, pvInfoV, ponderMove);
|
||||
} else {
|
||||
setSearchInfo(id);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void notifySearchResult(final int id, final String cmd, final Move ponder) {
|
||||
|
@ -758,7 +783,7 @@ public class DroidChessController {
|
|||
|
||||
private final void updateBookHints() {
|
||||
if (humansTurn()) {
|
||||
Pair<String, ArrayList<Move>> bi = computerPlayer.getBookHints(game.currPos());
|
||||
Pair<String, ArrayList<Move>> bi = computerPlayer.getBookHints(game.currPos(), localPt());
|
||||
listener.notifyBookInfo(searchId, bi.first, bi.second);
|
||||
}
|
||||
}
|
||||
|
@ -906,8 +931,7 @@ public class DroidChessController {
|
|||
*/
|
||||
private final boolean doMove(Move move) {
|
||||
Position pos = game.currPos();
|
||||
ArrayList<Move> moves = new MoveGen().pseudoLegalMoves(pos);
|
||||
moves = MoveGen.removeIllegal(pos, moves);
|
||||
ArrayList<Move> moves = new MoveGen().legalMoves(pos);
|
||||
int promoteTo = move.promoteTo;
|
||||
for (Move m : moves) {
|
||||
if ((m.from == move.from) && (m.to == move.to)) {
|
||||
|
@ -917,7 +941,7 @@ public class DroidChessController {
|
|||
return false;
|
||||
}
|
||||
if (m.promoteTo == promoteTo) {
|
||||
String strMove = TextIO.moveToString(pos, m, false);
|
||||
String strMove = TextIO.moveToString(pos, m, false, false, moves);
|
||||
game.processString(strMove);
|
||||
return true;
|
||||
}
|
||||
|
@ -943,7 +967,7 @@ public class DroidChessController {
|
|||
}
|
||||
} else {
|
||||
if ((s.state == GameState.DRAW_REP) || (s.state == GameState.DRAW_50))
|
||||
s.drawInfo = game.getDrawInfo();
|
||||
s.drawInfo = game.getDrawInfo(localPt());
|
||||
}
|
||||
gui.setStatus(s);
|
||||
updateMoveList();
|
||||
|
@ -957,7 +981,7 @@ public class DroidChessController {
|
|||
if (i > 0) sb.append(' ');
|
||||
if (i == game.tree.currentNode.defaultChild)
|
||||
sb.append(Util.boldStart);
|
||||
sb.append(TextIO.moveToString(pos, prevVarList.get(i), false));
|
||||
sb.append(TextIO.moveToString(pos, prevVarList.get(i), false, localPt()));
|
||||
if (i == game.tree.currentNode.defaultChild)
|
||||
sb.append(Util.boldStop);
|
||||
}
|
||||
|
@ -985,6 +1009,7 @@ public class DroidChessController {
|
|||
tmpOptions.exp.playerAction = false;
|
||||
tmpOptions.exp.clockInfo = false;
|
||||
tmpOptions.exp.moveNrAfterNag = false;
|
||||
tmpOptions.exp.pieceType = pgnOptions.view.pieceType;
|
||||
gameTextListener.clear();
|
||||
game.tree.pgnTreeWalker(tmpOptions, gameTextListener);
|
||||
}
|
||||
|
|
|
@ -185,8 +185,8 @@ public class Game {
|
|||
}
|
||||
}
|
||||
|
||||
public final String getDrawInfo() {
|
||||
return tree.getGameStateInfo();
|
||||
public final String getDrawInfo(boolean localized) {
|
||||
return tree.getGameStateInfo(localized);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -404,7 +404,7 @@ public class Game {
|
|||
if (valid) {
|
||||
String playerAction = rep ? "draw rep" : "draw 50";
|
||||
if (m != null)
|
||||
playerAction += " " + TextIO.moveToString(pos, m, false);
|
||||
playerAction += " " + TextIO.moveToString(pos, m, false, false);
|
||||
addToGameTree(new Move(0, 0, 0), playerAction);
|
||||
} else {
|
||||
pendingDrawOffer = true;
|
||||
|
|
|
@ -218,10 +218,38 @@ public class GameTree {
|
|||
}
|
||||
}
|
||||
|
||||
/** Update moveStrLocal in all game nodes. */
|
||||
public final void translateMoves() {
|
||||
List<Integer> currPath = new ArrayList<Integer>();
|
||||
while (currentNode != rootNode) {
|
||||
Node child = currentNode;
|
||||
goBack();
|
||||
int childNum = currentNode.children.indexOf(child);
|
||||
currPath.add(childNum);
|
||||
}
|
||||
translateMovesHelper();
|
||||
for (int i = currPath.size() - 1; i >= 0; i--)
|
||||
goForward(currPath.get(i), false);
|
||||
}
|
||||
|
||||
private final void translateMovesHelper() {
|
||||
ArrayList<Move> moves = MoveGen.instance.legalMoves(currentPos);
|
||||
currentNode.verifyChildren(currentPos, moves);
|
||||
int nc = currentNode.children.size();
|
||||
for (int i = 0; i < nc; i++) {
|
||||
Node child = currentNode.children.get(i);
|
||||
child.moveStrLocal = TextIO.moveToString(currentPos, child.move, false, true, moves);
|
||||
goForward(i, false);
|
||||
translateMovesHelper();
|
||||
goBack();
|
||||
}
|
||||
}
|
||||
|
||||
/** Export game tree in PGN format. */
|
||||
public final String toPGN(PGNOptions options) {
|
||||
PgnText pgnText = new PgnText();
|
||||
options.exp.pgnPromotions = true;
|
||||
options.exp.pieceType = PGNOptions.PT_ENGLISH;
|
||||
pgnTreeWalker(options, pgnText);
|
||||
return pgnText.getPgnString();
|
||||
}
|
||||
|
@ -235,7 +263,7 @@ public class GameTree {
|
|||
while (currentNode != rootNode) {
|
||||
Node child = currentNode;
|
||||
goBack();
|
||||
int childNum = variations().indexOf(child);
|
||||
int childNum = currentNode.children.indexOf(child);
|
||||
currPath.add(childNum);
|
||||
}
|
||||
while (variations().size() > 0)
|
||||
|
@ -692,11 +720,17 @@ public class GameTree {
|
|||
int idx = currentNode.children.size();
|
||||
Node node = new Node(currentNode, moveStr, playerAction, Integer.MIN_VALUE, nag, preComment, postComment);
|
||||
Move move = TextIO.UCIstringToMove(moveStr);
|
||||
if (move == null)
|
||||
move = TextIO.stringToMove(currentPos, moveStr);
|
||||
ArrayList<Move> moves = null;
|
||||
if (move == null) {
|
||||
moves = MoveGen.instance.legalMoves(currentPos);
|
||||
move = TextIO.stringToMove(currentPos, moveStr, moves);
|
||||
}
|
||||
if (move == null)
|
||||
return -1;
|
||||
node.moveStr = TextIO.moveToString(currentPos, move, false);
|
||||
if (moves == null)
|
||||
moves = MoveGen.instance.legalMoves(currentPos);
|
||||
node.moveStr = TextIO.moveToString(currentPos, move, false, false, moves);
|
||||
node.moveStrLocal = TextIO.moveToString(currentPos, move, false, true, moves);
|
||||
node.move = move;
|
||||
node.ui = new UndoInfo();
|
||||
currentNode.children.add(node);
|
||||
|
@ -831,7 +865,7 @@ public class GameTree {
|
|||
}
|
||||
|
||||
/** Get additional info affecting gameState. A player "draw" or "resign" command. */
|
||||
final String getGameStateInfo() {
|
||||
final String getGameStateInfo(boolean localized) {
|
||||
String ret = "";
|
||||
String action = currentNode.playerAction;
|
||||
if (action.startsWith("draw rep ")) {
|
||||
|
@ -840,6 +874,25 @@ public class GameTree {
|
|||
if (action.startsWith("draw 50 ")) {
|
||||
ret = action.substring(8).trim();
|
||||
}
|
||||
if (localized) {
|
||||
StringBuilder sb = new StringBuilder();
|
||||
for (int i = 0; i < ret.length(); i++) {
|
||||
int p = Piece.EMPTY;
|
||||
switch (ret.charAt(i)) {
|
||||
case 'Q': p = Piece.WQUEEN; break;
|
||||
case 'R': p = Piece.WROOK; break;
|
||||
case 'B': p = Piece.WBISHOP; break;
|
||||
case 'N': p = Piece.WKNIGHT; break;
|
||||
case 'K': p = Piece.WKING; break;
|
||||
case 'P': p = Piece.WPAWN; break;
|
||||
}
|
||||
if (p == Piece.EMPTY)
|
||||
sb.append(ret.charAt(i));
|
||||
else
|
||||
sb.append(TextIO.pieceToCharLocalized(p));
|
||||
}
|
||||
ret = sb.toString();
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
@ -930,7 +983,8 @@ public class GameTree {
|
|||
* The root node is special in that it doesn't have a move.
|
||||
*/
|
||||
public static class Node {
|
||||
String moveStr; // String representation of move leading to this node. Empty string root node.
|
||||
String moveStr; // String representation of move leading to this node. Empty string in root node.
|
||||
String moveStrLocal; // Localized version of moveStr
|
||||
Move move; // Computed on demand for better PGN parsing performance.
|
||||
// Subtrees of invalid moves will be dropped when detected.
|
||||
// Always valid for current node.
|
||||
|
@ -948,6 +1002,7 @@ public class GameTree {
|
|||
|
||||
public Node() {
|
||||
this.moveStr = "";
|
||||
this.moveStrLocal = "";
|
||||
this.move = null;
|
||||
this.ui = null;
|
||||
this.playerAction = "";
|
||||
|
@ -963,6 +1018,7 @@ public class GameTree {
|
|||
public Node(Node parent, String moveStr, String playerAction, int remainingTime, int nag,
|
||||
String preComment, String postComment) {
|
||||
this.moveStr = moveStr;
|
||||
this.moveStrLocal = moveStr;
|
||||
this.move = null;
|
||||
this.ui = null;
|
||||
this.playerAction = playerAction;
|
||||
|
@ -981,12 +1037,18 @@ public class GameTree {
|
|||
|
||||
/** nodePos must represent the same position as this Node object. */
|
||||
private final boolean verifyChildren(Position nodePos) {
|
||||
return verifyChildren(nodePos, null);
|
||||
}
|
||||
private final boolean verifyChildren(Position nodePos, ArrayList<Move> moves) {
|
||||
boolean anyToRemove = false;
|
||||
for (Node child : children) {
|
||||
if (child.move == null) {
|
||||
Move move = TextIO.stringToMove(nodePos, child.moveStr);
|
||||
if (moves == null)
|
||||
moves = MoveGen.instance.legalMoves(nodePos);
|
||||
Move move = TextIO.stringToMove(nodePos, child.moveStr, moves);
|
||||
if (move != null) {
|
||||
child.moveStr = TextIO.moveToString(nodePos, move, false);
|
||||
child.moveStr = TextIO.moveToString(nodePos, move, false, false, moves);
|
||||
child.moveStrLocal = TextIO.moveToString(nodePos, move, false, true, moves);
|
||||
child.move = move;
|
||||
child.ui = new UndoInfo();
|
||||
} else {
|
||||
|
@ -1053,6 +1115,7 @@ public class GameTree {
|
|||
static final void readFromStream(DataInputStream dis, Node node) throws IOException {
|
||||
while (true) {
|
||||
node.moveStr = dis.readUTF();
|
||||
node.moveStrLocal = node.moveStr;
|
||||
int from = dis.readByte();
|
||||
if (from >= 0) {
|
||||
int to = dis.readByte();
|
||||
|
@ -1105,7 +1168,7 @@ public class GameTree {
|
|||
}
|
||||
}
|
||||
|
||||
/** Export this node in PGN format. */
|
||||
/** Export this node in PGN (or display text) format. */
|
||||
private final boolean addPgnDataOneNode(PgnToken.PgnTokenReceiver out, MoveNumber mn,
|
||||
boolean needMoveNr, PGNOptions options) {
|
||||
if ((preComment.length() > 0) && options.exp.comments) {
|
||||
|
@ -1125,8 +1188,12 @@ public class GameTree {
|
|||
out.processToken(this, PgnToken.PERIOD, null);
|
||||
}
|
||||
}
|
||||
String str = moveStr;
|
||||
if (options.exp.pgnPromotions && (move != null) && (move.promoteTo != Piece.EMPTY)) {
|
||||
String str;
|
||||
if (options.exp.pieceType == PGNOptions.PT_LOCAL) {
|
||||
str = moveStrLocal;
|
||||
} else {
|
||||
str = moveStr;
|
||||
if (options.exp.pgnPromotions && (move != null) && (move.promoteTo != Piece.EMPTY))
|
||||
str = TextIO.pgnPromotion(str);
|
||||
}
|
||||
out.processToken(this, PgnToken.SYMBOL, str);
|
||||
|
@ -1261,6 +1328,7 @@ public class GameTree {
|
|||
moveAdded = false;
|
||||
}
|
||||
nodeToAdd.moveStr = tok.token;
|
||||
nodeToAdd.moveStrLocal = tok.token;
|
||||
moveAdded = true;
|
||||
}
|
||||
break;
|
||||
|
|
|
@ -31,9 +31,16 @@ public class MoveGen {
|
|||
instance = new MoveGen();
|
||||
}
|
||||
|
||||
/** Generate and return a list of legal moves. */
|
||||
public final ArrayList<Move> legalMoves(Position pos) {
|
||||
ArrayList<Move> moveList = pseudoLegalMoves(pos);
|
||||
moveList = MoveGen.removeIllegal(pos, moveList);
|
||||
return moveList;
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate and return a list of pseudo-legal moves.
|
||||
* Pseudo-legal means that the moves doesn't necessarily defend from check threats.
|
||||
* Pseudo-legal means that the moves don't necessarily defend from check threats.
|
||||
*/
|
||||
public final ArrayList<Move> pseudoLegalMoves(Position pos) {
|
||||
ArrayList<Move> moveList = getMoveListObj();
|
||||
|
|
|
@ -37,21 +37,6 @@ public interface SearchListener {
|
|||
ArrayList<Move> pv;
|
||||
String pvStr = "";
|
||||
|
||||
public PvInfo(PvInfo pvi) {
|
||||
depth = pvi.depth;
|
||||
score = pvi.score;
|
||||
time = pvi.time;
|
||||
nodes = pvi.nodes;
|
||||
nps = pvi.nps;
|
||||
isMate = pvi.isMate;
|
||||
upperBound = pvi.upperBound;
|
||||
lowerBound = pvi.lowerBound;
|
||||
pv = new ArrayList<Move>(pvi.pv.size());
|
||||
for (int i = 0; i < pvi.pv.size(); i++)
|
||||
pv.add(pvi.pv.get(i));
|
||||
pvStr = pvi.pvStr;
|
||||
}
|
||||
|
||||
public PvInfo(int depth, int score, int time, int nodes, int nps,
|
||||
boolean isMate, boolean upperBound, boolean lowerBound, ArrayList<Move> pv) {
|
||||
this.depth = depth;
|
||||
|
|
|
@ -25,12 +25,22 @@ import org.petero.droidfish.R;
|
|||
|
||||
|
||||
/**
|
||||
*
|
||||
* Handle conversion of positions and moves to/from text format.
|
||||
* @author petero
|
||||
*/
|
||||
public class TextIO {
|
||||
static public final String startPosFEN = "rnbqkbnr/pppppppp/8/8/8/8/PPPPPPPP/RNBQKBNR w KQkq - 0 1";
|
||||
|
||||
/** Localized version of "P N B R Q K". */
|
||||
private static String[] pieceNames = null;
|
||||
|
||||
/** Set localized piece names. */
|
||||
public static final void setPieceNames(String pieceNames) {
|
||||
String[] pn = pieceNames.split(" ");
|
||||
if (pn.length == 6)
|
||||
TextIO.pieceNames = pn;
|
||||
}
|
||||
|
||||
/** Parse a FEN string and return a chess Position object. */
|
||||
public static final Position readFEN(String fen) throws ChessParseError {
|
||||
Position pos = new Position();
|
||||
|
@ -312,15 +322,15 @@ public class TextIO {
|
|||
* @param pos The chess position.
|
||||
* @param move The executed move.
|
||||
* @param longForm If true, use long notation, eg Ng1-f3.
|
||||
* Otherwise, use short notation, eg Nf3
|
||||
* Otherwise, use short notation, eg Nf3.
|
||||
* @param localized If true, use localized piece names.
|
||||
*/
|
||||
public static final String moveToString(Position pos, Move move, boolean longForm) {
|
||||
ArrayList<Move> moves = MoveGen.instance.pseudoLegalMoves(pos);
|
||||
moves = MoveGen.removeIllegal(pos, moves);
|
||||
return moveToString(pos, move, longForm, moves);
|
||||
public static final String moveToString(Position pos, Move move, boolean longForm,
|
||||
boolean localized) {
|
||||
return moveToString(pos, move, longForm, localized, null);
|
||||
}
|
||||
private static final String moveToString(Position pos, Move move, boolean longForm,
|
||||
List<Move> moves) {
|
||||
public static final String moveToString(Position pos, Move move, boolean longForm,
|
||||
boolean localized, List<Move> moves) {
|
||||
if ((move == null) || move.equals(new Move(0, 0, 0)))
|
||||
return "--";
|
||||
StringBuilder ret = new StringBuilder();
|
||||
|
@ -342,7 +352,12 @@ public class TextIO {
|
|||
}
|
||||
}
|
||||
if (ret.length() == 0) {
|
||||
if (pieceNames == null)
|
||||
localized = false;
|
||||
int p = pos.getPiece(move.from);
|
||||
if (localized)
|
||||
ret.append(pieceToCharLocalized(p));
|
||||
else
|
||||
ret.append(pieceToChar(p));
|
||||
int x1 = Position.getX(move.from);
|
||||
int y1 = Position.getY(move.from);
|
||||
|
@ -361,6 +376,8 @@ public class TextIO {
|
|||
int numSameTarget = 0;
|
||||
int numSameFile = 0;
|
||||
int numSameRow = 0;
|
||||
if (moves == null)
|
||||
moves = MoveGen.instance.legalMoves(pos);
|
||||
int mSize = moves.size();
|
||||
for (int mi = 0; mi < mSize; mi++) {
|
||||
Move m = moves.get(mi);
|
||||
|
@ -389,9 +406,13 @@ public class TextIO {
|
|||
}
|
||||
ret.append((char) (x2 + 'a'));
|
||||
ret.append((char) (y2 + '1'));
|
||||
if (move.promoteTo != Piece.EMPTY)
|
||||
if (move.promoteTo != Piece.EMPTY) {
|
||||
if (localized)
|
||||
ret.append(pieceToCharLocalized(move.promoteTo));
|
||||
else
|
||||
ret.append(pieceToChar(move.promoteTo));
|
||||
}
|
||||
}
|
||||
UndoInfo ui = new UndoInfo();
|
||||
pos.makeMove(move, ui);
|
||||
boolean givesCheck = MoveGen.inCheck(pos);
|
||||
|
@ -453,6 +474,10 @@ public class TextIO {
|
|||
* information as long as it matches exactly one valid move.
|
||||
*/
|
||||
public static final Move stringToMove(Position pos, String strMove) {
|
||||
return stringToMove(pos, strMove, null);
|
||||
}
|
||||
public static final Move stringToMove(Position pos, String strMove,
|
||||
ArrayList<Move> moves) {
|
||||
if (strMove.equals("--"))
|
||||
return new Move(0, 0, 0);
|
||||
|
||||
|
@ -530,8 +555,8 @@ public class TextIO {
|
|||
info.promPiece = Piece.EMPTY;
|
||||
}
|
||||
|
||||
ArrayList<Move> moves = MoveGen.instance.pseudoLegalMoves(pos);
|
||||
moves = MoveGen.removeIllegal(pos, moves);
|
||||
if (moves == null)
|
||||
moves = MoveGen.instance.legalMoves(pos);
|
||||
|
||||
ArrayList<Move> matches = new ArrayList<Move>(2);
|
||||
for (int i = 0; i < moves.size(); i++) {
|
||||
|
@ -717,6 +742,17 @@ public class TextIO {
|
|||
return "";
|
||||
}
|
||||
|
||||
public final static String pieceToCharLocalized(int p) {
|
||||
switch (p) {
|
||||
case Piece.WQUEEN: case Piece.BQUEEN: return pieceNames[4];
|
||||
case Piece.WROOK: case Piece.BROOK: return pieceNames[3];
|
||||
case Piece.WBISHOP: case Piece.BBISHOP: return pieceNames[2];
|
||||
case Piece.WKNIGHT: case Piece.BKNIGHT: return pieceNames[1];
|
||||
case Piece.WKING: case Piece.BKING: return pieceNames[5];
|
||||
}
|
||||
return "";
|
||||
}
|
||||
|
||||
private final static int charToPiece(boolean white, char c) {
|
||||
switch (c) {
|
||||
case 'Q': case 'q': return white ? Piece.WQUEEN : Piece.BQUEEN;
|
||||
|
|
|
@ -60,7 +60,7 @@ public class BookTest extends TestCase {
|
|||
public void testGetAllBookMoves() throws ChessParseError {
|
||||
Position pos = TextIO.readFEN(TextIO.startPosFEN);
|
||||
DroidBook book = DroidBook.getInstance();
|
||||
String moveListString = book.getAllBookMoves(pos).first;
|
||||
String moveListString = book.getAllBookMoves(pos, false).first;
|
||||
String[] strMoves = moveListString.split(":[0-9]* ");
|
||||
assertTrue(strMoves.length > 1);
|
||||
for (String strMove : strMoves) {
|
||||
|
|
|
@ -140,7 +140,7 @@ public class GameTest extends TestCase {
|
|||
game.setPos(TextIO.readFEN(fen));
|
||||
game.processString("draw 50 Nc3");
|
||||
assertEquals(Game.GameState.DRAW_50, game.getGameState()); // Draw claim valid
|
||||
assertEquals("Nc3", game.getDrawInfo());
|
||||
assertEquals("Nc3", game.getDrawInfo(false));
|
||||
|
||||
game.setPos(TextIO.readFEN(fen));
|
||||
game.processString("draw 50 a6");
|
||||
|
|
|
@ -225,7 +225,7 @@ public class GameTreeTest extends TestCase {
|
|||
for (int i = 0; i < vars.size(); i++) {
|
||||
if (i > 0)
|
||||
ret.append(' ');
|
||||
String moveStr = TextIO.moveToString(gt.currentPos, vars.get(i), false);
|
||||
String moveStr = TextIO.moveToString(gt.currentPos, vars.get(i), false, false);
|
||||
ret.append(moveStr);
|
||||
}
|
||||
return ret.toString();
|
||||
|
@ -477,7 +477,7 @@ public class GameTreeTest extends TestCase {
|
|||
assertEquals("A \"good\" player", gt.white);
|
||||
assertEquals("e4", getVariationsAsString(gt));
|
||||
|
||||
// Test for broken PGN headers: [White "A "good" player"]
|
||||
// Test for broken PGN headers: [White "A "good old" player"]
|
||||
res = gt.readPGN("[White \"A \"good old\" player\"]\ne4", options);
|
||||
assertEquals(true, res);
|
||||
assertEquals("A \"good old\" player", gt.white);
|
||||
|
|
|
@ -195,7 +195,7 @@ public class MoveGenTest extends TestCase {
|
|||
}
|
||||
ArrayList<String> strMoves = new ArrayList<String>();
|
||||
for (Move m : moves) {
|
||||
String mStr = TextIO.moveToString(pos, m, true);
|
||||
String mStr = TextIO.moveToString(pos, m, true, false);
|
||||
strMoves.add(mStr);
|
||||
// System.out.println(mStr);
|
||||
}
|
||||
|
|
|
@ -123,6 +123,10 @@ public class TextIOTest extends TestCase {
|
|||
return wasError;
|
||||
}
|
||||
|
||||
private final static String moveToString(Position pos, Move move, boolean longForm) {
|
||||
return TextIO.moveToString(pos, move, longForm, false);
|
||||
}
|
||||
|
||||
/**
|
||||
* Test of moveToString method, of class TextIO.
|
||||
*/
|
||||
|
@ -132,39 +136,39 @@ public class TextIOTest extends TestCase {
|
|||
Move move = new Move(Position.getSquare(4, 1), Position.getSquare(4, 3),
|
||||
Piece.EMPTY);
|
||||
boolean longForm = true;
|
||||
String result = TextIO.moveToString(pos, move, longForm);
|
||||
String result = moveToString(pos, move, longForm);
|
||||
assertEquals("e2-e4", result);
|
||||
|
||||
move = new Move(Position.getSquare(6, 0), Position.getSquare(5, 2), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("Ng1-f3", result);
|
||||
|
||||
move = new Move(Position.getSquare(4, 7), Position.getSquare(2, 7),
|
||||
Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("O-O-O", result);
|
||||
|
||||
String fen = "1r3k2/2P5/8/8/8/4K3/8/8 w - - 0 1";
|
||||
pos = TextIO.readFEN(fen);
|
||||
assertEquals(fen, TextIO.toFEN(pos));
|
||||
move = new Move(Position.getSquare(2,6), Position.getSquare(1,7), Piece.WROOK);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("c7xb8R+", result);
|
||||
|
||||
move = new Move(Position.getSquare(2,6), Position.getSquare(2,7), Piece.WKNIGHT);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("c7-c8N", result);
|
||||
|
||||
move = new Move(Position.getSquare(2,6), Position.getSquare(2,7), Piece.WQUEEN);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("c7-c8Q+", result);
|
||||
|
||||
// Test null move
|
||||
pos = TextIO.readFEN(TextIO.startPosFEN);
|
||||
Move nullMove = new Move(0, 0, 0);
|
||||
result = TextIO.moveToString(pos, nullMove, false);
|
||||
result = moveToString(pos, nullMove, false);
|
||||
assertEquals("--", result);
|
||||
result = TextIO.moveToString(pos, nullMove, true);
|
||||
result = moveToString(pos, nullMove, true);
|
||||
assertEquals("--", result);
|
||||
}
|
||||
|
||||
|
@ -176,19 +180,19 @@ public class TextIOTest extends TestCase {
|
|||
boolean longForm = true;
|
||||
|
||||
Move move = new Move(Position.getSquare(1, 6), Position.getSquare(1, 7), Piece.WROOK);
|
||||
String result = TextIO.moveToString(pos, move, longForm);
|
||||
String result = moveToString(pos, move, longForm);
|
||||
assertEquals("b7-b8R+", result); // check
|
||||
|
||||
move = new Move(Position.getSquare(1, 6), Position.getSquare(1, 7), Piece.WQUEEN);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("b7-b8Q#", result); // check mate
|
||||
|
||||
move = new Move(Position.getSquare(1, 6), Position.getSquare(1, 7), Piece.WKNIGHT);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("b7-b8N", result);
|
||||
|
||||
move = new Move(Position.getSquare(1, 6), Position.getSquare(1, 7), Piece.WBISHOP);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("b7-b8B", result); // stalemate
|
||||
}
|
||||
|
||||
|
@ -202,43 +206,43 @@ public class TextIOTest extends TestCase {
|
|||
boolean longForm = false;
|
||||
|
||||
Move move = new Move(Position.getSquare(4,5), Position.getSquare(4,3), Piece.EMPTY);
|
||||
String result = TextIO.moveToString(pos, move, longForm);
|
||||
String result = moveToString(pos, move, longForm);
|
||||
assertEquals("Qee4", result); // File disambiguation needed
|
||||
|
||||
move = new Move(Position.getSquare(2,5), Position.getSquare(4,3), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("Qc6e4", result); // Full disambiguation needed
|
||||
|
||||
move = new Move(Position.getSquare(2,3), Position.getSquare(4,3), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("Q4e4", result); // Row disambiguation needed
|
||||
|
||||
move = new Move(Position.getSquare(2,3), Position.getSquare(2,0), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("Qc1+", result); // No disambiguation needed
|
||||
|
||||
move = new Move(Position.getSquare(0,1), Position.getSquare(0,0), Piece.BQUEEN);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("a1Q", result); // Normal promotion
|
||||
|
||||
move = new Move(Position.getSquare(0,1), Position.getSquare(1,0), Piece.BQUEEN);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("axb1Q#", result); // Capture promotion and check mate
|
||||
|
||||
move = new Move(Position.getSquare(0,1), Position.getSquare(1,0), Piece.BKNIGHT);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("axb1N", result); // Capture promotion
|
||||
|
||||
move = new Move(Position.getSquare(3,6), Position.getSquare(4,4), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("Ne5", result); // Other knight pinned, no disambiguation needed
|
||||
|
||||
move = new Move(Position.getSquare(7,6), Position.getSquare(7,4), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("h5", result); // Regular pawn move
|
||||
|
||||
move = new Move(Position.getSquare(5,7), Position.getSquare(3,7), Piece.EMPTY);
|
||||
result = TextIO.moveToString(pos, move, longForm);
|
||||
result = moveToString(pos, move, longForm);
|
||||
assertEquals("Rfd8", result); // File disambiguation needed
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue
Block a user