|
Joined: Dec 2002
Posts: 32
Ameglian cow
|
OP
Ameglian cow
Joined: Dec 2002
Posts: 32 |
Looking for some help on pathfinding for a pirate game. The game consists of multiple ships where they can sail across the game world. The game world is divided into cells starting at A1 thru A16 and S1 thru S16. Ships move to a new location using a trigger such as !P A1 or !P port name. This moves the ship across the map slowly across the map in a nondiagonal path. Example: Ship is at Margarita (Q14) and sails to Barbados (S12) the path would be Q14, R14, R13, S13, S12 I would like for ships to sail around the cells designated as land (in red) and any help would be appreciated. A copy of map.ini is located hereHere is the code I currently use:
alias Cell.Restricted {
;$Cell.Restricted(cell) - returns if a cell (a1 thru s16) is land or inaccessible/restricted area
var %file map.ini, %x $left($1,1), %y $right($1,-1)
if (!%y) || (!%x) || ($len(%x $+ %y) < 2) || (%x !isalpha) || ($alph(%x) > 19) || (%y > 16) || (%y < 1) return $true
elseif ($readini(%file,landorsea,%x $+ %y) == land) return $true
elseif ($readini(%file,landorsea,%x $+ %y) == restricted) return $true
else return $false
}
alias FindPath {
;$FindPath(start,destination,N) - returns the estimated (straight line) path it will take to get to goal/destination
;if N is 1, returns cells to move and saves findpath q
;if N is 2, returns cells to move
;if N is 3, shows # of moves
var %current.x $left($1,1), %current.y $right($1,-1), %d.x $left($2,1), %d.y $right($2,-1)
var %total 0, %moves $1, %i 0
if ($3 == 1) hdel epirate.pathfind q
while (%i < 75) {
inc %i
if ($isodd(%i)) {
if ($alph(%current.x) < $alph(%d.x)) set %current.x $alph($calc($alph(%current.x) + 1))
elseif ($alph(%current.x) > $alph(%d.x)) set %current.x $alph($calc($alph(%current.x) - 1))
inc %total
}
else {
if (%current.y < %d.y) set %current.y $calc(%current.y + 1)
elseif (%current.y > %d.y) set %current.y $calc(%current.y - 1)
inc %total
}
set %current.x $upper(%current.x)
set %current.y $upper(%current.y)
set %moves $addtok(%moves,%current.x $+ %current.y,44)
if (%current.x == %d.x) && (%current.y == %d.y) {
set %total $gettok(%moves,0,44)
if ($3) {
if ($3 == 1) {
if (!$hget(pathfind)) hmake pathfind
hadd pathfind q $addtok($hget(pathfind,q),%moves,44)
return %moves
}
elseif ($3 == 2) return %moves
}
return %total
break
}
}
}
Last edited by mruno; 11/03/21 09:12 PM.
|
|
|
|
Joined: Jul 2006
Posts: 4,019
Hoopy frood
|
Hoopy frood
Joined: Jul 2006
Posts: 4,019 |
Is your code not working? what do you need help with? I use A* in my pacman game to find paths, i originally implemented the code from an old friend which was posted as a snippet and can still be found here https://codes-sources.commentcamarche.net/source/46577-algorithme-aI since got Sreject to rewrite it (or well, reimplement an existing A* algorithm in js) in js, which runs via COM, which is way faster than doing it in mIRC script. The code is dynamic and can be used for any map:
maptobvar pacservg
noop $jsAStarLoadMap(&map)
var %as $jsAStarSearch(x,y,x1,y1)
where x would be your Q, y would be your 14, x1 S and y1 would be 12, except the letter would be converter to numbers. and it would start at 0 not 1. It works with binary variable, but there is a function (maptobvar) which convert an hash table to a binvar, which you could use or rewrite to suit your need with the ini. The binvar needs to represent your map on a single line, where each byte value represent a state, 0 for a square you can go to, and 1 for a square you can't go to. the first byte represent the width of the map. it would return the list of squares required to reach the end if it's possible, in the form X.Y X1.Y1 Here is the code for the sake of it, but you'll probably need help setting things up, feel free to join the channel in my signature for that.
alias -l comShell return Pacman/jsAStar/Shell
alias -l comEngine return Pacman/jsAStar/JSEngine
alias -l comMap return Pacman/jsAStar/Map
alias -l jsAStarLoadMap {
if ($jsAStarInit) {
return $v1
}
if ($com($comMap)) {
.comclose $v1
}
if (!$com($comEngine, createMap, 1, &bstr, $1, dispatch* $comMap) || $comerr) {
return Failed to load the map
}
}
alias jsAStarSearch {
if (!$com($comMap, search, 1, integer, $1, integer, $2, integer, $3, integer, $4, bool, false) || $comerr) {
echo -s Failed to perform astar search > $1- > $com($comMap).errortext
return
}
return $com($comMap).result
}
alias -l jsAStarInit {
var %error
if ($com($comShell) && $com($comEngine)) return
jsAStarCleanup
.comopen $comShell MSScriptControl.ScriptControl
if (!$com($comShell) || $comerr) %error = Failed to create MSScriptControl.ScriptControl instance
elseif (!$com($comShell, language, 4, bstr, jscript)) %error = Failed to set shell language
elseif (!$com($comShell, AllowUI, 4, bool, $false) || $comerr) %error = Failed to disable js UI
elseif (!$com($comShell, timeout, 4, integer, -1) || $comerr) %error = Failed to unset js timeout
elseif (!$com($comShell, ExecuteStatement, 1, &bstr, $jsAStarScript) || $comerr) %error = Failed to execute js script
elseif (!$com($comShell, Eval, 1, bstr, this, dispatch* $comEngine) || $comerr || !$com($comEngine)) %error = Failed to create reference to the JS engine
else return
jsAStarCleanup
return %error
}
alias -l jsAStarCleanup {
if ($com($comMap)) .comclose $v1
if ($com($comEngine)) .comclose $v1
if ($com($comShell)) .comclose $v1
}
alias -l jsAStarScript {
var %file = $scriptdirmAStar.js
bread $qt(%file) 0 $file(%file).size &jsAStarScript
return &jsAStarScript
}
The js file can be found here https://www.dropbox.com/s/s70z4gnikfatr57/mastar.js?dl=0
Last edited by Wims; 11/03/21 10:30 PM.
#mircscripting @ irc.swiftirc.net == the best mIRC help channel
|
|
|
|
|