diff --git a/www/js/game.js b/www/js/game.js index f55c6a3..5918aae 100644 --- a/www/js/game.js +++ b/www/js/game.js @@ -408,17 +408,13 @@ GAME.Game = class { this.update_board(); } - movement_tiles(piece, tile) { + movement_tiles(piece, tile, check_drop=false) { let tiles = [ ]; let moves = piece.moves(); let hex = this.board.tiles[tile].hex; let directions = moves.direction; - let permitted_moves = directions; - let block_directions = piece.blocking; - if(block_directions != 0) { - block_directions |= BITWISE.rotate_blocks(piece.blocking); - } + let block_directions = piece.blocking | BITWISE.rotate_blocks(piece.blocking); // Check directions of movement. for(let mask = BITWISE.lsb(directions); directions > 0; mask = BITWISE.lsb(directions)) { @@ -430,7 +426,7 @@ GAME.Game = class { if((dir_mask & 0xFFF) == 0) { dir_mask >>= 12; } // Get initial status in direction. - let valid = true; //(permitted_moves & mask) != 0; + let valid = true; let pieces_blocking = 0; let move_hex = hex.copy(); @@ -543,6 +539,73 @@ GAME.Game = class { directions &= ~mask; } + // Handle drop rules for promoted castle + if(!check_drop && piece.piece == GAME.Const.PieceId.Castle && piece.promoted) { + let move_hex = hex.copy(); + let mask_back = 1 << 3; + if(piece.player == GAME.Const.Player.Dusk) { + mask_back = BITWISE.rotate_blocks(mask_back); + } + let mask_column = mask_back | BITWISE.rotate_blocks(mask_back); + + let direction = GAME.Const.get_direction(BITWISE.ffs(mask_back)); + move_hex.add(direction); + + let status = (block_directions == 0 || (mask_back & block_directions) != 0); + + // Check if backward tile meets placement rules. + for(let i = 0; i < 9; ++i) { + move_hex.add(direction); + + if(HEX.is_valid_board(move_hex)) { + let valid = status; + + let tile_id = HEX.hex_to_tile(move_hex); + let tile_data = this.board.tiles[tile_id]; + let target_id = tile_data.piece; + + // Check tile is empty. + if(target_id !== null) { + valid = false; + + // Prevent change in blocking status + if((mask_column & block_directions) != 0) { + status = false; + } + } + + // 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(piece.player == (this.turn & 1) && this.state.check != 0) { + if(check_direct == 0 && check_count == 1) { + valid = valid && tile.checking != 0; + } else { + valid = false; + } + } + + // Check off-sides. + if(piece.player == 0) { + valid = valid && (move_hex.y <= this.board.columns[move_hex.x].extent[+(!piece.player)]); + } else { + valid = valid && (move_hex.y >= this.board.columns[move_hex.x].extent[+(!piece.player)]); + } + + // Check if position puts king in check. + let movements = this.movement_tiles(piece, tile_id, true); + for(let movement of movements) { + if(movement.check) { + valid = false; + break; + } + } + + tiles.push(new GAME.MovementTile(tile_id, valid, false, 0, 0)); + } else { break; } + } + } + return tiles; } @@ -602,7 +665,7 @@ GAME.Game = class { // Check if position puts king in check. let checking = false; - let movements = this.movement_tiles(piece, i); + let movements = this.movement_tiles(piece, i, true); for(let movement of movements) { if(movement.check) { checking = true; @@ -717,19 +780,17 @@ GAME.Const = { .add(14) .add(16) .add(17), - /*new GAME.PieceMovement() - .add(12) + new GAME.PieceMovement() + .add(0) + .add(3) + .add(6) + .add(8) + .add(9) + .add(11) .add(13) .add(14) - .add(15) .add(16) - .add(17) - .add(18) - .add(19) - .add(20) - .add(21) - .add(22) - .add(23),*/ + .add(17), ), new GAME.GamePiece( "Tower", @@ -769,8 +830,8 @@ GAME.Const = { .add(3) .add(4) .add(5) - .add_stride(7) - .add_stride(10), + .add(7) + .add(10), ), new GAME.GamePiece( "Dragon",