You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
hexmap/common/src/state/HexMap.ts

106 lines
3.6 KiB

/** Data associated with a single cell of the map. */
import {StorageCoordinates} from "./Coordinates";
export interface HexCell {
/** A color in #RRGGBBAA format, or null indicating that the cell should simply be hidden altogether. */
readonly color: string
}
export const EMPTY_CELL: HexCell = {
color: "#FFFFFFFF"
}
export type HexLine = readonly (HexCell|null)[]
export enum HexagonOrientation {
/**
* The pointy side is vertical and the flat side is horizontal.
* Use the Y axis for pointy coordinates and the X axis for flat coordinates.
* Lines are rows that go straight across the X axis.
*/
POINTY_TOP = "POINTY_TOP",
/**
* The pointy side is horizontal and the flat side is vertical.
* Use the Y axis for flat coordinates and the X axis for pointy coordinates.
* Lines are columns that go straight down the Y axis.
*/
FLAT_TOP = "FLAT_TOP",
}
/** Which lines should be indented - odds or evens. */
export enum LineParity {
/** Odd lines (1, 3, 5, ...) are staggered inward (right or down) by 1/2 cell. */
ODD = "ODD",
/** Even lines (0, 2, 4, ...) are staggered inward (right or down) by 1/2 cell. */
EVEN = "EVEN"
}
/** The type of map this map is. */
export interface HexLayout {
readonly orientation: HexagonOrientation
readonly indentedLines: LineParity
}
/** Data corresponding to an entire hex map. */
export interface HexMap {
/** The way the map is displayed, which also affects how coordinates are calculated. */
readonly layout: HexLayout
/**
* The number of lines on the map.
* In ROWS and EVEN_ROWS mode, this is the height of the map.
* In COLUMNS and EVEN_COLUMNS mode, this is the width of the map.
*/
readonly lines: number
/**
* The number of cells per line.
* In ROWS and EVEN_ROWS mode, this is the width of the map.
* In COLUMNS and EVEN_COLUMNS mode, this is the height of the map.
*/
readonly cellsPerLine: number
/**
* The list of tile lines. There are always exactly {lines} lines.
* Lines have a constant length; there are always exactly {cells_per_line} cells in a line.
* In COLUMNS and EVEN_COLUMNS mode, lines represent columns.
* In ROWS and EVEN_ROWS mode, lines represent rows.
*/
readonly layer: readonly HexLine[]
/**
* A unique identifier in https://github.com/rs/xid format for this map. Lets the client know when it is connecting
* to a different map with the same name as this one, and its old map has been destroyed.
*/
readonly xid: string
}
export function initializeMap({lines, cellsPerLine, layout, xid}: {lines: number, cellsPerLine: number, layout: HexLayout, xid: string}): HexMap {
const layer: HexLine[] = [];
const emptyLine: HexCell[] = [];
for (let cell = 0; cell < cellsPerLine; cell += 1) {
emptyLine.push(EMPTY_CELL)
}
for (let line = 0; line < lines; line += 1) {
layer.push(emptyLine)
}
return {
lines,
cellsPerLine,
layout,
layer,
xid
}
}
export function isValidCoordinate(map: HexMap, {line, cell}: StorageCoordinates) {
return line >= 0 && line < map.lines && Number.isInteger(line)
&& cell >= 0 && cell < map.cellsPerLine && Number.isInteger(cell);
}
export function areCellsEquivalent(left: HexCell|null, right: HexCell|null): boolean {
return left === right || (left?.color === right?.color)
}
export function getCell(map: HexMap, {line, cell}: StorageCoordinates): HexCell|null {
if (!isValidCoordinate(map, {line, cell})) {
return null
}
return map.layer[line][cell]
}