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_animateMoves_title">Animate Moves</string>
<string name="prefs_animateMoves_summary">Animate piece movements</string>
<string name="prefs_oneTouchMoves_title">One Touch Moves</string>
<string name="prefs_oneTouchMoves_summary">Touching a square that corresponds to one unique move makes that move immediately</string>
<string name="prefs_quickMoveInput_title">Quick Move Input</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_summary">Play sound when computer makes a move</string>
<string name="prefs_vibrateEnabled_title">Enable Vibration</string>

View File

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

View File

@ -24,6 +24,7 @@ import java.util.List;
import org.petero.droidfish.gamelogic.Move;
import org.petero.droidfish.gamelogic.MoveGen;
import org.petero.droidfish.gamelogic.Pair;
import org.petero.droidfish.gamelogic.Piece;
import org.petero.droidfish.gamelogic.Position;
import org.petero.droidfish.gamelogic.UndoInfo;
@ -44,6 +45,8 @@ public class ChessBoard extends View {
public Position pos;
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 boolean cursorVisible;
protected int x0, y0, sqSize;
@ -88,6 +91,7 @@ public class ChessBoard extends View {
super(context, attrs);
pos = new Position();
selectedSquare = -1;
userSelectedSquare = false;
cursorX = cursorY = 0;
cursorVisible = false;
x0 = y0 = sqSize = 0;
@ -344,6 +348,7 @@ public class ChessBoard extends View {
selectedSquare = square;
invalidate();
}
userSelectedSquare = true;
}
protected int getWidth(int sqSize) { return sqSize * 8; }
@ -592,52 +597,85 @@ public class ChessBoard extends View {
if (sq < 0)
return null;
cursorVisible = false;
if (selectedSquare != -1) {
int p = pos.getPiece(selectedSquare);
if (!myColor(p)) {
setSelection(-1); // Remove selection of opponents last moving piece
}
}
if ((selectedSquare != -1) && !userSelectedSquare)
setSelection(-1); // Remove selection of opponents last moving piece
int p = pos.getPiece(sq);
if (selectedSquare != -1) {
if (sq == selectedSquare)
return null;
if (!myColor(p)) {
Move m = new Move(selectedSquare, sq, Piece.EMPTY);
setSelection(sq);
return m;
if (!oneTouchMoves) {
int p = pos.getPiece(sq);
if (selectedSquare != -1) {
if (sq == selectedSquare)
return null;
if (!myColor(p)) {
Move m = new Move(selectedSquare, sq, Piece.EMPTY);
setSelection(sq);
userSelectedSquare = false;
return m;
} else
setSelection(sq);
} else {
setSelection(sq);
if (myColor(p))
setSelection(sq);
}
} else {
if (oneTouchMoves) {
ArrayList<Move> moves = new MoveGen().legalMoves(pos);
Move matchingMove = null;
int toSq = -1;
for (Move m : moves) {
if ((m.from == sq) || (m.to == sq)) {
if (matchingMove == null) {
matchingMove = m;
toSq = m.to;
} else {
matchingMove = null;
break;
}
}
}
if (matchingMove != null) {
setSelection(toSq);
return matchingMove;
}
int prevSq = userSelectedSquare ? selectedSquare : -1;
if (prevSq == sq)
return null;
ArrayList<Move> moves = new MoveGen().legalMoves(pos);
Move matchingMove = null;
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 (myColor(p)) {
setSelection(sq);
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) {
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 void onTrackballEvent(MotionEvent event) { }
}

View File

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

View File

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