BlackKing, BlackMan, BlackKnight, BlackRook }
};
+ChessSquare lionArray[2][BOARD_FILES] = {
+ { WhiteRook, WhiteLion, WhiteBishop, WhiteQueen,
+ WhiteKing, WhiteBishop, WhiteKnight, WhiteRook },
+ { BlackRook, BlackLion, BlackBishop, BlackQueen,
+ BlackKing, BlackBishop, BlackKnight, BlackRook }
+};
+
#if (BOARD_FILES>=10)
ChessSquare ShogiArray[2][BOARD_FILES] = {
case VariantSChess: /* S-Chess, should work */
case VariantGrand: /* should work */
case VariantSpartan: /* should work */
+ case VariantLion: /* should work */
break;
}
}
SendToICS(ics_type == ICS_ICC ? "tag result Game in progress\n" : "commit\n");
}
-static int killX = -1, killY = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove
+int killX = -1, killY = -1; // [HGM] lion: used for passing e.p. capture square to MakeMove
void
CoordsToComputerAlgebraic (int rf, int ff, int rt, int ft, char promoChar, char move[7])
else if(promoSweep == WhiteKing && step > 0) promoSweep = BlackKing;
if(!step) step = -1;
} while(PieceToChar(promoSweep) == '.' || PieceToChar(promoSweep) == '~' || promoSweep == pawn ||
- appData.testLegality && (promoSweep == king ||
- IS_SHOGI(gameInfo.variant) && promoSweep != CHUPROMOTED last && last != CHUPROMOTED promoSweep && last != promoSweep));
+ appData.testLegality && (promoSweep == king || promoSweep == WhiteLion || promoSweep == BlackLion) ||
+ IS_SHOGI(gameInfo.variant) && promoSweep != CHUPROMOTED last && last != CHUPROMOTED promoSweep && last != promoSweep);
if(toX >= 0) {
int victim = boards[currentMove][toY][toX];
boards[currentMove][toY][toX] = promoSweep;
case WhiteNonPromotion:
case BlackNonPromotion:
case NormalMove:
+ case FirstLeg:
case WhiteCapturesEnPassant:
case BlackCapturesEnPassant:
case WhiteKingSideCastle:
pieces = SpartanArray;
SetCharTable(pieceToChar, "PNBRQ................K......lwg.....c...h..k");
break;
+ case VariantLion:
+ pieces = lionArray;
+ SetCharTable(pieceToChar, "PNBRQ................LKpnbrq................lk");
+ break;
case VariantFairy:
pieces = fairyArray;
SetCharTable(pieceToChar, "PNBRQFEACWMOHIJGDVLSUKpnbrqfeacwmohijgdvlsuk");
if(gameInfo.variant == VariantChu) {
int p = piece >= BlackPawn ? BLACK_TO_WHITE piece : piece;
promotionZoneSize = BOARD_HEIGHT/3;
- highestPromotingPiece = (p >= WhiteLion || PieceToChar(piece + 22) == '.') ? WhitePawn : WhiteKing;
+ highestPromotingPiece = (p >= WhiteLion || PieceToChar(piece + 22) == '.') ? WhitePawn : WhiteLion;
} else if(gameInfo.variant == VariantShogi) {
promotionZoneSize = BOARD_HEIGHT/3;
highestPromotingPiece = (int)WhiteAlfil;
{
typedef char Markers[BOARD_RANKS][BOARD_FILES];
Markers *m = (Markers *) closure;
- if(rf == fromY && ff == fromX)
+ if(rf == fromY && ff == fromX && (killX < 0 && !(rt == rf && ft == ff) || abs(ft-killX) < 2 && abs(rt-killY) < 2))
(*m)[rt][ft] = 1 + (board[rt][ft] != EmptySquare
|| kind == WhiteCapturesEnPassant
- || kind == BlackCapturesEnPassant);
+ || kind == BlackCapturesEnPassant) + 3*(kind == FirstLeg && killX < 0);
else if(flags & F_MANDATORY_CAPTURE && board[rt][ft] != EmptySquare) (*m)[rt][ft] = 3;
}
HoverEvent (int xPix, int yPix, int x, int y)
{
static char baseMarker[BOARD_RANKS][BOARD_FILES], baseLegal[BOARD_RANKS][BOARD_FILES];
+ static int oldX = -1, oldY = -1, oldFromX = -1, oldFromY = -1;
int r, f;
if(dragging == 2) DragPieceMove(xPix, yPix); // [HGM] lion: drag without button for second leg
if(!first.highlight) return;
- if(hiX == -1 && hiY == -1 && x == fromX && y == fromY) // record markings
+ if(fromX != oldFromX || fromY != oldFromY) oldX = oldY = -1; // kludge to fake entry on from-click
+ if(x == oldX && y == oldY) return; // only do something if we enter new square
+ oldFromX = fromX; oldFromY = fromY;
+ if(oldX == -1 && oldY == -1 && x == fromX && y == fromY) // record markings after from-change
for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++)
baseMarker[r][f] = marker[r][f], baseLegal[r][f] = legal[r][f];
- else if(hiX != x || hiY != y) {
+ else if(oldX != x || oldY != y) {
// [HGM] lift: entered new to-square; redraw arrow, and inform engine
for(r=0; r<BOARD_HEIGHT; r++) for(f=BOARD_LEFT; f<BOARD_RGHT; f++)
marker[r][f] = baseMarker[r][f], legal[r][f] = baseLegal[r][f];
snprintf(buf, MSG_SIZ, "hover %c%d\n", x + AAA, y + ONE - '0');
SendToProgram(buf, &first);
}
- SetHighlights(fromX, fromY, x, y);
+ oldX = x; oldY = y;
+// SetHighlights(fromX, fromY, x, y);
}
}
if(gameMode == AnalyzeMode && (pausing || controlKey) && first.excludeMoves) { // use pause state to exclude moves
doubleClick = TRUE; gatingPiece = boards[currentMove][y][x];
}
- fromX = x; fromY = y; toX = toY = -1;
+ fromX = x; fromY = y; toX = toY = killX = killY = -1;
if(!appData.oneClick || !OnlyMove(&x, &y, FALSE) ||
// even if only move, we treat as normal when this would trigger a promotion popup, to allow sweep selection
appData.sweepSelect && CanPromote(boards[currentMove][fromY][fromX], fromY) && originalY != y) {
}
/* fromX != -1 */
- if (clickType == Press && gameMode != EditPosition && killX < 0) {
+ if (clickType == Press && gameMode != EditPosition) {
ChessSquare fromP;
ChessSquare toP;
int frc;
fromP = boards[currentMove][fromY][fromX];
toP = boards[currentMove][y][x];
frc = gameInfo.variant == VariantFischeRandom || gameInfo.variant == VariantCapaRandom || gameInfo.variant == VariantSChess;
- if ((WhitePawn <= fromP && fromP <= WhiteKing &&
+ if( (killX < 0 || x != fromX || y != fromY) && // [HGM] lion: do not interpret igui as deselect!
+ ((WhitePawn <= fromP && fromP <= WhiteKing &&
WhitePawn <= toP && toP <= WhiteKing &&
!(fromP == WhiteKing && toP == WhiteRook && frc) &&
!(fromP == WhiteRook && toP == WhiteKing && frc)) ||
(BlackPawn <= fromP && fromP <= BlackKing &&
BlackPawn <= toP && toP <= BlackKing &&
!(fromP == BlackRook && toP == BlackKing && frc) && // allow also RxK as FRC castling
- !(fromP == BlackKing && toP == BlackRook && frc))) {
+ !(fromP == BlackKing && toP == BlackRook && frc)))) {
/* Clicked again on same color piece -- changed his mind */
second = (x == fromX && y == fromY);
+ killX = killY = -1;
if(second && gameMode == AnalyzeMode && SubtractTimeMarks(&lastClickTime, &prevClickTime) < 200) {
second = FALSE; // first double-click rather than scond click
doubleClick = first.excludeMoves; // used by UserMoveEvent to recognize exclude moves
clearFlag = 0;
- if(gameMode != EditPosition && !appData.testLegality && !legal[y][x] && (x != killX || y != killY)) {
+ if(gameMode != EditPosition && !appData.testLegality && !legal[y][x] && (x != killX || y != killY) && !sweepSelecting) {
if(dragging) DragPieceEnd(xPix, yPix), dragging = 0;
DisplayMessage(_("only marked squares are legal"),"");
DrawPosition(TRUE, NULL);
if(!sweepSelecting) {
toX = x;
toY = y;
- } else sweepSelecting = 0; // this must be the up-click corresponding to the down-click that started the sweep
+ }
saveAnimate = appData.animate;
if (clickType == Press) {
} else {
ClearHighlights();
}
+ } else if(sweepSelecting) { // this must be the up-click corresponding to the down-click that started the sweep
+ sweepSelecting = 0;
+ if (appData.animate || appData.highlightLastMove) {
+ SetHighlights(fromX, fromY, toX, toY);
+ } else {
+ ClearHighlights();
+ }
} else {
#if 0
// [HGM] this must be done after the move is made, as with arrow it could lead to a board redraw with piece still on from square
ClearHighlights();
}
#endif
- if(!dragging || marker[y][x] == 5) { // [HGM] lion: this was the release of a to-click or drag on a cyan square
+ if(marker[y][x] == 5) { // [HGM] lion: this was the release of a to-click or drag on a cyan square
dragging *= 2; // flag button-less dragging if we are dragging
MarkTargetSquares(1);
if(x == killX && y == killY) killX = killY = -1; else {
killX = x; killY = y; //remeber this square as intermediate
+ MarkTargetSquares(0);
ReportClick("put", x, y); // and inform engine
ReportClick("lift", x, y);
return;
case WhiteNonPromotion:
case BlackNonPromotion:
case NormalMove:
+ case FirstLeg:
case WhiteCapturesEnPassant:
case BlackCapturesEnPassant:
case WhiteKingSideCastle:
}
piece = board[toY][toX] = (ChessSquare) fromX;
} else {
+ ChessSquare victim;
int i;
if( killX >= 0 && killY >= 0 ) // [HGM] lion: Lion trampled over something
+ victim = board[killY][killX],
board[killY][killX] = EmptySquare,
board[EP_STATUS] = EP_CAPTURE;
- if( board[toY][toX] != EmptySquare )
+ if( board[toY][toX] != EmptySquare ) {
board[EP_STATUS] = EP_CAPTURE;
+ if( (fromX != toX || fromY != toY) && // not igui!
+ (captured == WhiteLion && board[fromY][fromX] != BlackLion ||
+ captured == BlackLion && board[fromY][fromX] != WhiteLion ) ) { // [HGM] lion: Chu Lion-capture rules
+ board[EP_STATUS] = EP_IRON_LION; // non-Lion x Lion: no counter-strike allowed
+ }
+ }
if( board[fromY][fromX] == WhiteLance || board[fromY][fromX] == BlackLance ) {
if( gameInfo.variant != VariantSuper && gameInfo.variant != VariantShogi )
board[BOARD_HEIGHT-1-k][0] = EmptySquare;
}
}
-
}
/* Updates forwardMostMove */
strcat(parseList[forwardMostMove - 1], "#");
break;
}
-
- killX = killY = -1; // [HGM] lion: used up
}
/* Updates currentMove if not pausing */
currentMove = forwardMostMove;
}
+ killX = killY = -1; // [HGM] lion: used up
+
if (instant) return;
DisplayMove(currentMove - 1);
result, resultDetails ? resultDetails : "(null)", whosays);
}
- fromX = fromY = -1; // [HGM] abort any move the user is entering.
+ fromX = fromY = killX = killY = -1; // [HGM] abort any move the user is entering. // [HGM] lion
if(pausing) PauseEvent(); // can happen when we abort a paused game (New Game or Quit)
ClearPremoveHighlights();
gotPremove = FALSE;
alarmSounded = FALSE;
+ killX = killY = -1; // [HGM] lion
GameEnds(EndOfFile, NULL, GE_PLAYER);
if(appData.serverMovesName != NULL) {
case WhiteNonPromotion:
case BlackNonPromotion:
case NormalMove:
+ case FirstLeg:
case WhiteKingSideCastle:
case WhiteQueenSideCastle:
case BlackKingSideCastle:
toX = currentMoveString[2] - AAA;
toY = currentMoveString[3] - ONE;
promoChar = currentMoveString[4];
+ if(promoChar == ';') promoChar = NULLCHAR;
break;
case WhiteDrop:
thinkOutput[0] = NULLCHAR;
MakeMove(fromX, fromY, toX, toY, promoChar);
+ killX = killY = -1; // [HGM] lion: used up
currentMove = forwardMostMove;
return TRUE;
}
case WhiteNonPromotion:
case BlackNonPromotion:
case NormalMove:
+ case FirstLeg:
case WhiteKingSideCastle:
case WhiteQueenSideCastle:
case BlackKingSideCastle:
if (gameMode != BeginningOfGame) {
Reset(FALSE, TRUE);
}
+ killX = killY = -1; // [HGM] lion: in case we did not Reset
gameFileFP = f;
if (lastLoadGameFP != NULL && lastLoadGameFP != f) {
break;
case NormalMove:
+ case FirstLeg:
/* Only a NormalMove can be at the start of a game
* without a position diagram. */
if (lastLoadGameStart == EndOfFile ) {