UNPKG

catan-board-generator

Version:
202 lines (201 loc) 7.82 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); exports.generateExpansionBoard = exports.generateCatanBoard = void 0; // Mapping of each tile to its neighbors based on their indices var neighbors = { // Each key is a tile index, and its value is an array of indices of neighboring tiles 0: [1, 10, 11], 1: [0, 2, 11, 12], 2: [1, 12, 13], 10: [0, 11, 20, 21], 11: [0, 1, 10, 12, 21, 22], 12: [1, 2, 11, 13, 22, 23], 13: [2, 12, 23, 24], 20: [10, 21, 30], 21: [10, 11, 20, 22, 30, 31], 22: [11, 12, 21, 23, 31, 32], 23: [12, 13, 22, 24, 32, 33], 24: [13, 23, 33], 30: [20, 21, 31, 40], 31: [21, 22, 30, 32, 40, 41], 32: [22, 23, 31, 33, 41, 42], 33: [23, 24, 32, 42], 40: [30, 31, 41], 41: [31, 32, 40, 42], 42: [32, 33, 41], }; var expandedNeighbors = { 0: [1, 10, 11], 1: [0, 2, 11, 12], 2: [1, 12, 13], 10: [0, 11, 20, 21], 11: [0, 1, 10, 12, 21, 22], 12: [1, 2, 11, 13, 22, 23], 13: [2, 12, 23, 24], 20: [10, 21, 30, 31], 21: [10, 11, 20, 22, 31, 32], 22: [11, 12, 21, 23, 32, 33], 23: [12, 13, 22, 24, 33, 34], 24: [13, 23, 34, 35], 30: [20, 31, 40], 31: [20, 21, 30, 32, 40, 41], 32: [21, 22, 31, 33, 41, 42], 33: [22, 23, 32, 34, 42, 43], 34: [23, 24, 33, 35, 43, 44], 35: [24, 34, 44], 40: [30, 31, 41, 50], 41: [31, 32, 40, 42, 50, 51], 42: [32, 33, 41, 43, 51, 52], 43: [33, 34, 42, 44, 52, 53], 44: [34, 35, 43, 53], 50: [40, 41, 51, 60], 51: [41, 42, 50, 52, 60, 61], 52: [42, 43, 51, 53, 61, 62], 53: [43, 44, 52, 62], 60: [50, 51, 61], 61: [51, 52, 60, 62], 62: [52, 53, 61] }; // Function to shuffle an array in place function shuffleArray(array) { var _a; // Loop backwards through the array for (var i = array.length - 1; i > 0; i--) { // Pick a random index before the current one var j = Math.floor(Math.random() * (i + 1)); // Swap elements at indices i and j _a = [array[j], array[i]], array[i] = _a[0], array[j] = _a[1]; } } // Function to determine the next index, with special cases function incrementCounter(num, expansion) { // Map of special cases where the next index jumps ahead var nextIndexMap; if (expansion) { nextIndexMap = { 2: 10, 13: 20, 24: 30, 35: 40, 44: 50, 53: 60 }; } else { nextIndexMap = { 2: 10, 13: 20, 24: 30, 33: 40 }; } // Return the mapped value if it exists, otherwise increment by 1 return nextIndexMap[num] !== undefined ? nextIndexMap[num] : num + 1; } // Function to fill the board with resources function fillResources(board, expansion) { // Array of tiles to be distributed on the board var tiles = ['Wood', 'Wood', 'Wood', 'Wood', 'Brick', 'Brick', 'Brick', 'Wheat', 'Wheat', 'Wheat', 'Wheat', 'Sheep', 'Sheep', 'Sheep', 'Sheep', 'Ore', 'Ore', 'Ore', 'Desert']; if (expansion) { tiles = ['Wood', 'Wood', 'Wood', 'Wood', 'Wood', 'Wood', 'Brick', 'Brick', 'Brick', 'Brick', 'Brick', 'Wheat', 'Wheat', 'Wheat', 'Wheat', 'Wheat', 'Wheat', 'Sheep', 'Sheep', 'Sheep', 'Sheep', 'Sheep', 'Sheep', 'Ore', 'Ore', 'Ore', 'Ore', 'Ore', 'Desert', 'Desert']; } // Shuffle the tiles to randomize their distribution shuffleArray(tiles); // Iterator for placing tiles on the board var itr = 0; // Loop until all tiles are placed while (tiles.length > 0) { // Place the tile on the board and set its number to 0 initially board[Math.floor(itr / 10)][itr % 10] = { resource: tiles.pop() || 'Desert', number: 0 }; // Move to the next index, with special cases handled by incrementCounter itr = incrementCounter(itr, expansion); } } // Helper function for fillNumbers to check if the board's number distribution follows the game's rules function checkNeighbors(board, expansion) { var neighborMap = expansion ? expandedNeighbors : neighbors; var limit = expansion ? 62 : 42; var itr = 0; // Iterator for checking each tile // Loop through all possible tile positions while (itr <= limit) { // Get the current tile var tile = board[Math.floor(itr / 10)][itr % 10]; // Check all neighbors for rule violations for (var _i = 0, _a = neighborMap[itr]; _i < _a.length; _i++) { var neighborNum = _a[_i]; var neighbor = board[Math.floor(neighborNum / 10)][neighborNum % 10]; // Return false if a rule is violated if (tile.resource === "Desert" && neighbor.resource === "Desert") { fillResources(board, true); return checkNeighbors(board, true); } if (neighbor.number === tile.number || ((tile.number === 6 || tile.number === 8) && (neighbor.number === 6 || neighbor.number === 8)) || ((tile.number === 2 || (tile.number === 12)) && (neighbor.number === 2 || neighbor.number === 12))) { return false; } } // Move to the next tile itr = incrementCounter(itr, expansion); } // Return true if all tiles pass the checks return true; } // Function to fill the board with numbers, ensuring no rule violations function fillNumbers(board, expansion) { // Flag to indicate a valid configuration has been found var valid = false; // Loop until a valid configuration is found while (!valid) { // Array of numbers to be distributed on the board var numbers = [2, 3, 3, 4, 4, 5, 5, 6, 6, 8, 8, 9, 9, 10, 10, 11, 11, 12]; if (expansion) { numbers = [2, 2, 3, 3, 3, 4, 4, 4, 5, 5, 5, 6, 6, 6, 8, 8, 8, 9, 9, 9, 10, 10, 10, 11, 11, 11, 12, 12]; } // Shuffle the numbers to randomize their distribution shuffleArray(numbers); // Iterator for placing numbers on the board var itr = 0; // Loop until all numbers are placed while (numbers.length > 0) { // Calculate row and index within the row for the current number var row = Math.floor(itr / 10); var index = itr % 10; // Skip desert tiles when assigning numbers if (board[row][index].resource !== "Desert") { board[row][index].number = numbers.pop() || 0; } // Move to the next index itr = incrementCounter(itr, expansion); } // Check if the current configuration is valid valid = checkNeighbors(board, expansion); } } // Main function to generate a Catan board function generateCatanBoard() { // Initialize the board with empty rows of varying lengths var board = [ new Array(3).fill(null), new Array(4).fill(null), new Array(5).fill(null), new Array(4).fill(null), new Array(3).fill(null) ]; // Fill the board with resources and then numbers fillResources(board, false); fillNumbers(board, false); // Return the completed board return board; } exports.generateCatanBoard = generateCatanBoard; // Main function to generate a Catan board function generateExpansionBoard() { // Initialize the board with empty rows of varying lengths var board = [ new Array(3).fill(null), new Array(4).fill(null), new Array(5).fill(null), new Array(6).fill(null), new Array(5).fill(null), new Array(4).fill(null), new Array(3).fill(null) ]; // Fill the board with resources and then numbers fillResources(board, true); fillNumbers(board, true); // Return the completed board return board; } exports.generateExpansionBoard = generateExpansionBoard; var board = generateExpansionBoard(); console.log(board);