{"id":824,"date":"2020-12-15T12:24:59","date_gmt":"2020-12-15T11:24:59","guid":{"rendered":"https:\/\/oussamaameur.fr\/?p=824"},"modified":"2020-12-15T15:46:52","modified_gmt":"2020-12-15T14:46:52","slug":"code-from-my-doodle-jump-genetic-algorithm","status":"publish","type":"post","link":"https:\/\/oussamaameur.fr\/index.php\/2020\/12\/15\/code-from-my-doodle-jump-genetic-algorithm\/","title":{"rendered":"Code from my Doodle Jump Genetic Algorithm"},"content":{"rendered":"\n<div class=\"wp-block-uagb-advanced-heading uagb-block-cd39f43d\" id=\"Game_Functions\"><h2 class=\"uagb-heading-text\">Game Functions<\/h2><div class=\"uagb-separator-wrap\"><div class=\"uagb-separator\"><\/div><\/div><p class=\"uagb-desc-text\"><\/p><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"atomic\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">void spawn_players(PLAY** players_list)\n{\n\tfor (int index=0;index&lt;numberPlayers; index++)\n\t{\n\t\tplayers_list[index]->Xpos=215;\n\t\tplayers_list[index]->Ypos=120;\n\t\tplayers_list[index]->score=0;\n\t\tplayers_list[index]->jump=10; \/\/Arbitrary value that can't be obtain naturally in the program\n\t\tplayers_list[index]->jumpTime=0;\n\t\tplayers_list[index]->alive=TRUE;\n\t\tplayers_list[index]->keyboard=0;\n\t\tfor (int index2=0; index2&lt;3; index2++)\n\t\t{\n\t\t\tplayers_list[index]->color[index2]=random_int_generator(0,255);\n\t\t}\n\t}\n}\n\n\nvoid move_player(PLAY* player)\n{\n\tif (player->keyboard==0) \/\/No movements\n\t{\n\t\tplayer->Xpos=player->Xpos;\n\t}\n\tif (player->keyboard==1 &amp;&amp; player->Xpos+50&lt;largeurFenetre()) \/\/ to right\n\t{\n\t\tplayer->Xpos=player->Xpos+lateralSpeed;\n\t}\n\tif (player->keyboard==2 &amp;&amp; player->Xpos>0)\t\/\/to left\n\t{\n\t\tplayer->Xpos=player->Xpos-lateralSpeed;\n\t}\n}\n\n\nvoid platform_bounce(PLAY* player, PLA** platforms_list)\n{\n\tfor (int index=0;index&lt;6;index++)\n\t{\n\t\tif ((((platforms_list[index]->Ypos)+15&lt;=player->Ypos)&amp;&amp;((platforms_list[index]->Ypos)+25>=player->Ypos))&amp;&amp;(((platforms_list[index]->Xpos)-48&lt;=player->Xpos)&amp;&amp;((platforms_list[index]->Xpos)+69>=player->Xpos)))\n\t\t{\n\t\t\tplayer->jump=index;\n\t\t\tplayer->Ypos=player->Ypos+jumpSpeed;\n\t\t\tplayer->jumpTime=1;\n\t\t    score_up(player);\n\t\t\tbreak;\n\t\t}\n\t}\n\tif (player->jumpTime!=0)\n\t{\n\t\tplayer->Ypos=player->Ypos+jumpSpeed;\n\t\tplayer->jumpTime=player->jumpTime+1;\n\t\tif (player->jumpTime>=40)\n\t\t{\n\t\t\tplayer->jumpTime=0;\n\t\t}\n\t\trafraichisFenetre();\n\t}\n\telse\n\t{\n\t\tplayer->Ypos=player->Ypos-fallSpeed;\n\t\trafraichisFenetre();\n\t}\n}\n\n\nvoid score_up(PLAY* player)\n{\n\tplayer->score=player->score+1;\n}\n\n\nint death_player(PLAY* player, int playersCount)\n{\n\tif (player->Ypos&lt;=0)\n\t{\n\t\tplayer->alive=FALSE;\n\t\tplayersCount=playersCount-1;\n\t}\n\treturn(playersCount);\n}\n<\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-0c345129\" id=\"Genome\"><h2 class=\"uagb-heading-text\">Genome<\/h2><div class=\"uagb-separator-wrap\"><div class=\"uagb-separator\"><\/div><\/div><p class=\"uagb-desc-text\"><\/p><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"atomic\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">PLAY** malloc_players_list(void)\n{\n\tPLAY** players_list;\n\tplayers_list=(PLAY**)malloc(sizeof(PLAY*)*numberPlayers);\n\tfor (int index=0; index&lt;numberPlayers; index++)\n\t{\n\t\tplayers_list[index]=(PLAY*)malloc(sizeof(PLAY));\n\t}\n    spawn_players(players_list);\n    for (int index=0; index&lt;numberPlayers; index++)\n\t{   for (int indexDepth=0; indexDepth&lt;3; indexDepth++)\n        {\n            for (int indexLine=0; indexLine&lt;3;indexLine++)\n            {\n                for (int indexColumn=0; indexColumn&lt;3;indexColumn++)\n                {\n                    players_list[index]->genome[indexDepth][indexLine][indexColumn]=random_float_generator(1);\n                }\n            }\n        }\n\t}\n\treturn(players_list);\n}<\/pre>\n\n\n\n<div class=\"wp-block-uagb-advanced-heading uagb-block-2548e167\" id=\"Crossovers_Mutations\"><h2 class=\"uagb-heading-text\">Crossovers and Mutations<\/h2><div class=\"uagb-separator-wrap\"><div class=\"uagb-separator\"><\/div><\/div><p class=\"uagb-desc-text\"><\/p><\/div>\n\n\n\n<pre class=\"EnlighterJSRAW\" data-enlighter-language=\"c\" data-enlighter-theme=\"atomic\" data-enlighter-highlight=\"\" data-enlighter-linenumbers=\"\" data-enlighter-lineoffset=\"\" data-enlighter-title=\"\" data-enlighter-group=\"\">PLAY crossover(PLAY** players_list)\n{\n    PLAY playerTempo; \/\/Used to easily return the nex genome at the end of the function\n    int mask[3][3][3];\n    int maskInverted[3][3][3];\n    int indexPlayer1;\n    int indexPlayer2;\n    \/\/ generation of a random mask\n    for (int indexDepth=0; indexDepth&lt;3; indexDepth++)\n    {\n        for (int indexLine=0;indexLine&lt;3;indexLine++)\n        {\n            for (int indexColumn=0; indexColumn&lt;3; indexColumn++)\n            {\n                mask[indexDepth][indexLine][indexColumn]=random_int_generator(0,1);\n            }\n        }\n    }\n    \/\/ creation of an inverted mask\n    for (int indexDepth=0; indexDepth&lt;3; indexDepth++)\n    {\n        for (int indexLine=0;indexLine&lt;3;indexLine++)\n        {\n            for (int indexColumn=0; indexColumn&lt;3; indexColumn++)\n            {\n                switch(mask[indexDepth][indexLine][indexColumn])\n                {\n                    case 0:\n                        maskInverted[indexDepth][indexLine][indexColumn]=1;\n                        break;\n\n                    case 1:\n                        maskInverted[indexDepth][indexLine][indexColumn]=0;\n                        break;\n                        \n                }\n            }\n        }\n    }\n    \/\/Selection of the two best players by their score\n    indexPlayer1=0;\n    indexPlayer2=1;\n    for (int index=0;index&lt;numberPlayers;index++)\n    {\n        if ((players_list[indexPlayer1]->score&lt;=players_list[index]->score)&amp;&amp;(players_list[index]->score!=players_list[indexPlayer2]->score))\n        {\n            indexPlayer1=index;\n        }\n        if ((players_list[indexPlayer2]->score&lt;=players_list[index]->score)&amp;&amp;(players_list[index]->score!=players_list[indexPlayer1]->score))\n        {\n            indexPlayer2=index;\n        }\n    }\n    \/\/Application of the mask\n    for (int indexDepth=0; indexDepth&lt;3; indexDepth++)\n    {\n        for (int indexLine=0;indexLine&lt;3;indexLine++)\n        {\n            for (int indexColumn=0;indexColumn&lt;3;indexColumn++)\n            {\n                playerTempo.genome[indexDepth][indexLine][indexColumn]=((players_list[indexPlayer1]->genome[indexDepth][indexLine][indexColumn])*(mask[indexDepth][indexLine][indexColumn])+(players_list[indexPlayer2]->genome[indexDepth][indexLine][indexColumn])*(maskInverted[indexDepth][indexLine][indexColumn]));\n            }\n        }\n    }\n    return(playerTempo);\n}\n\n\nvoid mutation(PLAY** players_list)\n{\n    int mutationsNumber;\n    int randomDepthIndex;\n    int randomLineIndex;\n    int randomColumnIndex;\n    int mutationChances;\n    float slightMutationTemp;\n    mutationsNumber=random_int_generator(2,10); \/\/Random selection of the number of potential mutations\n    int toMutateIndexes[mutationsNumber-1];\n    for (int index=0; index&lt;mutationsNumber-1; index++)\n    {\n        toMutateIndexes[index]=random_int_generator(0, numberPlayers-1); \/\/Random selection of the player to potentially mutate\n    }\n    for (int index=0; index&lt;mutationsNumber-1; index++)\n    {\n        randomLineIndex=random_int_generator(0,2); \/\/Those three are for choosing randomly a\n        randomColumnIndex=random_int_generator(0,2); \/\/ gene from a player and mutate it\n        randomDepthIndex=random_int_generator(0,2);\n        mutationChances=random_int_generator(0,2);\n        switch(mutationChances)\n        {\n            case 0: \/\/no mutations\n                break;\n            \n            case 1: \/\/Slight mutation, adapted from the algogen one\n                slightMutationTemp=(random_float_generator(1)-0.05)+(players_list[toMutateIndexes[index]]->genome[randomDepthIndex][randomLineIndex][randomColumnIndex]);\n                if (slightMutationTemp&lt;=0)\n                {\n                    slightMutationTemp=0;\n                }\n                if (slightMutationTemp>=1)\n                {\n                    slightMutationTemp=1;\n                }\n                players_list[toMutateIndexes[index]]->genome[randomDepthIndex][randomLineIndex][randomColumnIndex]=slightMutationTemp;        \n                break;\n            \n            case 2: \/\/Random mutation\n                players_list[toMutateIndexes[index]]->genome[randomDepthIndex][randomLineIndex][randomColumnIndex]=random_float_generator(1);\n                break;\n        }\n\n    }\n}\n\n\nint natural_selection(PLAY** players_list)\n{\n    PLAY storeNewGenome;\n    int minimalValue;\n    int mediumValue;\n    int maximalValue;\n    int playersExtinction; \/\/Used to print the number of changed players\n    playersExtinction=0;\n    storeNewGenome=crossover(players_list);\n    minimalValue=32000; \/\/Arbitrary value that can't be reach by a mistrained player\n    maximalValue=0;\n    \/\/Determination of a medium score value\n    for (int index=0; index&lt;numberPlayers;index++)\n    {\n        if (players_list[index]->score&lt;=minimalValue)\n        {\n            minimalValue=players_list[index]->score;\n        }\n        if (players_list[index]->score>=maximalValue)\n        {\n            maximalValue=players_list[index]->score;\n        }\n    }\n    mediumValue=(0.99*maximalValue-1.22*minimalValue)\/2; \/\/Values chosen after some tests\n    \/\/Determination of all the indexes of players whose genomes must be changed by the crossover one and replacement of those genomes\n    for (int index=0; index&lt;numberPlayers;index++)\n    {\n        if (players_list[index]->score&lt;mediumValue)\n        {\n            for (int indexDepth=0; indexDepth&lt;3; indexDepth++)\n            {\n                for (int indexLine=0;indexLine&lt;3;indexLine++)\n                {\n                    for (int indexColumn=0;indexColumn&lt;3;indexColumn++)\n                    {\n                        players_list[index]->genome[indexDepth][indexLine][indexColumn]=storeNewGenome.genome[indexDepth][indexLine][indexColumn];\n                    }\n                }\n            }\n            playersExtinction=playersExtinction+1;\n        }\n    }\n    mutation(players_list);\n    return(playersExtinction);\n}<\/pre>\n","protected":false},"excerpt":{"rendered":"","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"open","sticky":false,"template":"","format":"standard","meta":{"_editorskit_title_hidden":false,"_editorskit_reading_time":2,"_editorskit_typography_data":[],"_editorskit_blocks_typography":"","_editorskit_is_block_options_detached":false,"_editorskit_block_options_position":"{}"},"categories":[1],"tags":[],"uagb_featured_image_src":{"full":false,"thumbnail":false,"medium":false,"medium_large":false,"large":false,"1536x1536":false,"2048x2048":false,"post-thumbnail":false,"my-music-band-archive-top":false,"my-music-band-hero":false,"my-music-band-featured":false,"my-music-band-slider":false,"my-music-band-testimonial":false},"uagb_author_info":{"display_name":"AMEUR Oussama","author_link":"https:\/\/oussamaameur.fr\/index.php\/author\/admin4276\/"},"uagb_comment_info":1,"uagb_excerpt":null,"_links":{"self":[{"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/posts\/824"}],"collection":[{"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/comments?post=824"}],"version-history":[{"count":9,"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/posts\/824\/revisions"}],"predecessor-version":[{"id":864,"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/posts\/824\/revisions\/864"}],"wp:attachment":[{"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/media?parent=824"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/categories?post=824"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/oussamaameur.fr\/index.php\/wp-json\/wp\/v2\/tags?post=824"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}