}
// Workaround for passing: Execute a non-move with any piece
- if (pos.pass() && !pos.count<KING>(Us) && pos.pieces(Us))
+ if (pos.pass(Us) && !pos.count<KING>(Us) && pos.pieces(Us))
*moveList++ = make<SPECIAL>(lsb(pos.pieces(Us)), lsb(pos.pieces(Us)));
}
moveList = make_move_and_gating<NORMAL>(pos, moveList, Us, ksq, pop_lsb(b));
// Passing move by king
- if (pos.pass())
+ if (pos.pass(Us))
*moveList++ = make<SPECIAL>(ksq, ksq);
if ((Type == QUIETS || Type == NON_EVASIONS) && pos.can_castle(Us & ANY_CASTLING))
parse_attribute("seirawanGating", v->seirawanGating);
parse_attribute("cambodianMoves", v->cambodianMoves);
parse_attribute("diagonalLines", v->diagonalLines);
- parse_attribute("pass", v->pass);
- parse_attribute("passOnStalemate", v->passOnStalemate);
+ parse_attribute("pass", v->pass[WHITE]);
+ parse_attribute("pass", v->pass[BLACK]);
+ parse_attribute("passWhite", v->pass[WHITE]);
+ parse_attribute("passBlack", v->pass[BLACK]);
+ parse_attribute("passOnStalemate", v->passOnStalemate[WHITE]);
+ parse_attribute("passOnStalemate", v->passOnStalemate[BLACK]);
+ parse_attribute("passOnStalemateWhite", v->passOnStalemate[WHITE]);
+ parse_attribute("passOnStalemateBlack", v->passOnStalemate[BLACK]);
parse_attribute("makpongRule", v->makpongRule);
parse_attribute("flyingGeneral", v->flyingGeneral);
parse_attribute("soldierPromotionRank", v->soldierPromotionRank);
parse_attribute("connectRegion1Black", v->connectRegion1[BLACK]);
parse_attribute("connectRegion2Black", v->connectRegion2[BLACK]);
parse_attribute("connectNxN", v->connectNxN);
+ parse_attribute("connectValue", v->connectValue);
parse_attribute("materialCounting", v->materialCounting);
parse_attribute("countingRule", v->countingRule);
parse_attribute("castlingWins", v->castlingWins);
return false;
// Illegal king passing move
- if (pass_on_stalemate() && is_pass(m) && !checkers())
+ if (pass_on_stalemate(us) && is_pass(m) && !checkers())
{
for (const auto& move : MoveList<NON_EVASIONS>(*this))
if (!is_pass(move) && legal(move))
Piece captured = piece_on(type_of(m) == EN_PASSANT ? capture_square(to) : to);
if (to == from)
{
- assert((type_of(m) == PROMOTION && sittuyin_promotion()) || (is_pass(m) && pass()));
+ assert((type_of(m) == PROMOTION && sittuyin_promotion()) || (is_pass(m) && pass(us)));
captured = NO_PIECE;
}
st->capturedpromoted = is_promoted(to);
assert(type_of(m) == DROP || empty(from) || type_of(m) == CASTLING || is_gating(m)
|| (type_of(m) == PROMOTION && sittuyin_promotion())
- || (is_pass(m) && pass()));
+ || (is_pass(m) && pass(us)));
assert(type_of(st->capturedPiece) != KING);
// Reset wall squares
return bool(res);
}
-/// Position::is_optinal_game_end() tests whether the position may end the game by
+/// Position::is_optional_game_end() tests whether the position may end the game by
/// 50-move rule, by repetition, or a variant rule that allows a player to claim a game result.
bool Position::is_optional_game_end(Value& result, int ply, int countStarted) const {
b &= shift(d, b);
if (b)
{
- result = mated_in(ply);
+ result = convert_mate_value(-var->connectValue, ply);
return true;
}
}
if (newBitboard & target) {
// A connection has been made
- result = mated_in(ply);
+ result = convert_mate_value(-var->connectValue, ply);
return true;
}
connectors &= shift<SOUTH>(connectors) & shift<EAST>(connectors) & shift<SOUTH_EAST>(connectors);
if (connectors)
{
- result = mated_in(ply);
+ result = convert_mate_value(-var->connectValue, ply);
return true;
}
}
bool seirawan_gating() const;
bool cambodian_moves() const;
Bitboard diagonal_lines() const;
- bool pass() const;
- bool pass_on_stalemate() const;
+ bool pass(Color c) const;
+ bool pass_on_stalemate(Color c) const;
Bitboard promoted_soldiers(Color c) const;
bool makpong() const;
EnclosingRule flip_enclosed_pieces() const;
return var->diagonalLines;
}
-inline bool Position::pass() const {
+inline bool Position::pass(Color c) const {
assert(var != nullptr);
- return var->pass || var->passOnStalemate;
+ return var->pass[c] || var->passOnStalemate[c];
}
-inline bool Position::pass_on_stalemate() const {
+inline bool Position::pass_on_stalemate(Color c) const {
assert(var != nullptr);
- return var->passOnStalemate;
+ return var->passOnStalemate[c];
}
inline Bitboard Position::promoted_soldiers(Color c) const {
v->immobilityIllegal = false;
v->stalemateValue = -VALUE_MATE;
v->stalematePieceCount = true;
- v->passOnStalemate = true;
+ v->passOnStalemate[WHITE] = true;
+ v->passOnStalemate[BLACK] = true;
v->enclosingDrop = ATAXX;
v->flipEnclosedPieces = ATAXX;
v->materialCounting = UNWEIGHTED_MATERIAL;
v->immobilityIllegal = false;
v->stalemateValue = -VALUE_MATE;
v->stalematePieceCount = true;
- v->passOnStalemate = false;
+ v->passOnStalemate[WHITE] = false;
+ v->passOnStalemate[BLACK] = false;
v->enclosingDrop = REVERSI;
v->enclosingDropStart = make_bitboard(SQ_D4, SQ_E4, SQ_D5, SQ_E5);
v->flipEnclosedPieces = REVERSI;
Variant* flipello_variant() {
Variant* v = flipersi_variant()->init();
v->startFen = "8/8/8/3pP3/3Pp3/8/8/8[PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPpppppppppppppppppppppppppppppppp] w 0 1";
- v->passOnStalemate = true;
+ v->passOnStalemate[WHITE] = true;
+ v->passOnStalemate[BLACK] = true;
return v;
}
// Minixiangqi
v->materialCounting = JANGGI_MATERIAL;
v->diagonalLines = make_bitboard(SQ_D1, SQ_F1, SQ_E2, SQ_D3, SQ_F3,
SQ_D8, SQ_F8, SQ_E9, SQ_D10, SQ_F10);
- v->pass = true;
+ v->pass[WHITE] = true;
+ v->pass[BLACK] = true;
v->nFoldValue = VALUE_DRAW;
v->perpetualCheckIllegal = true;
return v;
bool seirawanGating = false;
bool cambodianMoves = false;
Bitboard diagonalLines = 0;
- bool pass = false;
- bool passOnStalemate = false;
+ bool pass[COLOR_NB] = {false, false};
+ bool passOnStalemate[COLOR_NB] = {false, false};
bool makpongRule = false;
bool flyingGeneral = false;
Rank soldierPromotionRank = RANK_1;
Bitboard connectRegion1[COLOR_NB] = {};
Bitboard connectRegion2[COLOR_NB] = {};
int connectNxN = 0;
+ Value connectValue = VALUE_MATE;
MaterialCounting materialCounting = NO_MATERIAL_COUNTING;
CountingRule countingRule = NO_COUNTING;
CastlingRights castlingWins = NO_CASTLING;
# cambodianMoves: enable special moves of cambodian chess, requires "gating = true" [bool] (default: false)
# diagonalLines: enable special moves along diagonal for specific squares (Janggi) [Bitboard]
# pass: allow passing [bool] (default: false)
+# passWhite: allow passing for white [bool] (default: false)
+# passBlack: allow passing for black [bool] (default: false)
# passOnStalemate: allow passing in case of stalemate [bool] (default: false)
+# passOnStalemateWhite: allow passing in case of stalemate for white [bool] (default: false)
+# passOnStalemateBlack: allow passing in case of stalemate for black [bool] (default: false)
# makpongRule: the king may not move away from check [bool] (default: false)
# flyingGeneral: disallow general face-off like in xiangqi [bool] (default: false)
# soldierPromotionRank: restrict soldier to shogi pawn movements until reaching n-th rank [Rank] (default: 1)
# connectRegion1Black: "
# connectRegion2Black: "
# connectNxN: connect a tight NxN square for win [int] (default: 0)
+# connectValue: result in case of connect [Value] (default: win)
# materialCounting: enable material counting rules [MaterialCounting] (default: none)
# countingRule: enable counting rules [CountingRule] (default: none)
# castlingWins: Specified castling moves are win conditions. Losing these rights is losing. [CastlingRights] (default: -)
startFen = 7/7/7/7/7/7/7[PPPPPPPPPPPPPPPPPPPPPPPPPpppppppppppppppppppppppp] w - - 0 1
enclosingDrop = anyside
+#http://gamescrafters.berkeley.edu/games.php?game=connect4
+[cfour-misere:cfour]
+connectValue = loss
std::getline(is >> std::ws, fen);
// Check if setboard actually indicates a passing move
// to avoid unnecessarily clearing the move history
- if (pos.pass())
+ if (pos.pass(~pos.side_to_move()))
{
StateInfo st;
Position p;