Started work on arena grid
This commit is contained in:
parent
d4635683e3
commit
c28d7ba8eb
29
src/core/ArenaGrid.spec.ts
Normal file
29
src/core/ArenaGrid.spec.ts
Normal file
|
@ -0,0 +1,29 @@
|
||||||
|
module TK.SpaceTac.Specs {
|
||||||
|
function checkLocation(check: TestContext, got: IArenaLocation, expected_x: number, expected_y: number) {
|
||||||
|
check.equals(got.x, expected_x, `x differs (${got.x},${got.y}) (${expected_x},${expected_y})`);
|
||||||
|
check.equals(got.y, expected_y, `y differs (${got.x},${got.y}) (${expected_x},${expected_y})`);
|
||||||
|
}
|
||||||
|
|
||||||
|
testing("HexagonalArenaGrid", test => {
|
||||||
|
test.case("snaps coordinates to the nearest grid point, on a biased grid", check => {
|
||||||
|
let grid = new HexagonalArenaGrid(4, 0.75);
|
||||||
|
checkLocation(check, grid.snap({ x: 0, y: 0 }), 0, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 1, y: 0 }), 0, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 1.9, y: 0 }), 0, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 2.1, y: 0 }), 4, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 1, y: 1 }), 0, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 1, y: 2 }), 2, 3);
|
||||||
|
checkLocation(check, grid.snap({ x: -1, y: -1 }), 0, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: -2, y: -2 }), -2, -3);
|
||||||
|
checkLocation(check, grid.snap({ x: -3, y: -1 }), -4, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 6, y: -5 }), 8, -6);
|
||||||
|
});
|
||||||
|
|
||||||
|
test.case("snaps coordinates to the nearest grid point, on a regular grid", check => {
|
||||||
|
let grid = new HexagonalArenaGrid(10);
|
||||||
|
checkLocation(check, grid.snap({ x: 0, y: 0 }), 0, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 8, y: 0 }), 10, 0);
|
||||||
|
checkLocation(check, grid.snap({ x: 1, y: 6 }), 5, 10 * Math.sqrt(0.75));
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
34
src/core/ArenaGrid.ts
Normal file
34
src/core/ArenaGrid.ts
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
module TK.SpaceTac {
|
||||||
|
/**
|
||||||
|
* Abstract grid for the arena where the battle takes place
|
||||||
|
*
|
||||||
|
* The grid is used to snap arena coordinates for ships and targets
|
||||||
|
*/
|
||||||
|
export interface IArenaGrid {
|
||||||
|
snap(loc: IArenaLocation): IArenaLocation;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hexagonal unbounded arena grid
|
||||||
|
*
|
||||||
|
* This grid is composed of regular hexagons where all vertices are at a same distance "unit" of the hexagon center
|
||||||
|
*/
|
||||||
|
export class HexagonalArenaGrid implements IArenaGrid {
|
||||||
|
private yunit: number;
|
||||||
|
|
||||||
|
constructor(private unit: number, private yfactor = Math.sqrt(0.75)) {
|
||||||
|
this.yunit = unit * yfactor;
|
||||||
|
}
|
||||||
|
|
||||||
|
snap(loc: IArenaLocation): IArenaLocation {
|
||||||
|
let yr = Math.round(loc.y / this.yunit);
|
||||||
|
let xr: number;
|
||||||
|
if (yr % 2 == 0) {
|
||||||
|
xr = Math.round(loc.x / this.unit);
|
||||||
|
} else {
|
||||||
|
xr = Math.round((loc.x - 0.5 * this.unit) / this.unit) + 0.5;
|
||||||
|
}
|
||||||
|
return new ArenaLocation((xr * this.unit) || 0, (yr * this.yunit) || 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -3,6 +3,9 @@ module TK.SpaceTac {
|
||||||
* A turn-based battle between fleets
|
* A turn-based battle between fleets
|
||||||
*/
|
*/
|
||||||
export class Battle {
|
export class Battle {
|
||||||
|
// Grid for the arena
|
||||||
|
grid?: IArenaGrid
|
||||||
|
|
||||||
// Battle outcome, if the battle has ended
|
// Battle outcome, if the battle has ended
|
||||||
outcome: BattleOutcome | null = null
|
outcome: BattleOutcome | null = null
|
||||||
|
|
||||||
|
@ -38,6 +41,8 @@ module TK.SpaceTac {
|
||||||
ai_playing = false
|
ai_playing = false
|
||||||
|
|
||||||
constructor(fleet1 = new Fleet(new Player("Attacker")), fleet2 = new Fleet(new Player("Defender")), width = 1808, height = 948) {
|
constructor(fleet1 = new Fleet(new Player("Attacker")), fleet2 = new Fleet(new Player("Defender")), width = 1808, height = 948) {
|
||||||
|
this.grid = new HexagonalArenaGrid(50);
|
||||||
|
|
||||||
this.fleets = [fleet1, fleet2];
|
this.fleets = [fleet1, fleet2];
|
||||||
this.ships = new RObjectContainer(fleet1.ships.concat(fleet2.ships));
|
this.ships = new RObjectContainer(fleet1.ships.concat(fleet2.ships));
|
||||||
this.play_order = [];
|
this.play_order = [];
|
||||||
|
|
|
@ -64,6 +64,18 @@ module TK.SpaceTac {
|
||||||
return new Target(x, y, null);
|
return new Target(x, y, null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Snap to battle grid
|
||||||
|
*/
|
||||||
|
snap(grid: IArenaGrid): Target {
|
||||||
|
if (this.ship_id) {
|
||||||
|
return this;
|
||||||
|
} else {
|
||||||
|
let location = grid.snap(this);
|
||||||
|
return Target.newFromLocation(location.x, location.y);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Get distance to another target
|
// Get distance to another target
|
||||||
getDistanceTo(other: { x: number, y: number }): number {
|
getDistanceTo(other: { x: number, y: number }): number {
|
||||||
var dx = other.x - this.x;
|
var dx = other.x - this.x;
|
||||||
|
|
Loading…
Reference in a new issue