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
|
||||
*/
|
||||
export class Battle {
|
||||
// Grid for the arena
|
||||
grid?: IArenaGrid
|
||||
|
||||
// Battle outcome, if the battle has ended
|
||||
outcome: BattleOutcome | null = null
|
||||
|
||||
|
@ -38,6 +41,8 @@ module TK.SpaceTac {
|
|||
ai_playing = false
|
||||
|
||||
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.ships = new RObjectContainer(fleet1.ships.concat(fleet2.ships));
|
||||
this.play_order = [];
|
||||
|
|
|
@ -64,6 +64,18 @@ module TK.SpaceTac {
|
|||
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
|
||||
getDistanceTo(other: { x: number, y: number }): number {
|
||||
var dx = other.x - this.x;
|
||||
|
|
Loading…
Reference in a new issue