Fix checking move handling.

This commit is contained in:
yukirij 2024-08-20 13:03:21 -07:00
parent 9de322afd3
commit c6fcb6bd78
2 changed files with 55 additions and 45 deletions

View File

@ -122,7 +122,7 @@ GAME.Tile = class {
this.piece = null;
this.threaten = [0, 0];
this.checking = false;
this.checking = 0;
this.hex = HEX.tile_to_hex(index);
}
@ -136,7 +136,7 @@ GAME.Tile = class {
reset() {
this.threaten = [0, 0];
this.checking = false;
this.checking = 0;
}
};
@ -260,13 +260,15 @@ GAME.Game = class {
// Reset tiles
this.board.reset();
this.state.check = false;
this.state.check = 0;
this.state.checkmate = false;
// Determine threaten, check, and blocking for each piece
let checking_pieces = 0;
for(let piece of this.board.pieces) {
if(piece !== null) {
let hex = this.board.tiles[piece.tile].hex;
let is_checking = false;
// Check if column has militia.
if(piece.piece == GAME.Const.PieceId.Militia && !piece.promoted) {
@ -282,20 +284,26 @@ GAME.Game = class {
if(movement.threat) {
this.board.tiles[movement.tile].threaten[piece.player] += 1;
}
if(movement.check) {
this.board.tiles[piece.tile].checking = true;
this.board.tiles[movement.tile].checking = true;
this.state.check = true;
if(movement.valid && movement.check != 0) {
is_checking = true;
this.board.tiles[movement.tile].checking |= movement.check;
this.state.check |= movement.check;
}
if(movement.block != 0) {
this.board.pieces[this.board.tiles[movement.tile].piece].blocking = movement.block;
}
}
if(is_checking) {
this.board.tiles[piece.tile].checking = 1;
checking_pieces++;
}
}
}
this.state.check += checking_pieces;
// Count moves available to next turn player to determine checkmate.
if(this.state.check) {
if(this.state.check != 0) {
let moves = 0;
// Search for valid board moves.
@ -396,8 +404,6 @@ GAME.Game = class {
// Recalculate new board state.
this.update_board();
// If check, detect checkmate.
}
movement_tiles(piece, tile) {
@ -410,9 +416,6 @@ GAME.Game = class {
let block_directions = piece.blocking;
if(block_directions != 0) {
block_directions |= BITWISE.rotate_blocks(piece.blocking);
//if(piece.piece != GAME.Const.PieceId.Omen) {
// permitted_moves &= piece.blocking;
//}
}
// Check directions of movement.
@ -433,7 +436,7 @@ GAME.Game = class {
move_hex.add(direction);
let threat = valid;
let check = false;
let check = 0;
let block = 0;
let swap = false;
let tile_occupied = false;
@ -441,15 +444,28 @@ GAME.Game = class {
if(HEX.is_valid(move_hex)) {
let tile_id = HEX.hex_to_tile(move_hex);
let tile_data = this.board.tiles[tile_id];
let target_id = tile_data.piece;
let result = valid;
// Prevent moves that do not uncheck the King.
if(piece.player == (this.turn & 1)
&& this.state.check && !tile_data.checking
&& piece.piece != GAME.Const.PieceId.Omen) {
// Prevent moves that do not uncheck King.
let check_direct = (this.state.check & 0x040) != 0;
let check_count = this.state.check & 0x3F;
if(piece.player == (this.turn & 1) && this.state.check != 0) {
if(piece.piece != GAME.Const.PieceId.Omen) {
if(tile_data.checking != 0) {
if(target_id !== null) {
if(check_count > 1) {
result = false;
}
} else if(check_direct != 0 || check_count > 1) {
result = false;
}
} else {
result = false;
}
}
}
// King may not move onto threatened tile.
if(piece.piece == GAME.Const.PieceId.Omen && tile_data.threaten[+(!piece.player)] > 0) {
@ -457,8 +473,8 @@ GAME.Game = class {
}
// Handle occupied tile.
if(tile_data.piece !== null) {
let target = this.board.pieces[tile_data.piece];
if(target_id !== null) {
let target = this.board.pieces[target_id];
tile_occupied = true;
// Target piece is ally.
@ -479,13 +495,14 @@ GAME.Game = class {
// Check if target piece is opposing king.
if(target.piece == GAME.Const.PieceId.Omen) {
if(valid) {
check = true;
if(dist == 1) { check = GAME.Const.Check.Direct; }
else { check = GAME.Const.Check.Stride; }
if(stride) { block = mask; }
// Apply check to previous moves.
for(let idist = 1; idist < dist; idist++) {
tiles[tiles.length - idist].check = true;
tiles[tiles.length - idist].check = GAME.Const.Check.Stride;
}
}
@ -555,9 +572,16 @@ GAME.Game = class {
if(tile.piece === null) {
let position_valid = true;
if(player == (this.turn & 1) && this.state.check && !tile.checking) {
// Prevent placement that does not uncheck King.
let check_direct = (this.state.check & GAME.Const.Check.Direct) != 0;
let check_count = this.state.check & 0x3F;
if(player == (this.turn & 1) && this.state.check != 0) {
if(check_direct == 0 && check_count == 1) {
position_valid = tile.checking != 0;
} else {
position_valid = false;
}
}
// Check off-sides.
if(piece.player == 0) {
@ -625,25 +649,11 @@ GAME.Const = {
new MATH.Vec2(-1, -2),
new MATH.Vec2(-2, -1),
new MATH.Vec2(-1, 1),
/*new MATH.Vec2(1, 3),
new MATH.Vec2(2, 3),
new MATH.Vec2(3, 2),
new MATH.Vec2(3, 1),
new MATH.Vec2(2, -1),
new MATH.Vec2(1, -2),
new MATH.Vec2(-1, -3),
new MATH.Vec2(-2, -3),
new MATH.Vec2(-3, -2),
new MATH.Vec2(-3, -1),
new MATH.Vec2(-2, 1),
new MATH.Vec2(-1, 2),*/
],
MoveStatus: {
Valid: 0,
Invalid: 1,
Check: 2,
Check: {
Direct: 0x0040,
Stride: 0x0080,
},
PieceId: {

View File

@ -371,7 +371,7 @@ const INTERFACE = {
}
if(GAME_DATA.turn > 0 && INTERFACE_DATA.play.source < 2 && (INTERFACE_DATA.play.to == i || (INTERFACE_DATA.play.source == 0 && INTERFACE_DATA.play.from == i))) {
ctx.fillStyle = INTERFACE.Color.HintPlay;
} else if(GAME_DATA.state.check && piece !== null && piece.piece == GAME.Const.PieceId.Omen && piece.player == (GAME_DATA.turn & 1)) {
} else if(GAME_DATA.state.check != 0 && piece !== null && piece.piece == GAME.Const.PieceId.Omen && piece.player == (GAME_DATA.turn & 1)) {
ctx.fillStyle = INTERFACE.Color.HintCheck;
}
switch(hover_state) {
@ -579,7 +579,7 @@ const INTERFACE = {
if(GAME_DATA.state.code == GAME.Const.State.Retire) {
ctx.fillStyle = INTERFACE.Color.HintCheck;
message = "Retire";
} else if(GAME_DATA.state.check) {
} else if(GAME_DATA.state.check != 0) {
ctx.fillStyle = INTERFACE.Color.HintCheck;
if(GAME_DATA.state.checkmate) {
message = "Checkmate";
@ -1003,7 +1003,7 @@ const INTERFACE = {
}
}
if(state.state.check) {
if(state.state.check != 0) {
if(turn == player) { score -= 20; }
else { score += 1; }
}