There's really no such thing as simple pathfinding. You generally stuck with needing some kind of recursion. I have found a way to do it without recursion in a generally straight-forward way. You have to essentially cover the entire field with ghosted rectangles, in which every rectangle can get to any point in an adjacent rectangle using a straight-line path.
Example (gray spots are walls, colored rectangles are the "invisible" rectangles):
Then, to circumvent the recursion algorithm, you have to manually create a list of "if I am in rectangle X and I want to get to rectangle Y, I should point at rectangle Z". Once the sprite is in the rectangle it wants to be in, it can take a straight-line path to the exact point. This approach can take a very long time to program if you have a lot of rectangles, but it gets the job done.
Edit: the ability to import lists can come in handy, as it is easier to type up these incredibly long lists than to manually create them.
Last edited by MoreGamesNow (2012-08-18 12:05:19)
Offline
If it always takes the same path, you can also set the exact path. Not true AI though.
Example:
when gf clicked if <(level) = [1]> set [alive v] to (1) go to x: (0) y: (0) show repeat until <(alive) = [0]> glide [1] secs to x: (5) y: (0) glide [1] secs to x: (5) y: (5) glide [1] secs to x: (0) y: (5) glide [1] secs to x: (0) y: (0) end hide end
Offline
All AIs are different. Try this.
forever //Replace this with your loop... delete (all v) of [paths v] change x by (20) //Width of path. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change x by (-20) //Width of path, negative. change y by (-20) //Width of path, negative. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change y by (20) //Width of path. change x by (-20) //Width of path, negative. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change x by (20) //Width of path. change y by (20) //Width of path. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change y by (-20) //Width of path, negative. delete (all v) of [directions v] add [1] to [directions v] add [2] to [directions v] add [3] to [directions v] add [4] to [directions v] set [sorted v] to [0] repeat until <(sorted) = [1]> set [sorted v] to [1] set [counter v] to [1] repeat (3) if <(item (counter) of [paths v]) > (item ((counter) + (1)) of [paths v])> set [sorted v] to [0] set [temp v] to (item ((counter) + (1)) of [paths v]) replace item ((counter) + (1)) of [paths v] with (item (counter) of [paths v]) replace item (counter) of [paths v] with (temp) set [temp v] to (item ((counter) + (1)) of [directions v]) replace item ((counter) + (1)) of [directions v] with (item (counter) of [directions v]) replace item (counter) of [directions v] with (temp) end change [counter v] by [1] end point in direction ((90) * (item (1 v) of [directions v])) move (20) steps //Width of path. point in direction (90 v) end
Offline
BirdByte wrote:
All AIs are different. Try this.
forever //Replace this with your loop... delete (all v) of [paths v] change x by (20) //Width of path. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change x by (-20) //Width of path, negative. change y by (-20) //Width of path, negative. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change y by (20) //Width of path. change x by (-20) //Width of path, negative. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change x by (20) //Width of path. change y by (20) //Width of path. if <touching [walls v]?> add [100000] to [paths v] else add (distance to [player v]) to [paths v] end change y by (-20) //Width of path, negative. delete (all v) of [directions v] add [1] to [directions v] add [2] to [directions v] add [3] to [directions v] add [4] to [directions v] set [sorted v] to [0] repeat until <(sorted) = [1]> set [sorted v] to [1] set [counter v] to [1] repeat (3) if <(item (counter) of [paths v]) > (item ((counter) + (1)) of [paths v])> set [sorted v] to [0] set [temp v] to (item ((counter) + (1)) of [paths v]) replace item ((counter) + (1)) of [paths v] with (item (counter) of [paths v]) replace item (counter) of [paths v] with (temp) set [temp v] to (item ((counter) + (1)) of [directions v]) replace item ((counter) + (1)) of [directions v] with (item (counter) of [directions v]) replace item (counter) of [directions v] with (temp) end change [counter v] by [1] end end point in direction ((90) * (item (1 v) of [directions v])) move (20) steps //Width of path. point in direction (90 v) end
Oops! Fixed. Use this one instead.
Offline
2 things ,1, thank you very much ,if i make a project with this i will give a very high credit to you and 2 can anyone please explain this script in detail
Offline
Jodymoses wrote:
Isn't paths not going to any use because no motion blocks are used?
What do you mean by no motion blocks used? I see several...
Offline
I don't have the time to interpret that entire script, birdbyte? Perhaps you could explain this massive script to Jodymoses?
Offline
I'm not going to try to understand the script, but it seems that "paths" affects "directions", which affects movement:
point in direction ((90) * (item (1 v) of [directions v])) move (20) steps
Offline
http://wiki.scratch.mit.edu/wiki/Artificial_Intelligence
http://scratch.mit.edu/projects/Lucario621/803990
Offline
Jodymoses wrote:
Why do you add the below?
when gf clicked if < touching {walls}> add (10000) to Paths
Assuming he's following a sort of recursive algorithm that's trying to find the shortest path, making one of the path-ways "10000" basically means such a path will never be optimal. Rather than adding extra conditionals to take walls into account, such routes are simply ignored because they are so high (or bad).
Offline