Difference between revisions of "Running code"

From RogueBasin
Jump to navigation Jump to search
(needs *s removed)
 
(Intro. Not from the Angband code.)
 
(3 intermediate revisions by the same user not shown)
Line 1: Line 1:
* Basically, once you start running, you keep moving until something
In general, pressing the [[User interface features|key to move left]] will move you one square left. This can induce boredom if you want to get all the way across the map, which leads to the obvious solution of holding the key down until you get where you want to go. Unfortunately this habit almost always leads to [[YASD]] when a powerful monster inevitably kills you before you can react. Running is a feature implemented in most major roguelikes which allows a character to travel long distances without boredom or danger. It is normally invoked by pressing the "run" key followed by the direction to run, or by using control+direction or some such.
* interesting happens.  In an enclosed space, you run straight, but
 
* you follow corners as needed (i.e. hallways).  In an open space,
Basically, once you start running, you keep moving until something
* you run straight, but you stop before entering an enclosed space
interesting happens.  In an enclosed space, you run straight, but
* (i.e. a room with a doorway).  In a semi-open space (with walls on
you follow corners as needed (i.e. hallways).  In an open space,
* one side only), you run straight, but you stop before entering an
you run straight, but you stop before entering an enclosed space
* enclosed space or an open space (i.e. running along side a wall).
(i.e. a room with a doorway).  In a semi-open space (with walls on
  *
one side only), you run straight, but you stop before entering an
* All discussions below refer to what the player can see, that is,
enclosed space or an open space (i.e. running along side a wall).
* an unknown wall is just like a normal floorThis means that we
   
* must be careful when dealing with "illegal" grids.
All discussions below refer to what the player can see, that is,
*
an unknown wall is just like a normal floorThis means that we
* No assumptions are made about the layout of the dungeon, so this
must be careful when dealing with "illegal" grids.
* algorithm works in hallways, rooms, town, destroyed areas, etc.
   
  *
No assumptions are made about the layout of the dungeon, so this
  * In the diagrams below, the player has just arrived in the grid
algorithm works in hallways, rooms, town, destroyed areas, etc.
* marked as '@', and he has just come from a grid marked as 'o',
* and he is about to enter the grid marked as 'x'.
In the diagrams below, the player has just arrived in the grid
  *
marked as '@', and he has just come from a grid marked as 'o',
* Running while confused is not allowed, and so running into a wall
and he is about to enter the grid marked as 'x'.
* is only possible when the wall is not seen by the player.  This
   
* will take a turn and stop the running.
Running while confused is not allowed, and so running into a wall
  *
is only possible when the wall is not seen by the player (when the player is blind or has no light source).  This
* Several conditions are tracked by the running variables.
will take a turn and stop the running.
  *
   
p_ptr->run_open_area (in the open on at least one side)
Several conditions are tracked by the running variables.
p_ptr->run_break_left (wall on the left, stop if it opens)
   
p_ptr->run_break_right (wall on the right, stop if it opens)
    p_ptr->run_open_area (in the open on at least one side)
  *
    p_ptr->run_break_left (wall on the left, stop if it opens)
* When running begins, these conditions are initialized by examining
    p_ptr->run_break_right (wall on the right, stop if it opens)
* the grids adjacent to the requested destination grid (marked 'x'),
   
* two on each side (marked 'L' and 'R').  If either one of the two
When running begins, these conditions are initialized by examining
* grids on a given side is a wall, then that side is considered to
the grids adjacent to the requested destination grid (marked 'x'),
* be "closed".  Both sides enclosed yields a hallway.
two on each side (marked 'L' and 'R').  If either one of the two
  *
grids on a given side is a wall, then that side is considered to
*    LL                    @L
be "closed".  Both sides enclosed yields a hallway.
*    @x      (normal)      RxL  (diagonal)
   
*    RR      (east)          R    (south-east)
    LL                    @L
  *
    @x      (normal)      RxL  (diagonal)
* In the diagram below, in which the player is running east along a
    RR      (east)          R    (south-east)
* hallway, he will stop as indicated before attempting to enter the
   
* intersection (marked 'x').  Starting a new run in any direction
In the diagram below, in which the player is running east along a
* will begin a new hallway run.
hallway, he will stop as indicated before attempting to enter the
  *
intersection (marked 'x').  Starting a new run in any direction
* #.#
will begin a new hallway run.
* ##.##
   
* o@x..
  #.#
* ##.##
  ##.##
* #.#
  o@x..
  *
  ##.##
* Note that a minor hack is inserted to make the angled corridor
  #.#
* entry (with one side blocked near and the other side blocked
   
* further away from the runner) work correctly. The runner moves
Note that a minor hack is inserted to make the angled corridor
* diagonally, but then saves the previous direction as being
entry (with one side blocked near and the other side blocked
* straight into the gap. Otherwise, the tail end of the other
further away from the runner) work correctly. The runner moves
* entry would be perceived as an alternative on the next move.
diagonally, but then saves the previous direction as being
  *
straight into the gap. Otherwise, the tail end of the other
* In the diagram below, the player is running east down a hallway,
entry would be perceived as an alternative on the next move.
* and will stop in the grid (marked '1') before the intersection.
   
* Continuing the run to the south-east would result in a long run
In the diagram below, the player is running east down a hallway,
* stopping at the end of the hallway (marked '2').
and will stop in the grid (marked '1') before the intersection.
  *
Continuing the run to the south-east would result in a long run
* ##################
stopping at the end of the hallway (marked '2').
* o@x      1
   
* ########### ######
  ##################
* #2          #
  o@x      1
* #############
  ########### ######
  *
  #2          #
* After each step, the surroundings are examined to determine if
  #############
* the running should stop, and to determine if the running should
   
* change direction.  We examine the new current player location
After each step, the surroundings are examined to determine if
* (at which the runner has just arrived) and the direction from
the running should stop, and to determine if the running should
* which the runner is considered to have come.
change direction.  We examine the new current player location
  *
(at which the runner has just arrived) and the direction from
* Moving one grid in some direction places you adjacent to three
which the runner is considered to have come.
* or five new grids (for straight and diagonal moves respectively)
   
* to which you were not previously adjacent (marked as '!').
Moving one grid in some direction places you adjacent to three
  *
or five new grids (for straight and diagonal moves respectively)
...!              ...
to which you were not previously adjacent (marked as '!').
.o@!  (normal)    .o.!  (diagonal)
   
...!  (east)      ..@!  (south east)
    ...!              ...
*                      !!!
    .o@!  (normal)    .o.!  (diagonal)
  *
    ...!  (east)      ..@!  (south east)
* If any of the newly adjacent grids are "interesting" (monsters,
                      !!!
* objects, some terrain features) then running stops.
   
  *
If any of the newly adjacent grids are "interesting" (monsters,
* If any of the newly adjacent grids seem to be open, and you are
objects, some terrain features) then running stops.
* looking for a break on that side, then running stops.
   
  *
If any of the newly adjacent grids seem to be open, and you are
* If any of the newly adjacent grids do not seem to be open, and
looking for a break on that side, then running stops.
* you are in an open area, and the non-open side was previously
   
* entirely open, then running stops.
If any of the newly adjacent grids do not seem to be open, and
  *
you are in an open area, and the non-open side was previously
* If you are in a hallway, then the algorithm must determine if
entirely open, then running stops.
* the running should continue, turn, or stop.  If only one of the
   
* newly adjacent grids appears to be open, then running continues
If you are in a hallway, then the algorithm must determine if
* in that direction, turning if necessary.  If there are more than
the running should continue, turn, or stop.  If only one of the
* two possible choices, then running stops.  If there are exactly
newly adjacent grids appears to be open, then running continues
* two possible choices, separated by a grid which does not seem
in that direction, turning if necessary.  If there are more than
* to be open, then running stops.  Otherwise, as shown below, the
two possible choices, then running stops.  If there are exactly
* player has probably reached a "corner".
two possible choices, separated by a grid which does not seem
  *
to be open, then running stops.  Otherwise, as shown below, the
*    ###            o##
player has probably reached a "corner".
*    o@x  (normal)  #@!  (diagonal)
   
*    ##!  (east)    ##x  (south east)
    ###            o##
  *
    o@x  (normal)  #@!  (diagonal)
* In this situation, there will be two newly adjacent open grids,
    ##!  (east)    ##x  (south east)
* one touching the player on a diagonal, and one directly adjacent.
   
* We must consider the two "option" grids further out (marked '?').
In this situation, there will be two newly adjacent open grids,
* We assign "option" to the straight-on grid, and "option2" to the
one touching the player on a diagonal, and one directly adjacent.
* diagonal grid.  For some unknown reason, we assign "check_dir" to
We must consider the two "option" grids further out (marked '?').
* the grid marked 's', which may be incorrectly labelled.
We assign "option" to the straight-on grid, and "option2" to the
  *
diagonal grid.  For some unknown reason, we assign "check_dir" to
*    ###s
the grid marked 's', which may be incorrectly labelled.
*    o@x?  (may be incorrect diagram!)
   
*    ##!?
    ###s
  *
    o@x?  (may be incorrect diagram!)
* If both "option" grids are closed, then there is no reason to enter
    ##!?
* the corner, and so we can cut the corner, by moving into the other
   
* grid (diagonally).  If we choose not to cut the corner, then we may
If both "option" grids are closed, then there is no reason to enter
* go straight, but we pretend that we got there by moving diagonally.
the corner, and so we can cut the corner, by moving into the other
* Below, we avoid the obvious grid (marked 'x') and cut the corner
grid (diagonally).  If we choose not to cut the corner, then we may
* instead (marked 'n').
go straight, but we pretend that we got there by moving diagonally.
  *
Below, we avoid the obvious grid (marked 'x') and cut the corner
*    ###:              o##
instead (marked 'n').
*    o@x#  (normal)    #@n    (maybe?)
   
*    ##n#  (east)      ##x#
    ###:              o##
*                      ####
    o@x#  (normal)    #@n    (maybe?)
  *
    ##n#  (east)      ##x#
* If one of the "option" grids is open, then we may have a choice, so
                        ####
* we check to see whether it is a potential corner or an intersection
   
* (or room entrance).  If the grid two spaces straight ahead, and the
If one of the "option" grids is open, then we may have a choice, so
* space marked with 's' are both open, then it is a potential corner
we check to see whether it is a potential corner or an intersection
* and we enter it if requested.  Otherwise, we stop, because it is
(or room entrance).  If the grid two spaces straight ahead, and the
* not a corner, and is instead an intersection or a room entrance.
space marked with 's' are both open, then it is a potential corner
*
and we enter it if requested.  Otherwise, we stop, because it is
*    ###
not a corner, and is instead an intersection or a room entrance.
*    o@x
*    ##!#
    ###
  *
    o@x
* I do not think this documentation is correct.
    ##!#
   
I do not think this documentation is correct.


From pathfind.c in the Angband 3.1.2v2 source code (GPL)
From pathfind.c in the Angband 3.1.2v2 source code (GPL)
[[Category:Articles]]

Latest revision as of 14:09, 5 June 2011

In general, pressing the key to move left will move you one square left. This can induce boredom if you want to get all the way across the map, which leads to the obvious solution of holding the key down until you get where you want to go. Unfortunately this habit almost always leads to YASD when a powerful monster inevitably kills you before you can react. Running is a feature implemented in most major roguelikes which allows a character to travel long distances without boredom or danger. It is normally invoked by pressing the "run" key followed by the direction to run, or by using control+direction or some such.

Basically, once you start running, you keep moving until something interesting happens. In an enclosed space, you run straight, but you follow corners as needed (i.e. hallways). In an open space, you run straight, but you stop before entering an enclosed space (i.e. a room with a doorway). In a semi-open space (with walls on one side only), you run straight, but you stop before entering an enclosed space or an open space (i.e. running along side a wall).

All discussions below refer to what the player can see, that is, an unknown wall is just like a normal floor. This means that we must be careful when dealing with "illegal" grids.

No assumptions are made about the layout of the dungeon, so this algorithm works in hallways, rooms, town, destroyed areas, etc.

In the diagrams below, the player has just arrived in the grid marked as '@', and he has just come from a grid marked as 'o', and he is about to enter the grid marked as 'x'.

Running while confused is not allowed, and so running into a wall is only possible when the wall is not seen by the player (when the player is blind or has no light source). This will take a turn and stop the running.

Several conditions are tracked by the running variables.

   p_ptr->run_open_area (in the open on at least one side)
   p_ptr->run_break_left (wall on the left, stop if it opens)
   p_ptr->run_break_right (wall on the right, stop if it opens)

When running begins, these conditions are initialized by examining the grids adjacent to the requested destination grid (marked 'x'), two on each side (marked 'L' and 'R'). If either one of the two grids on a given side is a wall, then that side is considered to be "closed". Both sides enclosed yields a hallway.

    LL                     @L
    @x      (normal)       RxL   (diagonal)
    RR      (east)          R    (south-east)

In the diagram below, in which the player is running east along a hallway, he will stop as indicated before attempting to enter the intersection (marked 'x'). Starting a new run in any direction will begin a new hallway run.

 #.#
 ##.##
 o@x..
 ##.##
 #.#

Note that a minor hack is inserted to make the angled corridor entry (with one side blocked near and the other side blocked further away from the runner) work correctly. The runner moves diagonally, but then saves the previous direction as being straight into the gap. Otherwise, the tail end of the other entry would be perceived as an alternative on the next move.

In the diagram below, the player is running east down a hallway, and will stop in the grid (marked '1') before the intersection. Continuing the run to the south-east would result in a long run stopping at the end of the hallway (marked '2').

 ##################
 o@x       1
 ########### ######
 #2          #
 #############

After each step, the surroundings are examined to determine if the running should stop, and to determine if the running should change direction. We examine the new current player location (at which the runner has just arrived) and the direction from which the runner is considered to have come.

Moving one grid in some direction places you adjacent to three or five new grids (for straight and diagonal moves respectively) to which you were not previously adjacent (marked as '!').

   ...!              ...
   .o@!  (normal)    .o.!  (diagonal)
   ...!  (east)      ..@!  (south east)
                      !!!

If any of the newly adjacent grids are "interesting" (monsters, objects, some terrain features) then running stops.

If any of the newly adjacent grids seem to be open, and you are looking for a break on that side, then running stops.

If any of the newly adjacent grids do not seem to be open, and you are in an open area, and the non-open side was previously entirely open, then running stops.

If you are in a hallway, then the algorithm must determine if the running should continue, turn, or stop. If only one of the newly adjacent grids appears to be open, then running continues in that direction, turning if necessary. If there are more than two possible choices, then running stops. If there are exactly two possible choices, separated by a grid which does not seem to be open, then running stops. Otherwise, as shown below, the player has probably reached a "corner".

    ###             o##
    o@x  (normal)   #@!   (diagonal)
    ##!  (east)     ##x   (south east)

In this situation, there will be two newly adjacent open grids, one touching the player on a diagonal, and one directly adjacent. We must consider the two "option" grids further out (marked '?'). We assign "option" to the straight-on grid, and "option2" to the diagonal grid. For some unknown reason, we assign "check_dir" to the grid marked 's', which may be incorrectly labelled.

    ###s
    o@x?   (may be incorrect diagram!)
    ##!?

If both "option" grids are closed, then there is no reason to enter the corner, and so we can cut the corner, by moving into the other grid (diagonally). If we choose not to cut the corner, then we may go straight, but we pretend that we got there by moving diagonally. Below, we avoid the obvious grid (marked 'x') and cut the corner instead (marked 'n').

    ###:               o##
    o@x#   (normal)    #@n    (maybe?)
    ##n#   (east)      ##x#
                       ####

If one of the "option" grids is open, then we may have a choice, so we check to see whether it is a potential corner or an intersection (or room entrance). If the grid two spaces straight ahead, and the space marked with 's' are both open, then it is a potential corner and we enter it if requested. Otherwise, we stop, because it is not a corner, and is instead an intersection or a room entrance.

    ###
    o@x
    ##!#

I do not think this documentation is correct.

From pathfind.c in the Angband 3.1.2v2 source code (GPL)