Skip to content

Commit

Permalink
Merge branch 'main' of https://github.com/poshypop/GROUP6 into poshyp…
Browse files Browse the repository at this point in the history
…op-main
  • Loading branch information
FergusonAJ committed Oct 19, 2023
2 parents 3652ee9 + f7808f4 commit e972675
Show file tree
Hide file tree
Showing 8 changed files with 1,143 additions and 7 deletions.
12 changes: 5 additions & 7 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,15 +1,13 @@
# vscode cmake build
build

# clion cmake build
cmake-build-debug
cmake-build-release
cmake-build-test
cmake-build-debug-mingw
cmake-build-debug-mingw-sfml
# CMake build directories
cmake-build-*/

# clion settings
# CLion-specific files
.idea/
.cmake/
*.iml

# vscode settings
.vscode/
Expand Down
3 changes: 3 additions & 0 deletions source/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
/build/
/debug/
/CMakeFiles/
*.swp
*.swo
game
Expand Down
203 changes: 203 additions & 0 deletions source/Worlds/BiomeGenerator.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,203 @@
/**
* @file BiomeGenerator.cpp
* @author Paul Schulte, Milan Mihailovic, ChatGPT
*/

#include <fstream>
#include <cmath>
#include <set>
#include <tuple>
#include <random>
#include "BiomeGenerator.h"

using std::vector;

/**
* Creates a generator with a grid of the given size and using the given seed
* @param biome The biome of the grid
* @param width The width of the grid
* @param height The height of the grid
* @param seed The seed used for random number generation
*/
BiomeGenerator::BiomeGenerator(BiomeType biome, unsigned int width, unsigned int height, unsigned int seed) : biome(biome), width(width), height(height) {

if (biome == BiomeType::Maze)
{
setTiles(' ', '#');
}
else if (biome == BiomeType::Grasslands)
{
setTiles('M', '~');
}

perlinNoise = PerlinNoise(seed);
grid = vector<vector<char>>(height, vector<char>(width));
}

/**
* Generates the grid with two types of tiles
*/
void BiomeGenerator::generate() {

char tile1 = tiles[0];
char tile2 = tiles[1];

for (unsigned int y = 0; y < height; y++) {
for (unsigned int x = 0; x < width; x++) {
const double val = perlinNoise.noise2D(x * frequency / width, y * frequency / height);
grid.at(y).at(x) = val < 0 ? tile1 : tile2;
}
}


if (biome == BiomeType::Maze)
{
placeSpecialTiles(tile1, 'X', 0.02); // Placing spike tiles
placeSpecialTiles(tile1, 'O', 0.05); // Placing tar tiles
placeDoorTile('D'); // placing door tile
placeKeyTile('K'); // placing key tile
}
}

/**
* Generates random coordinate to place Key tile
* @param keyTile Door Tile
*/
void BiomeGenerator::placeKeyTile(const char &keyTile)
{
bool counter = false;
while( counter == false )
{
std::random_device rd;
std::mt19937 gen(rd());

std::uniform_int_distribution<int> x_distribution(width/2, width-1);
std::uniform_int_distribution<int> y_distribution(height/2, height-1);
int random_x = x_distribution(gen);
int random_y = y_distribution(gen);

if( grid[random_y][random_x] == ' ' )
{
grid[random_y][random_x] = keyTile;
counter = true;
}
}
}

/**
* Generates door tile on grid at [0][0]
* @param doorTile Door Tile
*/
void BiomeGenerator::placeDoorTile(const char &doorTile)
{
grid[1][1] = doorTile;
}

/**
* Generates special tiles on the grid
* @param genericTile The tile that the special tile can spawn on
* @param specialTile The special tile to generate
* @param percentage Chance of special tile generating on the generic tile
*/
void BiomeGenerator::placeSpecialTiles(const char &genericTile, const char &specialTile, double percentage) {
std::vector<std::pair<int, int>> floorPositions;
for (int i = 0; i < height; ++i) {
for (int j = 0; j < width; ++j) {
if (grid[i][j] == genericTile) {
floorPositions.push_back({j, i});
}
}
}

int numSpikes = floorPositions.size() * percentage;
std::random_device rd;
std::mt19937 g(rd());
std::shuffle(floorPositions.begin(), floorPositions.end(), g);

// Convert some generic floor tiles to special tiles
for (int i = 0; i < numSpikes; ++i) {
grid[floorPositions[i].second][floorPositions[i].first] = specialTile;
}
}

/**
* Clears a randomized path from the top left of the
* grid, to any point on the rightmost side of the map
* @return A vector of points necessary for this path
*/
std::vector<Point> BiomeGenerator::clearPath() const {
std::vector<Point> path;

Point current(0, 0);
path.push_back(current);

while (current.x < width - 1) {
int randDirection = rand() % 3; // 0: Right, 1: Up, 2: Down

// Choose next point based on random direction
Point next = current;
if (randDirection == 0)
{
next.x++;
}

else if (randDirection == 1)
{
if (next.y > 0) // Ensure within grid bounds
next.y--;
}
else {

if (next.y < height - 1) // Ensure within grid bounds
next.y++;
}

// If the next point is the same as the current, then we chose an invalid direction
// (like trying to go up at the top edge), so just skip this iteration.
if (next != current) {
path.push_back(next);
current = next;
}
}

return path;
}

/**
* Clears the walls out of the grid, guaranteeing a path from the
* left of the grid, to any point on the rightmost side of the map
* @param path A vector of points necessary for this path
*/
void BiomeGenerator::applyPathToGrid(const std::vector<Point>& path) {
for (const Point& p : path) {
grid[p.y][p.x] = ' ';
}
}

/**
* Saves the grid to the given filepath
* @param filename The filename the grid will be saved to
*/
void BiomeGenerator::saveToFile(const std::string &filename) const {
std::ofstream out(filename);
for (const auto &row : grid) {
for (const auto &cell : row) {
out << cell;
}
out << "\n";
}
out.close();
}

/**
* Sets the tile vector for the biome
* @param firstTile Tile #1 for the biome
* @param secondTile Tile #2 for the biome
*/
void BiomeGenerator::setTiles(const char& firstTile, const char& secondTile)
{
tiles.clear();
tiles.push_back(firstTile);
tiles.push_back(secondTile);
}

88 changes: 88 additions & 0 deletions source/Worlds/BiomeGenerator.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,88 @@
/**
* @file BiomeGenerator.h
* @author Paul Schulte, Milan Mihailovic, ChatGPT
*
* Uses perlin noise to create dirt and grass on a grid
*/

#pragma once
#include <queue>
#include <functional>
#include <vector>


#include "PerlinNoise.hpp"
#include "../core/WorldGrid.hpp"

using siv::PerlinNoise;
using cse491::WorldGrid;

enum class BiomeType {
Maze,
Grasslands
};

/**
* Holds coordinate position on the grid
* @param biome The biome of the grid
*/
struct Point {
int x; ///< The x coordinate on the grid)
int y; ///< The y coordinate on the grid)

/**
* Creates an (x,y) coordinate point
* @param _x The x-coordinate
* @param _y The y-coordinate
*/
Point(int _x, int _y): x(_x), y(_y) {}

/**
* Comparison operator between 2 equal points
* @param other The other point that this point is being compared to
* @return True if the 2 points are equal, false otherwise
*/
bool operator==(const Point& other) const { return x == other.x && y == other.y; }

/**
* Comparison operator between 2 different points
* @param other The other point that this point is being compared to
* @return True if the 2 points are different, false otherwise
*/
bool operator!=(const Point& other) const { return !(*this == other); }
};

/**
* Generates a new grid based on a specified biome
*/
class BiomeGenerator {
private:
const double frequency = 8.0; ///< [0.1, 64.0]
const int octaves = 8; ///< [1, 16]

PerlinNoise perlinNoise; ///< The Perlin Noise procedural generation algorithm

BiomeType biome; ///< Biome for the gird
std::vector<char> tiles; ///< Vector to store tiles

unsigned int width; ///< Width of the grid
unsigned int height; ///< Height of the grid
std::vector<std::vector<char>> grid; ///< Grid of all tiles

public:
BiomeGenerator(BiomeType biome, unsigned int width, unsigned int height, unsigned int seed);
~BiomeGenerator() = default;

void generate();
void saveToFile(const std::string &filename) const;
void placeSpecialTiles(const char& genericTile, const char& specialTile, double percentage);

void setTiles(const char &firstTile, const char &secondTile);
[[nodiscard]] BiomeType getBiome() const { return biome; }

void placeDoorTile(const char &doorTile);
void placeKeyTile(const char &keyTile);

[[nodiscard]] std::vector<Point> clearPath() const;
void applyPathToGrid(const std::vector<Point>& path);
};
Loading

0 comments on commit e972675

Please sign in to comment.