Skip to content

Commit

Permalink
Merged pull request #768 with squash
Browse files Browse the repository at this point in the history
  • Loading branch information
RainRat committed Jul 5, 2024
1 parent 7d73bae commit 9750c5e
Show file tree
Hide file tree
Showing 5 changed files with 61 additions and 32 deletions.
16 changes: 13 additions & 3 deletions src/evaluate.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1281,8 +1281,17 @@ namespace {
}

// Connect-n
if (pos.connect_n() > 0)
if (pos.connect_n() > 0 && (pos.variant()->connectValue != VALUE_DRAW))
{
//Calculate eligible pieces for connection once.
//Still consider all opponent pieces as blocking.
Bitboard connectPiecesUs = 0;
for (PieceSet ps = pos.connect_piece_types(); ps;){
PieceType pt = pop_lsb(ps);
connectPiecesUs |= pos.pieces(pt);
};
connectPiecesUs &= pos.pieces(Us);

for (const Direction& d : pos.getConnectDirections())

{
Expand All @@ -1296,9 +1305,10 @@ namespace {
Square s = pop_lsb(b);
int c = 0;
for (int j = 0; j < pos.connect_n(); j++)
if (pos.pieces(Us) & (s - j * d))
if (connectPiecesUs & (s - j * d))
c++;
score += make_score(200, 200) * c / (pos.connect_n() - c) / (pos.connect_n() - c);
score += (pos.variant()->connectValue==VALUE_MATE ? 1 : -1) * //At least change the sign for misere variants.
(make_score(200, 200) * c / (pos.connect_n() - c) / (pos.connect_n() - c));
}
}
}
Expand Down
67 changes: 42 additions & 25 deletions src/position.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2884,7 +2884,7 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
connectPieces &= pieces(~sideToMove);

// Connect-n
if (connect_n() > 0)
if ((connect_n() > 0) && (popcount(connectPieces) >= connect_n()))
{
Bitboard b;

Expand Down Expand Up @@ -2926,8 +2926,8 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
current |= newBitboard;
}
}
if (connect_nxn())

if ((connect_nxn()) && (popcount(connectPieces) >= connect_nxn() * connect_nxn()))
{
Bitboard connectors = connectPieces;
for (int i = 1; i < connect_nxn() && connectors; i++)
Expand All @@ -2940,28 +2940,45 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
}

// Collinear-n
if (collinear_n() > 0) {
Bitboard allPieces = connectPieces;
for (Direction d : var->connect_directions) {
Bitboard b = allPieces;
while (b) {
Square s = pop_lsb(b);

int total_count = 1; // Start with the current piece

// Check in both directions
for (int sign : {-1, 1}) {
Bitboard shifted = shift(sign * d, square_bb(s));
while (shifted) {
if (shifted & b) {
total_count++;
b &= ~shifted; // Remove this piece from further consideration
}
shifted = shift(sign * d, shifted);
}
}
if ((collinear_n() > 0) && (popcount(connectPieces) >= collinear_n())) {
Bitboard pieces = connectPieces;
while (pieces) {


if (total_count >= collinear_n()) {
/*
//can't combine this with the (!is_ok(shifted_square)) optimization below
//if it relies on there being another piece to count it as part of its line,
//can't early out.
if (popcount(pieces) < collinear_n()) {
break; // Early out to the next section
}
*/
//Use pop_lsb to loop through the pieces. Then for each of the directions,
//use line_bb to calculate the entire row, column or diagonal that contains
//the piece and the shifted square, then use popcount to count the number
//of pieces on that line.
Square s = pop_lsb(pieces);
for (Direction d : var->connect_directions) {
Square shifted_square = s + d;


if (!is_ok(shifted_square)) continue; //This is totally fine.
//Pieces where the shift is outside the board will not be processed
//for that direction, but in order to be collinear with another piece,
//there would be another piece that counts it as part of its line.
//Even if say, all the pieces were on the EAST edge, it's the NORTH
//direction that would count them up.
//Only exception is that if collinearN was set to 1, and there was 1
//piece on the NORTH_EAST corner, it wouldn't count. Possible solutions:
//1. Ignore
//2. Tell user that collinearN=1 is silly, use flagPieces or connectN
//3. Special case here to check
//4. Quietly convert it to connectN=1


Bitboard line = line_bb(s, shifted_square);
int piece_count = popcount(line & connectPieces);
if (piece_count >= collinear_n()) {
result = convert_mate_value(-var->connectValue, ply);
return true;
}
Expand All @@ -2970,7 +2987,7 @@ bool Position::is_immediate_game_end(Value& result, int ply) const {
}

// Check for bikjang rule (Janggi), double passing, or board running full
if ( (st->pliesFromNull > 0 && ((st->bikjang && st->previous->bikjang) || (st->pass && st->previous->pass)))
if ( (st->pliesFromNull > 0 && ((st->bikjang && st->previous->bikjang) || ((st->pass && st->previous->pass)&&!var->wallOrMove)))
|| (var->adjudicateFullBoard && !(~pieces() & board_bb())))
{
result = var->materialCounting ? convert_mate_value(material_counting_result(), ply) : VALUE_DRAW;
Expand Down
2 changes: 1 addition & 1 deletion src/position.h
Original file line number Diff line number Diff line change
Expand Up @@ -1054,7 +1054,7 @@ inline int Position::connect_n() const {

inline PieceSet Position::connect_piece_types() const {
assert(var != nullptr);
return var->connectPieceTypes;
return var->connectPieceTypesTrimmed;
}

inline bool Position::connect_horizontal() const {
Expand Down
7 changes: 4 additions & 3 deletions src/variant.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2081,15 +2081,16 @@ Variant* Variant::conclude() {
connect_directions.push_back(SOUTH_EAST);
}

// If not a connect variant, set connectPieceTypes to no pieces.
// If not a connect variant, set connectPieceTypesTrimmed to no pieces.
// connectPieceTypesTrimmed is separated so that connectPieceTypes is left unchanged for inheritance.
if ( !(connectRegion1[WHITE] || connectRegion1[BLACK] || connectN || connectNxN || collinearN) )
{
connectPieceTypes = NO_PIECE_SET;
connectPieceTypesTrimmed = NO_PIECE_SET;
}
//Otherwise optimize to pieces actually in the game.
else
{
connectPieceTypes = connectPieceTypes & pieceTypes;
connectPieceTypesTrimmed = connectPieceTypes & pieceTypes;
};

return this;
Expand Down
1 change: 1 addition & 0 deletions src/variant.h
Original file line number Diff line number Diff line change
Expand Up @@ -180,6 +180,7 @@ struct Variant {
bool endgameEval = false;
bool shogiStylePromotions = false;
std::vector<Direction> connect_directions;
PieceSet connectPieceTypesTrimmed = ~NO_PIECE_SET;

void add_piece(PieceType pt, char c, std::string betza = "", char c2 = ' ') {
// Avoid ambiguous definition by removing existing piece with same letter
Expand Down

0 comments on commit 9750c5e

Please sign in to comment.