Advertisement
Guest User

Untitled

a guest
Aug 23rd, 2015
359
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Perl 4.09 KB | None | 0 0
  1. use Curses;
  2.  
  3. # Important variables:
  4. # @w - indexes of every tile on the map.
  5. # @m - offsets for movement keys.
  6. # $v - position of stairs
  7. # $p - position of player
  8. # @l - level
  9.  
  10. # Cell types:
  11. # 0 - "#" - wall
  12. # 1 - "." - floor
  13. # 2 - ">" - stairs
  14. # 3 - reserved
  15. # 4 - "B" - monster
  16.  
  17. # The level is 1D array, it is indexed by one variable. The index in it can be
  18. # converted to x, y coordinates by using division and modulo 80.
  19. # x = i % 80
  20. # y = i / 80
  21.  
  22. # To convert backwards:
  23. # i = y * 80 + k
  24.  
  25. for(
  26.       @w = 0..1920; # Used for indexing the map.
  27.       @m = (-1, clear, 80, -80, 1); # Directions, calls clear every update
  28.       $l[$v] = 2 # Put stairs in its place.
  29.    ){
  30.  
  31.    # Render level.
  32.  
  33.    # Since (x ^ y = 0) => (x != y)
  34.    # Xor is used to check that current cell isn't occupied by player.
  35.    # B in that array is same thing as "B" but uses less characters.
  36.    addch $_ ^ $p ? ("#", ".", ">", 0, B)[$l[$_]] : "@" for @w;
  37.  
  38.    # Read input from used and move.
  39.  
  40.    # Puts in variable $z new possible position of player.
  41.    # Movement is done by vi-keys so it expects keys h, j, k, l
  42.    # h has index 104 in ASCII table, j's index is 106 (that's why second element
  43.    # of @m is zero), k - 107, l - 108.
  44.    # $m[index - 104] is offset for new position on the map.
  45.    # x & 3 is zero when x is 4 or 0. It checks if new position is occupied by
  46.    # a wall or a monster.
  47.  
  48.    $p = $z if $l[$z = $p + $m[ord(getch) - 104]] & 3;
  49.  
  50.    # Since monsters are represented by value 4, and 4 % 3 == 1 (floor tile)
  51.    # it creates a floor tile in place where monster used to be when player
  52.    # moves into a montser.
  53.  
  54.    $l[$z] %= 3;
  55.  
  56.    # Player stepped on stairs.
  57.  
  58.    # x & 2 is not zero when x is 2. 2 represents stairs.
  59.    # This code generates new level when player steps on stairs.
  60.    if($l[$p] & 2){
  61.          # Generate level.
  62.  
  63.          @l = 0 * initscr; # initscr returns some data so 0 * is needed to
  64.          # create empty level.
  65.  
  66.          # map is used to repeat code 100 times.
  67.          map{
  68.             # Checks if current cell ($_) is inside a circle-like curve
  69.             # defined by formula x^2 + abs(y) < 6
  70.             # $n is offset of this curve from center.
  71.             ($_ % 80 - $n % 80)**2 + abs($_ - $n) / 80 < 6?
  72.  
  73.                # If it is, roll a 100 sided virtual die and check if result is
  74.                # 0 or 1. If it is put a monster in this cell and update $p
  75.                # if it isn't put a floor tile here.
  76.  
  77.                # 4 % ~($p = $_) is (almost?) always 4 and updates $p with $_.
  78.                # It will be useful later.
  79.                # $p here is not related to position of player.
  80.                $l[$_] = rand 99 < 2 ? 4 % ~($p = $_) : 1
  81.  
  82.                : 0 # Do nothing.
  83.  
  84.             for @w, # The code above is repeated for ever cell on
  85.             # the map, $_ is position of cell being worked on currently.
  86.  
  87.             $n = $p + $n % 4 # Set the new center of the curve to place where
  88.             # the last monster was put and add ($n % 4) to make it look a bit
  89.             # more random.
  90.          }  0..99;
  91.  
  92.          # Do nothing untill random values for $v (position of stairs) and $p
  93.          # (position of player) are found and are both on unocuppied tiles.
  94.          1 until $l[$v = rand @w] & $l[$p = rand @w]
  95.       }
  96.  
  97.       $l[$_] & 4? # Checks if cell is 4 (monster)
  98.          # $n is the new position of current monster.
  99.  
  100.          # This code checks if new position is floor ($l[$n] == 1)
  101.          # and if it's not occupied by player ($n ^ $p, xor being used as !=)
  102.          # if it isn't it changes current cell to 9 | something
  103.          # Which will be reset to 4 later.
  104.  
  105.          # If it is, it sets $l[$n] to 9 | something and current cell is reset
  106.          # to 1 by the second part of this expression.
  107.          $l[$l[$n] == 1 && $n ^ $p? $n : $_]=9 |
  108.          ($n = $_ + $m[rand 4 + ($l[$_]=1)])
  109.       : 0 # Do nothing.
  110.  
  111.       for @w; # For every cell on the map.
  112.  
  113.       # For every cell on the level, cells that are bigger than 3 with 4.
  114.       # Keep other cells same.
  115.       map $_ = $_ > 3? 4 : $_, @l
  116. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement