<commit_before>module TheWizardsCastle
class Castle

  attr_reader :backmap, :rooms

  def initialize
    @rooms = Array.new(8*8*8, RoomContent.to_intcode(:empty_room)) # unlike BASIC, index starts at 0

    set_in_room(1,4,1,:entrance)
    (1..7).each do |z|
      xroom = set_in_random_room(:stairs_down,z)
      xroom[2] = xroom[2]+1
      set_in_room(*xroom,:stairs_up)
    end

    monsters = [:kobold, :orc, :wolf, :goblin, :ogre, :troll, :bear, :minotaur, :gargoyle, :chimera, :balrog, :dragon]
    other_things = [:magic_pool, :chest, :gold, :flares, :warp, :sinkhole, :crystal_orb, :book, :vendor]
    (1..8).each do |z|
      monsters.each {|monster| set_in_random_room(monster,z)}
      other_things.each {|thing| 3.times { set_in_random_room(thing,z)}}
    end

    treasures = [:ruby_red, :norn_stone, :pale_pearl, :opal_eye, :green_gem, :blue_flame, :palantir, :silmaril]
    treasures.each {|treasure| set_in_random_room(treasure)}

    # I can't believe I'm using the same empty_room hack that Stetson-BASIC is using
    # Multiple curses can be in the same room, and the runestaff/orb may also be later placed into a curse room.
    # (This is just how the old game implemented it.)
    @curse_lethargy_location      = set_in_random_room(:empty_room)
    @curse_leech_location         = set_in_random_room(:empty_room)
    @curse_forgetfulness_location = set_in_random_room(:empty_room)

    set_in_random_room(:runestaff_and_monster)
    @runestaff_monster = monsters[Random.rand(monsters.length)]

    set_in_random_room(:orb_of_zot)
  end


  def self.room_index(row,col,floor)
    # Equivalent to FND from BASIC, except -1 because @rooms is indexing from 0.
    # z is the level
    raise "value out of range: (#{row},#{col},#{floor})" if [row,col,floor].any?{|n| n<1 || n>8}
    64*(floor-1)+8*(row-1)+col-1
  end

  def room(row,col,floor)
    RoomContent.new(@rooms[Castle.room_index(row,col,floor)])
  end

  def set_in_room(row,col,floor,symbol)
    @rooms[Castle.room_index(row,col,floor)] = RoomContent.to_intcode(symbol)
  end

  def set_in_random_room(symbol,floor=nil)
    10000.times do
      row = Random.rand(8)+1
      col = Random.rand(8)+1
      floor ||= Random.rand(8)+1
      if room(row,col,floor).symbol == :empty_room
        set_in_room(row,col,floor,symbol)<commit_msg>change "z" to "floor" a few more times<commit_after>module TheWizardsCastle
class Castle

  attr_reader :backmap, :rooms

  def initialize
    @rooms = Array.new(8*8*8, RoomContent.to_intcode(:empty_room)) # unlike BASIC, index starts at 0

    set_in_room(1,4,1,:entrance)
    (1..7).each do |floor|
      xroom = set_in_random_room(:stairs_down,floor)
      xroom[2] = xroom[2]+1
      set_in_room(*xroom,:stairs_up)
    end

    monsters = [:kobold, :orc, :wolf, :goblin, :ogre, :troll, :bear, :minotaur, :gargoyle, :chimera, :balrog, :dragon]
    other_things = [:magic_pool, :chest, :gold, :flares, :warp, :sinkhole, :crystal_orb, :book, :vendor]
    (1..8).each do |floor|
      monsters.each {|monster| set_in_random_room(monster,floor)}
      other_things.each {|thing| 3.times { set_in_random_room(thing,floor)}}
    end

    treasures = [:ruby_red, :norn_stone, :pale_pearl, :opal_eye, :green_gem, :blue_flame, :palantir, :silmaril]
    treasures.each {|treasure| set_in_random_room(treasure)}

    # I can't believe I'm using the same empty_room hack that Stetson-BASIC is using
    # Multiple curses can be in the same room, and the runestaff/orb may also be later placed into a curse room.
    # (This is just how the old game implemented it.)
    @curse_lethargy_location      = set_in_random_room(:empty_room)
    @curse_leech_location         = set_in_random_room(:empty_room)
    @curse_forgetfulness_location = set_in_random_room(:empty_room)

    set_in_random_room(:runestaff_and_monster)
    @runestaff_monster = monsters[Random.rand(monsters.length)]

    set_in_random_room(:orb_of_zot)
  end


  def self.room_index(row,col,floor)
    # Equivalent to FND from BASIC, except -1 because @rooms is indexing from 0.
    raise "value out of range: (#{row},#{col},#{floor})" if [row,col,floor].any?{|n| n<1 || n>8}
    64*(floor-1)+8*(row-1)+col-1
  end

  def room(row,col,floor)
    RoomContent.new(@rooms[Castle.room_index(row,col,floor)])
  end

  def set_in_room(row,col,floor,symbol)
    @rooms[Castle.room_index(row,col,floor)] = RoomContent.to_intcode(symbol)
  end

  def set_in_random_room(symbol,floor=nil)
    10000.times do
      row = Random.rand(8)+1
      col = Random.rand(8)+1
      floor ||= Random.rand(8)+1
      if room(row,col,floor).symbol == :empty_room
        set_in_room(row,col,floor,symbol)
{'fraction_non_alphanumeric': 0.132201203783319, 'fraction_numerical': 0.015477214101461736, 'mean_word_length': 4.187290969899665, 'pattern_counts': {'":': 0, '<': 5, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4129905', 'n_tokens_mistral': 1827, 'n_tokens_neox': 1753, 'n_words': 364}