DroidFish: Improved "one touch move" behavior. Based on patch from Leo Mayer.

This commit is contained in:
Peter Osterlund
2012-08-26 13:34:54 +00:00
parent db704232df
commit 1f01daf133
5 changed files with 81 additions and 40 deletions

View File

@@ -249,8 +249,8 @@ you are not actively using the program.\
<string name="prefs_user_interface">User Interface</string> <string name="prefs_user_interface">User Interface</string>
<string name="prefs_animateMoves_title">Animate Moves</string> <string name="prefs_animateMoves_title">Animate Moves</string>
<string name="prefs_animateMoves_summary">Animate piece movements</string> <string name="prefs_animateMoves_summary">Animate piece movements</string>
<string name="prefs_oneTouchMoves_title">One Touch Moves</string> <string name="prefs_quickMoveInput_title">Quick Move Input</string>
<string name="prefs_oneTouchMoves_summary">Touching a square that corresponds to one unique move makes that move immediately</string> <string name="prefs_quickMoveInput_summary">From and To squares can be touched in any order. Move is played as soon as uniquely defined.</string>
<string name="prefs_soundEnabled_title">Enable Sounds</string> <string name="prefs_soundEnabled_title">Enable Sounds</string>
<string name="prefs_soundEnabled_summary">Play sound when computer makes a move</string> <string name="prefs_soundEnabled_summary">Play sound when computer makes a move</string>
<string name="prefs_vibrateEnabled_title">Enable Vibration</string> <string name="prefs_vibrateEnabled_title">Enable Vibration</string>

View File

@@ -125,8 +125,8 @@
</CheckBoxPreference> </CheckBoxPreference>
<CheckBoxPreference <CheckBoxPreference
android:key="oneTouchMoves" android:key="oneTouchMoves"
android:title="@string/prefs_oneTouchMoves_title" android:title="@string/prefs_quickMoveInput_title"
android:summary="@string/prefs_oneTouchMoves_summary" android:summary="@string/prefs_quickMoveInput_summary"
android:defaultValue="false"> android:defaultValue="false">
</CheckBoxPreference> </CheckBoxPreference>
<CheckBoxPreference <CheckBoxPreference

View File

@@ -24,6 +24,7 @@ import java.util.List;
import org.petero.droidfish.gamelogic.Move; import org.petero.droidfish.gamelogic.Move;
import org.petero.droidfish.gamelogic.MoveGen; import org.petero.droidfish.gamelogic.MoveGen;
import org.petero.droidfish.gamelogic.Pair;
import org.petero.droidfish.gamelogic.Piece; import org.petero.droidfish.gamelogic.Piece;
import org.petero.droidfish.gamelogic.Position; import org.petero.droidfish.gamelogic.Position;
import org.petero.droidfish.gamelogic.UndoInfo; import org.petero.droidfish.gamelogic.UndoInfo;
@@ -44,6 +45,8 @@ public class ChessBoard extends View {
public Position pos; public Position pos;
public int selectedSquare; public int selectedSquare;
public boolean userSelectedSquare; // True if selectedSquare was set by user tap/click,
// false if selectedSquare used to highlight last move
public float cursorX, cursorY; public float cursorX, cursorY;
public boolean cursorVisible; public boolean cursorVisible;
protected int x0, y0, sqSize; protected int x0, y0, sqSize;
@@ -88,6 +91,7 @@ public class ChessBoard extends View {
super(context, attrs); super(context, attrs);
pos = new Position(); pos = new Position();
selectedSquare = -1; selectedSquare = -1;
userSelectedSquare = false;
cursorX = cursorY = 0; cursorX = cursorY = 0;
cursorVisible = false; cursorVisible = false;
x0 = y0 = sqSize = 0; x0 = y0 = sqSize = 0;
@@ -344,6 +348,7 @@ public class ChessBoard extends View {
selectedSquare = square; selectedSquare = square;
invalidate(); invalidate();
} }
userSelectedSquare = true;
} }
protected int getWidth(int sqSize) { return sqSize * 8; } protected int getWidth(int sqSize) { return sqSize * 8; }
@@ -592,13 +597,10 @@ public class ChessBoard extends View {
if (sq < 0) if (sq < 0)
return null; return null;
cursorVisible = false; cursorVisible = false;
if (selectedSquare != -1) { if ((selectedSquare != -1) && !userSelectedSquare)
int p = pos.getPiece(selectedSquare);
if (!myColor(p)) {
setSelection(-1); // Remove selection of opponents last moving piece setSelection(-1); // Remove selection of opponents last moving piece
}
}
if (!oneTouchMoves) {
int p = pos.getPiece(sq); int p = pos.getPiece(sq);
if (selectedSquare != -1) { if (selectedSquare != -1) {
if (sq == selectedSquare) if (sq == selectedSquare)
@@ -606,36 +608,72 @@ public class ChessBoard extends View {
if (!myColor(p)) { if (!myColor(p)) {
Move m = new Move(selectedSquare, sq, Piece.EMPTY); Move m = new Move(selectedSquare, sq, Piece.EMPTY);
setSelection(sq); setSelection(sq);
userSelectedSquare = false;
return m; return m;
} else
setSelection(sq);
} else { } else {
if (myColor(p))
setSelection(sq); setSelection(sq);
} }
} else { } else {
if (oneTouchMoves) { int prevSq = userSelectedSquare ? selectedSquare : -1;
if (prevSq == sq)
return null;
ArrayList<Move> moves = new MoveGen().legalMoves(pos); ArrayList<Move> moves = new MoveGen().legalMoves(pos);
Move matchingMove = null; Move matchingMove = null;
int toSq = -1; if (prevSq >= 0)
matchingMove = matchingMove(prevSq, sq, moves).first;
boolean anyMatch = false;
if (matchingMove == null) {
Pair<Move, Boolean> match = matchingMove(-1, sq, moves);
matchingMove = match.first;
anyMatch = match.second;
}
if (matchingMove != null) {
setSelection(matchingMove.to);
userSelectedSquare = false;
return matchingMove;
}
setSelection(anyMatch ? sq : -1);
}
return null;
}
/**
* Determine if there is a unique legal move corresponding to one or two selected squares.
* @param sq1 First square, or -1.
* @param sq2 Second square.
* @param moves List of legal moves.
* @return Matching move if unique.
* Boolean indicating if there was at least one match.
*/
private final Pair<Move, Boolean> matchingMove(int sq1, int sq2, ArrayList<Move> moves) {
Move matchingMove = null;
boolean anyMatch = false;
for (Move m : moves) { for (Move m : moves) {
if ((m.from == sq) || (m.to == sq)) { boolean match;
if (sq1 == -1)
match = (m.from == sq2) || (m.to == sq2);
else
match = (m.from == sq1) && (m.to == sq2) ||
(m.from == sq2) && (m.to == sq1);
if (match) {
if (matchingMove == null) { if (matchingMove == null) {
matchingMove = m; matchingMove = m;
toSq = m.to; anyMatch = true;
} else {
if ((matchingMove.from == m.from) &&
(matchingMove.to == m.to)) {
matchingMove.promoteTo = Piece.EMPTY;
} else { } else {
matchingMove = null; matchingMove = null;
break; break;
} }
} }
} }
if (matchingMove != null) {
setSelection(toSq);
return matchingMove;
} }
} return new Pair<Move, Boolean>(matchingMove, anyMatch);
if (myColor(p)) {
setSelection(sq);
}
}
return null;
} }
public static class OnTrackballListener { public static class OnTrackballListener {

View File

@@ -476,6 +476,7 @@ public class DroidFish extends Activity implements GUIInterface {
cb.setDrawSquareLabels(oldCB.drawSquareLabels); cb.setDrawSquareLabels(oldCB.drawSquareLabels);
cb.oneTouchMoves = oldCB.oneTouchMoves; cb.oneTouchMoves = oldCB.oneTouchMoves;
setSelection(oldCB.selectedSquare); setSelection(oldCB.selectedSquare);
cb.userSelectedSquare = oldCB.userSelectedSquare;
setStatusString(statusStr); setStatusString(statusStr);
moveListUpdated(); moveListUpdated();
updateThinkingInfo(); updateThinkingInfo();
@@ -1175,6 +1176,7 @@ public class DroidFish extends Activity implements GUIInterface {
@Override @Override
public void setSelection(int sq) { public void setSelection(int sq) {
cb.setSelection(sq); cb.setSelection(sq);
cb.userSelectedSquare = false;
setEgtbHints(sq); setEgtbHints(sq);
} }

View File

@@ -91,6 +91,7 @@ public class EditBoard extends Activity {
cb.cursorVisible = oldCB.cursorVisible; cb.cursorVisible = oldCB.cursorVisible;
cb.setPosition(oldCB.pos); cb.setPosition(oldCB.pos);
setSelection(oldCB.selectedSquare); setSelection(oldCB.selectedSquare);
cb.userSelectedSquare = oldCB.userSelectedSquare;
status.setText(statusStr); status.setText(statusStr);
} }