book cover
book cover

You Can Do It!

A Beginner's Introduction to Computer Programming

by Francis Glassborow with Roberta Allen

Home      Contact Us      News & Updates

Readers' Programs

This is the place where programs sent in by readers will be made available. If you wrote a program that was substantially different to a solution provided in the book please send it in so that others can share it.

Also if you wrote an original program based on what you have learnt please share it here. When you send it please include information about where you were in the book when you wrote it.

Towers of Hanoi by Richard Elderton

How to play

You are given a number of discs (normally 5), each a different size, and three base positions for stacking them. The game is set up by making a single tower of discs stacked in diminishing order of size.

The aim of the game is to transfer the tower of discs onto another base position by restacking them one disc at a time. No disc may be placed on top of a smaller disc at any time, but any base position may be used during the transfer process.

A tower of 5 discs can be restacked using only 31 moves, one having 9 discs requires 511 moves.

In this version of the game, bases are represented by hyphens (-), and discs by the numerals 1 - 5.

At the start of each game or autoplay demonstration you will be asked to choose the number of discs and the starting base position.

There is a counter to display the number of moves taken.

Source Code and Challenge

Download a zip file with the source code for Richard's program Hanoi Source

When you have got the provided code to work, improve it. In particular add a graphical visualisation of the solution in a Playpen.

The first correct solution sent to me, Francis Glassborow, will win a copy of my forthcoming book 'You Can Program in C++' which tackles much more of C++ and extends your knowledge of C++ as a programming language.

Lorenz Attractor from Martin Ross

Below is a reasonably simple program to plot the Lorenz attractor. Mostly I have used things in the book, though I have used a struct - I thought it would not look good to declare a class and then make all the data public. I have also retained elements of my own style where they did not go too much against the book's style. Where am I in the book? Difficult to say as I am a reasonably experienced programmer in a number of languages, some as a professional others as an amateur. In C++ I am an amateur though more experienced that the sort of beginner the book is aimed at.

[I am publishing the complete code as an example of what can be achieved whilst staying within the limits of this book.]

~~ Program: Lorenz.cpp ~~~~~~~~~~~~~~~~~~~~~~~~~~~

// This plots a Lorenz Attractor in the playpen

// Version Date Author Comments
// 01.00 Jan 2005 Martin Ross Initial Version
//

#include "keyboard.h"
#include "line_drawing.h"
#include "point2dx.h"

#include <iostream>

using namespace fgw;

//-------------------------------------

struct Point3d {
double x;
double y;
double z;

Point3d(double xx = 0.0,
double yy = 0.0,
double zz = 0.0)
: x(xx), y(yy), z(zz) {}
}; // end struct Point3d

//-------------------------------------

void draw_Lorenz(playpen & graph);

//-------------------------------------

int main() {
playpen graph;

draw_Lorenz(graph);

std::cout <<"Press [Enter] to finish...";
std::cin.get();

return EXIT_SUCCESS;
} // end main()
//-------------------------------------

// Works out the next point on the curve
Point3d next_point(Point3d const & p) {
double const eight_thirds = 8.0 / 3.0;
double const dx = 10.0 * (p.y - p.x);
double const dy = p.x * (28.0 - p.z) - p.y;
double const dz = p.x * p.y - eight_thirds * p.z;
double const dt = 0.01;
return Point3d(p.x + dt * dx,
p.y + dt * dy,
p.z + dt * dz);
} // end next_point()

//-------------------------------------

// Screen scaling constants
namespace {
double const screen_x_hi = 255.0;
double const screen_x_lo = -255.0;
double const screen_y_hi = 255.0;
double const screen_y_lo = -255.0;

double const logic_x_hi = 25.0;
double const logic_x_lo = -25.0;
double const logic_z_hi = 60.0;
double const logic_z_lo = 0.0;

double const x_scale = (screen_x_hi - screen_x_lo) /
(logic_x_hi - logic_x_lo);
double const y_scale = (screen_y_hi - screen_y_lo) /
(logic_z_hi - logic_z_lo);
} // close anonymous namespace

//-------------------------------------

// Converts from logical to screen coordinates
point2d scale_to_screen(Point3d const & p) {
return point2d(x_scale * (p.x - logic_x_lo) + screen_x_lo,
y_scale * (p.z - logic_z_lo) + screen_y_lo);
} // end scale_to_screen()

//-------------------------------------

void draw_Lorenz(playpen & graph) {
int const slowdown(2); // Increase this to slow down drawing
hue const colour(blue2 + blue4); // The colour of the plot
int const forever(32700);

Point3d new_point(1.0, 1.0, 1.0);
Point3d old_point;

keyboard kbd;
int count(0);
std::cout << "Press any key to stop drawing.\n";
do {
old_point = new_point;
new_point = next_point(old_point);
drawline(graph,
scale_to_screen(old_point),
scale_to_screen(new_point),
colour);
graph.display();
++count;
Wait(slowdown); // Don't run too fast
} while (count < forever and not kbd.key_pressed());

return;
} // end draw_Lorenz()

© F. Glassborow & R. Allen 2003