2021-10-17 21:59:21 +00:00
|
|
|
#include <SDL2/SDL.h>
|
|
|
|
|
|
|
|
#include <iostream>
|
2021-10-18 04:37:41 +00:00
|
|
|
#include <vector>
|
|
|
|
#include <chrono>
|
|
|
|
#include <math.h>
|
|
|
|
#include <stdlib.h>
|
|
|
|
#include <time.h>
|
|
|
|
|
|
|
|
#include "Field.hpp"
|
|
|
|
#include "Agent.hpp"
|
|
|
|
|
|
|
|
unsigned long long SYS_TIME_US()
|
|
|
|
{
|
|
|
|
return (unsigned long long)(std::chrono::duration_cast<std::chrono::microseconds>(std::chrono::system_clock::now().time_since_epoch()).count());
|
|
|
|
}
|
2021-10-17 21:59:21 +00:00
|
|
|
|
|
|
|
int main(int argc, char* argv[])
|
|
|
|
{
|
2021-10-18 04:37:41 +00:00
|
|
|
srand(time(0));
|
2021-10-17 21:59:21 +00:00
|
|
|
int width, height;
|
|
|
|
|
|
|
|
if (argc == 1)
|
|
|
|
{
|
|
|
|
width = height = 300;
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
width = atoi(argv[1]);
|
|
|
|
height = atoi(argv[2]);
|
|
|
|
}
|
|
|
|
|
|
|
|
if (SDL_Init(SDL_INIT_VIDEO) < 0)
|
|
|
|
{
|
|
|
|
std::cout << "Video Init Error." << std::endl;
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_Window* window = SDL_CreateWindow("Slime Mold Simulator", SDL_WINDOWPOS_CENTERED-width/2, SDL_WINDOWPOS_CENTERED-height/2, width, height, SDL_WINDOW_SHOWN);
|
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
SDL_Renderer* renderer = SDL_CreateRenderer(window, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE);
|
|
|
|
|
|
|
|
|
|
|
|
SDL_Texture* field_texture = SDL_CreateTexture(renderer, SDL_GetWindowPixelFormat(window), SDL_TEXTUREACCESS_TARGET, width, height);
|
|
|
|
|
|
|
|
Field field(width, height, 1.0f);
|
|
|
|
|
|
|
|
std::vector<Agent*> agents;
|
|
|
|
|
|
|
|
bool* start_positions = new bool[width*height];
|
|
|
|
for(int i = 0; i < width*height; i++)
|
|
|
|
{
|
|
|
|
start_positions[i] = false;
|
|
|
|
}
|
|
|
|
|
|
|
|
int created = 0;
|
|
|
|
int index = 0;
|
|
|
|
int max_count = (int)sqrt(width*height)*10;
|
|
|
|
while(created < max_count)
|
|
|
|
{
|
|
|
|
int rng_cur = rand()%(width*height/max_count);
|
|
|
|
if (rng_cur == 0 && !start_positions[index])
|
|
|
|
{
|
|
|
|
start_positions[index] = true;
|
|
|
|
created++;
|
|
|
|
}
|
|
|
|
|
|
|
|
index = (index+1)%(width*height);
|
|
|
|
}
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
for(int i = 0; i < width*height; i++)
|
|
|
|
{
|
|
|
|
if (start_positions[i])
|
|
|
|
{
|
|
|
|
Agent* next_agent = new Agent((float)(i%width), (float)(i/width), (float)width, (float)height, 2.0f*M_PI*((float)(rand()%100)/100.0f), 0.8f, 0.1f,3.0f);
|
|
|
|
agents.push_back(next_agent);
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
field.add_pheromone((float)(i%width),(float)(i/width), 0.8f);
|
|
|
|
}
|
|
|
|
}
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
delete[] start_positions;
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
SDL_Rect screen_rect = {0,0,width,height};
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
unsigned long long time_old, time_now;
|
|
|
|
time_now = time_old = SYS_TIME_US();
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
int iteration_duration = 16666/10;
|
|
|
|
int max_loops = 10000000/iteration_duration;
|
|
|
|
bool pause = true;
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
while(true)
|
|
|
|
{
|
|
|
|
SDL_Event event;
|
|
|
|
if (1 == SDL_PollEvent(&event))
|
|
|
|
{
|
|
|
|
if (event.type == SDL_KEYDOWN)
|
|
|
|
{
|
|
|
|
if (event.key.keysym.scancode == SDL_SCANCODE_Q)
|
|
|
|
{
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
else if (event.key.keysym.scancode == SDL_SCANCODE_P)
|
|
|
|
{
|
|
|
|
pause = !pause;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
time_now = SYS_TIME_US();
|
|
|
|
if (time_now >= time_old + iteration_duration)
|
|
|
|
{
|
|
|
|
time_old = time_now;
|
|
|
|
if (pause)
|
|
|
|
{
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
field.tick();
|
|
|
|
for(unsigned int i = 0; i < agents.size(); i++)
|
|
|
|
{
|
|
|
|
agents[i]->tick(&field);
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_SetRenderTarget(renderer, field_texture);
|
|
|
|
SDL_SetRenderDrawColor(renderer, 0,0,0,0);
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
|
|
|
|
float max_strength = field.get_pheromone_max();
|
|
|
|
|
|
|
|
for (int x = 0; x < width; x++)
|
|
|
|
{
|
|
|
|
for (int y = 0; y < height; y++)
|
|
|
|
{
|
|
|
|
float cur_strength = field.get_pheromone_strength(x, y);
|
|
|
|
|
|
|
|
int color_val = std::max(0,std::min(255,(int)(255.0f * cur_strength / max_strength)));
|
|
|
|
SDL_SetRenderDrawColor(renderer, color_val, color_val, color_val, 0xFF);
|
|
|
|
|
|
|
|
SDL_RenderDrawPoint(renderer, x, y);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
SDL_SetRenderTarget(renderer, NULL);
|
|
|
|
SDL_SetRenderDrawColor(renderer, 0,0,0,0);
|
|
|
|
SDL_RenderClear(renderer);
|
|
|
|
|
|
|
|
SDL_RenderCopy(renderer, field_texture, &screen_rect, &screen_rect);
|
|
|
|
|
|
|
|
SDL_RenderPresent(renderer);
|
|
|
|
}
|
|
|
|
}
|
2021-10-17 21:59:21 +00:00
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
SDL_DestroyRenderer(renderer);
|
2021-10-17 21:59:21 +00:00
|
|
|
SDL_DestroyWindow(window);
|
|
|
|
|
|
|
|
SDL_Quit();
|
|
|
|
|
2021-10-18 04:37:41 +00:00
|
|
|
for (unsigned int i = 0; i < agents.size(); i++)
|
|
|
|
{
|
|
|
|
delete agents[i];
|
|
|
|
}
|
|
|
|
|
2021-10-17 21:59:21 +00:00
|
|
|
return 0;
|
|
|
|
}
|