The Glass Bead Game - Preliminary Document

Theo Pavlidis (Sept. 5, 2006)


glassgame is a program implementing certain glass bead games in a parody of Herman Hesse's Das Glasperlenspiel. (The title of the English translation is Magister Ludi.) The program starts with a message screen where a glass bead bounces around. When the user hits a key, it switches to a combinatorial game. Right now there is only one game, rearranging colored beads around a circle, but the goal is to add more games in the future.

The main goal of the project is to provide a simple introduction to computer game programming (even simpler than the one provided by the seagame). The program offers in effect a framework for easy development of certain type of games. A zipped executable can be downloaded (latest version Sept. 12, 2006). A zipped version of the MS Visual Studio project with the source code can be requested by e-mail form t.pavlidis AT ieee DOT org.

The games may be combinatorial (as in the original story by Hesse) but with the added twist that some beads may have "free will" and act on their own (that's where animation comes in). This adds a bit of "real world" interference to the pure game.

While the basic architecture of the program (described below) is likely to stay the same, the implementation of the classes will be evolving.

Software Architecture - the ordinary stuff

The program is written as a C++ Microsoft Windows application, based on MFC. There is only window, a ChildView window, that does the display and handles all user input. There is a base game class CGenGame based on MFC's CObject which is abstract and specific games are derived from it. CGenGame has seven pure virtual functions, Paint(), MouseDown(), MouseMove(), etc. that must be implemented by its subclasses. ChildView has a member m_GamePtr of type CGenGame* that is set to the address of the particular game object. Then the various event handlers take a particularly simple form, for example

void CChildView::OnLButtonDown(UINT nFlags, CPoint point)
	m_GamePtr->MouseDown(nFlags, point);

This seems more efficient than the alternative of deriving CGenGame from CWnd and have each game do its own event handling. It also makes easier to port the games to other platforms.

There is a CBead class that is a subclass of CImage. Only the following CImage methods are called:

Create(int width, int height, int depth, CImage::createAlphaChannel)
Draw( HDC hdc, CRect r)
GetPixelAddress(int x, int y)

For porting to other platforms, CImage should be replaced by a class that provides, in effect, the ability to deal with the alpha channel so as to produce the effect shown below. There is no need for the methods that deal with image file I/O.

For porting to platforms that do not support alpha channels or even have a limited set of colors, CImage could be replaced by a simple drawing class that provides the six functions listed. As a matter of fact, for simple displays the implementation of these functions is trivial. To render the beads as discs (in a display that has only 8 bits, for example) all functions, except Draw() are trivial. In such a case the appearance of the above figure will be as shown below:

Software Architecture - Animation or Glass Beads with Free Will

There are two ways to do animation: by using separate threads or by using the idle time between message handling. Threads are generally preferable, but not all platforms support multithreading. Also for some simple forms of animation using idle time is simpler.

There is a CLiveBead class whose main members are a CBead object and a CWinThread object in order to achieve animation. In the current implementation the thread function implementations a bead that is dropped from a height and than bounces around according to the law of gravity. It is probably easier to introduce additional classes of animated beads since the implementation (other than for the thread function) is quite simple. One need supply only Start(), Stop(), and, possibly, Draw() methods. CLiveBead uses a Draw() method to provide the illusion of a rolling bead.

To use idle time one must start with the window application's OnIdle() function. Because we have made the game objects members of ChildView, we need an implementation such as that given below.

BOOL CglassgameApp::OnIdle(long lCount)
	CWnd * v = CWnd::GetFocus();
	if(v != NULL) return (((CChildView *)v)->m_GamePtr)->WhileIdle(lCount);
	else return FALSE;

WhileIdle()does one of two things: (1) If the user has just moved a bead, the other beads move around to make space. This could have been done instantaneously, but there is a better visual effect when the beads roll to the new positions; (2) at other times, it invokes the rand() function, and depending on the returned values it rearranges some beads. In the game where the user must arrange beads around a circle, the current implementation lets a pair of beads to switch positions. Site Map