Polyglot

Build Valuable Systems, Better and Faster

A Taste of Ruby (Part 7)

This is a multi-part series. The first in the series is here.

Tower of Hanoi — Rules on Rails

In part 6 we changed the algorithm of Tower Of Hanoi to work without requiring the stack – it instead “more naturally” put sufficient state and logic into the model that the model could start and stop and continue as needed. I believe with Ruby 1.8.x, this is required to have Rails be able to work with the Tower of Hanoi. So we should try it out and see how well it works :-)

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
require 'hanoi_7'

class HanoiController < ApplicationController
  def say
    @hanoi = session[:hanoi]

    if (@hanoi == nil) then
      @hanoi = createHanoi
      session[:count] = 0
      session[:consoleLog] = ""
    end


    @hanoi.initApp(self)
    @isDone = @hanoi.doNextMove_IsDone()

    #clear the app because otherwise it will be part of the attempted serialization
    #could also override the marshaling code, but this is simpler
    @hanoi.initApp(nil)

    #clear out the session variable, but @hanoi is still valid through
    #the rest of this interaction
    session[:hanoi] = @isDone ? nil : @hanoi

    @count = session[:count] ||= 0
    @count += 1
    session[:count] = @count

    if (@isDone) then
      render(:action => 'say_done')
    end
  end

  def appendLog(outString)
    logger.info("Append to Log: "+outString)
    @consoleLog = session[:consoleLog] ||= "\n"
    @consoleLog = @consoleLog + outString + "\n"
    session[:consoleLog] = @consoleLog
  end

  def noteChange

  end

  def createHanoi
    hanoi = RulesTowerOfHanoi.new
    hanoi.initHeight(5)
    hanoi.setup_disks

    return hanoi
  end

  def getAsciiTowers
    result = ""
    lines = Array.new
    @hanoi.stacks.each_with_index do | eachStack, i |
      0.upto(10) do | j |
        eachDisk = eachStack[j]
        if (eachDisk == nil) then
          newLine = " "*12
        else
          newLine = eachDisk.to_s
        end

        newLine << " "*(12 - newLine.length)

        currentLine = lines[j] ||= ""
        lines[j] = currentLine+" "+newLine
      end
    end
    lines.reverse.each {|line| result += line + "\n"}

    return result
  end

end
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
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN"
        "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">

<html xmlns="http://www.w3.org/1999/xhtml" xml:lang="en" lang="en">
<head>
<title>Foo <%= @page_title %></title>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8" />
<meta http-equiv="refresh" content="1">
<%= javascript_include_tag :defaults %>
</head>

<body<% if @page_class %> class="<%= @page_class %>"<% end %>>

<h1>Tower of Hanoi (Move <%= @count %>) </h1>

It's <%= Time.now %>.
<br/>
Done = <%= @isDone %>
<br/>
Render =
<pre>
<%= controller.getAsciiTowers %>
</pre>
Log =
<pre>
<%= @consoleLog %>
</pre>

</body>

Comments