mIRC Home    About    Download    Register    News    Help

Print Thread
pathfinding help #268552 11/03/21 09:11 PM
Joined: Dec 2002
Posts: 30
M
mruno Offline OP
Ameglian cow
OP Offline
Ameglian cow
M
Joined: Dec 2002
Posts: 30
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

[Linked Image from piratesirc.com]


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 here

Here is the code I currently use:

Code
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.
Re: pathfinding help [Re: mruno] #268553 11/03/21 10:16 PM
Joined: Jul 2006
Posts: 3,745
W
Wims Offline
Hoopy frood
Offline
Hoopy frood
W
Joined: Jul 2006
Posts: 3,745
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-a

I 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:

Code
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.


Code
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.

Looking for a good help channel about mIRC? Check #mircscripting @ irc.swiftirc.net