Platformer AI (v0.0.3)

Instructions: This is an experimental Platformer AI (V0.0.3)\n\nShould I release a B.E.T.A. tag game with this AI?\n\nIn this environment, you can edit the 16*16 grid by clicking on the tiles and setting the goal for the AI who will then try to reach it if he can. Any feedback would be very useful, thank you in advance for your help.\n\ninputs :\n - Click the grid to edit the block hovered \n - Press e to set the goal of the AI (put it somewhere \n   accessible for the AI or it won't move, meaning it \n   needs to be touching red lines and have them \n   connecting the AI and the tile you are selecting)\n\nInformation / warning:\n - uses a graphing algorithm \n - uses an A* algorithm \n - The AI core ( engine + movement ) is 700 blocks\n - The movement can clog sometimes I'm working on it.\n    You can simply move the goal somewhere else or edit \n    the block clogging the bot to fix this. \n - The graphing isn't up to date making it so the AI can't \n    fall down from more than 2 blocks. I'm currently \n    thinking about how to implement bigger falls. \n\nHow does it work :\nEach time the level is edited a new graph will be made. The graph is what the lines represent, showing which blocks can access which. Then an A* algorithm is applied to the graph when the goal is set to figure out the fastest path. After that, the AI will use its platformer movement mechanics, a movement that is exactly similar to the ones people use to control their player in platformer games but with the inputs controlled by the AI so he can move left and right as well as jump.  \n\nAim of this experiment :\nMy goal is to add reliable enemies that can challenge the player in all your grid platformers. When this experiment will reach its end scratch will be provided with its very own platformer bot sprite that would be very easy to implement and use in your own projects with simple functions and utility. \n\nLog :\n -v0.0.1\n    Graphing algorithm (not polished)\n    A* algorithm\n    AI movement (not polished)\n\n -v0.0.2\n    Added gap jumping as well as different jump powers\n\n-v0.0.3\n    Added smart jumping\n\nWhat else should I add/fix?

@Stage\n\n@title\n\nwhen flag clicked\nhide\n\n@A* Engine\n\ndefine Create Graph\ndelete all of [graph v]\nset ['index v] to [1]\nrepeat ((length of [map v]) - (1))\n    if <<(item ('index) of [map v]) = (((X lenght) * (Y lenght)) + (1))> and <not <(item (('index) - (X lenght)) of [map v]) = (((X lenght) * (Y lenght)) + (1))>>> then\n        if <(('index) - (X lenght)) > [0]> then\n            add (('index) - (X lenght)) to [graph v]\n        end\n    end\n    change ['index v] by (1)\nend\nset ['index v] to [1]\nrepeat (length of [graph v])\n    set ['ex h v] to [0]\n    repeat until <<('ex h) = [done]> or <('ex h) = [3]>>\n        set ['ex v v] to [0]\n        repeat until <<('ex v) = [done]> or <('ex v) = (letter (('ex h) + (1)) of [321])>>\n            if <<not <(item ((item ('index) of [graph v]) + ((('ex h) * ((X lenght) * (-1))) + (('ex v) + (1)))) of [map v]) = (((X lenght) * (Y lenght)) + (1))>> and < (((item ('index) of [graph v]) + ((('ex h) * (X lenght)) + ('ex v))) / (X lenght)) contains [.]?>> then\n                change ['ex v v] by (1)\n                if <[graph v] contains ((item ('index) of [graph v]) + ((('ex h) * ((X lenght) * (-1))) + ('ex v)))?> then\n                    add [] to [graph v]\n                    set ['rep i v] to [0]\n                    repeat ((length of [graph v]) - (('index) + (1)))\n                        replace item ((length of [graph v]) - ('rep i)) of [graph v] with (item ((length of [graph v]) - (('rep i) + (1))) of [graph v])\n                        change ['rep i v] by (1)\n                    end\n                    replace item (('index) + (1)) of [graph v] with (join [ ] ((item ('index) of [graph v]) + ((('ex h) * ((X lenght) * (-1))) + ('ex v))))\n                    set ['ex v v] to [done]\n                end\n            else\n                set ['ex v v] to [done]\n            end\n        end\n        set ['ex v v] to [0]\n        repeat until <<('ex v) = [done]> or <('ex v) = (letter (('ex h) + (1)) of [321])>>\n            if <<not <(item ((item ('index) of [graph v]) + ((('ex h) * ((X lenght) * (-1))) - (('ex v) + (1)))) of [map v]) = (((X lenght) * (Y lenght)) + (1))>> and < ((((item ('index) of [graph v]) + ((('ex h) * (X lenght)) - ('ex v))) + ((X lenght) - (1))) / (X lenght)) contains [.]?>> then\n                change ['ex v v] by (1)\n                if <[graph v] contains ((item ('index) of [graph v]) + ((('ex h) * ((X lenght) * (-1))) - ('ex v)))?> then\n                    add [] to [graph v]\n                    set ['rep i v] to [0]\n                    repeat ((length of [graph v]) - (('index) + (1)))\n                        replace item ((length of [graph v]) - ('rep i)) of [graph v] with (item ((length of [graph v]) - (('rep i) + (1))) of [graph v])\n                        change ['rep i v] by (1)\n                    end\n                    replace item (('index) + (1)) of [graph v] with (join [ ] ((item ('index) of [graph v]) + ((('ex h) * ((X lenght) * (-1))) - ('ex v))))\n                    set ['ex v v] to [done]\n                end\n            else\n                set ['ex v v] to [done]\n            end\n        end\n        if <not <(item ((item ('index) of [graph v]) + ((('ex h) + (1)) * ((X lenght) * (-1)))) of [map v]) = (((X lenght) * (Y lenght)) + (1))>> then\n            change ['ex h v] by (1)\n        else\n            set ['ex h v] to [done]\n        end\n    end\n    repeat until <not < (item (('index) + (1)) of [graph v]) contains [ ]?>>\n        change ['index v] by (1)\n    end\n    change ['index v] by (1)\nend\ndelete all of ['explored v]\nset ['ex h v] to []\nrepeat until <('ex h) = [done]>\n    set ['ex v v] to [0]\n    repeat until <<<not < (item ('ex v) of [graph v]) contains [ ]?>> and <not <['explored v] contains (item ('ex v) of [graph v])?>>> or <('ex v) = ((length of [graph v]) + (1))>>\n        change ['ex v v] by (1)\n    end\n    set ['index v] to (item ('ex v) of [graph v])\n    if <('ex v) = ((length of [graph v]) + (1))> then\n        set ['ex h v] to [done]\n    else\n        add (item ('ex v) of [graph v]) to ['explored v]\n        delete all of ['down v]\n        change ['ex v v] by (1)\n        repeat until <not < (item ('ex v) of [graph v]) contains [ ]?>>\n            if <([abs v] of (('index) - (item ('ex v) of [graph v])) ) > ((X lenght) - (3))> then\n                add (item ('ex v) of [graph v]) to ['down v]\n            end\n            change ['ex v v] by (1)\n        end\n        set ['ex h v] to [1]\n        repeat (length of ['down v])\n            set ['ex v v] to [0]\n            repeat until <<not < (item ('ex v) of [graph v]) contains [ ]?>> and <(item ('ex v) of [graph v]) = (item ('ex h) of ['down v])>>\n                change ['ex v v] by (1)\n            end\n            add [] to [graph v]\n            set ['rep i v] to [0]\n            repeat ((length of [graph v]) - (('ex v) + (1)))\n                replace item ((length of [graph v]) - ('rep i)) of [graph v] with (item ((length of [graph v]) - (('rep i) + (1))) of [graph v])\n                change ['rep i v] by (1)\n            end\n            replace item (('ex v) + (1)) of [graph v] with (join [ ] ('index))\n            change ['ex h v] by (1)\n        end\n    end\nend\n\nwhen I receive [new map v]\nClean Map\nCreate Graph\nCreate Gap\nCreate Path\nbroadcast (Draw arrows v)\n\ndefine Create Gap\nreset timer\ndelete all of ['anchor v]\nset ['index v] to [1]\nif <<[graph v] contains (End)?> and <[graph v] contains (Start)?>> then\n    add (End) to ['anchor v]\n    repeat until <<<<('index) = [done]> or <('index) = (length of [graph v])>> or <(length of ['anchor v]) = [0]>> or <(timer) > [0.1]>>\n        set ['ex h v] to (length of ['anchor v])\n        set ['rep i v] to [1]\n        repeat (length of ['anchor v])\n            set ['ex v v] to [1]\n            repeat until <<(item ('ex v) of [graph v]) = (item ('rep i) of ['anchor v])> and <not < (item ('ex v) of [graph v]) contains [ ]?>>>\n                change ['ex v v] by (1)\n            end\n            change ['ex v v] by (1)\n            repeat until <<not < (item ('ex v) of [graph v]) contains [ ]?>> or <('index) = [done]>>\n                if <(item (item ('ex v) of [graph v]) of [map v]) = [0]> then\n                    replace item (item ('ex v) of [graph v]) of [map v] with ('index)\n                    add (item ('ex v) of [graph v]) to ['anchor v]\n                    change ['index v] by (1)\n                else\n                    if <(item ('ex v) of [graph v]) = (Start)> then\n                        set ['index v] to [done]\n                    end\n                end\n                change ['ex v v] by (1)\n            end\n            change ['rep i v] by (1)\n        end\n        repeat ('ex h)\n            delete (1) of ['anchor v]\n        end\n    end\nend\n\ndefine Clean Map\nset ['index v] to [0]\nrepeat (length of [map v])\n    if <([abs v] of (item ('index) of [map v]) ) < ((X lenght) * (Y lenght))> then\n        replace item ('index) of [map v] with [0]\n    end\n    change ['index v] by (1)\nend\n\ndefine Create Path\nreset timer\ndelete all of [path v]\nif <<[graph v] contains (Start)?> and <[graph v] contains (End)?>> then\n    add (join [ ] (Start)) to [path v]\n    set ['index v] to [1]\n    repeat until <<<('index) = [done]> or <('index) = (length of [graph v])>> or <(timer) > [0.1]>>\n        set ['ex v v] to [1]\n        repeat until <<(item ('ex v) of [graph v]) = (item (length of [path v]) of [path v])> and <not < (item ('ex v) of [graph v]) contains [ ]?>>>\n            change ['ex v v] by (1)\n        end\n        change ['ex v v] by (1)\n        set ['rep i v] to []\n        repeat until <not < (item ('ex v) of [graph v]) contains [ ]?>>\n            if <<(item (item (length of [path v]) of [path v]) of [map v]) > (item (item ('ex v) of [graph v]) of [map v])> and <not <(item (item ('ex v) of [graph v]) of [map v]) = [0]>>> then\n                set ['rep i v] to (item ('ex v) of [graph v])\n            end\n            change ['ex v v] by (1)\n        end\n        if <(item ('rep i) of [map v]) = ((((X lenght) * (Y lenght)) + (1)) * (-1))> then\n            set ['index v] to [done]\n            add (End) to [path v]\n        else\n            if <('rep i) = []> then\n                set ['index v] to [done]\n            else\n                add ('rep i) to [path v]\n                change ['index v] by (1)\n            end\n        end\n    end\nend\n\n@Render\n\ndefine Create Map\ndelete all of [path v]\ndelete all of [map v]\nshow\nswitch costume to (big v)\nset size to (70) %\nset [size v] to (((size) * (30)) / (100))\nswitch costume to (1 v)\ngo to x: ((((X lenght) + (-1)) * (Size)) / (-2)) y: ((((Y lenght) + (-1)) * (Size)) / (2))\nset ['grid v] to [1]\nrepeat ((Y lenght) - (1))\n    repeat (X lenght)\n        create clone of (_myself_ v)\n        change x by (Size)\n        change ['grid v] by (1)\n        add [0] to [map v]\n    end\n    change y by ((Size) * (-1))\n    set x to ((((X lenght) + (-1)) * (Size)) / (-2))\nend\nrepeat (X lenght)\n    create clone of (_myself_ v)\n    change x by (Size)\n    change ['grid v] by (1)\n    add (((X lenght) * (Y lenght)) + (1)) to [map v]\nend\nswitch costume to (big v)\nhide\nadd (((X lenght) * (Y lenght)) + (1)) to [map v]\n\nwhen I start as a clone\nset ['grid v] to ('Grid)\nif <('Grid) < (((X lenght) * (Y lenght)) - ((X lenght) - (1)))> then\n    forever\n        if <touching (mouse-pointer v)?> then\n            set [ghost v] effect to (70)\n            if <<mouse down?> = [true]> then\n                if <not <(item ('Grid) of [map v]) = (((X lenght) * (Y lenght)) + (1))>> then\n                    replace item ('Grid) of [map v] with (((X lenght) * (Y lenght)) + (1))\n                else\n                    replace item ('Grid) of [map v] with [0]\n                end\n                wait until <<mouse down?> = [false]>\n                set [edit v] to [no]\n            end\n            if <key (e v) pressed?> then\n                if <(item ('Grid) of [map v]) < ((X lenght) * (Y lenght))> then\n                    replace item (item # of ((((X lenght) * (Y lenght)) + (1)) * (-1)) in [map v]) of [map v] with [0]\n                    replace item ('Grid) of [map v] with ((((X lenght) * (Y lenght)) + (1)) * (-1))\n                    set [end v] to ('Grid)\n                else\n                    delete all of [path v]\n                end\n                if <(Start) = ('Grid)> then\n                    set [start v] to []\n                end\n                wait until <not <key (e v) pressed?>>\n                set [edit v] to [no]\n            end\n        else\n            set [ghost v] effect to (100)\n        end\n        Actions\n    end\nelse\n    set [brightness v] effect to (-40)\n    set [ghost v] effect to (70)\nend\n\ndefine Actions\nset [color v] effect to (0)\nif <([abs v] of (item ('Grid) of [map v]) ) > ((X lenght) * (Y lenght))> then\n    set [ghost v] effect to (70)\n    if <(Start) = ('Grid)> then\n        set [color v] effect to (0)\n    else\n        if <(End) = ('Grid)> then\n            set [color v] effect to (80)\n        else\n            set [brightness v] effect to (-40)\n        end\n    end\nelse\n    set [brightness v] effect to (0)\n    set [color v] effect to (0)\nend\nbroadcast (New map v)\n\ndefine Arrows\npen up\nerase all\nset ['index v] to [1]\nrepeat (length of [graph v])\n    if <not < (item ('index) of [graph v]) contains [ ]?>> then\n        set ['anchor v] to (item ('index) of [graph v])\n    else\n        set ['aim v] to (item ('index) of [graph v])\n        if <<[path v] contains ('aim)?> and <(item ((item # of ('aim) in [path v]) + (1)) of [path v]) = ('anchor)>> then\n            set pen color to (#47da2a)\n            set pen (transparency v) to (80)\n        else\n            set pen color to (#e8391a)\n            set pen (transparency v) to (90)\n        end\n        pen up\n        go to x: (((((X lenght) + (-1)) * (Size)) / (-2)) + (((('anchor) - (1)) mod (X lenght)) * (Size))) y: (((((Y lenght) + (1)) * (Size)) / (2)) - ((round ((('anchor) + ((X lenght) - ((('anchor) - (1)) mod (X lenght)))) / (X lenght))) * (Size)))\n        pen down\n        go to x: (((((X lenght) + (-1)) * (Size)) / (-2)) + (((('aim) - (1)) mod (X lenght)) * (Size))) y: (((((Y lenght) + (1)) * (Size)) / (2)) - ((round ((('aim) + ((X lenght) - ((('aim) - (1)) mod (X lenght)))) / (X lenght))) * (Size)))\n        pen up\n        set pen size to (2)\n    end\n    change ['index v] by (1)\nend\n\nwhen I receive [draw arrows v]\nif <(costume [name v]) = [big]> then\n    Arrows\nend\n\nwhen flag clicked\nset [end v] to []\nset [start v] to []\nset [edit v] to [no]\nset [x lenght v] to [16]\nset [y lenght v] to [16]\nCreate Map\n\nwhen I start as a clone\nforever\n    if <(Start) = ('Grid)> then\n        replace item (item # of (((X lenght) * (Y lenght)) + (2)) in [map v]) of [map v] with [0]\n        replace item ('Grid) of [map v] with (((X lenght) * (Y lenght)) + (2))\n    end\nend\n\n@AI\n\ndefine Move (x) (y)\nrepeat ([abs v] of (x) )\n    change x by (((x) / ([abs v] of (x) )) * (1))\n    if <touching color (#cdcdcd)?> then\n        change x by (((x) / ([abs v] of (x) )) * (-1))\n        set ['x velocity v] to [0]\n    end\nend\nchange x by (((x) / ([abs v] of (x) )) * (-1))\nrepeat ([abs v] of (y) )\n    change y by (((y) / ([abs v] of (y) )) * (1))\n    if <touching color (#cdcdcd)?> then\n        change y by (((y) / ([abs v] of (y) )) * (-1))\n        set ['y velocity v] to [0]\n        set ['jump v] to [1]\n    end\nend\n\nwhen flag clicked\nshow\ngo to x: (-133) y: (0)\nset ['x velocity v] to [0]\nset ['y velocity v] to [0]\nset ['x next v] to [0]\nset ['y next v] to [0]\nforever\n    Locate\n    Prompt\n    Execute\nend\n\ndefine Execute\nMove ('X velocity) ('Y velocity)\n\ndefine Prompt\nchange y by (1)\nif <touching color (#cdcdcd)?> then\n    change ['y velocity v] by (-1)\n    change y by (-1)\nelse\n    change ['y velocity v] by (-1)\nend\nif <(length of [path v]) > [1]> then\n    if <('X next) > (x position)> then\n        if <('X velocity) < [5]> then\n            change ['x velocity v] by (1)\n        end\n        if <('jump) = [1]> then\n            if <<(('Y next) - (y position)) > (Size)> or <<([abs v] of (('X next) - (x position)) ) > ((1.5) * (Size))> and <(('Y next) - (y position)) > [0]>>> then\n                Jump\n            end\n        end\n    else\n        if <[-5] < ('X velocity)> then\n            change ['x velocity v] by (-1)\n        end\n        if <('jump) = [1]> then\n            if <<(('Y next) - (y position)) > (Size)> or <<([abs v] of (('X next) - (x position)) ) > ((1.5) * (Size))> and <(('Y next) - (y position)) > [0]>>> then\n                Jump\n            end\n        end\n    end\nelse\n    change ['x velocity v] by ((('X velocity) / ([abs v] of ('X velocity) )) * (-1))\nend\nset ['jump v] to [0]\n\ndefine Locate\nset ['x center v] to (((((round ((((x position) * (-1)) + ((Size) / (2))) / (Size))) * (Size)) / ((Size) * (-1))) + ((X lenght) / (2))) + (1))\nset ['y center v] to ((((((round ((((y position) * (-1)) + ((Size) / (2))) / (Size))) * (Size)) / (Size)) + ((X lenght) / (2))) * (X lenght)) - (X lenght))\nif <(('X center) + ('Y center)) = (End)> then\n    set [start v] to (('X center) + ('Y center))\n    set [end v] to []\n    set ['x next v] to [0]\n    set ['y next v] to [0]\nelse\n    if <[graph v] contains (('X center) + ('Y center))?> then\n        set [start v] to (('X center) + ('Y center))\n        set ['x next v] to (((((X lenght) + (-1)) * (Size)) / (-2)) + ((((item (2) of [path v]) - (1)) mod (X lenght)) * (Size)))\n        set ['y next v] to (((((Y lenght) + (1)) * (Size)) / (2)) - ((round (((item (2) of [path v]) + ((X lenght) - (((item (2) of [path v]) - (1)) mod (X lenght)))) / (X lenght))) * (Size)))\n    end\nend\n\nwhen flag clicked\nset size to (((Size) * (100)) / (30)) %\n\ndefine Jump\nif <not <(End) = []>> then\n    if <((('X next) - (x position)) * ('X velocity)) > [0]> then\n        if <(('Y next) - (y position)) > ((Size) * (2))> then\n            set ['y velocity v] to [8]\n        else\n            if <(('Y next) - (y position)) < ((Size) * (0.20))> then\n                set ['y velocity v] to [5]\n            else\n                set ['y velocity v] to [6]\n            end\n        end\n    end\nend\n\n