diff options
author | eug-vs <eugene@eug-vs.xyz> | 2022-03-12 15:10:54 +0300 |
---|---|---|
committer | eug-vs <eugene@eug-vs.xyz> | 2022-03-12 15:10:54 +0300 |
commit | 2e6a4a8761bf037283f7eb8dbfd57ab7b9e977a9 (patch) | |
tree | 22012ec08067f92d8baf9ab3039f3f7cda3e7402 /src/Tile | |
parent | 8aa2213390e01996e3f9682abfd5910c698df0e2 (diff) | |
download | carcassonne-engine-ts-2e6a4a8761bf037283f7eb8dbfd57ab7b9e977a9.tar.gz |
refactor: rename Cell -> Tile, Item -> Feature
Diffstat (limited to 'src/Tile')
-rw-r--r-- | src/Tile/Tile.test.ts | 56 | ||||
-rw-r--r-- | src/Tile/Tile.ts | 76 |
2 files changed, 132 insertions, 0 deletions
diff --git a/src/Tile/Tile.test.ts b/src/Tile/Tile.test.ts new file mode 100644 index 0000000..62ac51e --- /dev/null +++ b/src/Tile/Tile.test.ts @@ -0,0 +1,56 @@ +import assert from 'assert'; +import Tile, { Direction, Feature } from './Tile'; + +const { North, East, South, West } = Direction; +const { Road, Town, Empty, River } = Feature; + +describe('Tile', () => { + describe('getSide', () => { + it('Should get North, East, South and West sides correctly', () => { + const cell = new Tile(Empty, [Road, Town, Empty, River]); + + assert.strictEqual(cell.getSide(North), Road); + assert.strictEqual(cell.getSide(East), Town); + assert.strictEqual(cell.getSide(South), Empty); + assert.strictEqual(cell.getSide(West), River); + }); + + it('Should respect cell orientation', () => { + const cell = new Tile(Empty, [Road, Town, Empty, River]); + cell.rotate(5); + + assert.strictEqual(cell.getSide(North), River); + assert.strictEqual(cell.getSide(East), Road); + assert.strictEqual(cell.getSide(South), Town); + assert.strictEqual(cell.getSide(West), Empty); + }); + + it('Should work with negative orientation', () => { + const cell = new Tile(Empty, [Road, Town, Empty, River]); + cell.rotate(-7); + + assert.strictEqual(cell.getSide(North), River); + assert.strictEqual(cell.getSide(East), Road); + assert.strictEqual(cell.getSide(South), Town); + assert.strictEqual(cell.getSide(West), Empty); + }); + }); + + describe('getAttachments', () => { + it('Should correclty list legal attachments', () => { + const attachTo = new Tile(Town, [Road, Town, Town, Road]) + const cell = new Tile(Road, [Empty, Road, Road, Empty]) + + cell.print(); + attachTo.print(); + + const attachments = attachTo.getAttachments(cell); + assert.strictEqual(attachments.length, 4); + assert.deepStrictEqual(attachments[0], { side: 0, rotation: 0, cell, attachTo }); + assert.deepStrictEqual(attachments[1], { side: 0, rotation: 1, cell, attachTo }); + assert.deepStrictEqual(attachments[2], { side: 3, rotation: 0, cell, attachTo }); + assert.deepStrictEqual(attachments[3], { side: 3, rotation: 3, cell, attachTo }); + }); + }); +}); + diff --git a/src/Tile/Tile.ts b/src/Tile/Tile.ts new file mode 100644 index 0000000..4eee263 --- /dev/null +++ b/src/Tile/Tile.ts @@ -0,0 +1,76 @@ +import _ from 'lodash'; +import Debug, { Debugger } from 'debug'; + +const debug = Debug('cell'); + +export enum Direction { + North, + East, + South, + West +} + +export enum Feature { + Empty = " ", + Road = "R", + Town = "T", + River = "I", + Church = "C", +} + +export interface Attachment { + attachTo: Tile; + side: Direction; + cell: Tile; + rotation: number; // Clockwise rotation of a cell +} + + +export default class Tile { + center: Feature; + private sides: [Feature, Feature, Feature, Feature]; + neighbors: [Tile, Tile, Tile, Tile]; + private orientation: number // amount of 90-degree counter-clockwise rotations from original orientation + shield?: boolean; + + debug: Debugger; + + public constructor(center: Feature, sides: [Feature, Feature, Feature, Feature], 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: Tile) { + 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 Tile + })) + })); + } + + attach(cell: Tile, side: Direction) { + if (this.neighbors[side]) throw new Error('There is something already attached to this side!'); + this.neighbors[side] = cell; + } +} |