Skip to content

Instantly share code, notes, and snippets.

@earthday47
Created December 13, 2016 20:20
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save earthday47/8f3dadb8f90eea04aca54cd3441428c4 to your computer and use it in GitHub Desktop.
Save earthday47/8f3dadb8f90eea04aca54cd3441428c4 to your computer and use it in GitHub Desktop.
An attempt to apply mathematical logic to Myst IV Revelation's insane memory puzzles. Turns out the permutations are on the order of 10^55, but this script will run the moves that produce the solution.
class Place
attr_accessor :name
attr_accessor :phrases
attr_accessor :left_place
attr_accessor :right_place
def initialize(name, initial_phrases)
@name = name
@phrases = initial_phrases
@left_place = nil
@right_place = nil
end
def show
puts "#{@name}"
if @left_place.is_a?(Place) && @right_place.is_a?(Place)
puts " #{@left_place.name} <-> #{@right_place.name}"
end
@phrases.each do |phrase|
puts " #{phrase.id} #{phrase.text}"
end
end
end
class Phrase
attr_accessor :id
attr_accessor :text
def initialize(id, text)
@id = id
@text = text
end
end
class Test
attr_accessor :places
attr_accessor :current_move
attr_accessor :current_place
attr_accessor :phrase_stack
def initialize(places)
@places = places
@current_move = 0
@current_place = nil
@phrase_stack = []
end
def show
@places.each do |place|
place.show
end
puts "Current move: #{@current_move}"
if !@current_place.nil?
puts "Current place: #{@current_place.name}"
else
puts "Current place: (none)"
end
if !@phrase_stack.nil? && @phrase_stack.length > 0
puts "Phrase stack: "
@phrase_stack.each do |phrase|
puts " #{phrase.id} #{phrase.text}"
end
else
puts "Phrase stack: (empty)"
end
end
def availableMoves
if @phrase_stack.length > 0
return ['left', 'right']
else
# if move stack is empty, we can select Places.
commandList = []
@places.each do |place|
commandList << place.name
end
return commandList
end
end
def move(command)
# Check if move is possible.
if !self.availableMoves.nil? and self.availableMoves.include? command
# Execute command.
if command == 'left'
# Move left.
@current_place = @current_place.left_place
# Shift first phrase off the stack and assign it to left_place.
@places[@places.index(@current_place)].phrases << @phrase_stack.shift
elsif command == 'right'
# Move right.
@current_place = @current_place.right_place
# Shift first phrase off the stack and assign it to left_place.
@places[@places.index(@current_place)].phrases << @phrase_stack.shift
else
# Select Place.
placeIndex = @places.index { |place| place.name == command }
@current_place = @places[placeIndex]
# Move Phrases to phrase_stack.
@phrase_stack = @current_place.phrases
@places[placeIndex].phrases = []
end
# Increment move counter.
@current_move += 1
else
puts "Move not possible"
end
end
end
phrase1 = Phrase.new(1, "Daddy's really good at chess.")
phrase2 = Phrase.new(2, "You should play him.")
phrase3 = Phrase.new(3, "I'd like to sis, but I don't have a chess set...")
phrase4 = Phrase.new(4, "You could make one, just like you made my spirit guide...")
phrase5 = Phrase.new(5, "I could...but it's really hard to carve figurines that small.")
phrase6 = Phrase.new(6, "They break so easily.")
phrase7 = Phrase.new(7, "Well, maybe mom and dad could give you a set, as a present.")
phrase8 = Phrase.new(8, "I'll tell them to when I link home.")
phrase9 = Phrase.new(9, "Right. And I suppose you'll tell them to make it out of the same rock as this chamber.")
phrase10 = Phrase.new(10, "That way I'll never be able to break it!")
chessboard = Place.new("chessboard", [phrase8, phrase4, phrase3])
statue = Place.new("statue", [phrase1])
picture = Place.new("picture", [phrase7, phrase9])
book = Place.new("book", [phrase2, phrase5, phrase10])
door = Place.new("door", [phrase6])
# Define Place assocations.
chessboard.left_place = statue
chessboard.right_place = door
statue.left_place = picture
statue.right_place = chessboard
picture.left_place = book
picture.right_place = statue
book.left_place = door
book.right_place = picture
door.left_place = chessboard
door.right_place = book
# Start first test to get solution.
test1 = Test.new([chessboard, statue, picture, book, door])
# test1.show
# Move 1: door, left
test1.move('door')
test1.move('left')
# Move 2: book, left, right, right
test1.move('book')
test1.move('left')
test1.move('right')
test1.move('right')
# Move 3: door, left
test1.move('door')
test1.move('left')
# Move 4: book, left
test1.move('book')
test1.move('left')
# Move 5: door, left
test1.move('door')
test1.move('left')
# Move 6: statue, right
test1.move('statue')
test1.move('right')
# Move 7: chessboard, left, right, right, left, right, left, right
test1.move('chessboard')
test1.move('left')
test1.move('right')
test1.move('right')
test1.move('left')
test1.move('right')
test1.move('left')
test1.move('right')
# Move 8: statue, left
test1.move('statue')
test1.move('left')
# Move 9: chessboard, left, right, left
test1.move('chessboard')
test1.move('left')
test1.move('right')
test1.move('left')
# Move 10: chessboard, left
test1.move('chessboard')
test1.move('left')
# Move 11: door, left, right, left
test1.move('door')
test1.move('left')
test1.move('right')
test1.move('left')
# Move 12: chessboard, right, left
test1.move('chessboard')
test1.move('right')
test1.move('left')
# Move 13: door, left, right
test1.move('door')
test1.move('left')
test1.move('right')
# Move 14: door, left
test1.move('door')
test1.move('left')
# Move 15: picture, left, left, right, right
test1.move('picture')
test1.move('left')
test1.move('left')
test1.move('right')
test1.move('right')
# Move 16: book, right, left
test1.move('book')
test1.move('right')
test1.move('left')
# Move 17: book, left
test1.move('book')
test1.move('left')
# Move 18: picture, left, right
test1.move('picture')
test1.move('left')
test1.move('right')
test1.show
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment