public void setTile(HexagonalCoordinate coord, Tile?tile) { if (!isOnBoard(coord)) { throw new ArithmeticException(); } boardState[getIndex(coord)] = tile; }
public Tile?getTile(HexagonalCoordinate coord) { if (!isOnBoard(coord)) { throw new ArithmeticException(); } return(boardState[getIndex(coord)]); }
private static Board?getNextValidState(Tile tile, HexagonalCoordinate coord, Board currentState) { Board nextState = new Board(currentState); nextState.setTile(coord, tile); if (evaluateNeighboringCoordinates(nextState, coord)) { return(nextState); } else { return(null); } }
public static bool evaluateNeighboringCoordinates(Board board, HexagonalCoordinate coord) { if (!evaluateCoordinate(board, coord)) { return(false); } foreach (var neighboringCoord in coord.getNeighbors()) { if (Board.isOnBoard(neighboringCoord)) { if (!evaluateCoordinate(board, neighboringCoord)) { return(false); } } } return(true); }
/** * Returns true if the coordinate meets all constraints. */ public static bool evaluateCoordinate(Board board, HexagonalCoordinate coord) { Tile?current = board.getTile(coord); if (current == null) { return(true); } else if (current == Tile.DESERT) { return(true); } else if (board.isOkay(coord)) { return(true); } foreach (HexagonalCoordinate neighborCoord in coord.getNeighbors()) { if (Board.isOnBoard(neighborCoord)) { Tile?tile = board.getTile(neighborCoord); if (tile == null) { return(true); } else if (tile == current) { board.markOkay(neighborCoord); return(true); } } } return(false); }
/** * Returns the index that the hexagonal coordinate corresponds to. */ public static int getIndex(HexagonalCoordinate coordinate) { /* * PURPOSE: * This algorithim maps a hexagonal coordinate to a corresponding index. * * OVERVIEW: * The array is split into sections representing each of the rings. Each of the rings is mapped onto the array "clockwise" from a given axis. * It doesn't really matter which direction you go around in, or what axis is your starting point. * I am using +z as the starting point. * * ALGORITHIM: * * -- Determining what ring the tile is on * This is pretty simple. Take absolute value of each of the three axises. The greatest of the three is the ring number. * For example, (1, 1, -2) is on ring 2. * * -- Distance to center axis * * ----Overview * We will approach this by dividing the problem into two parts. * First, we will determine the distance from the tile to the nearest axis. * Last, we will determine the distance from the nearest axis to the center axis. * * ----Note on axis names * In order to distinguish between the axes, I have given them some names. +z - (z = 0) and x > 0 * -z - (z = 0) and x < 0 +y - (y = 0) and x > 0 * -y - (y = 0) and x < 0 +x - (x = 0) and y > 0 * -x - (x = 0) and y < 0 * * ----Distance to nearest axis * The axises of the board split the board much like a pizza. What is left after removing is a slice. * We can determine which slice we are in by comparing the numbers in the coordinates. Specifically, we can look at the placement and sign of the ring number. * The following were determined by experimentation and observation, but I don't have any reason to doubt that they are accurate. * - If RN in X, and RN is + => Next axis is (+z), and distance to axis is abs(z). * - If RN in X, and RN is - => Next axis is (-z), and distance to axis is abs(z). * - If RN in Y, and RN is + => Next axis is (+x), and distance to axis is abs(x). * - If RN in Y, and RN is - => Next axis is (-x), and distance to axis is abs(x). * - If RN in Z, and RN is + => Next axis is (+y), and distance to axis is abs(y). * - If RN in Z, and RN is - => Next axis is (-y), and distance to axis is abs(y). * (Of course, one should first check that you aren't on an axis. If you are, then the distance to the next axis is 0 (duh)) * * ----Distance from nearest axis to center axis * The first thing to realize is that the distance between the axises is equal to (RingNumber-1). * Next, we should establish how many axises are between the current axis and the center axis. I call this "axial distance" * - +x is 2 away * - -x is 5 away * - +y is 1 away * - -y is 4 away * - +z is 0 away * - -z is 3 away * The distance from the nearest axis to the center axis is therefore AxialDistance*RingNumber */ if (coordinate.isOrigin()) { return(0); } int x = coordinate.x; int y = coordinate.y; int z = coordinate.z; int ringNumber = Math.Max(Math.Abs(x), Math.Max(Math.Abs(y), Math.Abs(z))); //Get the max of x, y, and z int ringOffset = tilesInBoard(ringNumber - 1); int axialDistance; int tilesToNextAxis; if (y == ringNumber && z == -1 * ringNumber) { //On the +x axis axialDistance = 2; tilesToNextAxis = 0; } else if (z == ringNumber && y == -1 * ringNumber) { //On the -x axis axialDistance = 5; tilesToNextAxis = 0; } else if (x == ringNumber && z == -1 * ringNumber) { //On the +y axis axialDistance = 1; tilesToNextAxis = 0; } else if (z == ringNumber && x == -1 * ringNumber) { //On the -y axis axialDistance = 4; tilesToNextAxis = 0; } else if (x == ringNumber && y == -1 * ringNumber) { //On the +z axis axialDistance = 0; tilesToNextAxis = 0; } else if (x == -1 * ringNumber && y == ringNumber) { //On the -z axis axialDistance = 3; tilesToNextAxis = 0; } else if (x == ringNumber) { //Next axis is +Z axialDistance = 0; tilesToNextAxis = Math.Abs(z); } else if (x == -1 * ringNumber) { //Next axis is -Z axialDistance = 3; tilesToNextAxis = Math.Abs(z); } else if (y == ringNumber) { //Next axis is +X axialDistance = 2; tilesToNextAxis = Math.Abs(x); } else if (y == -1 * ringNumber) { //Next axis is -X axialDistance = 5; tilesToNextAxis = Math.Abs(x); } else if (z == ringNumber) { //Next axis is +Y axialDistance = 4; tilesToNextAxis = Math.Abs(y); } else { //Next axis is -Y axialDistance = 1; tilesToNextAxis = Math.Abs(y); } int result = ringOffset + tilesToNextAxis + (axialDistance * ringNumber); return(result); }
/** * Returns true if the given coordinates exist on the board. */ public static bool isOnBoard(HexagonalCoordinate coordinate) { return(Math.Abs(coordinate.x) <= SIZE && Math.Abs(coordinate.y) <= SIZE && Math.Abs(coordinate.z) <= SIZE); }
public bool isOkay(HexagonalCoordinate coord) { return(isTileOkay[getIndex(coord)]); }
public void markOkay(HexagonalCoordinate coord) { isTileOkay[getIndex(coord)] = true; }
public static List <Board> getBiomeConfigurationsRecursive(Stack <HexagonalCoordinate> coordinates, TileCounts tileCounts, Board currentState) { if (coordinates.Count == 0) { return(new List <Board> { currentState }); } List <Board> toReturn = new List <Board>(); HexagonalCoordinate nextCoordinate = coordinates.Pop(); if (tileCounts.clay > 0) { Board?nextState = getNextValidState(Tile.CLAY, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(new Stack <HexagonalCoordinate>(coordinates), tileCounts.removeClay(), nextState)); } } if (tileCounts.wood > 0) { Board?nextState = getNextValidState(Tile.WOOD, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(new Stack <HexagonalCoordinate>(coordinates), tileCounts.removeWood(), nextState)); } } if (tileCounts.wheat > 0) { Board?nextState = getNextValidState(Tile.WHEAT, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(new Stack <HexagonalCoordinate>(coordinates), tileCounts.removeWheat(), nextState)); } } if (tileCounts.sheep > 0) { Board?nextState = getNextValidState(Tile.SHEEP, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(new Stack <HexagonalCoordinate>(coordinates), tileCounts.removeSheep(), nextState)); } } if (tileCounts.stone > 0) { Board?nextState = getNextValidState(Tile.STONE, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(new Stack <HexagonalCoordinate>(coordinates), tileCounts.removeStone(), nextState)); } } if (tileCounts.desert > 0) { Board?nextState = getNextValidState(Tile.DESERT, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(new Stack <HexagonalCoordinate>(coordinates), tileCounts.removeDesert(), nextState)); } } return(toReturn); }
public static List <Board> getBiomeConfigurationsRecursive(int currentIndex, int maxIndex, TileCounts tileCounts, Board currentState) { if (currentIndex == maxIndex) { return(new List <Board> { currentState }); } List <Board> toReturn = new List <Board>(); HexagonalCoordinate nextCoordinate = Board.indexToCoordinate(currentIndex); if (tileCounts.clay > 0) { Board?nextState = getNextValidState(Tile.CLAY, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(currentIndex + 1, maxIndex, tileCounts.removeClay(), nextState)); } } if (tileCounts.wood > 0) { Board?nextState = getNextValidState(Tile.WOOD, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(currentIndex + 1, maxIndex, tileCounts.removeWood(), nextState)); } } if (tileCounts.wheat > 0) { Board?nextState = getNextValidState(Tile.WHEAT, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(currentIndex + 1, maxIndex, tileCounts.removeWheat(), nextState)); } } if (tileCounts.sheep > 0) { Board?nextState = getNextValidState(Tile.SHEEP, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(currentIndex + 1, maxIndex, tileCounts.removeSheep(), nextState)); } } if (tileCounts.stone > 0) { Board?nextState = getNextValidState(Tile.STONE, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(currentIndex + 1, maxIndex, tileCounts.removeStone(), nextState)); } } if (tileCounts.desert > 0) { Board?nextState = getNextValidState(Tile.DESERT, nextCoordinate, currentState); if (nextState != null) { toReturn.AddRange(getBiomeConfigurationsRecursive(currentIndex + 1, maxIndex, tileCounts.removeDesert(), nextState)); } } return(toReturn); }