Add simple auto move to practice.
This commit is contained in:
parent
6d22410658
commit
f74396f257
@ -102,14 +102,14 @@ GAME.Tile = class {
|
||||
constructor(index) {
|
||||
this.piece = null;
|
||||
|
||||
this.threaten = [false, false];
|
||||
this.threaten = [0, 0];
|
||||
this.checking = false;
|
||||
|
||||
this.hex = HEX.tile_to_hex(index);
|
||||
}
|
||||
|
||||
reset() {
|
||||
this.threaten = [false, false];
|
||||
this.threaten = [0, 0];
|
||||
this.checking = false;
|
||||
}
|
||||
};
|
||||
@ -236,7 +236,7 @@ GAME.Game = class {
|
||||
// Get threatened tiles.
|
||||
for(let movement of this.movement_tiles(piece, piece.tile)) {
|
||||
if(movement.threat) {
|
||||
this.board.tiles[movement.tile].threaten[piece.player] = true;
|
||||
this.board.tiles[movement.tile].threaten[piece.player] += 1;
|
||||
}
|
||||
if(movement.check) {
|
||||
this.board.tiles[piece.tile].checking = true;
|
||||
@ -408,7 +408,7 @@ GAME.Game = class {
|
||||
}
|
||||
|
||||
// King may not move onto threatened tile.
|
||||
if(piece.piece == GAME.Const.PieceId.Omen && tile_data.threaten[+(!piece.player)]) {
|
||||
if(piece.piece == GAME.Const.PieceId.Omen && tile_data.threaten[+(!piece.player)] > 0) {
|
||||
result = false;
|
||||
}
|
||||
|
||||
@ -490,7 +490,7 @@ GAME.Game = class {
|
||||
// King cannot swap onto tile that is threatened.
|
||||
// This case should also cover blocking.
|
||||
if(target.piece == GAME.Const.PieceId.Omen
|
||||
&& (this.board.tiles[tile].threaten[+(!target.player)] || piece.blocking != 0)) {
|
||||
&& (this.board.tiles[tile].threaten[+(!target.player)] > 0 || piece.blocking != 0)) {
|
||||
return false;
|
||||
}
|
||||
return ((moves.direction & mask) != 0 && (range == 1 || (moves.stride & mask) != 0));
|
||||
|
@ -87,7 +87,7 @@ const INTERFACE = {
|
||||
if(movement.valid) {
|
||||
// Show valid/threat hints if piece belongs to player and is player turn.
|
||||
if(INTERFACE_DATA.player == 2 || (player == INTERFACE_DATA.player && (GAME_DATA.turn & 1) == player)) {
|
||||
if(GAME_DATA.board.tiles[movement.tile].threaten[+(!player)]) {
|
||||
if(GAME_DATA.board.tiles[movement.tile].threaten[+(!player)] > 0) {
|
||||
INTERFACE_DATA.board_state[movement.tile][zone] = INTERFACE.TileStatus.Threat;
|
||||
} else {
|
||||
INTERFACE_DATA.board_state[movement.tile][zone] = INTERFACE.TileStatus.Valid;
|
||||
@ -200,39 +200,8 @@ const INTERFACE = {
|
||||
|
||||
// Handle player action.
|
||||
if(is_valid) {
|
||||
|
||||
// Send message to server for online game.
|
||||
switch(INTERFACE_DATA.mode) {
|
||||
|
||||
// Apply action and change turn for local game.
|
||||
case INTERFACE.Mode.Local: {
|
||||
let play = new GAME.Play(INTERFACE_DATA.select.source, INTERFACE_DATA.select.tile, INTERFACE_DATA.hover.tile);
|
||||
INTERFACE_DATA.play = play;
|
||||
GAME_DATA.process(play);
|
||||
|
||||
INTERFACE_DATA.player = +(!INTERFACE_DATA.player);
|
||||
INTERFACE_DATA.rotate = +(!INTERFACE_DATA.rotate);
|
||||
|
||||
INTERFACE.draw();
|
||||
} break;
|
||||
|
||||
// Send action to server for validation.
|
||||
case INTERFACE.Mode.Online: {
|
||||
let move_data = INTERFACE_DATA.select.source | (INTERFACE_DATA.select.tile << 1) | (INTERFACE_DATA.hover.tile << 7);
|
||||
MESSAGE_COMPOSE([
|
||||
PACK.u16(OpCode.GamePlay),
|
||||
PACK.u16(0),
|
||||
PACK.u16(GAME_DATA.turn),
|
||||
PACK.u16(move_data),
|
||||
]);
|
||||
} break;
|
||||
|
||||
// Branch into local game from here.
|
||||
case INTERFACE.Mode.Replay: {
|
||||
|
||||
} break;
|
||||
}
|
||||
|
||||
let play = new GAME.Play(INTERFACE_DATA.select.source, INTERFACE_DATA.select.tile, INTERFACE_DATA.hover.tile);
|
||||
INTERFACE.process(play);
|
||||
INTERFACE_DATA.select = null;
|
||||
}
|
||||
|
||||
@ -860,6 +829,38 @@ const INTERFACE = {
|
||||
}
|
||||
},
|
||||
|
||||
process(play) {
|
||||
// Send message to server for online game.
|
||||
switch(INTERFACE_DATA.mode) {
|
||||
// Apply action and change turn for local game.
|
||||
case INTERFACE.Mode.Local: {
|
||||
INTERFACE_DATA.play = play;
|
||||
GAME_DATA.process(play);
|
||||
|
||||
INTERFACE_DATA.player = +(!INTERFACE_DATA.player);
|
||||
INTERFACE_DATA.rotate = +(!INTERFACE_DATA.rotate);
|
||||
|
||||
INTERFACE.draw();
|
||||
} break;
|
||||
|
||||
// Send action to server for validation.
|
||||
case INTERFACE.Mode.Online: {
|
||||
let move_data = play.source | (play.from << 1) | (play.to << 7);
|
||||
MESSAGE_COMPOSE([
|
||||
PACK.u16(OpCode.GamePlay),
|
||||
PACK.u16(0),
|
||||
PACK.u16(GAME_DATA.turn),
|
||||
PACK.u16(move_data),
|
||||
]);
|
||||
} break;
|
||||
|
||||
// Branch into local game from here.
|
||||
case INTERFACE.Mode.Replay: {
|
||||
|
||||
} break;
|
||||
}
|
||||
},
|
||||
|
||||
rotate() {
|
||||
INTERFACE_DATA.rotate ^= 1;
|
||||
INTERFACE.draw();
|
||||
@ -909,6 +910,109 @@ const INTERFACE = {
|
||||
}
|
||||
}
|
||||
},
|
||||
|
||||
auto() {
|
||||
let moves = [ ];
|
||||
let player = GAME_DATA.turn & 1;
|
||||
let opponent = +(!player);
|
||||
|
||||
// Get available placement moves.
|
||||
for(let p = 0; p < 8; ++p) {
|
||||
if(GAME_DATA.pools[player].pieces[p] > 0) {
|
||||
for(let move of GAME_DATA.placement_tiles(p, player)) {
|
||||
if(move.valid) {
|
||||
let hex = HEX.tile_to_hex(move.tile);
|
||||
|
||||
let score = GAME_DATA.board.tiles[move.tile].threaten[player] - GAME_DATA.board.tiles[move.tile].threaten[opponent];
|
||||
if(player == 0) {
|
||||
score += 2 * Math.max(0, GAME_DATA.board.columns[hex.x].extent[player] - hex.y);
|
||||
} else {
|
||||
score += 2 * Math.max(0, hex.y - GAME_DATA.board.columns[hex.x].extent[player]);
|
||||
}
|
||||
|
||||
let moves_from = GAME_DATA.movement_tiles(new GAME.Piece(p, player), move.tile);
|
||||
for(let next_move of moves_from) {
|
||||
if(next_move.valid) {
|
||||
// Add score for taking.
|
||||
let target_id = GAME_DATA.board.tiles[next_move.tile].piece;
|
||||
if(target_id !== null) {
|
||||
let target = GAME_DATA.board.pieces[target_id];
|
||||
if(target.player == opponent) { score += 1 + target.piece; }
|
||||
}
|
||||
|
||||
if(next_move.check) { score += 2; }
|
||||
}
|
||||
}
|
||||
|
||||
moves.push({
|
||||
score: score,
|
||||
play: new GAME.Play(1, p, move.tile),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get available piece moves.
|
||||
for(let i = 0; i < GAME_DATA.board.pieces.length; ++i) {
|
||||
let piece = GAME_DATA.board.pieces[i];
|
||||
if(piece !== null) {
|
||||
if(piece.player == player) {
|
||||
let current_hex = HEX.tile_to_hex(piece.tile);
|
||||
|
||||
for(let move of GAME_DATA.movement_tiles(piece, piece.tile)) {
|
||||
if(move.valid) {
|
||||
let hex = HEX.tile_to_hex(move.tile);
|
||||
|
||||
// Calculate base score.
|
||||
let score = ((piece.piece + 1) * GAME_DATA.board.tiles[piece.tile].threaten[opponent])
|
||||
+ GAME_DATA.board.tiles[move.tile].threaten[player]
|
||||
- ((piece.piece + 1) * GAME_DATA.board.tiles[move.tile].threaten[opponent]);
|
||||
|
||||
// Add score for taking.
|
||||
let target_id = GAME_DATA.board.tiles[move.tile].piece;
|
||||
if(target_id !== null) {
|
||||
let target = GAME_DATA.board.pieces[target_id];
|
||||
if(target.player == opponent) { score += 2 * (1 + target.piece); }
|
||||
else { score -= 1; }
|
||||
}
|
||||
|
||||
score += +((-MATH.sign_branch(player) * (hex.y - current_hex.y)) > 0);
|
||||
|
||||
// Add score for check.
|
||||
if(move.check) { score += 2; }
|
||||
|
||||
let moves_from = GAME_DATA.movement_tiles(piece, move.tile);
|
||||
for(let next_move of moves_from) {
|
||||
if(next_move.valid) {
|
||||
// Add score for taking.
|
||||
let target_id = GAME_DATA.board.tiles[next_move.tile].piece;
|
||||
if(target_id !== null) {
|
||||
let target = GAME_DATA.board.pieces[target_id];
|
||||
if(target.player == opponent) { score += 1 + target.piece; }
|
||||
}
|
||||
|
||||
if(next_move.check) { score += 2; }
|
||||
}
|
||||
}
|
||||
|
||||
moves.push({
|
||||
score: score,
|
||||
play: new GAME.Play(0, piece.tile, move.tile),
|
||||
});
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if(moves.length > 0) {
|
||||
moves = moves.sort((a, b) => { return b.score - a.score; });
|
||||
|
||||
let select = Math.floor(Math.random() * Math.min(moves.length, 3));
|
||||
INTERFACE.process(moves[select].play);
|
||||
}
|
||||
},
|
||||
};
|
||||
|
||||
INTERFACE.Radius = 2.0 / Math.sqrt(3.0);
|
||||
|
@ -564,6 +564,7 @@ const SCENES = {
|
||||
UI.nav([
|
||||
UI.button("Rotate", () => { INTERFACE.rotate(); }),
|
||||
UI.button("Mirror", () => { INTERFACE.mirror(); }),
|
||||
UI.button("Auto", () => { INTERFACE.auto(); }),
|
||||
], buttons_bottom);
|
||||
|
||||
let canvas = document.createElement("canvas");
|
||||
|
Loading…
x
Reference in New Issue
Block a user