This is a multi-part series. The first in the series is here.
Tower of Hanoi — With Graphics
To follow the flow of code progress within “A Taste of Smalltalk”, we next need to include a graphical representation of the disks and their movement between the poles. As mentioned previously, converting this part to Ruby has a problem: Ruby doesn’t include graphic capabilities. So we have to pick an extension or add-on to Ruby that will enable us to hook into the graphics system.
Because it seems the easiest to work with, I chose ‘Shoes’ (http://code.whytheluckystiff.net/shoes/). The installation of Shoes is very simple and you just run your ‘app’ inside Shoes application world, which includes Ruby itself, the graphic capabilities, and the UI framework.
Shoes seems simple and clean, the only problem is it doesn’t work within an IDE, so I lost a bit of tooling while doing this. With the final running program, this isn’t a problem but it can be painful if you are learning, tweaking, or studying things. So because this could be painful to others as well, I made the main code base able to run inside a normal irb, and in that case it just logs to the console like it always has been.
The main new class is AnimatedTowerOfHanoi, which is really just a notifying version of ModeledTowerOfHanoi. This pass also has some cleanup of the previous code of ModeledTowerOfHanoi. So I include all three classes below
The New Classes
TowerOfHanoi
This is still the same as the original from ‘Part 2’
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 |
|
ModeledTowerOfHanoi
The ModeledTowerOfHanoi has been cleaned up a little to make subclassing easier and just because it was the right thing to do. Specifically,
There was a fix to the ‘move’ algorithm, so we tell the disk onto which disk it is moving
Some common methods are pulled out
Disks are now responsible for describing the move
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 109 110 111 112 113 114 115 116 |
|
AnimatedTowerOfHanoi
Now we are finally to the new “animated” class. The main changes for this class are to enable it to talk to an owning ‘application’ if it exists and also it starts hooking into the Shoes code. For convenience, I made the behavior of the class branch based on whether that ‘@app’ exists. The final change is that AnimatedHanoiDisk does a sleep so we can see the animation. This affects both console and graphic behavior.
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 |
|
Running via ‘irb’
You can test the above code by running it in the normal Ruby console
1
|
|
Putting on the Shoes
If you have Shoes running successfully, you can combine the above code with a Shoes app which visualizes the state of the towers. The Shoes code is:
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 |
|
The Shoes app has the main drawing area at the top and then a logging area beneath it. The HanoiStacks are cleared and redrawn any time they change. The original Smalltalk code used deltas (disks were moved individually) but that didn’t seem critical to match, and partially the code is relying on being on a black-and-white screen.
Comments
Not having a standard Graphics capability is not surprising or a problem for a scripting language (limited in context of usage) but is quite a problem for a language that wants to be mainstream. There is a similar problem on the server-side with a standard (off-screen) image processing. Shoes and RMagick and the like are trying to fill these holes but Ruby has been around for a long time for these aspects to not be addressed and part of the standard.
In terms of the resulting code with Shoes, the Ruby version is certainly nice and clean.
Where Next?
The last code-changing chapter deals with making the Algorithm a little more human-natural. If people are interested, I may do that change too. But comparatively it is a pretty minor change and does not bring out any interesting language aspects.