#include #include #include #include #include #include #include #include "Field.hpp" #include "Agent.hpp" unsigned long long SYS_TIME_US() { return (unsigned long long)(std::chrono::duration_cast(std::chrono::system_clock::now().time_since_epoch()).count()); } int main(int argc, char* argv[]) { srand(time(0)); 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); 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 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); } 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); field.add_pheromone((float)(i%width),(float)(i/width), 0.8f); } } delete[] start_positions; SDL_Rect screen_rect = {0,0,width,height}; unsigned long long time_old, time_now; time_now = time_old = SYS_TIME_US(); int iteration_duration = 16666/10; int max_loops = 10000000/iteration_duration; bool pause = true; 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); } } SDL_DestroyRenderer(renderer); SDL_DestroyWindow(window); SDL_Quit(); for (unsigned int i = 0; i < agents.size(); i++) { delete agents[i]; } return 0; }