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,52 +597,85 @@ 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); setSelection(-1); // Remove selection of opponents last moving piece
if (!myColor(p)) {
setSelection(-1); // Remove selection of opponents last moving piece
}
}
int p = pos.getPiece(sq); if (!oneTouchMoves) {
if (selectedSquare != -1) { int p = pos.getPiece(sq);
if (sq == selectedSquare) if (selectedSquare != -1) {
return null; if (sq == selectedSquare)
if (!myColor(p)) { return null;
Move m = new Move(selectedSquare, sq, Piece.EMPTY); if (!myColor(p)) {
setSelection(sq); Move m = new Move(selectedSquare, sq, Piece.EMPTY);
return m; setSelection(sq);
userSelectedSquare = false;
return m;
} else
setSelection(sq);
} else { } else {
setSelection(sq); if (myColor(p))
setSelection(sq);
} }
} else { } else {
if (oneTouchMoves) { int prevSq = userSelectedSquare ? selectedSquare : -1;
ArrayList<Move> moves = new MoveGen().legalMoves(pos); if (prevSq == sq)
Move matchingMove = null; return null;
int toSq = -1; ArrayList<Move> moves = new MoveGen().legalMoves(pos);
for (Move m : moves) { Move matchingMove = null;
if ((m.from == sq) || (m.to == sq)) { if (prevSq >= 0)
if (matchingMove == null) { matchingMove = matchingMove(prevSq, sq, moves).first;
matchingMove = m; boolean anyMatch = false;
toSq = m.to; if (matchingMove == null) {
} else { Pair<Move, Boolean> match = matchingMove(-1, sq, moves);
matchingMove = null; matchingMove = match.first;
break; anyMatch = match.second;
}
}
}
if (matchingMove != null) {
setSelection(toSq);
return matchingMove;
}
} }
if (myColor(p)) { if (matchingMove != null) {
setSelection(sq); setSelection(matchingMove.to);
userSelectedSquare = false;
return matchingMove;
} }
setSelection(anyMatch ? sq : -1);
} }
return null; 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) {
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) {
matchingMove = m;
anyMatch = true;
} else {
if ((matchingMove.from == m.from) &&
(matchingMove.to == m.to)) {
matchingMove.promoteTo = Piece.EMPTY;
} else {
matchingMove = null;
break;
}
}
}
}
return new Pair<Move, Boolean>(matchingMove, anyMatch);
}
public static class OnTrackballListener { public static class OnTrackballListener {
public void onTrackballEvent(MotionEvent event) { } public void onTrackballEvent(MotionEvent event) { }
} }

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);
} }