class WizardsCastle::Runner
Attributes
castle[RW]
player[RW]
printer[RW]
prompter[RW]
Public Class Methods
new()
click to toggle source
# File lib/wizards-castle/runner.rb, line 28 def initialize @prompter = nil @castle = nil @player = nil @printer = nil end
run()
click to toggle source
# File lib/wizards-castle/runner.rb, line 12 def self.run n=0 loop do runner = Runner.new runner.setup runner.intro if n==0 runner.character_creation break unless runner.play n+=1 end end
Public Instance Methods
ask_armor()
click to toggle source
# File lib/wizards-castle/runner.rb, line 188 def ask_armor allowed = Player::ARMORS.collect{|x| [x.to_s[0].upcase,x]}.to_h costs = { plate: 30, chainmail: 20, leather: 10, nothing: 0 } answer = @prompter.ask(allowed.keys, @printer.prompt_armor) armor = allowed[answer] @player.set_armor(armor) @player.gp(-1 * costs[armor]) end
ask_attributes()
click to toggle source
# File lib/wizards-castle/runner.rb, line 150 def ask_attributes @printer.attributes_header ask_strength ask_intelligence ask_dexterity end
ask_dexterity()
click to toggle source
# File lib/wizards-castle/runner.rb, line 177 def ask_dexterity if @player.custom_attribute_points > 0 max = 18-@player.dex max = @player.custom_attribute_points if max>@player.custom_attribute_points n = @prompter.ask_integer(0,max,@printer.prompt_add_to_dexterity) @player.custom_attribute_points(-n) @player.dex(+n) end end
ask_flares()
click to toggle source
# File lib/wizards-castle/runner.rb, line 213 def ask_flares return if @player.gp < 1 n = @prompter.ask_integer(0,@player.gp,@printer.prompt_flares) @player.flares(+n) @player.gp(-n) end
ask_gender()
click to toggle source
# File lib/wizards-castle/runner.rb, line 140 def ask_gender allowed = { 'M' => :male, 'F' => :female } answer = @prompter.ask(allowed.keys, @printer.prompt_gender) @player.set_gender(allowed[answer]) end
ask_intelligence()
click to toggle source
# File lib/wizards-castle/runner.rb, line 167 def ask_intelligence if @player.custom_attribute_points > 0 max = 18-@player.int max = @player.custom_attribute_points if max>@player.custom_attribute_points n = @prompter.ask_integer(0,max,@printer.prompt_add_to_intelligence) @player.custom_attribute_points(-n) @player.int(+n) end end
ask_lamp()
click to toggle source
# File lib/wizards-castle/runner.rb, line 206 def ask_lamp return if @player.gp < 20 answer = @prompter.ask(["Y","N"], @printer.prompt_lamp) @player.gp(-20) if @player.set_lamp(answer=="Y") end
ask_race()
click to toggle source
Character creation prompts
# File lib/wizards-castle/runner.rb, line 106 def ask_race allowed = { 'E' => :elf, 'D' => :dwarf, 'M' => :human, 'H' => :hobbit } answer = @prompter.ask(allowed.keys, @printer.prompt_race) @player.set_race(allowed[answer]) case @player.race when :hobbit @player.str(+4) @player.int(+8) @player.dex(+12) @player.custom_attribute_points(+4) when :elf @player.str(+6) @player.int(+8) @player.dex(+10) @player.custom_attribute_points(+8) when :human @player.str(+8) @player.int(+8) @player.dex(+8) @player.custom_attribute_points(+8) when :dwarf @player.str(+10) @player.int(+8) @player.dex(+6) @player.custom_attribute_points(+8) end end
ask_strength()
click to toggle source
# File lib/wizards-castle/runner.rb, line 157 def ask_strength if @player.custom_attribute_points > 0 max = 18-@player.str max = @player.custom_attribute_points if max>@player.custom_attribute_points n = @prompter.ask_integer(0,max,@printer.prompt_add_to_strength) @player.custom_attribute_points(-n) @player.str(+n) end end
ask_weapon()
click to toggle source
# File lib/wizards-castle/runner.rb, line 197 def ask_weapon allowed = Player::WEAPONS.collect{|x| [x.to_s[0].upcase,x]}.to_h costs = { sword: 30, mace: 20, dagger: 10, nothing: 0 } answer = @prompter.ask(allowed.keys, @printer.prompt_weapon) weapon = allowed[answer] @player.set_weapon(weapon) @player.gp(-1 * costs[weapon]) end
book()
click to toggle source
# File lib/wizards-castle/runner.rb, line 539 def book effect = random_book_effect() case effect when :flash @player.set_blind(true) when :poetry,:magazine # no effect when :dex_manual @player.dex(+18) when :str_manual @player.str(+18) when :sticky @player.set_stickybook(true) else raise "unrecognized book effect '#{effect.to_s}'" end @printer.book_effect(effect) end
character_creation()
click to toggle source
# File lib/wizards-castle/runner.rb, line 46 def character_creation @printer.character_creation_header ask_race ask_gender ask_attributes @printer.gold_report1 ask_armor @printer.gold_report2 ask_weapon ask_lamp if @player.gp > 0 @printer.gold_report3 ask_flares end end
chest()
click to toggle source
# File lib/wizards-castle/runner.rb, line 575 def chest effect = random_chest_effect gold_gain = 0 case effect when :kaboom dmg = chest_explosion_damage @player.take_a_hit!(dmg,@printer) when :gold gold_gain = chest_gold() @player.gp(+gold_gain) when :gas dir = chest_gas_random_direction @player.turns(+20) @player.set_facing dir @player.set_location *Castle.move(dir.to_s.upcase,*@player.location) else raise "unrecognized chest effect '#{effect.to_s}'" end @printer.chest_effect(effect,gold_gain) effect end
chest_explosion_damage()
click to toggle source
# File lib/wizards-castle/runner.rb, line 563 def chest_explosion_damage 1+Random.rand(6) end
chest_gas_random_direction()
click to toggle source
# File lib/wizards-castle/runner.rb, line 571 def chest_gas_random_direction [:n,:e,:w,:s].sample end
chest_gold()
click to toggle source
# File lib/wizards-castle/runner.rb, line 567 def chest_gold 1+Random.rand(1000) end
combat()
click to toggle source
# File lib/wizards-castle/runner.rb, line 641 def combat loc = @player.location rc = @castle.room(*loc) outcome = run_battle(rc.monster_symbol) case outcome when BattleRunner::Result::RETREAT @printer.you_have_escaped dir = @prompter.ask(['N','S','E','W'], @printer.prompt_retreat_direction) @player.set_location *Castle.move(dir,*loc) @player.set_facing(dir.downcase.to_sym) return PlayerState::NEW_ROOM when BattleRunner::Result::PLAYER_DEAD return PlayerState::DIED when BattleRunner::Result::ENEMY_DEAD @printer.monster_is_dead eat_monster_maybe() if rc.symbol==:vendor @player.set_armor(:plate) @player.set_weapon(:sword) @player.str(+Random.rand(6)+1) @player.int(+Random.rand(6)+1) @player.dex(+Random.rand(6)+1) @player.set_lamp(true) @printer.vendor_loot else if rc.symbol==:runestaff_and_monster @printer.you_got_the_runestaff @player.set_runestaff(true) end end gp_gain = monster_random_gp() @player.gp(+gp_gain) @printer.you_got_monster_gold(gp_gain) @castle.set_in_room(*loc,:empty_room) return PlayerState::ACTION when BattleRunner::Result::BRIBED @player.set_vendor_rage(false) if rc.symbol==:vendor return PlayerState::ACTION else raise "illegal BattleRunner::Result '#{outcome}'" end end
display_map()
click to toggle source
# File lib/wizards-castle/runner.rb, line 445 def display_map floor = @player.location.last lines = [] (1..8).each do |row| lines << '' (1..8).each do |col| c = @player.knows_room?(row,col,floor) ? @castle.room(row,col,floor).display : "?" if [row,col,floor]==@player.location lines.last << "<#{c}> " else lines.last << " #{c} " end end lines << "" end lines << Strings.you_are_here(@player) puts lines puts end
do_random_flavor_text?()
click to toggle source
# File lib/wizards-castle/runner.rb, line 313 def do_random_flavor_text? Random.rand(5) == 0 # 20% chance end
drink()
click to toggle source
# File lib/wizards-castle/runner.rb, line 478 def drink effect = random_drink_effect() case effect when :stronger @player.str(random_drink_attr_change) when :weaker @player.str(-1 * random_drink_attr_change) when :smarter @player.int(random_drink_attr_change) when :dumber @player.int(-1 * random_drink_attr_change) when :nimbler @player.dex(random_drink_attr_change) when :clumsier @player.dex(-1 * random_drink_attr_change) when :change_race newrace = random_drink_race_change() @player.set_race(newrace) when :change_gender newgender = @player.gender==:male ? :female : :male @player.set_gender(newgender) else raise "unrecognized drink effect '#{effect.to_s}'" end @printer.drink_effect(effect) end
eat_monster_maybe()
click to toggle source
# File lib/wizards-castle/runner.rb, line 696 def eat_monster_maybe if @player.turns >= (@player.last_ate_turn+60) @printer.eat_a_monster @player.update_last_ate_turn! end end
enter_room()
click to toggle source
End of character creation prompts
# File lib/wizards-castle/runner.rb, line 224 def enter_room # returns a Player::Status loc = @player.location rc = @castle.room(*loc) entered_via_teleport = @player.teleported? @player.set_teleported(false) if @player.blind? @printer.you_are_here_blind else @printer.you_are_here end @printer.stat_block @player.remember_room(*loc) #remember even if blind symbol_for_text = if rc.symbol==:runestaff_and_monster @castle.runestaff_monster else rc.symbol end @printer.here_you_find(symbol_for_text) case rc.symbol when :gold n = Random.rand(10)+1 @player.gp(+n) @printer.new_gold_count @castle.set_in_room(*loc,:empty_room) return PlayerState::ACTION when :flares n = Random.rand(5)+1 @player.flares(+n) @printer.new_flare_count @castle.set_in_room(*loc,:empty_room) return PlayerState::ACTION when :warp @player.set_location *Castle.random_room return PlayerState::NEW_ROOM when :sinkhole @player.set_location *Castle.down(*loc) return PlayerState::NEW_ROOM when :orb_of_zot if entered_via_teleport @printer.found_orb_of_zot @player.set_runestaff(false) @player.set_orb_of_zot(true) @castle.set_in_room(*loc,:empty_room) return PlayerState::ACTION else @player.set_location *Castle.move(@player.facing.to_s.upcase,*loc) return PlayerState::NEW_ROOM end end if rc.treasure? @player.add_treasure(rc.symbol) @printer.got_a_treasure(rc.symbol) @castle.set_in_room(*loc,:empty_room) return PlayerState::ACTION elsif rc.monster? return combat elsif rc.symbol==:vendor return combat if @player.vendor_rage? case @prompter.ask(["T","A","I"], @printer.prompt_vendor_encounter) when "I" return PlayerState::ACTION when "A" @player.set_vendor_rage(true) @printer.vendor_responds_to_attack return combat when "T" ShoppingTrip.new(@player,@printer,@prompter).run() return PlayerState::ACTION end end PlayerState::ACTION end
flare()
click to toggle source
# File lib/wizards-castle/runner.rb, line 507 def flare if @player.flares < 1 @printer.out_of_flares return end @player.flares(-1) Castle.flare_locs(*@player.location).each do |loc| @player.remember_room(*loc) end @printer.flare end
gaze()
click to toggle source
# File lib/wizards-castle/runner.rb, line 611 def gaze effect = random_gaze_effect() effect_location = nil case effect when :bloody_heap @player.str(-1*random_gaze_attr_change) when :random_room effect_location = Castle.random_room @player.remember_room(*effect_location) when :zot_location effect_location = random_gaze_show_orb_of_zot? ? @castle.orb_of_zot_location : Castle.random_room when :drink_and_become,:monster_gazing_back,:soap_opera_rerun # no effect else raise "unrecognized gaze effect '#{effect.to_s}'" end @printer.gaze_effect(effect,effect_location) end
intro()
click to toggle source
# File lib/wizards-castle/runner.rb, line 35 def intro @printer.intro end
leech_gp_loss()
click to toggle source
# File lib/wizards-castle/runner.rb, line 309 def leech_gp_loss 1+Random.rand(5) end
monster_random_gp()
click to toggle source
# File lib/wizards-castle/runner.rb, line 692 def monster_random_gp Random.rand(1000)+1 end
play()
click to toggle source
# File lib/wizards-castle/runner.rb, line 62 def play # returns true if user wants to play again @player.set_location(1,4,1) #entrance @printer.entering_the_castle status = PlayerState::NEW_ROOM loop do case status when PlayerState::NEW_ROOM status = enter_room when PlayerState::ACTION status = player_action end break if [PlayerState::QUIT, PlayerState::EXITED, PlayerState::DIED].include? status end case status when PlayerState::DIED @printer.death when PlayerState::QUIT @printer.quit when PlayerState::EXITED @printer.exit_castle end @printer.endgame_possessions answer = @prompter.ask(["Y","N"], @printer.prompt_play_again) if answer=="Y" @printer.play_again @printer.restock return true end @printer.shut_down return false end
player_action()
click to toggle source
# File lib/wizards-castle/runner.rb, line 317 def player_action loc = @player.location rc = @castle.room(*loc) @player.turns(+1) unless @player.runestaff? || @player.orb_of_zot? @player.turns(+1) if @player.lethargic? && !@player.have_treasure?(:ruby_red) @player.gp(-leech_gp_loss) if @player.leech? && !@player.have_treasure?(:pale_pearl) @player.forget_random_room if @player.forgetful? && !@player.have_treasure?(:green_gem) @player.set_lethargic(true) if rc.cursed_with_lethargy? @player.set_leech(true) if rc.cursed_with_leech? @player.set_forgetful(true) if rc.cursed_with_forgetfulness? end @printer.player_action_flavor_text if do_random_flavor_text? if @player.blind? && @player.have_treasure?(:opal_eye) @printer.cure_blindness @player.set_blind(false) end if @player.stickybook? && @player.have_treasure?(:blue_flame) @printer.cure_stickybook @player.set_stickybook(false) end valid_cmds = ["H","N","S","E","W","U","D","DR","M","F","L","O","G","T","Q"] cmd = @prompter.ask(valid_cmds, @printer.prompt_standard_action) if ['M','F','L','G'].include?(cmd) && @player.blind? @printer.blind_command_error return PlayerState::ACTION end case cmd when "H" @printer.help_message return PlayerState::ACTION when "N","S","E","W" if cmd=="N" && rc.symbol==:entrance return PlayerState::EXITED else @player.set_location *Castle.move(cmd,*loc) @player.set_facing(cmd.downcase.to_sym) return PlayerState::NEW_ROOM end when 'U' if rc.symbol==:stairs_up @player.set_location *Castle.up(*loc) return PlayerState::NEW_ROOM end @printer.stairs_up_error return PlayerState::ACTION when 'D' if rc.symbol==:stairs_down @player.set_location *Castle.down(*loc) return PlayerState::NEW_ROOM end @printer.stairs_down_error return PlayerState::ACTION when 'DR' if rc.symbol==:magic_pool drink return PlayerState::DIED if @player.dead? return PlayerState::ACTION else @printer.no_pool_error return PlayerState::ACTION end when 'M' @printer.display_map return PlayerState::ACTION when 'F' flare return PlayerState::ACTION when 'L' shine_lamp return PlayerState::ACTION when 'O' if rc.symbol==:book book @castle.set_in_room(*loc,:empty_room) return PlayerState::ACTION elsif rc.symbol==:chest chest_effect = chest() @castle.set_in_room(*loc,:empty_room) return PlayerState::DIED if @player.dead? return PlayerState::NEW_ROOM if chest_effect==:gas return PlayerState::ACTION else @printer.nothing_to_open_error return PlayerState::ACTION end when 'G' if rc.symbol==:crystal_orb gaze return PlayerState::DIED if @player.dead? return PlayerState::ACTION else @printer.no_crystal_orb_error return PlayerState::ACTION end when 'T' if @player.runestaff? teleport return PlayerState::NEW_ROOM else @printer.no_runestaff_error return PlayerState::ACTION end when 'Q' if @prompter.confirm("Y",@printer.prompt_confirm_quit) return PlayerState::QUIT end return PlayerState::ACTION else puts "UNRECOGNIZED COMMAND <#{cmd}>" # should never happen end PlayerState::ACTION end
random_book_effect()
click to toggle source
# File lib/wizards-castle/runner.rb, line 535 def random_book_effect [:flash,:poetry,:magazine,:dex_manual,:str_manual,:sticky].sample end
random_chest_effect()
click to toggle source
# File lib/wizards-castle/runner.rb, line 559 def random_chest_effect [:kaboom,:gold,:gas,:gold].sample end
random_drink_attr_change()
click to toggle source
# File lib/wizards-castle/runner.rb, line 470 def random_drink_attr_change 1+Random.rand(3) end
random_drink_effect()
click to toggle source
# File lib/wizards-castle/runner.rb, line 466 def random_drink_effect [:stronger,:weaker,:smarter,:dumber,:nimbler,:clumsier,:change_race,:change_gender].sample end
random_drink_race_change()
click to toggle source
# File lib/wizards-castle/runner.rb, line 474 def random_drink_race_change (Player::RACES - [@player.race]).sample end
random_gaze_attr_change()
click to toggle source
# File lib/wizards-castle/runner.rb, line 603 def random_gaze_attr_change 1+Random.rand(2) end
random_gaze_effect()
click to toggle source
# File lib/wizards-castle/runner.rb, line 599 def random_gaze_effect [:bloody_heap,:drink_and_become,:monster_gazing_back,:random_room,:zot_location,:soap_opera_rerun].sample end
random_gaze_show_orb_of_zot?()
click to toggle source
# File lib/wizards-castle/runner.rb, line 607 def random_gaze_show_orb_of_zot? Random.rand(2)==0 end
run_battle(monster_symbol)
click to toggle source
# File lib/wizards-castle/runner.rb, line 687 def run_battle(monster_symbol) br = BattleRunner.new(@player,monster_symbol,@printer,@prompter) br.run() end
setup(h={})
click to toggle source
# File lib/wizards-castle/runner.rb, line 39 def setup(h={}) @prompter = h[:prompter] || Prompter.new @castle = h[:castle] || Castle.new @player = h[:player] || Player.new @printer = h[:printer] || StetsonPrinter.new(@player,@castle) end
shine_lamp()
click to toggle source
# File lib/wizards-castle/runner.rb, line 523 def shine_lamp unless @player.lamp? @printer.no_lamp_error return end dir = @prompter.ask(["N","E","W","S"], @printer.prompt_shine_lamp) target_loc = Castle.move(dir,*@player.location) @player.remember_room(*target_loc) @printer.lamp_shine(*target_loc) end
teleport()
click to toggle source
# File lib/wizards-castle/runner.rb, line 632 def teleport row = @prompter.ask_integer(1,8,@printer.prompt_teleport_row) col = @prompter.ask_integer(1,8,@printer.prompt_teleport_column) floor = @prompter.ask_integer(1,8,@printer.prompt_teleport_floor) @player.set_location(row,col,floor) @player.set_teleported(true) end