Skip to content

Instantly share code, notes, and snippets.

@br3nt
Last active July 16, 2019 13:36
Show Gist options
  • Save br3nt/2c7ef1afdbc4d0be924ecd5c17050f96 to your computer and use it in GitHub Desktop.
Save br3nt/2c7ef1afdbc4d0be924ecd5c17050f96 to your computer and use it in GitHub Desktop.
The Caves of Lemaria

One of the earliest Ruby constructs I learned about was Hash.new {|h, k| h[k] = {} }. This small one-liner is explored in many Ruby tutorials and it completely captured my imagination. I've never been able to use this in a production app as I've always found a better solution. However, one thing it might be good for is to take you on a short journey.

This journey will be interactive, so you will need to copy snippets of code into an irb or pry console. I recommend using ruby 2.6 or higher as the copy-paste functionality is better (and I havn't debugged on lower versions).

UPDATE: I've now added the caves_of_lemaria.rb script which will run through the whole adventure!

Before we begin, lets make a slight change to my chosen code snippet...

def map
  Hash.new do |places, o| # an outer hash to hold a bunch of places
    places[o] =
      Hash.new do |destinations, d| # an inner hash to hold all the destinations
        destinations[d] = nil
      end
  end
end

You will play the part of the main character in this journey!

puts "What is your name, epic adventurer?"; our_hero = gets.chomp

So, the story has to start somewhere...

Somewhere = Struct.new(:name, :description, :map)

our_hero lives in a place called Lemaria...

lemaria = Somewhere.new('Lemaria', 'A beautiful remote village', map).

Lemaria has a bit of everything...

home = Somewhere.new('Home', 'A peaceful cottage with a nice warm fire crackling inside.', map)
town = Somewhere.new('Town Center', 'A bustling town with a vibrant and noisy market bazzar', map)
forest = Somewhere.new('Forest', 'A forest with an abundance of flora and fauna', map)
mountains = Somewhere.new('Mountains', 'A towering mountain range with snow covered peaks', map)
cave = Somewhere.new('Cave', 'A dark damp cave with many winding and forking passages', map)

The map of Lemaria looks something like this...

#        T <---+
#        ^     |     H = Home
#        v     V     T = Town Center
#        F <-> H     F = Forest
# ^      ^           M = Mountains
#    ^   |           C = Cave
# ^   ^  V
#   +--> M     ^
# ^ |    ^  ^    ^       ^
#   | ^  |    ^     ^
#   C----+ ^    ^    ^

lemaria.map[home][town]
lemaria.map[home][forest]
lemaria.map[town][home]
lemaria.map[town][forest]
lemaria.map[forest][home]
lemaria.map[forest][town]
lemaria.map[forest][mountains]
lemaria.map[mountains][forest]
lemaria.map[mountains][cave]
lemaria.map[cave][mountains]

our_hero heads to town and overhears one of the shop owners talking about a group of tourists that have ventured up the mountains and noone has heard from them for several days.

our_hero is adventurous and courageous, and volunteers to look for the lost tourists. our_hero heads back home to pack some supplies for the potentially perilous journey ahead.

As our_hero treks through the forest, a woodcutter approaches. The woodcutter confirms the tourists passed by this way, and that they were going to map the passages in the cave up the mountain.

our_hero has travelled up the mountain many times before and has no trouble finding the cave.

The cave network is vast, many people have attempted to navigate the cave system, but very few have returned. It's was the site of an old mine, and is even rumoured to have been used for satanic cult worship!

our_hero has very little idea of what the cave system actually looks like. The dark dank cave looms before our_hero:

# I would recommend copying this line bby line to prevent errors
e = "VGhlIGVudHJhbmNlIHRvIHRoZSBjYXZlIHN0YW5kcyBiZWZvcmUgJXM="; a = "QW4gaW5zY3JpcHRpb24gb24gdGhlIHdhbGwgcmVhZHMgIk51bWVyYSBvbW5l\ncyBxdWkgaW5ncmVkaXVudHVyIGNhdmVhbnQi"; cave.map[:entrance][a] = "JXMgZW50ZXJzIHRoZSBjYXZl"; cave.map[a][:entrance] = "JXMgbGVhdmVzIHRoZSBjYXZl"; cave.map[a][19]; cave.map[19][a]; cave.map[a][2]; cave.map[2][a]; cave.map[2][3]; cave.map[3][2]; cave.map[2][4]; cave.map[4][2]; d1 = "JXMgZmFsbHMgZG93biBhIGRlZXAgaG9sZS4="; cave.map[3][d1];
cave.map[3][5] = "JXMgZm91bmQgYSBtYXAhCgogICAgICAgICAgICAqCiAgICAgICAgICAgIHwK\nICAgICAgIE8gICAgKi0tKi0tKiAgICAgICAgICAgICotLS0qLS0tKgogICAg\nICAgfCAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICB8CiAgICAgICAq\nLS0tLSotLSotLUAgICAgKiAgICAgICA9ICAgICAgIHwKICAgICAgIHwgICAg\nfCAgfCAgICAgICB8ICAgICAgIHwgICAgICAgfAogICAgICAgfCAgICB8ICAq\nICAgICotLSogICAgICAgKiAgICAgICB8CiAgICAgICAqLS0tLSogIHwgICAg\nICAgfCAgICAgICB8ICAgICAgIHwKICAgICAgIHwgICAgICAgKi0tLSotLS0q\nLS0tKi0tLSogICAgICAgfCAgICAgICAqCmUgLS0tLSAqICAgICAgICAgICAg\nICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgfAogICAgICAgfCAgICAgICAg\nICAgICAgICogICAgICAgKi0tLS0tLS0qLS0tKi0tLSoKICAgICAgIHwgICAg\nICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICB8CiAgICAgICB8\nICAgICAgIF9fXyAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgKgogICAg\nICAgKi0tLS0tLXsgX18gICAgIEwgICAgICAgICAgICAgICAgICAgICAgIHwK\nICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\nICB8CiAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAg\nICAgICAgKgogICAgICAgICAgICAgICotLS0tIwo=\n";
cave.map[5][3]; cave.map[4][5]; cave.map[5][4]; cave.map[5][8]; cave.map[8][5]; cave.map[5][6]; cave.map[6][5]; a2 = "QW4gYWx0ZXIgc3RhbmRzIGluIHRoZSBjZW50ZXIgb2YgdGhlIHJvb20gd2l0\naCBjcmVlcHkgbXVyYWxzIG9mIGRhZW1vbnM="; cave.map[6][a2]; cave.map[a2][6]; cave.map[6][13]; cave.map[13][6]; h = "QW4gb2xkIG1pbmVycyBoYXQgc2l0cyBieSB0aGUgd2FsbA=="; cave.map[8][h]; cave.map[h][8]; cave.map[8][9]; cave.map[9][8]; cave.map[9][11]; cave.map[11][9]; b = "QW4gb2xkIGJvb3Qgc2l0cyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBjYXZl"; cave.map[13][b]; cave.map[b][13]; cave.map[b][15]; cave.map[15][b]; cave.map[15][16]; cave.map[16][15]; cave.map[16][18]; cave.map[18][16]; b1 = "QXJnISBCYXRz"; cave.map[16][b1]; cave.map[b1][16]; cave.map[16][21]; cave.map[21][16];
cave.map[21][22]; cave.map[22][21]; cave.map[21][39]; cave.map[39][21]; t = "dG91cmlzdHM="; cave.map[39][t]; cave.map[t][39]; c3 = "QXQgdGhlIHRvcCBhIGNsaWZmIGluIGEgbGFyZ2UgY2F2ZXJuLCAlcyBkb2Vz\nbid0IHNlZSB0aGUgZWRnZSBhbmQgZmFsbHM="; cave.map[18][c3]; c1 = "JXMgZW50ZXJzIGEgbGFyZ2UgY2F2ZXJu"; cave.map[19][c1] ; cave.map[c1][19]; cave.map[c1][36]; cave.map[36][c1]; c2 = "JXMgaXMgaW4gYSBsYXJnZSBjYXZlcm4gYXQgdGhlIGJhc2Ugb2YgYSBjbGlm\nZg=="; cave.map[c1][c2]; cave.map[c2][c1]; m = "QW4gYWJhbmRvbmVkIG1pbmUgc2hhZnQ="; cave.map[36][m]; cave.map[m][36]; cave.map[17][23]; cave.map[23][17]; cave.map[23][25]; cave.map[25][23]; cave.map[23][24]; cave.map[24][23]; cave.map[24][30]; cave.map[30][24]; n = "JXMgc3F1ZWV6ZXMgdGhyb3VnaCBhIG5hcnJvdyBwYXNzYWdld2F5"; cave.map[25][n]; cave.map[n][25]; cave.map[n][27];
cave.map[27][n]; cave.map[27][28]; cave.map[28][27]; w = "JXMgd2Fsa3MgaW50byBhIGdpYW50IHNwaWRlcndlYiE="; cave.map[28][w]; cave.map[w][28]; cave.map[w][30]; cave.map[30][w]; cave.map[30][32]; cave.map[32][30]; cave.map[32][33]; cave.map[33][32]; cave.map[33][34]; cave.map[34][33]; cave.map[33][35]; cave.map[35][33]; s = "QSBodW1hbiBza2VsZXRvbi4uLiBwb29yIGd1eQ==";
cave.map[35][s]; cave.map[s][35];

our_hero decides to come up with a navigation strategy before entering the cave:

def navigation_strategy(graph, start_node)
  Enumerator.new do |enum|
    visited_rooms = []
    unvisited_queue = [start_node]
    path = []

    while unvisited_queue.any?
      room = unvisited_queue.pop
      previous_room = path.last
      path.push(room) unless path.last == room
      selected_room = enum.yield(room, graph[room], visited_rooms, previous_room, path)
      path = path[0...path.index(selected_room)]
      unvisited_queue.push(selected_room)
      visited_rooms.push(room)
    end
  end
end

our_hero wants to document the journey incase the worst should happen:

narration = proc do |room, options, visited, previous_room|
  require 'base64'

  passage_text = cave.map[previous_room][room] if cave.map[previous_room].keys.include?(room)
  puts Base64.decode64(passage_text) % our_hero if passage_text
  puts

  if room == :entrance then puts Base64.decode64("VGhlIGVudHJhbmNlIHRvIHRoZSBjYXZlIHN0YW5kcyBiZWZvcmUgJXMhCg==") % our_hero
  elsif options.count == 0 then puts Base64.decode64("JXMgZGllcyE=") % our_hero
  elsif options.count == 1 then puts Base64.decode64("QSBkZWFkIGVuZCEgJXMgbXVzdCBoZWFkIGJhY2s=") % our_hero
  elsif options.count == 2 then puts Base64.decode64("JXMgY29udGludWVzIGRvd24gYSBwYXNzYWdld2F5") % our_hero
  elsif options.count > 2 then puts Base64.decode64("JXMgZW5jb3VudGVycyBhIGZvcmtpbmcgcGF0aCE=") % our_hero
  end
  puts

  if room.is_a?(String)
    text = Base64.decode64(room)
    if text == 'tourists'
      puts Base64.decode64("JXMgZm91bmQgdGhlIHRvdXJpc3RzIQ==") % our_hero
      puts Base64.decode64("VGhleSBhcmUgc28gaGFwcHkgdG8gYmUgcmVzY3VlZCE=") % our_hero
    else
      puts text % our_hero
    end
  end

  puts Base64.decode64("JXMgaGFzIGJlZW4gaGVyZSBiZWZvcmU=") % our_hero if visited.include?(room)
  puts
end

our_hero feels that some devine intervention may be required on this epic quest:

interaction = proc do |room, room_options, visited, previous_room, path|
  narration.call(room, room_options, visited, previous_room)
  next if room_options.empty?

  available_paths = room_options.each_with_index.collect do |(key, _), i|
    attributes = []
    if key == :entrance
      attributes << :entrance
    else
      attributes << :visited if visited.include?(key)
      attributes << :back if previous_room == key
    end
    text = (i + 1).to_s
    text = '%s (%s)' % [text, attributes.join('|')] if attributes.any?
    [key, text]
  end

  puts 'Which way will %s go? Available paths: %s' % [our_hero, available_paths.collect {|_, t| t}.join(', ')]
  
  while (option = gets.chomp.to_i) == 0 || option > room_options.count
    puts "I'm sorry %s, I'm afraid you can't do that" % our_hero
  end
  puts

  available_paths[option - 1].first
end

Finally, our_hero is ready to venture into the cave to resucue the poor tourists. our_hero can leave the cave at any time by pressing ctrl+c.

navigation_strategy(cave.map, :entrance).each(&interaction)

our_hero saved the day!!

A great feast is held in lemaria to celbrate the return of our_hero and the rescued tourists.

I really hope you enjoyed the interactive journey! I wanted to give you something different, yet very truely in the spirit of Ruby.

In closing, my code snippet, Hash.new {|h, k| h[k] = {} }, did the job, but there were many gotchas and edgecases that made debugging very hard and confusing. As always, a dedecated object model would have been a better solution. Oh well...

Best regards, Brent

#!/usr/bin/env ruby
puts
puts
puts "What is your name, epic adventurer?"
print "> "
our_hero = gets.chomp
while our_hero =~ /\A\s*\Z/
puts
puts "Come now, step up to the challenge!"
puts "What is your name?"
print "> "
our_hero = gets.chomp
end
puts
puts "#{our_hero}, you will play the part of the main character in this journey!"
puts
print "Do you want to continue? "
gets
puts
puts "Well then, let's go!"
sleep 2
##################
# Set up Lemaria
##################
def map
Hash.new do |places, o| # an outer hash to hold a bunch of places
places[o] =
Hash.new do |destinations, d| # an inner hash to hold all the destinations
destinations[d] = nil
end
end
end
Somewhere = Struct.new(:name, :description, :map)
lemaria = Somewhere.new('Lemaria', 'A beautiful remote village', map)
home = Somewhere.new('Home', 'A peaceful cottage with a nice warm fire crackling inside.', map)
town = Somewhere.new('Town Center', 'A bustling town with a vibrant and noisy market bazzar', map)
forest = Somewhere.new('Forest', 'A forest with an abundance of flora and fauna', map)
mountains = Somewhere.new('Mountains', 'A towering mountain range with snow covered peaks', map)
cave = Somewhere.new('Cave', 'A dark damp cave with many winding and forking passages', map)
lemaria.map[home][town]
lemaria.map[home][forest]
lemaria.map[town][home]
lemaria.map[town][forest]
lemaria.map[forest][home]
lemaria.map[forest][town]
lemaria.map[forest][mountains]
lemaria.map[mountains][forest]
lemaria.map[mountains][cave]
lemaria.map[cave][mountains]
puts
puts "#{our_hero} lives in a place called #{lemaria.name}..."
sleep 2
puts
puts "#{lemaria.name} has a bit of everything..."
lemaria.map.keys.each do |place|
sleep 2
puts place.description
end
sleep 2
puts
puts "The map of #{lemaria.name} looks something like this..."
sleep 1
puts
puts <<-MAP
T <---+
^ | H = Home
v V T = Town Center
F <-> H F = Forest
^ ^ M = Mountains
^ ^ | C = Cave
^ ^ ^ V
+--> M ^
^ | ^ ^ ^ ^
^ | ^ | ^ ^
C----+ ^ ^ ^
^ ^ ^
^ ^ ^
MAP
puts
puts
sleep 4
puts <<-TEXT
#{our_hero} heads to town and overhears one of the shop owners that a group of tourists have
ventured up the mountains and noone has heard from them for several days.
TEXT
sleep 2
puts
puts <<-TEXT
#{our_hero} is adventurous and courageous, and volunteers to look for the lost tourists.
TEXT
sleep 2
puts
puts <<-TEXT
#{our_hero} heads back home to pack some supplies for the potentially perilous journey ahead.
TEXT
sleep 4
puts
puts <<-TEXT
As #{our_hero} treks through the forest, a woodcutter approaches.
TEXT
sleep 4
puts
puts <<-TEXT
The woodcutter confirms the tourists passed by this way, and that they were going to map the
passages in the cave up the mountain.
TEXT
sleep 4
puts
puts <<-TEXT
#{our_hero} has travelled up the mountain many times before and has no trouble finding the cave.
TEXT
sleep 2
puts
puts <<-TEXT
The cave network is vast, many people have attempted to navigate the cave system, but very few
have returned.
TEXT
sleep 2
puts
puts <<-TEXT
It's was the site of an old mine, and is even rumoured to have been used for satanic cult worship!
TEXT
sleep 4
puts
puts <<-TEXT
#{our_hero} has very little idea of what the cave system actually looks like.
TEXT
sleep 4
puts
puts <<-TEXT
The dark dank cave looms before #{our_hero}:
TEXT
sleep 4
#########################
# Set up the cave system
#########################
e = "VGhlIGVudHJhbmNlIHRvIHRoZSBjYXZlIHN0YW5kcyBiZWZvcmUgJXM="; a = "QW4gaW5zY3JpcHRpb24gb24gdGhlIHdhbGwgcmVhZHMgIk51bWVyYSBvbW5l\ncyBxdWkgaW5ncmVkaXVudHVyIGNhdmVhbnQi"; cave.map[:entrance][a] = "JXMgZW50ZXJzIHRoZSBjYXZl"; cave.map[a][:entrance] = "JXMgbGVhdmVzIHRoZSBjYXZl"; cave.map[a][19]; cave.map[19][a]; cave.map[a][2]; cave.map[2][a]; cave.map[2][3] = "VGhlIHNvdW5kIG9mIHdhdGVyIHRyaWNrbGUgdGhyb3VnaCB0aGUgY2F2ZQ=="; cave.map[3][2]; cave.map[2][4]; cave.map[4][2]; d1 = "JXMgZmFsbHMgZG93biBhIGRlZXAgaG9sZS4="; cave.map[3][d1];
cave.map[3][5] = "JXMgZm91bmQgYSBtYXAhCgogICAgICAgICAgICAqCiAgICAgICAgICAgIHwK\nICAgICAgIE8gICAgKi0tKi0tKiAgICAgICAgICAgICotLS0qLS0tKgogICAg\nICAgfCAgICB8ICAgICAgICAgICAgICAgICAgfCAgICAgICB8CiAgICAgICAq\nLS0tLSotLSotLUAgICAgKiAgICAgICA9ICAgICAgIHwKICAgICAgIHwgICAg\nfCAgfCAgICAgICB8ICAgICAgIHwgICAgICAgfAogICAgICAgfCAgICB8ICAq\nICAgICotLSogICAgICAgKiAgICAgICB8CiAgICAgICAqLS0tLSogIHwgICAg\nICAgfCAgICAgICB8ICAgICAgIHwKICAgICAgIHwgICAgICAgKi0tLSotLS0q\nLS0tKi0tLSogICAgICAgfCAgICAgICAqCmUgLS0tLSAqICAgICAgICAgICAg\nICAgfCAgICAgICB8ICAgICAgIHwgICAgICAgfAogICAgICAgfCAgICAgICAg\nICAgICAgICogICAgICAgKi0tLS0tLS0qLS0tKi0tLSoKICAgICAgIHwgICAg\nICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICB8CiAgICAgICB8\nICAgICAgIF9fXyAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgKgogICAg\nICAgKi0tLS0tLXsgX18gICAgIEwgICAgICAgICAgICAgICAgICAgICAgIHwK\nICAgICAgICAgICAgICB8ICAgICAgICAgICAgICAgICAgICAgICAgICAgICAg\nICB8CiAgICAgICAgICAgICAgfCAgICAgICAgICAgICAgICAgICAgICAgICAg\nICAgICAgKgogICAgICAgICAgICAgICotLS0tIwo=\n";
cave.map[5][3]; cave.map[4][5]; cave.map[5][4]; cave.map[5][8]; cave.map[8][5]; cave.map[5][6]; cave.map[6][5]; a2 = "QW4gYWx0ZXIgc3RhbmRzIGluIHRoZSBjZW50ZXIgb2YgdGhlIHJvb20gd2l0\naCBjcmVlcHkgbXVyYWxzIG9mIGRhZW1vbnM="; cave.map[6][a2]; cave.map[a2][6]; cave.map[6][13]; cave.map[13][6]; h = "QW4gb2xkIG1pbmVycyBoYXQgc2l0cyBieSB0aGUgd2FsbA=="; cave.map[8][h]; cave.map[h][8]; cave.map[8][9]; cave.map[9][8]; cave.map[9][11]; cave.map[11][9]; b = "QW4gb2xkIGJvb3Qgc2l0cyBpbiB0aGUgbWlkZGxlIG9mIHRoZSBjYXZl"; cave.map[13][b]; cave.map[b][13]; cave.map[b][15]; cave.map[15][b]; cave.map[15][16]; cave.map[16][15]; cave.map[16][18]; cave.map[18][16]; b1 = "QXJnISBCYXRz"; cave.map[16][b1]; cave.map[b1][16]; cave.map[16][21]; cave.map[21][16];
cave.map[21][22]; cave.map[22][21]; cave.map[21][39]; cave.map[39][21]; t = "dG91cmlzdHM="; cave.map[39][t]; cave.map[t][39]; c3 = "QXQgdGhlIHRvcCBhIGNsaWZmIGluIGEgbGFyZ2UgY2F2ZXJuLCAlcyBkb2Vz\nbid0IHNlZSB0aGUgZWRnZSBhbmQgZmFsbHM="; cave.map[18][c3]; c1 = "JXMgZW50ZXJzIGEgbGFyZ2UgY2F2ZXJu"; cave.map[19][c1] ; cave.map[c1][19]; cave.map[c1][36]; cave.map[36][c1]; c2 = "JXMgaXMgaW4gYSBsYXJnZSBjYXZlcm4gYXQgdGhlIGJhc2Ugb2YgYSBjbGlm\nZg=="; cave.map[c1][c2]; cave.map[c2][c1]; m = "QW4gYWJhbmRvbmVkIG1pbmUgc2hhZnQ="; cave.map[36][m]; cave.map[m][36]; cave.map[17][23]; cave.map[23][17]; cave.map[23][25]; cave.map[25][23]; cave.map[23][24]; cave.map[24][23]; cave.map[24][30]; cave.map[30][24]; n = "JXMgc3F1ZWV6ZXMgdGhyb3VnaCBhIG5hcnJvdyBwYXNzYWdld2F5"; cave.map[25][n]; cave.map[n][25]; cave.map[n][27];
cave.map[27][n]; cave.map[27][28]; cave.map[28][27]; w = "JXMgd2Fsa3MgaW50byBhIGdpYW50IHNwaWRlcndlYiE="; cave.map[28][w]; cave.map[w][28]; cave.map[w][30]; cave.map[30][w]; cave.map[30][32]; cave.map[32][30]; cave.map[32][33]; cave.map[33][32]; cave.map[33][34]; cave.map[34][33]; cave.map[33][35]; cave.map[35][33]; s = "QSBodW1hbiBza2VsZXRvbi4uLiBwb29yIGd1eQ==";
cave.map[35][s]; cave.map[s][35];
#########################
# Set up the game engine
#########################
tourists_found = false
end_game = false
def navigation_strategy(graph, start_node)
Enumerator.new do |enum|
visited_rooms = []
unvisited_queue = [start_node]
path = []
while unvisited_queue.any?
room = unvisited_queue.pop
previous_room = path.last
path.push(room) unless path.last == room
selected_room = enum.yield(room, graph[room], visited_rooms, previous_room, path)
path = path[0...path.index(selected_room)]
unvisited_queue.push(selected_room)
visited_rooms.push(room)
end
end
end
narration = proc do |room, options, visited, previous_room|
require 'base64'
passage_text = cave.map[previous_room][room] if cave.map[previous_room].keys.include?(room)
puts Base64.decode64(passage_text) % our_hero if passage_text
puts
if room == :entrance
puts Base64.decode64("VGhlIGVudHJhbmNlIHRvIHRoZSBjYXZlIHN0YW5kcyBiZWZvcmUgJXMhCg==") % our_hero
elsif options.count == 0
end_game = true
puts Base64.decode64("JXMgZGllcyE=") % our_hero
elsif options.count == 1
puts Base64.decode64("QSBkZWFkIGVuZCEgJXMgbXVzdCBoZWFkIGJhY2s=") % our_hero
elsif options.count == 2
puts Base64.decode64("JXMgY29udGludWVzIGRvd24gYSBwYXNzYWdld2F5") % our_hero
elsif options.count > 2
puts Base64.decode64("JXMgZW5jb3VudGVycyBhIGZvcmtpbmcgcGF0aCE=") % our_hero
end
puts
if room.is_a?(String)
text = Base64.decode64(room)
if text == 'tourists'
tourists_found = true
puts Base64.decode64("JXMgZm91bmQgdGhlIHRvdXJpc3RzIQ==") % our_hero
puts Base64.decode64("VGhleSBhcmUgc28gaGFwcHkgdG8gYmUgcmVzY3VlZCE=") % our_hero
else
puts text % our_hero
end
end
puts Base64.decode64("JXMgaGFzIGJlZW4gaGVyZSBiZWZvcmU=") % our_hero if visited.include?(room)
puts
end
interaction = proc do |room, room_options, visited, previous_room, path|
narration.call(room, room_options, visited, previous_room)
next if room_options.empty?
next if room == :entrance && tourists_found
available_paths = room_options.each_with_index.collect do |(key, _), i|
attributes = []
if key == :entrance
attributes << :entrance
else
attributes << :visited if visited.include?(key)
attributes << :back if previous_room == key
end
text = (i + 1).to_s
text = '%s (%s)' % [text, attributes.join('|')] if attributes.any?
[key, text]
end
puts 'Which way will %s go? Available paths: %s' % [our_hero, available_paths.collect {|_, t| t}.join(', ')]
while (option = gets.chomp.to_i) == 0 || option > room_options.count
puts "I'm sorry %s, I'm afraid you can't do that" % our_hero
end
puts
available_paths[option - 1].first
rescue => e
binding.pry
raise e
end
navigation_strategy(cave.map, :entrance).each(&interaction)
puts
if tourists_found
puts
puts "#{our_hero} saved the day!!"
sleep 5
puts
puts "A great feast is held in lemaria to celbrate the return of #{our_hero} and the rescued tourists."
sleep 5
elsif end_game
else
puts
puts "#{our_hero}..."
sleep 5
puts
puts "The villiage of Lemaria will just need to wait for another epic adventurer..."
sleep 5
puts
puts "I hope the tourists will survive until then..."
sleep 5
puts
puts "I hope you're happy... this is a very dissapointing end to the story!"
end
puts
puts "THE END"
gets
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment