373 lines
9.5 KiB
JavaScript
373 lines
9.5 KiB
JavaScript
const GAME = { };
|
|
let GAME_DATA = null;
|
|
|
|
GAME.Board = class {
|
|
constructor() {
|
|
this.tiles = [ ]; for(let i = 0; i < 61; ++i) { this.tiles.push(new GAME.Tile()); }
|
|
this.pieces = [ ];
|
|
|
|
this.init();
|
|
}
|
|
|
|
init() {
|
|
this.pieces = [ ];
|
|
|
|
// Describe Dawn layout
|
|
let layout = [
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(0, 1) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(1, 1) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(2, 2) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(3, 2) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(4, 3) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(5, 3) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(6, 4) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(7, 4) },
|
|
{ piece:GAME.Const.PieceId.Militia, hex:new MATH.Vec2(8, 5) },
|
|
|
|
{ piece:GAME.Const.PieceId.Lance, hex:new MATH.Vec2(0, 0) },
|
|
{ piece:GAME.Const.PieceId.Lance, hex:new MATH.Vec2(8, 4) },
|
|
|
|
{ piece:GAME.Const.PieceId.Knight, hex:new MATH.Vec2(1, 0) },
|
|
{ piece:GAME.Const.PieceId.Knight, hex:new MATH.Vec2(7, 3) },
|
|
|
|
{ piece:GAME.Const.PieceId.Castle, hex:new MATH.Vec2(2, 0) },
|
|
{ piece:GAME.Const.PieceId.Castle, hex:new MATH.Vec2(6, 2) },
|
|
|
|
{ piece:GAME.Const.PieceId.Tower, hex:new MATH.Vec2(3, 0) },
|
|
{ piece:GAME.Const.PieceId.Tower, hex:new MATH.Vec2(5, 1) },
|
|
|
|
{ piece:GAME.Const.PieceId.Dragon, hex:new MATH.Vec2(4, 1) },
|
|
{ piece:GAME.Const.PieceId.Omen, hex:new MATH.Vec2(4, 0) },
|
|
];
|
|
|
|
// Add Dawn pieces
|
|
for(let piece of layout) {
|
|
this.place_piece(piece.piece, GAME.Const.Player.Dawn, piece.hex);
|
|
}
|
|
|
|
// Add Dusk pieces
|
|
for(let piece of layout) {
|
|
let hex = new MATH.Vec2(8 - piece.hex.x, 8 - piece.hex.y);
|
|
this.place_piece(piece.piece, GAME.Const.Player.Dusk, hex);
|
|
}
|
|
}
|
|
|
|
place_piece(piece, player, hex) {
|
|
let game_piece = new GAME.Piece(piece, player);
|
|
game_piece.tile = this.hex_to_tile(hex);
|
|
this.tiles[game_piece.tile].piece = this.pieces.length;
|
|
this.pieces.push(game_piece);
|
|
}
|
|
|
|
hex_to_tile(hex) {
|
|
let a = ((hex.x + 4) * (hex.x + 5) / 2) - 10;
|
|
let b = (hex.x > 4) * ((hex.x - 4) + ((hex.x - 5) * (hex.x - 4)));
|
|
return a - b + hex.y;
|
|
}
|
|
|
|
tile_to_hex(tile) {
|
|
const ROWS = [ 0, 5, 11, 18, 26, 35, 43, 50, 56, 61 ];
|
|
let column = 0;
|
|
while(tile >= ROWS[column + 1]) { column += 1; }
|
|
let row = tile - ROWS[column] + ((column > 4) * (column - 4));
|
|
return new MATH.Vec2(column, row);
|
|
}
|
|
};
|
|
|
|
GAME.Player = class {
|
|
constructor() {
|
|
this.handle = "";
|
|
this.pool = new GAME.Pool();
|
|
}
|
|
};
|
|
|
|
GAME.Pool = class {
|
|
constructor() {
|
|
this.pieces = [ ]; for(let i = 0; i < 6; ++i) { this.pieces.push(0); }
|
|
}
|
|
};
|
|
|
|
GAME.Tile = class {
|
|
constructor() {
|
|
this.piece = null;
|
|
this.threaten = { dawn: 0, dusk: 0 };
|
|
this.checking = { dawn: false, dusk: false };
|
|
}
|
|
|
|
reset() {
|
|
this.threaten = { dawn: 0, dusk: 0 };
|
|
this.checking = { dawn: false, dusk: false };
|
|
}
|
|
};
|
|
|
|
GAME.Move = class {
|
|
constructor(source, from, to) {
|
|
this.source = source;
|
|
this.from = from;
|
|
this.to = to;
|
|
}
|
|
};
|
|
|
|
GAME.GamePiece = class {
|
|
constructor(name, assets, moves, promote_moves) {
|
|
this.name = name;
|
|
this.moves = moves;
|
|
this.pmoves = promote_moves;
|
|
this.assets = null;
|
|
|
|
if(assets !== null) {
|
|
this.assets = [
|
|
new Image(),
|
|
new Image()
|
|
];
|
|
this.assets[0].src = assets[0];
|
|
this.assets[1].src = assets[1];
|
|
}
|
|
}
|
|
};
|
|
|
|
GAME.PieceMovement = class {
|
|
constructor() {
|
|
this.direction = 0;
|
|
this.stride = 0;
|
|
}
|
|
|
|
add(direction) {
|
|
this.direction |= 1 << direction;
|
|
return this;
|
|
}
|
|
|
|
add_stride(direction) {
|
|
this.direction |= 1 << direction;
|
|
this.stride |= 1 << direction;
|
|
return this;
|
|
}
|
|
|
|
rotate() {
|
|
let copy = new GAME.PieceMovement();
|
|
copy.direction = BITWISE.rotate_blocks(this.direction);
|
|
copy.stride = BITWISE.rotate_blocks(this.stride);
|
|
return copy;
|
|
}
|
|
};
|
|
|
|
GAME.Piece = class {
|
|
constructor(piece, player) {
|
|
this.piece = piece;
|
|
this.player = player;
|
|
this.promoted = false;
|
|
|
|
this.tile = 0;
|
|
this.blocking = 0;
|
|
}
|
|
};
|
|
|
|
GAME.Game = class {
|
|
constructor() {
|
|
this.turn = 0;
|
|
|
|
this.board = new GAME.Board();
|
|
this.dawn = new GAME.Player();
|
|
this.dusk = new GAME.Player();
|
|
}
|
|
|
|
update_board() {
|
|
// Reset tiles
|
|
for(tile of this.board.tiles) { tile.reset(); }
|
|
|
|
// Determine threaten, check, and blocking for each piece
|
|
for(piece of this.board.pieces) {
|
|
|
|
}
|
|
}
|
|
|
|
process(move) {
|
|
|
|
|
|
// Recalculate new board state.
|
|
GAME.update_board();
|
|
}
|
|
|
|
validate(move) {
|
|
|
|
}
|
|
|
|
get_move_tiles(piece_id) {
|
|
|
|
}
|
|
};
|
|
|
|
GAME.Const = {
|
|
Player: {
|
|
Dawn: 0,
|
|
Dusk: 1,
|
|
},
|
|
|
|
Source: {
|
|
Board: 0,
|
|
Pool: 1,
|
|
},
|
|
|
|
Direction: [
|
|
new MATH.Vec2(0, 1),
|
|
new MATH.Vec2(1, 1),
|
|
new MATH.Vec2(1, 0),
|
|
new MATH.Vec2(0, -1),
|
|
new MATH.Vec2(-1, -1),
|
|
new MATH.Vec2(-1, 0),
|
|
|
|
new MATH.Vec2(1, 2),
|
|
new MATH.Vec2(2, 1),
|
|
new MATH.Vec2(1, -1),
|
|
new MATH.Vec2(-1, -2),
|
|
new MATH.Vec2(-2, -1),
|
|
new MATH.Vec2(-1, 1),
|
|
],
|
|
|
|
PieceId: {
|
|
Militia: 0,
|
|
Knight: 1,
|
|
Lance: 2,
|
|
Tower: 3,
|
|
Castle: 4,
|
|
Dragon: 5,
|
|
Omen: 6,
|
|
},
|
|
|
|
Piece: [
|
|
new GAME.GamePiece(
|
|
"Militia",
|
|
["asset/militia_dusk.svg", "asset/militia_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(5),
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(2)
|
|
.add(4)
|
|
.add(5),
|
|
),
|
|
new GAME.GamePiece(
|
|
"Knight",
|
|
["asset/knight_dusk.svg", "asset/knight_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add(3)
|
|
.add(6)
|
|
.add(11)
|
|
.add(13)
|
|
.add(17),
|
|
new GAME.PieceMovement()
|
|
.add(3)
|
|
.add(6)
|
|
.add(7)
|
|
.add(10)
|
|
.add(11)
|
|
.add(13)
|
|
.add(14)
|
|
.add(16)
|
|
.add(17),
|
|
),
|
|
new GAME.GamePiece(
|
|
"Lance",
|
|
["asset/lance_dusk.svg", "asset/lance_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add_stride(0)
|
|
.add(1)
|
|
.add(5),
|
|
new GAME.PieceMovement()
|
|
.add_stride(0)
|
|
.add_stride(1)
|
|
.add_stride(2)
|
|
.add_stride(3)
|
|
.add_stride(4)
|
|
.add_stride(5),
|
|
),
|
|
new GAME.GamePiece(
|
|
"Tower",
|
|
["asset/tower_dusk.svg", "asset/tower_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(3)
|
|
.add(5)
|
|
.add(6)
|
|
.add(11),
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(2)
|
|
.add(3)
|
|
.add(4)
|
|
.add(5)
|
|
.add(6)
|
|
.add(8)
|
|
.add(9)
|
|
.add(11),
|
|
),
|
|
new GAME.GamePiece(
|
|
"Castle",
|
|
["asset/castle_dusk.svg", "asset/castle_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(2)
|
|
.add(4)
|
|
.add(5)
|
|
.add(7)
|
|
.add(10),
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(2)
|
|
.add(3)
|
|
.add(4)
|
|
.add(5)
|
|
.add_stride(7)
|
|
.add_stride(10),
|
|
),
|
|
new GAME.GamePiece(
|
|
"Dragon",
|
|
["asset/dragon_dusk.svg", "asset/dragon_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add_stride(6)
|
|
.add_stride(7)
|
|
.add_stride(8)
|
|
.add_stride(9)
|
|
.add_stride(10)
|
|
.add_stride(11),
|
|
new GAME.PieceMovement()
|
|
.add_stride(0)
|
|
.add_stride(1)
|
|
.add_stride(2)
|
|
.add_stride(3)
|
|
.add_stride(4)
|
|
.add_stride(5)
|
|
.add_stride(6)
|
|
.add_stride(7)
|
|
.add_stride(8)
|
|
.add_stride(9)
|
|
.add_stride(10)
|
|
.add_stride(11),
|
|
),
|
|
new GAME.GamePiece(
|
|
"Omen",
|
|
["asset/king_dusk.svg", "asset/king_dawn.svg"],
|
|
new GAME.PieceMovement()
|
|
.add(0)
|
|
.add(1)
|
|
.add(2)
|
|
.add(3)
|
|
.add(4)
|
|
.add(5)
|
|
.add(7)
|
|
.add(10),
|
|
),
|
|
],
|
|
};
|
|
|
|
GAME.init = () => {
|
|
GAME_DATA = new GAME.Game();
|
|
};
|