// // Genetic Algorithm Example // Strategy board game war. Units(2-blue) try to capture the target(4-white/yellow) objective // and eliminate the enemy units(3-red) // // A random movement phase is executed. Here a random spot is selected on the map // if there is a movable unit than this is moved in any direction. If the new position // is a enemy than this enemy is taken out. The objective can also be captured. // // There are MAX_CODE of moves per set. Then a score is calculated based on how // close the units are to the GOAL(4) and how many enemies are destroyed(3) and if // the GOAL(4) has been captured. // There are MAX_ARC amount of moves per set stored. The top 3 scoring runs get // copied and these copies get mutated so they might score better. Also a number // of random new runs are added. // // The process of simulating the moves and scoring and mutating is done MAX_RUNS amount of times. // The final top scoring set of moves is played on the canvas. // // Better scoring could be done by storing the amount of move taken to take out x enemy units and capturing target. // // Building on this you might change the amount of units for each side. maybe mod the amount of goals to be captured. // In a real game you might use this to simulate if a war for a ai player would be doable in a certain tested setting like this. // // Create unit types with different att and def, more scoring with 1+units attacking at the same time. // add scoring in the execute script stage : units stay close to each other, direct path to target etc. // If move on enemy position (chance of being destroyed itself(.5) .25 if more units of own side are nearby) #include "raylib.h" #include #define MAX_RUNS 150 #define MAX_CODE 1500 #define MAX_ARC 64 enum terrain{TREE=1,GROUND=0,AIPLAYER1=2,AIPLAYER2=3,GOAL=4,GOALREACHED=5}; enum flag{UP,DOWN,LEFT,RIGHT,WAIT}; //1=border,2=ai unit,3=defensiveunit,4=objective int map1[10][10] = { {1,1,1,1,1,1,1,1,1,1}, {1,0,0,0,0,0,0,0,0,1}, {1,0,0,0,0,0,3,4,0,1}, {1,0,0,3,0,0,0,0,0,1}, {1,0,0,0,0,0,3,0,0,1}, {1,2,0,0,0,0,0,3,0,1}, {1,0,2,0,0,0,0,0,0,1}, {1,0,2,2,0,0,0,0,0,1}, {1,0,0,0,0,0,0,0,0,1}, {1,1,1,1,1,1,1,1,1,1} }; int map[10][10] = {0}; typedef struct code{ Vector2 position; Vector2 move; }code; static struct code arr_code[MAX_CODE]; typedef struct codearc{ Vector2 position[MAX_CODE]; Vector2 move[MAX_CODE]; int score; }codearc; static struct codearc arr_codearc[MAX_ARC]; static struct codearc arr_temparc[MAX_ARC]; int getscore(); void executescript(); void storescript(int z,int score); void sortarc();//copy top 3 to max-5 void mutateandnew(); void geneticalgorithm(); static float distance(float x1,float y1,float x2,float y2); static float edistance(float x1,float y1,float x2,float y2); int screenWidth; int screenHeight; int tileWidth,tileHeight,mapWidth,mapHeight; int main(void) { // Initialization //-------------------------------------------------------------------------------------- screenWidth = 800; screenHeight = 600; mapWidth = 10; mapHeight = 10; tileWidth = ceil((float)screenWidth/(float)mapWidth); tileHeight = ceil((float)screenHeight/(float)mapHeight); InitWindow(screenWidth, screenHeight, "raylib example."); SetTargetFPS(120); // Set our game to run at 60 frames-per-second //-------------------------------------------------------------------------------------- geneticalgorithm(); int playposition=0; // Main game loop while (!WindowShouldClose()) // Detect window close button or ESC key { // Update //---------------------------------------------------------------------------------- if(IsKeyPressed(KEY_SPACE)|| playposition>MAX_CODE-2){ geneticalgorithm(); playposition=0; } if(playposition==0){ // restore map for(int y=0;y<10;y++){ for(int x=0;x<10;x++){ map[y][x]=map1[y][x]; }} } // execute script if(map[ (int)arr_code[playposition].position.y ][ (int)arr_code[playposition].position.x ]==AIPLAYER1){ Vector2 p=arr_code[playposition].position; Vector2 m=arr_code[playposition].move; Vector2 np=(Vector2){p.x+m.x,p.y+m.y}; if(map[ (int)np.y ][ (int)np.x ]==GOAL){ map[ (int)np.y ][ (int)np.x ] = GOALREACHED; } if(map[ (int)np.y ][ (int)np.x ]==GROUND){ map[ (int)np.y ][ (int)np.x ] = AIPLAYER1; map[ (int)p.y ][ (int)p.x ] = GROUND; } if(map[ (int)np.y ][ (int)np.x ]==AIPLAYER2){ map[ (int)np.y ][ (int)np.x ] = AIPLAYER1; map[ (int)p.y ][ (int)p.x ] = GROUND; } } playposition+=1; if(playposition>MAX_CODE-1){ playposition=0; } //---------------------------------------------------------------------------------- // Draw //---------------------------------------------------------------------------------- BeginDrawing(); ClearBackground(RAYWHITE); //drawmap for(int y=0;y<10;y++){ for(int x =0;x<10;x++){ int m=map[y][x]; if(m==TREE){ DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,(Color){40,90,20,255}); DrawCircle(x*tileWidth+tileWidth/1.5,y*tileHeight+tileHeight/1.5,tileWidth/5,(Color){20,50,20,255}); DrawRectangle(x*tileWidth+tileWidth/2.2,y*tileHeight+tileHeight/2,tileWidth/8,tileHeight/3,BROWN); DrawCircle(x*tileWidth+tileWidth/2,y*tileHeight+tileHeight/3,tileWidth/4,(Color){120,250,20,255}); DrawCircle(x*tileWidth+tileWidth/2.2,y*tileHeight+tileHeight/4,tileWidth/9,(Color){220,255,220,155}); } if(m==GROUND){ DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,DARKGREEN); DrawRectangle(x*tileWidth+5,y*tileHeight+10,2,1,GREEN); DrawRectangle(x*tileWidth+tileWidth/6,y*tileHeight+tileHeight/6,2,1,GREEN); DrawRectangle(x*tileWidth+tileWidth/1.5,y*tileHeight+tileHeight/1.5,2,1,GREEN); DrawRectangle(x*tileWidth+tileWidth/2,y*tileHeight+tileHeight/2,2,1,GREEN); } if(m==AIPLAYER1){ DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,BLUE); DrawText("AI_Player",x*tileWidth,y*tileHeight+tileHeight/4,16,BLACK); } if(m==AIPLAYER2){ DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,RED); DrawText("F",x*tileWidth+tileWidth/3,y*tileHeight+tileHeight/4,40,WHITE); } if(m==GOAL){ DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,WHITE); DrawText("City",x*tileWidth+tileWidth/4,y*tileHeight+tileHeight/4,26,BLACK); } if(m==GOALREACHED){ DrawRectangle(x*tileWidth,y*tileHeight,tileWidth,tileHeight,YELLOW); DrawText("Captured",x*tileWidth+4,y*tileHeight+tileHeight/4,16,BLACK); } } } DrawText("Press space for new simulation.(Autorun=on)",10,10,26,BLACK); DrawText("Press space for new simulation.(Autorun=on)",9,9,26,WHITE); /* int c=0; for(int y=0;y<40;y++){ for(int x=0;x<5;x++){ if(c0 && currentpos<3){ for(int i=0;i4)allclose=false; } if(allclose==true)score+=100; //score=avdist; if(score<0)score=9999; return score; } void executescript(){ // execute script for(int i=0;i