Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #include <iostream>
- #include <stdio.h>
- #include <stdlib.h>
- #include <vector>
- #include <time.h>
- #include <unistd.h>
- #include <algorithm>
- #include <math.h>
- #include <string>
- using namespace std;
- #define FIELD_WIDTH 50
- #define FIELD_HEIGHT 50
- #define COMMON_VOLE_NEIGHBOURS_X 1
- #define COMMON_VOLE_NEIGHBOURS_Y 1
- // USER ARGUMENTS
- int arg_deepPlowingWeek = 0;
- int arg_commonVolesToSpawn = 0;
- int arg_planting = 0;
- int arg_acid = 0;
- int weeks_count = 0;
- int common_voles_count = 0;
- bool overcrowded = false;
- /**
- * Single common vole structure
- */
- struct CommonVole {
- bool isMale;
- unsigned int age;
- unsigned int remainingWeeksOfPregnancy;
- unsigned int foodSupply;
- };
- /**
- * Represents one single food unit in field
- */
- struct FoodUnit {
- bool available;
- int timeToRenew;
- };
- /**
- * Structure for next move propability
- */
- struct MovePropability {
- int x;
- int y;
- float propability;
- };
- /**
- * Field
- */
- vector<CommonVole> fieldOfCommonVoles[FIELD_HEIGHT][FIELD_WIDTH];
- FoodUnit food[FIELD_HEIGHT][FIELD_WIDTH];
- /**
- * Calculate amount of predators
- * @return
- */
- int getPredatorsAmount() {
- return (pow(common_voles_count, 2) / 15000);
- }
- /**
- * Print field of common voles
- * @param field
- */
- void printField(){
- printf("\n\n\n\n\nWeek number: %d\nCommon voles amount: %d\nPredators: %d\n", weeks_count, common_voles_count, getPredatorsAmount());
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- // Setting the right background color
- if(food[y][x].available){
- cout << "\033[37;43m";
- } else {
- cout << "\033[0m";
- }
- if(fieldOfCommonVoles[y][x].size() > 0){
- cout << fieldOfCommonVoles[y][x].size() << " ";
- } else {
- printf("- ");
- }
- cout << "\033[0m";
- }
- printf("\n");
- }
- }
- /**
- * Clears field from food
- */
- void clearFood(){
- for(int i = 0; i < FIELD_HEIGHT; i++){
- fill_n(food[i], FIELD_WIDTH, (FoodUnit){.available = false, .timeToRenew = 0});
- }
- }
- /**
- * Makes food
- */
- void spawnFood(){
- for(int i = 0; i < FIELD_HEIGHT; i++){
- fill_n(food[i], FIELD_WIDTH, (FoodUnit){.available = true, .timeToRenew = 0});
- }
- }
- /**
- * Checks whether food should be renewed
- * if so, renew it!
- */
- void foodCheck(){
- if(weeks_count >= 12 && weeks_count <= 35){
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- if(!food[y][x].available){
- food[y][x].timeToRenew--;
- if(food[y][x].timeToRenew == 0){
- food[y][x].available = true;
- }
- }
- }
- }
- }
- }
- /**
- * Manage common vole starvation
- */
- void commonVoleStarvation(){
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- if(fieldOfCommonVoles[y][x].size() > 0){
- for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
- fieldOfCommonVoles[y][x].at(i).foodSupply--;
- if(fieldOfCommonVoles[y][x].at(i).foodSupply == 0){
- fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
- common_voles_count--;
- continue;
- }
- }
- }
- }
- }
- }
- /**
- * Deep plowing apears!
- */
- void deepPlowing(){
- bool shouldRemove = true;
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- if(fieldOfCommonVoles[y][x].size() > 0){
- for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
- if(shouldRemove){
- fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
- shouldRemove = false;
- common_voles_count--;
- } else {
- shouldRemove = true;
- }
- }
- }
- }
- }
- clearFood();
- }
- /**
- * Acid application
- */
- void acidApplication(){
- int amountOfCommonVolesToKill = common_voles_count * (50 + rand() % 45) / 100;
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- if(fieldOfCommonVoles[y][x].size() > 0){
- for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
- if(amountOfCommonVolesToKill > 0){
- fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
- amountOfCommonVolesToKill--;
- common_voles_count--;
- }
- }
- }
- }
- }
- clearFood();
- }
- /**
- * Get most possible move
- */
- MovePropability chooseMoveDependingOnPropability(vector<MovePropability> moveRecords){
- random_shuffle(moveRecords.begin(), moveRecords.end());
- MovePropability move = moveRecords[0];
- for(int i = 0; i < moveRecords.size(); i++){
- if(moveRecords[i].propability > move.propability) move = moveRecords[i];
- }
- return move;
- }
- /**
- * Check whether any female
- * should have children.. If so, DO IT!
- */
- void commonVoleReproductionCheck(){
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- if(fieldOfCommonVoles[y][x].size() > 0){
- for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
- // Increment their age
- fieldOfCommonVoles[y][x].at(i).age++;
- // THE REPRODUCTION!!!!
- if(fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy == 1){
- fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy--;
- int numberOfChilds = 3 + rand() % 8;
- for(int childs = 0; childs < numberOfChilds; childs++){
- int dx = -1 + rand() % 3;
- int dy = -1 + rand() % 3;
- if((y + dy) >= 0 && (y + dy < FIELD_HEIGHT) && (x + dx) >= 0 && (x + dx) < FIELD_WIDTH){
- fieldOfCommonVoles[y + dy][x + dx].push_back((CommonVole){
- .isMale = ((rand() % 100) > 60) ? false : true,
- .age = 0,
- .remainingWeeksOfPregnancy = 0,
- .foodSupply = 2
- });
- common_voles_count++;
- } else {
- childs--;
- }
- }
- } else if(fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy > 0){
- fieldOfCommonVoles[y][x].at(i).remainingWeeksOfPregnancy--;
- }
- }
- }
- }
- }
- }
- /**
- * Apply evil predators
- */
- void applyPredators(){
- int predators_count = getPredatorsAmount();
- for(int i = 0; i < predators_count; i++){
- int chance = rand() % 100;
- int propabilityForHunt = (int)((sin((weeks_count / 10.0) - (M_PI)) + 1.0) / 2 * 100);
- if(overcrowded == true) propabilityForHunt *= 4;
- if(chance < propabilityForHunt){
- int amountOfCommonVolesToKill = rand() % (35 * ((overcrowded == true) ? 5 : 1));
- for(int j = 0; j < amountOfCommonVolesToKill; j++){
- int randX = rand() % (FIELD_WIDTH - 1);
- int randY = rand() % (FIELD_HEIGHT - 1);
- if(fieldOfCommonVoles[randY][randX].size() > 0){
- amountOfCommonVolesToKill -= fieldOfCommonVoles[randY][randX].size();
- common_voles_count -= fieldOfCommonVoles[randY][randX].size();
- fieldOfCommonVoles[randY][randX].clear();
- }
- }
- }
- }
- }
- int main(int argc, char *argv[]) {
- try{
- int opt;
- while ((opt = getopt(argc, argv, "c:d:p:a:")) != -1){ // Iterate through all command line arguments
- switch(opt){
- case 'd':
- arg_deepPlowingWeek = stoi(optarg);
- break;
- case 'p':
- arg_planting = stoi(optarg);
- break;
- case 'c':
- arg_commonVolesToSpawn = stoi(optarg);
- break;
- case 'a':
- arg_acid = stoi(optarg);
- break;
- default:
- abort();
- }
- }
- } catch (exception e){
- fprintf(stderr, "Error while parsing arguments\n");
- exit(10);
- }
- if(arg_commonVolesToSpawn == 0){
- fprintf(stderr, "-c parameter is mandatory\n");
- exit(10);
- }
- srand(time(NULL)); // Seed random number generator
- int commonVolesToSpawn = arg_commonVolesToSpawn; // Common voles to start with
- for(int i = 0; i < commonVolesToSpawn; i++){ // Spawn common voles into field
- int random_x = rand() % FIELD_WIDTH;
- int random_y = rand() % FIELD_HEIGHT;
- fieldOfCommonVoles[random_y][random_x].push_back((CommonVole){
- .isMale = ((rand() % 100) > 60) ? false : true,
- .age = 0,
- .remainingWeeksOfPregnancy = 0,
- .foodSupply = 14
- });
- common_voles_count++;
- }
- // Initialize food array
- clearFood();
- // Main loop
- while(true){
- // Creating food if it is the right time
- if(weeks_count == ((arg_planting == 0) ? 12 : arg_planting)) spawnFood();
- foodCheck();
- // If we are harvesting
- if(weeks_count == ((arg_deepPlowingWeek == 0) ? 35 : arg_deepPlowingWeek)) deepPlowing();
- // If it is acid application week
- if(arg_acid != 0 && arg_acid == weeks_count) acidApplication();
- // Common vole reproduction check
- commonVoleReproductionCheck();
- if(common_voles_count >= 1000) overcrowded = true;
- // Check if any common vole starved to death
- commonVoleStarvation();
- // Apply predators
- applyPredators();
- // Moving common voles
- for(int y = 0; y < FIELD_HEIGHT; y++){
- for(int x = 0; x < FIELD_WIDTH; x++){
- if(fieldOfCommonVoles[y][x].size() > 0){
- for(int i = 0; i < fieldOfCommonVoles[y][x].size(); i++){
- // Make some children
- for(int dy = y - COMMON_VOLE_NEIGHBOURS_Y; dy <= y + COMMON_VOLE_NEIGHBOURS_Y; dy++){
- for(int dx = x - COMMON_VOLE_NEIGHBOURS_X; dx <= x + COMMON_VOLE_NEIGHBOURS_X; dx++){
- if( // If we are within field boundaries
- ((dx >= 0) && (dx < FIELD_WIDTH)) &&
- ((dy >= 0) && (dy < FIELD_HEIGHT)) &&
- fieldOfCommonVoles[dy][dx].size() > 0)
- {
- for(int parentCandidate = 0; parentCandidate < fieldOfCommonVoles[dy][dx].size(); parentCandidate++){
- if(
- fieldOfCommonVoles[y][x].at(i).isMale &&
- fieldOfCommonVoles[y][x].at(i).age >= 3 &&
- !fieldOfCommonVoles[dy][dx].at(parentCandidate).isMale &&
- fieldOfCommonVoles[dy][dx].at(parentCandidate).remainingWeeksOfPregnancy == 0 &&
- fieldOfCommonVoles[dy][dx].at(parentCandidate).age >= 3 &&
- weeks_count >= 12 &&
- weeks_count <= 35
- ){
- // We have found girl to have children with
- fieldOfCommonVoles[dy][dx].at(parentCandidate).remainingWeeksOfPregnancy = 3;
- }
- }
- }
- }
- }
- // Calculate move propabilities for each neighbour
- vector<MovePropability> possibleMoves;
- for(int dy = y - COMMON_VOLE_NEIGHBOURS_Y; dy <= y + COMMON_VOLE_NEIGHBOURS_Y; dy++){
- for(int dx = x - COMMON_VOLE_NEIGHBOURS_X; dx <= x + COMMON_VOLE_NEIGHBOURS_X; dx++){
- if(dx == 0 && dy == 0) continue;
- int nextX = dx, nextY = dy;
- if(nextX < 0) nextX = FIELD_WIDTH - abs(nextX);
- if(nextX > FIELD_WIDTH - 1) nextX = nextX - FIELD_WIDTH;
- if(nextY < 0) nextY = FIELD_HEIGHT - abs(nextY);
- if(nextY > FIELD_HEIGHT - 1) nextY = nextY - FIELD_HEIGHT;
- possibleMoves.push_back((MovePropability){
- .x = nextX,
- .y = nextY,
- .propability = (float)(food[nextY][nextX].available / ((COMMON_VOLE_NEIGHBOURS_X * 2) * (COMMON_VOLE_NEIGHBOURS_Y * 2) - 1.0))
- });
- }
- }
- // Choose THE move
- MovePropability choosedMove = chooseMoveDependingOnPropability(possibleMoves);
- if(choosedMove.propability > 0){
- fieldOfCommonVoles[y][x].at(i).foodSupply = fieldOfCommonVoles[y][x].at(i).foodSupply + 3;
- fieldOfCommonVoles[choosedMove.y][choosedMove.x].push_back(fieldOfCommonVoles[y][x].at(i));
- food[choosedMove.y][choosedMove.x] = (FoodUnit){
- .available = false,
- .timeToRenew = 3
- };
- fieldOfCommonVoles[y][x].erase(fieldOfCommonVoles[y][x].begin() + i);
- }
- }
- }
- }
- }
- printField();
- weeks_count++;
- if(weeks_count >= 50) overcrowded = false;
- weeks_count = weeks_count % 52;
- usleep(500000);
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement