Conway's game of life simulator made in SkeletonGL & C++ with a focus on performance
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 

112 lines
3.2 KiB

// Author: XENOBYTE.XYZ
// License: MIT License
// Website: https://xenobyte.xyz/projects/?nav=skeletongl
#include "cell_auto_simulation.hpp"
CellAutoSimulation::CellAutoSimulation() : _simulationStarted(false)
{
resetSimulation();
}
void CellAutoSimulation::update()
{
// Copy the current state of the simulation
_simulationDelta = _simulation;
// Reset render vector
// _cellsToRender.clear();
clearActiveCells();
auto getCellStatus = [&](std::uint16_t x, std::uint16_t y)
{
return _simulationDelta[(y * SIMULATION_WIDTH) + x];
};
// BLACK MAGIK
for (std::uint16_t x = 1; x < SIMULATION_WIDTH - 1; ++x)
{
for (std::uint16_t y = 1; y < SIMULATION_HEIGHT - 1; ++y)
{
// Add the cells surrounding slots
std::uint8_t neighbors =
getCellStatus(x-1, y-1) + getCellStatus(x, y-1) + getCellStatus(x+1, y-1) +
getCellStatus(x-1, y) + 0/*YOU ARE HERE*/ + getCellStatus(x+1, y) +
getCellStatus(x-1, y+1) + getCellStatus(x, y+1) + getCellStatus(x+1, y+1);
if (getCellStatus(x, y) == 1) // Cell is active
{
//SGL_Log("Active CELL X:" + std::to_string(x) + " Y: " + std::to_string(y));
std::pair<std::uint16_t, std::uint16_t>pos;
pos.first = x;
pos.second = y;
_cellsToRender.push_back(pos);
_simulation[(y * SIMULATION_WIDTH) + x] = (neighbors == 2 || neighbors == 3);
}
else // Activate the cell if at least three neighboring cells are active
_simulation[(y * SIMULATION_WIDTH) + x] = (neighbors == 3);
}
}
_iterations++;
}
void CellAutoSimulation::setCell(std::uint16_t x, std::uint16_t y, std::string str)
{
// Check for oob requests
// Process the input string at the requested location
std::uint64_t counter = 0;
for (std::string::const_iterator byteChar = str.begin(); byteChar != str.end(); byteChar++)
{
// By multiplying the Y value by the width of the screen it simulates the limitations of a 2D array
// without actually decalring it so
_simulation[(y * SIMULATION_WIDTH) + x + counter] = ((*byteChar) == '#' ? 1 : 0);
counter++;
}
}
std::vector<std::pair<std::uint16_t, std::uint16_t>> CellAutoSimulation::cellsToRender()
{
return _cellsToRender;
_cellsToRender.clear();
}
std::pair<std::uint16_t, std::uint16_t> CellAutoSimulation::getActiveCell(std::uint16_t cellID)
{
if (cellID < 0 || cellID >= _cellsToRender.size())
return std::pair<std::uint16_t, std::uint16_t>{0,0};
return _cellsToRender[cellID];
}
std::uint16_t CellAutoSimulation::getTotalActiveCells()
{
return _cellsToRender.size();
}
void CellAutoSimulation::clearActiveCells()
{
_cellsToRender.clear();
}
void CellAutoSimulation::resetSimulation()
{
_simulation.fill(0);
_simulationDelta.fill(0);
_cellsToRender.clear();
_iterations = 0;
}
std::uint64_t CellAutoSimulation::getIterations()
{
return _iterations;
}
std::array<std::uint16_t, SIMULATION_WIDTH*SIMULATION_HEIGHT> CellAutoSimulation::getArrayValues()
{
return _simulation;
}