import _ from 'lodash'; import Debug, { Debugger } from 'debug'; const debug = Debug('cell'); export enum Direction { North, East, South, West } export enum Item { Empty = " ", Road = "R", Town = "T", River = "I", Church = "C", } export interface Attachment { attachTo: Cell; side: Direction; cell: Cell; rotation: number; // Clockwise rotation of a cell } export default class Cell { center: Item; private sides: [Item, Item, Item, Item]; neighbors: [Cell, Cell, Cell, Cell]; private orientation: number // amount of 90-degree counter-clockwise rotations from original orientation shield?: boolean; debug: Debugger; public constructor(center: Item, sides: [Item, Item, Item, Item], orientation = 0, shield = false) { this.center = center; this.sides = sides; this.shield = shield; this.orientation = orientation; } print() { console.log( ` ${this.getSide(Direction.North)} \n${this.getSide(Direction.West)}${this.center}${this.getSide(Direction.East)}\n ${this.getSide(Direction.South)} `); } getSide(direction: Direction) { return this.sides[(((this.orientation + direction) % 4) + 4) % 4]; } rotate(rotation = 1) { debug(`Rotating ${rotation} clockwise`) this.orientation = this.orientation - rotation; } getAttachments(cell: Cell) { return _.flatten([0, 1, 2, 3].map(side => { const item = this.getSide(side); return [0, 1, 2, 3] .filter(rotation => cell.getSide(side - rotation + 2) === item) .map(rotation => ({ cell, rotation, side, attachTo: this as Cell })) })); } attach(cell: Cell, side: Direction) { if (this.neighbors[side]) throw new Error('There is something already attached to this side!'); this.neighbors[side] = cell; } }