diff --git a/src/utils.ts b/src/utils.ts index fb6c0dc..e60d4e5 100644 --- a/src/utils.ts +++ b/src/utils.ts @@ -58,3 +58,32 @@ export function getBuilding(V: VillageState, buildingId: number): Building { export function getKeysAsNumbers(dict: Object): Array { return Object.keys(dict).map(i => parseInt(i)).sort((a, b) => a - b); } + + +/** + * Creates an array of shuffled values, using a version of the + * [Fisher-Yates shuffle](https://en.wikipedia.org/wiki/Fisher-Yates_shuffle). + * + * @since 0.1.0 + * @category Array + * @param {Array} array The array to shuffle. + * @returns {Array} Returns the new shuffled array. + * @example + * + * shuffle([1, 2, 3, 4]) + * // => [4, 1, 3, 2] + */ +export function shuffle(array: Array): Array { + const length = array.length; + if (!length) { + return []; + } + let index = -1; + const lastIndex = length - 1; + const result = [ ...array ]; + while (++index < length) { + const rand = index + Math.floor(Math.random() * (lastIndex - index + 1)); + [ result[rand], result[index] ] = [ result[index], result[rand] ]; + } + return result; +} diff --git a/src/village.ts b/src/village.ts index bb6547d..6a207e5 100644 --- a/src/village.ts +++ b/src/village.ts @@ -3,7 +3,8 @@ import { writable } from "svelte/store"; import buildings from "./buildings"; import { createBuilding } from "./create"; import type { Building } from "./types"; -import { getTilesAtDistance } from "./hexgrid"; +import { getTilesAtDistance, Hex } from "./hexgrid"; +import { getKeysAsNumbers, shuffle } from "./utils"; type Board = { @@ -66,11 +67,8 @@ function getInitialOutsideBoard() { function getInitialState() { - const townhall = createBuilding(buildings.townhall); - const state = { - buildings: [ - townhall, - ], + const state: VillageState = { + buildings: [], resources: { wood: 60, stone: 60, @@ -82,7 +80,34 @@ function getInitialState() { outsideTiles: getInitialOutsideBoard(), }; + // Create the Town hall. + const townhall = createBuilding(buildings.townhall); state.villageTiles[0][0] = townhall.id; + state.buildings.push(townhall); + + // Create all the resource buildings. + const resourceBuildingTypes: Array = shuffle([ + 'woodcutter', 'woodcutter', 'woodcutter', 'woodcutter', + 'mine', 'mine', 'mine', 'mine', + 'pit', 'pit', 'pit', 'pit', + 'field', 'field', 'field', 'field', 'field', 'field', + ]); + getKeysAsNumbers(state.outsideTiles).forEach(y => { + getKeysAsNumbers(state.outsideTiles[y]).forEach(x => { + if (state.outsideTiles[y][x] !== DEFAULT_TILE) { + return; + } + + const type = resourceBuildingTypes.pop(); + if (type === undefined) { + throw new Error("Not enough building types for outside resource buildings"); + } + const newBuilding = createBuilding(buildings[type]); + newBuilding.tile = new Hex(x, y); + state.outsideTiles[y][x] = newBuilding.id; + state.buildings.push(newBuilding); + }); + }); return state; }