Object oriented solution to The Tower of Hanoi.
by Rabbit
Here’s my solution to the Tower of Hanoi. I suck at math, so I did it with objects and a story. Join the discussion over at the Ruby Forum.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 | class Peg attr_accessor :discs def initialize(number_of_discs = 0, target = false) @discs, @target = Array.new, target number_of_discs.times { |x| @discs << Disc.new(x) } @discs.reverse! end def take_disc @discs.pop end def acceptable_disc?(disc) return true if @discs.empty? return true if disc.size < @discs.last.size false end def accept_disc(disc) @discs << disc end def target? @target end def full? @discs.size.eql?(4) end def last_disc @discs.pop end def empty? @discs.empty? end end class Disc def initialize(size) @size = size end def size @size end end class Hand def initialize @disc = nil end def disc @disc end def get_disc(peg) @disc = peg.last_disc end def place_disc_on_peg(peg) peg.accept_disc(@disc) @disc = nil end def empty? @disc.nil? end end class Tower def initialize @pegs = [ Peg.new(4), Peg.new, Peg.new(0, true) ] @hand = Hand.new end def play until solved? @pegs.each do |peg| if @hand.empty? @hand.get_disc(peg) unless peg.empty? next end @hand.place_disc_on_peg(peg) if peg.acceptable_disc?(@hand.disc) end end end def solved? target_peg.full? end def target_peg @pegs.find { |peg| peg.target? } end end |
Comments
[...] to my object-oriented solution to the Tower of Hanoi, (portions of) my code read like a story. Stories are easier to grasp than mathematics. At least [...]